Repository navigation
Roadmap: photos in Docbank #465
Description
Docbank stores photos as ordinary files and has no photo workflow, so anyone who keeps a photo library still needs Fotobank running beside it. Fotobank embeds Docbank for storage and keeps its own catalog, albums, hidden-media auth, shares, checkouts, and scheduled backups on the side.
This roadmap brings everything Fotobank does today into Docbank, except multiple owners and sharing, so Fotobank can retire. Existing Fotobank libraries don't migrate. Every photo file stays an ordinary Docbank node. Photo state is a small set of tables beside it, searched through Docbank's query, protected by Docbank's revision checks and receipts, and covered by Docbank's backup. It is epic 1 of #407; the later epics (photographer workflow, people, machine help, operations) build on it.
Outcomes
- A photo library lives in a Docbank vault. Importing a folder of RAW, JPEG, sidecar, and video files groups them into photos, extracts camera metadata, and renders previews.
- The web app has a Photos mode beside Documents: a fast grid, a loupe, a map, albums, search with facets, and a trash that keeps a photo's files together.
- Docbank stays single-user: whoever holds the vault key sees every photo. Hidden photos stay out of the Photos views until you unlock them with a passcode; their files still show under Documents. Albums show only how many hidden photos they hold.
- You can check photos out to a folder, edit them in Lightroom or another tool, and commit the edits back as new versions.
- Backups cover all of it. Scheduled backups run on an interval with retention.
Delivery sequence
Four parts, built in order: library (1 to 8), organize and privacy (9 to 13), checkouts (14 and 15), backup and settings (16 to 18).
-
Photo asset and file tables: group RAW, JPEG, and sidecar files into one photo with a display choice, and make ordinary image and video files photos on ingest.
PR: feat(store): group photo files into revisioned assets #564 -
Import: scan a folder, group files by name, wait for them to settle, skip duplicates, and record each group in one transaction.
PR: feat(photos): import camera groups #730 -
Technical metadata: camera, lens, exposure, dimensions, capture time, orientation, GPS, and a location label.
PR: feat(store): index photo technical metadata (#465) #729 -
Previews: grid, fit, and large previews, produced by a background job on Docbank's existing worker machinery so they survive restarts.
PR: feat(store): add recipe-sized photo previews #750 -
Photo search predicates and the browse route: camera, lens, date, location, and the rest, through Docbank's query.
PR: feat(store): browse photo assets with QueryV1 photo predicates #777 -
Photos workspace, grid, and preferences: the Photos mode in the web app with a virtual grid, month chunks, and a year scrubber.
PR: feat(photos): browse a windowed photo library #818 -
Loupe and detail: open a photo, step through the current query, view the original where the browser can show it.
PR: feat(photos): inspect photos in a loupe #845 -
Map: GPS photos clustered on a map for the current query, when a tile provider is configured.
PR: feat(photos): add optional clustered photo map #885 -
Hidden media: hide photos from the Photos views behind a passcode, with lockout after failed attempts. The Hidden view shows them after an unlock.
PR: feat(photos): add passcode-protected hidden photos #846
PR: fix(photos): lock Hidden when you leave #892 -
Albums: hand-picked sets, with revision checks and receipts.
PR: feat(photos): add albums with query-based membership #826 -
Search and facets: ranked text search over photo metadata and counts per camera, lens, year, location, and album.
PR: feat(photos): search and filter the photo library #847 -
Albums view: list albums, open one to scope the grid, add photos by action, drag, or key.
PR: feat(photos): browse and organize albums #844 -
Trash: deleting a photo moves all its files to trash together and restores them together.
PR: feat(photos): move photo groups to recoverable trash #841 -
Checkout creation and inspection: write verified copies of an album, a selection, or a year range to a folder.
PR: feat(photos): create verified photo checkouts #903 -
Checkout commit and retirement: commit edited working files back as new versions bound to the checkout base.
PR: feat(checkout): commit edited photo copies as new versions #967 -
Backup coverage and restore: every owner decision and photo file round-trips through Docbank's backup, with restored checkouts unbound.
PR: feat(backup): expose photo recovery coverage #977 -
Scheduled backups and retention: capture on an interval, keep the last N, warn when the newest point is stale.
PR: feat(backup): schedule backups with retention and vault ownership #1010 -
Settings overrides: change the backup schedule and hidden unlock lifetime at runtime without editing config.
PR: feat(settings): change backup schedule and hidden unlock lifetime at runtime #1019
Design constraints
- Every photo file is an ordinary node with a content version. Tags, search, trash, previews, and backup reach photos the way they reach documents.
- Human decisions are current values with a revision and an immutable receipt, Docbank's tag pattern. Receipts are records, not a ledger that restore replays.
- Albums are the one new grouping table. Smart sets are saved queries. Keywords are tags.
- Backup covers owner decisions and content, and a table that holds them ships its backup export and import in the same PR. Run records, queues, caches, and projections that rebuild from backed-up data stay out of backup unless a step names them.
- Background work runs on Docbank's existing storage operations and supervisor jobs. A step adds a new worker or run table only when it names what those lack.
- Each step names the existing mechanism it checked before adding a table or surface. CLI, HTTP, and MCP each need their own reason, and MCP tools default to reads.
- Restored state stays inactive until an operator acts.
- Files cataloged in place without copying are deferred. When they arrive they will be nodes with a referenced version kind, so nothing here changes for them.
Adjacent
- Bring Fotobank and Teststrip's photo workflows into Docbank #407 is the origin. Its tracking comment lists the five epics and links each design.
- The later epics have their own roadmaps: photographer workflow at Roadmap: photographer workflow #838, people at Roadmap: people in photos #612, machine help at Roadmap: machine help for photos #839, and operations at Roadmap: photo job controls and live updates #840.
- Deferred past all five epics: files cataloged in place, the Teststrip catalog importer, contact seeding, and export presets.
Activity
fix(cli): let photo inspect find trashed files by stable id (#465)
feat(migration): inventory Fotobank installs (kenn-io#465)
feat(migration): match Fotobank inventory to source schemas (kenn-io#465
fix(cli): let photo inspect find trashed files by stable id (#465)
feat(migration): inventory Fotobank installs (#465)
feat(migration): match Fotobank inventory to source schemas (#465)
feat(migration): inventory Fotobank installs (#465)
feat(migration): match Fotobank inventory to source schemas (#465)
feat(store): group photo files into revisioned assets (#564)
feat(migration): inventory Fotobank installs (#465)
feat(migration): match Fotobank inventory to source schemas (#465)
feat(migration): inventory Fotobank installs (#465)
feat(migration): match Fotobank inventory to source schemas (#465)
fix(geo): preserve embedded map bytes on Windows (kenn-io#465)
docs(review): clarify photo GPS projection scope (kenn-io#465)
130 remaining items
feat(store): browse photo assets with QueryV1 photo predicates (#777)
feat(photos): browse a windowed photo library (#818)
fix(photos): document album query removal and test album guards
feat(photos): add albums with query-based membership (#826)
feat(photos): move photo groups to recoverable trash (#841)
feat(photos): inspect photos in a loupe (#845)
feat(photos): add passcode-protected hidden photos (#846)
feat(photos): browse and organize albums (#844)
feat(photos): search and filter the photo library (#847)
feat(photos): add optional clustered photo map (#885)
fix(photos): lock Hidden when you leave (#892)
feat(photos): create verified photo checkouts (#903)
feat(checkout): commit edited photo copies as new versions (#967)
feat(backup): expose photo recovery coverage (#977)