feat(app): card types, whose fields merge separately

A card has a type: front/back, multiple choice (drawn on a map when it
names one), vocabulary or matching, and the fields of that type. The card
payload's schema 2 holds the type and the fields in use; schema 1 reads
as front/back. Revisions merge per field rather than per side (ADR 0003,
amended): a field one device changed takes the change, a field changed
differently is a conflict, lists included as a whole.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-01 18:17:00 +02:00
commit 927017bf15
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -33,6 +33,13 @@ conflict: "big" changed to "large" on one device and to "huge" on another become
version until the person keeps one. Merging happens when reading; nothing is written
until the person saves. The code is
`halkyon_learn_flutter/lib/src/feature/card/model/card_merge.dart`.
**Amended 2026-10-01, card types:** a card now has a type (front/back, multiple
choice, vocabulary, matching) and the fields of that type, and the merge runs per
field instead of per side: the type itself, the front, the back, the answers, the
reading, the meanings, the matching, the map. A list (the answers, the meanings)
merges as one field: two devices changing it differently are a conflict, as two
versions of one side were. Finer merging, per answer, would need a stable id per
answer; it can come when shared spaces make concurrent edits of one card common.
3. **An explicit position.** `Card.position` is a fractional index (rocicorp's
algorithm, through `fractional_indexing_dart`, checked against the algorithm's
reference test vectors) in a column of its own, where the last writer wins. Two devices