Commit Graph
355 Commits
Author SHA1 Message Date
REDCODE 445b030160 feat(cosplayer-detail): add SortFilterBar for album search and sort
- Backend: accept PagedSearchParametersDto on GET /api/person/{id}
  with in-memory search (case-insensitive title Contains) and sort
  (name/created/updated/assets) before pagination
- Frontend service: add search, sortBy, sortAsc params to GetByIdAsync
- Frontend page: replace inline action buttons with reusable SortFilterBar
  component, wire search/sort state into initial load and infinite scroll
2026-07-12 20:11:06 +02:00
REDCODE 4cffc9b424 feat(api): paginate PersonController.GetAll with sort/search params
Accept PersonSearchParametersDto, forward sort/search/pagination to repository.
Returns paginated results instead of loading all people into memory.
2026-07-11 16:56:54 +02:00
REDCODE 4ea0afe9f6 feat(api): add SearchQuery to PersonRepository with sort/search/pagination
SQL-level search by name, sorting (name, created, albums), and pagination.
Access-level filtering for regular users pushed to SQL via subquery.
Replaces the in-memory GetAllVisible pattern.
2026-07-11 16:56:54 +02:00
REDCODE 334451238b feat(api): pass sort and filter params through AlbumController.Search
Forward SortBy, SortAsc, and Unassigned from AlbumSearchParametersDto to repository.
Remove in-memory unassigned filter (now handled in SQL).
2026-07-11 13:11:12 +02:00
REDCODE 48ebbebee1 feat(api): add sorting and unassigned filter to AlbumRepository.SearchQuery
Extend SearchQuery with sortBy, sortAsc, and unassigned parameters.
Sorting applied via switch expression: name, created, updated, assets, person.
Unassigned filter pushed to SQL instead of in-memory.
2026-07-11 13:11:07 +02:00
REDCODE 31d917c56e fix: remove soft-delete from Person model
Person had a DeletedAt property and all queries filtered by it, but the
controller was hard-deleting via context.People.Remove(). This removes
the DeletedAt property, drops the column via migration, and cleans up
all stale DeletedAt filters in queries.
2026-07-10 18:49:59 +02:00
REDCODE 89c91b2291 refactor: replace tuple + custom header with ChildrenResponse DTO
- Add ChildrenResponse DTO (Children + Since) in Butter.Dtos.Jobs
- JobManager.GetChildren returns List<JobStatusDto> only (no tuple),
  active children filtered via LINQ over activeJobs.Values
- JobsController generates Since timestamp, returns ChildrenResponse
  instead of setting x-delta-timestamp header
- JobsService deserializes ChildrenResponse instead of parsing headers
2026-07-10 17:40:28 +02:00
REDCODE 4a6bc2f8aa Merge branch 'develop' into fix/preview-subjob-status-reporting 2026-07-10 17:37:34 +02:00
REDCODE ac5b75c0d6 fix: suppress nullable warnings on Include chain in GetAllVisible 2026-07-10 17:36:52 +02:00
REDCODE 7e1a2a7ed6 Merge branch 'develop' into fix/preview-subjob-status-reporting 2026-07-10 15:36:11 +00:00
REDCODE e98aa6167e fix: translate GetAllVisible to client-side eval for SharedWith navigation
EF Core cannot translate three-level nested Any through many-to-many
navigation (Person→Albums→Assets→SharedWith). Load data with Include
chain and filter visible persons in-memory instead.
2026-07-10 17:28:13 +02:00
REDCODE 17ddd1c332 feat: hide cosplayers with no visible content from regular users
- IPersonRepository.GetAllVisible filters persons by asset visibility
- For User level: only returns persons that have at least one album
  with a non-deleted asset that is publicly shared, owned by the user,
  or explicitly shared with the user
- For Admin/Curator: returns all persons (unchanged behavior)
- PersonController.GetAll extracts user data and uses GetAllVisible
2026-07-10 17:21:47 +02:00
REDCODE 0203644b3e feat: implement delta-based children endpoint with ?since parameter
- JobManager.GetChildren now accepts optional 'since' parameter
- Returns only children with LastChange/ModifiedAt > since
- Includes seenIds dedup between active and past children
- Returns response timestamp for next poll
- Controller sets x-delta-timestamp header
2026-07-10 12:49:43 +02:00
REDCODE dd43d069d5 feat: add ModifiedAt to JobRecord with delta query support
- Add ModifiedAt (DateTime?) to JobRecord
- Auto-set on Insert/Update in repository
- Add GetChildrenModifiedSince to interface + implementation
- EF Core migration AddModifiedAtToJobRecord
2026-07-10 12:49:40 +02:00
REDCODE 7dc5eff14b feat: add LastChange tracking to JobStatus
Set LastChange = UtcNow on every status/progress transition
for delta-based children sync.
2026-07-10 12:49:36 +02:00
REDCODE 5514bf89d9 fix: remove double-count of failed assets in master Done handler
The Interlocked.Increment(ref failedAssets) for Failed subjobs
caused double-counting: a subjob with N/12 failed assets would
add 1 (failed subjob) + 12 (individual assets) = 13, exceeding
the total asset count. Removed the Increment since subjob's
failedAssets is already the accurate per-asset count.
2026-07-10 12:17:50 +02:00
REDCODE 8ad378b649 fix: batch-processing subjobs report correct status on asset failures
Subjobs (SlaveJob) now check failedAssets after processing:
- All failed -> JobStatus.Fail()
- Some failed -> JobStatus.CompleteWithErrors()
- None failed -> JobStatus.Complete()

Also fixed race condition in master Done handler:
- Replaced non-atomic failedAssets += sub.failedAssets
- with Interlocked.Add(ref failedAssets, sub.failedAssets)

Affects: PreviewJob, ThumbnailJob, MetadataJob, PHashJob

Refs #76
2026-07-10 12:05:45 +02:00
REDCODE 3bddd4385d feat: add server-side password policy validation (admin bypass) 2026-07-10 10:22:36 +02:00
REDCODE 15b3fcedf1 feat: enforce old-password verification on own password change, allow admin override 2026-07-10 10:15:03 +02:00
REDCODE 652143d738 feat: allow users to update own albums and curators to update any album
- Users: changed from blanket Forbid to ownership check (can update own albums)
- Curators: changed from ownership check to full access (can update any album)
2026-07-09 23:46:02 +02:00
REDCODE 2f7cd3d7da fix: resolve UI issues #61, #62, #66
- #61: wrap standalone fallback div in cosplayer-card-img-wrap on
  Cosplayers page so placeholder icon gets proper sizing/positioning
- #62: add mobile breakpoint rule for modal-overlay so edit form
  appears centered on small screens instead of at page bottom
- #66: make cosplayer name in ImagePreview, AlbumDetail, AlbumCard,
  and Home asset tiles a clickable link to /cosplayer/{id}
- add CosplayerIds to AssetPreviewDto and populate via mapper for
  linked navigation from the home page image previewer
2026-07-09 22:36:07 +02:00
MrFastwind ede759b50b feat: migrate to UTC timestamps — remove legacy Npgsql timestamp behavior
- Remove EnableLegacyTimestampBehavior switch from Program.cs
- Add ConfigureConventions to DbContext pinning DateTime → timestamptz
- Add migration to convert all 17 DateTime columns across 5 tables
  (Albums, Assets, Users, People, JobRecords) with safe AT TIME ZONE 'UTC'
- Add Roslyn analyzer (MS001-MS004) enforcing UTC-only DateTime at compile time
  with code fix provider for auto-replacement
- Fix pre-existing DateTime.Now in AuthController.cs:119
- Add AllowMissingPrunePackageData to work around .NET 10 SDK issue
2026-07-09 21:43:46 +02:00
REDCODE c1aafc4223 refactor: replace individual albumPage/albumSize params with PagedParametersDto in person detail endpoint 2026-07-09 17:42:37 +02:00
REDCODE a8d06959b5 feat: person hard delete with album cascade, AlbumCard select mode, cosplayer list multi-select 2026-07-09 17:07:43 +02:00
REDCODE dbbb25da32 fix: create AlbumSearchParametersDto, add album pagination to person detail, fix duplicate XML param 2026-07-09 16:46:18 +02:00
REDCODE 9f180742cd fix(test): update name assertion to match renamed person 2026-07-09 16:40:32 +02:00
REDCODE e8c1a80264 test: all tests create their own data — create album returns ID, all mutations use self-created resources 2026-07-09 16:38:43 +02:00
REDCODE 7e16c77cb6 test: use real album from search for update test, not zero-GUID fallback 2026-07-09 16:36:01 +02:00
REDCODE 8f6a4396db test: add album update test without removePerson field 2026-07-09 16:34:47 +02:00
REDCODE 34fbbc91a0 chore(test): remove Swagger test — disabled in container environments 2026-07-09 16:32:47 +02:00
REDCODE 9be49ac9c6 fix(test): use response.body directly instead of JSON.parse (already parsed object) 2026-07-09 16:32:00 +02:00
REDCODE c96b22fe62 fix(tests): fix pre-existing auth route tests and handle empty unassigned albums gracefully 2026-07-09 16:30:53 +02:00
REDCODE 7f50d3c3e2 test(api): add comprehensive http tests for all person and album endpoints 2026-07-09 16:26:11 +02:00
REDCODE 191cba4946 fix(pr): implement BulkUpdate, BulkDelete, revert docker-compose, explain [FromQuery] 2026-07-09 16:22:51 +02:00
REDCODE a38f627ca4 feat(dto): add RemovePerson flag to AlbumUpdateDto for explicit person unlinking 2026-07-09 15:56:20 +02:00
REDCODE f31b753182 refactor(dto): move Unassigned filter into PagedSearchParametersDto 2026-07-09 15:54:02 +02:00
REDCODE 1377d02520 fix: prevent album title from being overwritten when only setting Person in update DTO 2026-07-09 15:19:03 +02:00
REDCODE fa434b180d fix(api): allow unlinking person from album by directly assigning null PersonOwnerId 2026-07-09 15:12:34 +02:00
REDCODE e1d7822b7c refactor(api): fold unassigned album filter into search endpoint via query param 2026-07-09 15:09:09 +02:00
REDCODE cc611828b9 feat(ui): unassigned album selector in PersonForm, Add Albums button in CosplayerDetail 2026-07-09 15:07:19 +02:00
REDCODE 9aead51481 feat(ui): add New Cosplayer button on list page with create endpoint and form 2026-07-09 15:00:52 +02:00
REDCODE 22b15c387b feat(ui): redesigned profile cropper with movable circle, dimmed exterior, square boundary, zoom controls; added ProfileCropZoom to model; switched avatars to background-image for zoom support 2026-07-09 13:15:19 +02:00
REDCODE d3ef5ff4c1 feat(backend): add ProfileCropX/Y to Person model for profile picture cropping 2026-07-09 13:01:01 +02:00
REDCODE 2dc0153b10 fix(backend): add [FromQuery] to person list endpoint to fix 415 error 2026-07-09 12:16:24 +02:00
REDCODE 7143af14f0 feat(client): add Cosplayers and CosplayerDetail pages, fix NavMenu, add modularity docs 2026-07-09 12:13:12 +02:00
REDCODE 20fd6a930b test(api): add person endpoint tests to WepApiTest.http 2026-07-09 12:09:40 +02:00
REDCODE 8f0af8d544 feat(backend): implement person detail, update, and delete endpoints 2026-07-09 12:03:33 +02:00
REDCODE 16161ebfb8 feat(backend): add PersonMapper with ToPersonPreviewDto and ToPersonDetailedDto 2026-07-09 12:02:36 +02:00
REDCODE ca224feafb feat(backend): eager-load ProfileAsset and Albums in PersonRepository 2026-07-09 12:01:46 +02:00
REDCODE 9c785423a9 feat(backend): add ProfileAssetId to Person model + migration 2026-07-09 12:00:56 +02:00