Commit Graph
2 Commits
Author SHA1 Message Date
dtourolle d5b1f6bff5 Add collections, ratings, and soft delete to the catalog
Three features over a shared schema migration.

Collections: a tree of manual collections plus smart collections whose
membership *is* their stored selector. Dropping images onto a smart
collection is refused rather than silently discarded, so the UI can say why
the drop did nothing — member rows there would be a second source of truth
that nothing reads.

Ratings: the star and pick/reject axes, kept independent.

Trash: soft delete to a folder, then permanent delete.

Catalog::open now backfills after migrating. A migration adds a column but
cannot know what the value should be for rows that already existed;
backfilling on open is what stops those rows being silently partial.

Timeline queries exclude shadowed JPEGs, which would otherwise double every
paired shot in the histogram, and gain a range-bounded variant so zooming in
returns finer buckets rather than the same coarse ones with the ends cropped.

Assisted-by: LLM
2026-08-09 20:42:13 +02:00
dtourolle c8bb08e661 Add folder scan with format selection; validate A3 on a real library
Library setup as the user described it: pick a folder, choose which RAW
types to look for, scan recursively.

  dr-types::FormatFilter  the tick-box selection, seeing through VFS
                          placeholder suffixes so a dehydrated CR2 still
                          matches as a CR2
  dr-sync::scan           recursive walk, Depth:1 per directory, pruning
                          unchanged subtrees where the backend propagates
                          directory ETags

Verified against nextcloud.tourolle.paris (34.0.2) on a real library:

  browse root      32 entries, 98ms
  scan PhotosRaw   17,185 RAW files in 334 directories, 34.1s
                   (7,836 CR2 + 9,349 DNG)
  range read       262KB of a 21.5MB DNG in 119ms — 1.22% of the file,
                   and enough to read "Canon EOS 6D | ISO 100"

That last line is assumption A3 validated on real data. Cataloguing this
library by whole-file fetch would move roughly 370GB; the range path
moves a few MB.

Pruning is capability-gated rather than assumed: with per-entry ETags a
probe costs a request and proves nothing about children, so it is skipped
entirely. A test asserts zero probes in that case.

Still unresolved: /core/preview returns 400 for every parameter
combination tried, including on a JPEG the server reports as having a
preview. Not a request-shape bug — it fails identically bare. Recorded
rather than worked around; ARCH §6.7 already treats server previews as
opportunistic, so nothing depends on it.
2026-08-09 12:22:31 +02:00