| 1 | --- |
| 2 | name: event-contract-cross-platform |
| 3 | description: Web (chat.js) and native apps (iOS/Mac) validated against shared event vectors for chat/todo/remind events |
| 4 | metadata: |
| 5 | type: project |
| 6 | --- |
| 7 | |
| 8 | ## Cross-platform event contract |
| 9 | |
| 10 | **Problem:** chat.js, todo.js, remind.js (web) and native implementations must stay in sync. Without a spec, fold handlers can drift. |
| 11 | |
| 12 | **Solution:** Shared event vectors in `test/event-vectors/` (organized by app) + tests on both sides catch drift on PR. |
| 13 | |
| 14 | **Structure:** |
| 15 | - `test/event-vectors/chat.json` — message/reaction/edit/delete vectors (web: source of truth) |
| 16 | - `test/event-vectors/todo.json` — to-do fold logic vectors (web: source of truth) |
| 17 | - `test/event-vectors/remind.json` — remind fold logic vectors (web: source of truth) |
| 18 | - `test/event-vectors/groupapps.json` — group-apps registry vectors: which trusted apps a group chat has added (web source of truth: the `groupapps` app in `web/static/apps.js`) |
| 19 | - `test/event-vectors/index.js` — loader for tests |
| 20 | |
| 21 | **Maintenance:** |
| 22 | 1. **Changing a web app's fold handlers** → update the app's vector file + run `npm test` |
| 23 | 2. **Changing a native structure** (MessagePayload, etc.) → update native tests + run iOS tests |
| 24 | 3. **Adding a feature** → add vector entry + test case to both sides |
| 25 | |
| 26 | **Key invariants:** |
| 27 | - Todo: `done` items with `doneAt > (now - 750ms)` stay active; older → archived |
| 28 | - Remind: items always sorted by `when` (soonest first); fired with `firedAt > (now - 750ms)` stay active |
| 29 | - Both: grace period derived in render, never mutated by a timer |
| 30 | - Both: duplicate adds are deduped; unicode text preserved |
| 31 | |
| 32 | **Why this matters:** Different rendering on different clients destroys trust. These tests prevent silent mismatches. |
| 33 | |
| 34 | **Vectors are the spec.** If tests fail, code diverged—fix the implementations, not the vectors. |
| 35 | |