videoskilletdecisions Open the app ↗

0010 — The account holds the session, not just the library

Status: accepted, 2026-09-14; the single session is superseded by 0012.

Context#

0005 put saved profiles in Firestore and drew a line around them: an account buys the library and nothing else, and no other feature moved behind it. That line held while signing in was something you did once, inside the app, to get a save box.

Signing in is now the landing page's main offer, and a signed-in visitor lands on a home page at / instead of the marketing page. A home page has to have something on it. The two things a returning visitor wants are the setup they were last running and a way to tell their saved looks apart, and neither survives the trip: the last session lives in the URL of a tab that is gone, and the library is a list of names with no picture beside them.

So the account carries two more things. The session last open, as the same packed query a profile holds plus a clock; and one still per saved profile, a small webp of the picture as it was when the profile was saved.

Decision#

The user document holds the session, and a subcollection holds the stills.

users/{uid} gains an optional current, either {query, at} or null, merged into the same document the profile list lives in. It is one more field on a document the app already reads on load, so the home page's "Continue where you left off" card costs no extra read.

Stills go to users/{uid}/stills/{id}, keyed by the profile's id, holding {webp, at}. They are not fields on the user document for two reasons a document cannot get around. A Firestore document is capped at 1 MiB, and the profile list is capped at 200 entries — two hundred stills of a few KB each passes the ceiling. And a still is written when one profile is saved, while the list is written whenever any of them changes; separate documents mean the two writes do not collide.

Both new fields are optional, and so is profiles. Two writers merge into the user document from paths of their own: the session autosave can land before the first profile is ever saved, and a profile save must leave current as it found it. A rule that required either key would refuse one of those writes.

Per-device state stays local. The rundown, the clip library, the pinned sliders, the 1–9 scenes and the drift switches stay in localStorage. They describe how one machine is set up — which clips are on its disk, which sliders its operator keeps to hand — and syncing them would mean reconciling two machines' hardware. The account carries what is portable: the look, and the picture of the look.

Consequences#