- 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
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.
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.
- 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
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.
- 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
- 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
- Add ModifiedAt (DateTime?) to JobRecord
- Auto-set on Insert/Update in repository
- Add GetChildrenModifiedSince to interface + implementation
- EF Core migration AddModifiedAtToJobRecord
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.
- Users: changed from blanket Forbid to ownership check (can update own albums)
- Curators: changed from ownership check to full access (can update any album)
- #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
- 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