feat(versions): link at ingest, hide in listings, version endpoints

XMP (PNG iTXt DerivedFrom, native chunk reader) then file-name convention
links at ingest; unlinked name candidates are retried each tick. Versions
are hidden from /photos (SQL for the recursive listing, hidden-row set for
the walk and tag branches), /memories, reels, /photos/exif, the GPS summary,
unified search and the media gauges while their original is reachable in the
view; include_versions=true lists them. /photos gains the parallel arrays
photo_display_paths / photo_version_counts, memories / search hits /
/photos/exif rows gain display_path / version_count, all skipped when empty.
GET /image/versions and PUT /image/versions/display (library optional).
Tags and favorites on a version path bind to the original; faces, CLIP and
duplicate grouping skip version hashes; insight generation redirects to the
original. Orphan GC and the back-ref refresh cover the new tables.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Cameron CordesandClaude Opus 5.5 committed 2026-10-30 11:28:34 -04:00
1 parent 044240037a
commit 080a75c336
24 files changed
+1614 -47

No files matched your search

+4
View File
@@ -433,6 +433,7 @@ mod tests {
camera_offset_minutes: None,
date_taken_tz_source: None,
wall_clock: None,
versions: Default::default(),
},
memories::MemoryItem {
path: "b".into(),
@@ -443,6 +444,7 @@ mod tests {
camera_offset_minutes: None,
date_taken_tz_source: None,
wall_clock: None,
versions: Default::default(),
},
memories::MemoryItem {
path: "c".into(),
@@ -453,6 +455,7 @@ mod tests {
camera_offset_minutes: None,
date_taken_tz_source: None,
wall_clock: None,
versions: Default::default(),
},
];
assert_eq!(
@@ -472,6 +475,7 @@ mod tests {
camera_offset_minutes: None,
date_taken_tz_source: None,
wall_clock: None,
versions: Default::default(),
}
}
fn item_at(ts: i64, name: &str) -> memories::MemoryItem {