xy: test sessions become a board entity, and labels compose onto them #42
Loading…
Reference in a new issue
No description provided.
Delete branch "labels-test-sessions"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
Five open issues about labels were one issue about a string: a test label's only tie to its session was the name baked into it at creation, so it could not be renamed (#25), was too long (#8), carried a timestamp nobody could re-render in another zone (#7, #33), and said взяли/не взяли when the user wanted «видели» (#12).
A Test Session is now a board-level entity rather than a card in a special list, which closes #2 on the way past. A card carries Playings (it was played at that test), and a label ASSIGNMENT carries an optional session — so «взяли» is one ordinary board label composed onto a playing instead of one label per sitting.
See
xy/docs/labels-redesign.md, ADR-0003 and ADR-0004.🤖 Posted by Claude
# Why Reported from xytest. - The town autocomplete only worked on Enter: its popup is absolutely positioned, and the parent was marked as the positioning context at BIND time, when a field wired before being appended still has no parent. Marked at append time instead, so all three autocompletes (testers, towns, timezones) anchor to their own row. - City chips wore .label-pick, which paints grey-on-white — unreadable for both the name and its UTC offset. They get their own surface+border chip. - A section heading belongs to what is under it: «Лента» sat nearer the delete button above than its own feed. - On a board card a test's verdicts are DOTS rather than pills (a card can carry several tests, and pills ate the row), and the author's own pills are shorter and taller so they line up with the 🧪 instead of sitting as thin bars. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com># Why Both reported from xytest. - The suggestion popup had position:absolute with no offsets, so it stayed at its STATIC position — inline after the input, off to the right of the row. Pinned to the anchor's bottom-left, which is what makes it read as a dropdown rather than a detached panel. - The 🧪 glyph overflows a line-height of 1, so it sat on the group's bottom border. It now centres in a box tall enough to hold it (2px clear either side), and the group's padding is even. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com># Why card_labels shipped as a flat list of rows while card_sessions stayed a map of card id to session ids, so two things that mirror two identical tables were read two different ways — and the map was keyed by string but indexed with numbers everywhere. That mismatch is what let `delete state.cardLabels[c.id]` survive the conversion and delete by array index. Both are rows now, server to mirror to client: {card_id, session_id} beside {card_id, label_id, session_id}. The offline mirror folds the old map shape forward, since a device that synced before this holds one. Verified in a browser that a playing survives remove, re-add and reload, and that its scoped labels still cascade when it goes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>