### One version of a card's content, never changed once written (ADR 0001, ### rule 2): editing appends a revision whose parents are the versions it ### replaces, and a card's current versions are the revisions no other ### replaces. Deleting a card blanks every revision's payload first (ADR 0002, ### rule 2). class: CardRevision table: card_revision database: sync fields: ### The card this is a version of; its revisions go with it. card: Card?, relation(onDelete=Cascade, deferred) ### The revisions this one replaces: none for a card's first, several when it ### resolves a conflict (decided 2026-09-30). Plain ids, since revisions can ### arrive in any order. parents: List ### Who wrote it: the AuthUser's id (a synced table can't relate to the ### server-only AuthUser). authorId: UuidValue ### The report this revision answers, once reports exist; null otherwise. reportId: UuidValue? ### The encryption key's id; always null (ADR 0002, rule 6). keyId: String? ### The content as UTF-8 JSON: {"schemaVersion", "front", "back"}. payload: ByteData ### The encryption nonce; always null, like keyId. nonce: ByteData? indexes: # Deleting a space finds its rows through this index (see studyset.spy.yaml). card_revision_space_idx: fields: spaceId # A card's revisions. card_revision_card_idx: fields: cardId