eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1{
2 "description": "Reminders app event vectors: ensures remind fold handlers produce consistent state. Source of truth: web/static/apps/remind.js",
3 "app": "remind",
4 "source": "web/static/apps/remind.js",
5 "state_shape": { "items": [{ "id": "string", "text": "string", "when": "number (epoch ms, due time)", "ts": "number (epoch ms, add time)", "sid": "string (server schedule id, empty if offline)", "fired": "boolean", "firedAt": "number (epoch ms)" }] },
6 "vectors": [
7 {
8 "name": "remind_add",
9 "description": "Add a reminder with a future due time (sid = server schedule id, empty if offline).",
10 "event": {
11 "type": "remind.add",
12 "id": "remind-1",
13 "text": "call plumber",
14 "when": 1700003600000,
15 "ts": 1700000000000,
16 "sid": "sch-abc123"
17 },
18 "expected_state_update": {
19 "items": [
20 {
21 "id": "remind-1",
22 "text": "call plumber",
23 "when": 1700003600000,
24 "ts": 1700000000000,
25 "sid": "sch-abc123",
26 "fired": false,
27 "firedAt": 0
28 }
29 ]
30 },
31 "note": "Items are sorted by `when` (soonest first). `sid` is the server's scheduled-message id; empty string if scheduling failed (client falls back to best-effort firing). `when` is absolute epoch ms. No chat projection (reminders are silent in chat)."
32 },
33 {
34 "name": "remind_fire",
35 "description": "A scheduled reminder fires (delivered at the due time, either by server schedule or client best-effort).",
36 "event": {
37 "type": "remind.fire",
38 "id": "remind-1",
39 "notice": {
40 "title": "⏰ Reminder",
41 "body": "call plumber"
42 },
43 "ts": 1700003600000
44 },
45 "initial_state": {
46 "items": [
47 {
48 "id": "remind-1",
49 "text": "call plumber",
50 "when": 1700003600000,
51 "ts": 1700000000000,
52 "sid": "sch-abc123",
53 "fired": false,
54 "firedAt": 0
55 }
56 ]
57 },
58 "expected_state_update": {
59 "items": [
60 {
61 "id": "remind-1",
62 "text": "call plumber",
63 "when": 1700003600000,
64 "ts": 1700000000000,
65 "sid": "sch-abc123",
66 "fired": true,
67 "firedAt": 1700003600000
68 }
69 ]
70 },
71 "expected_chat_projection": {
72 "text": "⏰ Reminder: call plumber",
73 "action": false
74 },
75 "note": "`notice` has the title + body shown by push/toast (the text the user sees on alert). `firedAt` is the server delivery time (for grace-period animation, same 750ms linger-then-tuck as todo). When this event lands in the chat thread, it's surfaced as a message (not an action line) with the title+body from the notice."
76 },
77 {
78 "name": "remind_done",
79 "description": "Dismiss a reminder (removes it from the list; if unfired, also cancels the server schedule via the sid).",
80 "event": {
81 "type": "remind.done",
82 "id": "remind-1"
83 },
84 "initial_state": {
85 "items": [
86 {
87 "id": "remind-1",
88 "text": "call plumber",
89 "when": 1700003600000,
90 "ts": 1700000000000,
91 "sid": "sch-abc123",
92 "fired": false,
93 "firedAt": 0
94 }
95 ]
96 },
97 "expected_state_update": {
98 "items": []
99 },
100 "note": "If `fired=false` and `sid` is set, the client sends an unschedule request to cancel the server's scheduled remind.fire. If the cancel races the delivery, the late remind.fire folds onto a missing id (a no-op)."
101 },
102 {
103 "name": "remind_grace_period_partition",
104 "description": "Grace period: active (unfired or recently fired within 750ms) vs. archived (fired + >750ms ago).",
105 "note": "Like todo, this is derived in render from Date.now() and firedAt, never by a timer. Native should partition: unfired items + recently-fired (firedAt > now - 750ms) stay visible; older fired reminders move to 'Previous reminders' section.",
106 "constants": {
107 "REMIND_GRACE_MS": 750
108 }
109 },
110 {
111 "name": "remind_multiple_sorted",
112 "description": "Multiple reminders are kept sorted by `when` (soonest first), regardless of add order.",
113 "event_sequence": [
114 {
115 "type": "remind.add",
116 "id": "remind-1",
117 "text": "late one",
118 "when": 1700010000000,
119 "ts": 1700000000000,
120 "sid": "sch-abc123"
121 },
122 {
123 "type": "remind.add",
124 "id": "remind-2",
125 "text": "early one",
126 "when": 1700003600000,
127 "ts": 1700000100000,
128 "sid": "sch-def456"
129 }
130 ],
131 "expected_final_state": {
132 "items": [
133 {
134 "id": "remind-2",
135 "text": "early one",
136 "when": 1700003600000,
137 "ts": 1700000100000,
138 "sid": "sch-def456",
139 "fired": false,
140 "firedAt": 0
141 },
142 {
143 "id": "remind-1",
144 "text": "late one",
145 "when": 1700010000000,
146 "ts": 1700000000000,
147 "sid": "sch-abc123",
148 "fired": false,
149 "firedAt": 0
150 }
151 ]
152 },
153 "note": "The list is re-sorted on every remind.add, so the order is always soonest-first regardless of user input order."
154 }
155 ]
156}
157