Quick Cards Cloud Save

Syncs the CardMirror Quick Cards reusable-snippet library to a signed-in user's account, closing the same account-linking gap flows, rounds, word-count history, judge decisions, Reason Editor documents, and the Speech Documents send log already closed — the library was device-local (IndexedDB) only.

  • Package: debate-editor (quickCardsStore, validator), apps/debate-ai.com (/api/quick-cards, saved_quick_cards D1 table)

What it does

On boot, quickCardsStore.init() merges once against the account: any card synced from another device but missing from this browser's IndexedDB library is adopted, and any card that exists only here (saved offline, or before this feature shipped) is best-effort pushed up — neither side ever overwrites the other, it only fills gaps. Every later add, edit, or bulk import mirrors itself to the account per-record; a single-card delete mirrors as one DELETE /api/quick-cards/[cardId] call, and a full-library "clear" mirrors as one DELETE /api/quick-cards bulk call instead of one request per card. Signed out, the library keeps working exactly as before, purely on-device.

Every per-record push carries optimistic concurrency: PUT /api/quick-cards/[cardId] compares the incoming card's own updatedAt against whatever's already saved for that id, and rejects (409) instead of overwriting when the saved version is newer — an edit made on another device that hasn't reached this browser yet. On that rejection, this browser adopts the newer version into its own local library instead of losing it, the same "never overwrite, only reconcile" rule init()'s merge already follows.

Known gaps

None open.