@laitszkin/apollo-toolkit 3.10.0 → 3.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/analyse-app-logs/scripts/__pycache__/filter_logs_by_time.cpython-312.pyc +0 -0
- package/analyse-app-logs/scripts/__pycache__/log_cli_utils.cpython-312.pyc +0 -0
- package/analyse-app-logs/scripts/__pycache__/search_logs.cpython-312.pyc +0 -0
- package/docs-to-voice/scripts/__pycache__/docs_to_voice.cpython-312.pyc +0 -0
- package/generate-spec/SKILL.md +17 -15
- package/generate-spec/agents/openai.yaml +1 -1
- package/generate-spec/references/TEMPLATE_SPEC.md +103 -84
- package/generate-spec/scripts/__pycache__/create-specscpython-312.pyc +0 -0
- package/init-project-html/SKILL.md +117 -125
- package/init-project-html/agents/openai.yaml +18 -9
- package/init-project-html/lib/atlas/assets/architecture.css +161 -0
- package/init-project-html/lib/atlas/assets/viewer.client.js +136 -0
- package/init-project-html/lib/atlas/cli.js +1023 -0
- package/init-project-html/lib/atlas/layout.js +330 -0
- package/init-project-html/lib/atlas/render.js +583 -0
- package/init-project-html/lib/atlas/schema.js +347 -0
- package/init-project-html/lib/atlas/state.js +402 -0
- package/init-project-html/references/TEMPLATE_SPEC.md +140 -83
- package/init-project-html/sample-demo/resources/project-architecture/assets/architecture.css +160 -1058
- package/init-project-html/sample-demo/resources/project-architecture/assets/viewer.client.js +136 -0
- package/init-project-html/sample-demo/resources/project-architecture/atlas/atlas.index.yaml +34 -0
- package/init-project-html/sample-demo/resources/project-architecture/atlas/features/get-invite-codes.yaml +172 -0
- package/init-project-html/sample-demo/resources/project-architecture/atlas/features/invite-code-registration.yaml +160 -0
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/index.html +67 -52
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/invite-code-generator.html +64 -163
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/invite-issuance-service.html +102 -196
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/postgresql.html +82 -163
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/public-api.html +88 -150
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/web-get-invite-ui.html +83 -138
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/index.html +61 -51
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/postgresql.html +84 -159
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/public-api.html +81 -143
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/registration-service.html +98 -188
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/web-register-ui.html +83 -138
- package/init-project-html/sample-demo/resources/project-architecture/index.html +256 -335
- package/init-project-html/scripts/architecture.js +65 -247
- package/katex/scripts/__pycache__/render_katex.cpython-312.pyc +0 -0
- package/open-github-issue/scripts/__pycache__/open_github_issue.cpython-312.pyc +0 -0
- package/package.json +6 -2
- package/read-github-issue/scripts/__pycache__/find_issues.cpython-312.pyc +0 -0
- package/read-github-issue/scripts/__pycache__/read_issue.cpython-312.pyc +0 -0
- package/resolve-review-comments/scripts/__pycache__/review_threads.cpython-312.pyc +0 -0
- package/spec-to-project-html/SKILL.md +74 -67
- package/spec-to-project-html/agents/openai.yaml +14 -8
- package/spec-to-project-html/references/TEMPLATE_SPEC.md +98 -83
- package/text-to-short-video/scripts/__pycache__/enforce_video_aspect_ratio.cpython-312.pyc +0 -0
|
@@ -1,337 +1,258 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
</
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
<!-- ============ CROSS-FEATURE DATA-ROW EDGE ============ -->
|
|
260
|
-
<!-- B5 produces row → A4 consumes row -->
|
|
261
|
-
<g class="m-edge m-edge--cross" data-edge-id="x-row-flow">
|
|
262
|
-
<path
|
|
263
|
-
d="M 740 742 C 600 880, 600 880, 460 742"
|
|
264
|
-
marker-end="url(#mk-cross)"
|
|
265
|
-
></path>
|
|
266
|
-
<text x="600" y="900" text-anchor="middle" class="m-edge__label m-edge__label--cross">
|
|
267
|
-
資料行流向:B5 寫入 <tspan font-style="italic">invite_codes</tspan> 行 → A4 之後讀取/核銷該行(非函式呼叫)
|
|
268
|
-
</text>
|
|
269
|
-
</g>
|
|
270
|
-
</svg>
|
|
271
|
-
</div>
|
|
272
|
-
|
|
273
|
-
<ol class="flow-edge-manifest flow-edge-manifest--macro">
|
|
274
|
-
<li data-edge-id="e-A-1" data-edge-kind="call"><span class="flow-edge-from">#actor-visitor</span> → <span class="flow-edge-to">#m-A1</span> <span class="flow-edge-label">提交註冊</span></li>
|
|
275
|
-
<li data-edge-id="e-A-2" data-edge-kind="call"><span class="flow-edge-from">#m-A1</span> → <span class="flow-edge-to">#m-A2</span> <span class="flow-edge-label">HTTP POST</span></li>
|
|
276
|
-
<li data-edge-id="e-A-3" data-edge-kind="call"><span class="flow-edge-from">#m-A2</span> → <span class="flow-edge-to">#m-A3</span> <span class="flow-edge-label">RegisterWithInvite(ctx, in)</span></li>
|
|
277
|
-
<li data-edge-id="e-A-4-read" data-edge-kind="call"><span class="flow-edge-from">#m-A3</span> → <span class="flow-edge-to">#m-A4</span> <span class="flow-edge-label">SELECT FOR UPDATE invite_codes</span></li>
|
|
278
|
-
<li data-edge-id="e-A-4-row" data-edge-kind="return"><span class="flow-edge-from">#m-A4</span> ⇠ <span class="flow-edge-to">#m-A3</span> <span class="flow-edge-label">InviteRow | NotFound</span></li>
|
|
279
|
-
<li data-edge-id="e-A-4-insert-user" data-edge-kind="call"><span class="flow-edge-from">#m-A3</span> → <span class="flow-edge-to">#m-A4</span> <span class="flow-edge-label">INSERT users</span></li>
|
|
280
|
-
<li data-edge-id="e-A-4-update" data-edge-kind="call"><span class="flow-edge-from">#m-A3</span> → <span class="flow-edge-to">#m-A4</span> <span class="flow-edge-label">UPDATE invite_codes SET consumed_at</span></li>
|
|
281
|
-
<li data-edge-id="e-A-resp" data-edge-kind="return"><span class="flow-edge-from">#m-A2</span> ⇠ <span class="flow-edge-to">#actor-visitor</span> <span class="flow-edge-label">201 / 409</span></li>
|
|
282
|
-
|
|
283
|
-
<li data-edge-id="e-B-1" data-edge-kind="call"><span class="flow-edge-from">#actor-member</span> → <span class="flow-edge-to">#m-B1</span> <span class="flow-edge-label">點生成</span></li>
|
|
284
|
-
<li data-edge-id="e-B-2" data-edge-kind="call"><span class="flow-edge-from">#m-B1</span> → <span class="flow-edge-to">#m-B2</span> <span class="flow-edge-label">HTTP POST</span></li>
|
|
285
|
-
<li data-edge-id="e-B-3" data-edge-kind="call"><span class="flow-edge-from">#m-B2</span> → <span class="flow-edge-to">#m-B3</span> <span class="flow-edge-label">IssueInviteCode(ctx, userID)</span></li>
|
|
286
|
-
<li data-edge-id="e-B-3-gen-call" data-edge-kind="call"><span class="flow-edge-from">#m-B3</span> → <span class="flow-edge-to">#m-B4</span> <span class="flow-edge-label">Next() · 純函式</span></li>
|
|
287
|
-
<li data-edge-id="e-B-3-gen-ret" data-edge-kind="return"><span class="flow-edge-from">#m-B4</span> ⇠ <span class="flow-edge-to">#m-B3</span> <span class="flow-edge-label">候選字串</span></li>
|
|
288
|
-
<li data-edge-id="e-B-5-insert" data-edge-kind="call"><span class="flow-edge-from">#m-B3</span> → <span class="flow-edge-to">#m-B5</span> <span class="flow-edge-label">INSERT invite_codes</span></li>
|
|
289
|
-
<li data-edge-id="e-B-5-ret" data-edge-kind="return"><span class="flow-edge-from">#m-B5</span> ⇠ <span class="flow-edge-to">#m-B3</span> <span class="flow-edge-label">ok / unique_violation(碰撞 → 重新 Next)</span></li>
|
|
290
|
-
<li data-edge-id="e-B-resp" data-edge-kind="return"><span class="flow-edge-from">#m-B2</span> ⇠ <span class="flow-edge-to">#actor-member</span> <span class="flow-edge-label">201 / 429</span></li>
|
|
291
|
-
|
|
292
|
-
<li data-edge-id="x-row-flow" data-edge-kind="data-row"><span class="flow-edge-from">#m-B5</span> ⇒ <span class="flow-edge-to">#m-A4</span> <span class="flow-edge-label">同一 invite_codes 表:B 寫入行被 A 讀取/核銷(非函式呼叫,純資料行傳遞)</span></li>
|
|
293
|
-
</ol>
|
|
294
|
-
<figcaption class="flow-caption">
|
|
295
|
-
「同一對節點 N 條邊」是真實的(例如 A3 → A4 同時有 SELECT、INSERT、UPDATE 三條;B3 ↔ B4、B3 ↔ B5 皆有呼叫/回傳對)。子模組頁不重述這些跨界邊;它們只在此處統一呈現。
|
|
296
|
-
</figcaption>
|
|
297
|
-
</figure>
|
|
298
|
-
</section>
|
|
299
|
-
|
|
300
|
-
<nav class="atlas-submodule-index">
|
|
301
|
-
<h2>子模組索引(每一個子模組各一頁)</h2>
|
|
302
|
-
<ul>
|
|
303
|
-
<li>
|
|
304
|
-
<strong>邀請碼註冊 ▸</strong>
|
|
305
|
-
<a href="features/invite-code-registration/web-register-ui.html">web-register-ui</a> ·
|
|
306
|
-
<a href="features/invite-code-registration/public-api.html">public-api</a> ·
|
|
307
|
-
<a href="features/invite-code-registration/registration-service.html">registration-service</a> ·
|
|
308
|
-
<a href="features/invite-code-registration/postgresql.html">postgresql</a>
|
|
309
|
-
</li>
|
|
310
|
-
<li>
|
|
311
|
-
<strong>獲取邀請碼 ▸</strong>
|
|
312
|
-
<a href="features/get-invite-codes/web-get-invite-ui.html">web-get-invite-ui</a> ·
|
|
313
|
-
<a href="features/get-invite-codes/public-api.html">public-api</a> ·
|
|
314
|
-
<a href="features/get-invite-codes/invite-issuance-service.html">invite-issuance-service</a> ·
|
|
315
|
-
<a href="features/get-invite-codes/invite-code-generator.html">invite-code-generator</a> ·
|
|
316
|
-
<a href="features/get-invite-codes/postgresql.html">postgresql</a>
|
|
317
|
-
</li>
|
|
318
|
-
</ul>
|
|
319
|
-
<p class="atlas-meta">
|
|
320
|
-
每一頁只描述<strong>該子模組自身的函式輸入/輸出/副作用</strong>與<strong>內部資料流</strong>;跨子模組的呼叫關係請回到上方宏觀圖。
|
|
321
|
-
</p>
|
|
322
|
-
</nav>
|
|
323
|
-
|
|
324
|
-
<nav class="atlas-features">
|
|
325
|
-
<h2>功能模組總覽(中層)</h2>
|
|
326
|
-
<ul>
|
|
327
|
-
<li><a href="features/invite-code-registration/index.html">邀請碼註冊(功能總覽)</a></li>
|
|
328
|
-
<li><a href="features/get-invite-codes/index.html">獲取邀請碼(功能總覽)</a></li>
|
|
329
|
-
</ul>
|
|
330
|
-
</nav>
|
|
331
|
-
|
|
332
|
-
<footer class="atlas-meta" style="margin-top: 2rem">
|
|
333
|
-
<p>示範:<code>init-project-html/sample-demo/resources/project-architecture/</code></p>
|
|
334
|
-
</footer>
|
|
335
|
-
</main>
|
|
336
|
-
</body>
|
|
2
|
+
<html lang="en" data-atlas-page="macro">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Acme App — sample atlas</title>
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
+
<link rel="stylesheet" href="assets/architecture.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header class="atlas-header">
|
|
11
|
+
<h1>Acme App — sample atlas</h1>
|
|
12
|
+
<p class="atlas-summary">Two end-to-end feature modules — minting invite codes and consuming them during account registration — produced by `apltk architecture` from a declarative YAML source. The macro diagram surfaces both feature clusters and every sub-module they own, plus the cross-feature data-row that carries an `invite_codes` row between them.</p>
|
|
13
|
+
</header>
|
|
14
|
+
<main class="atlas-main">
|
|
15
|
+
<section class="atlas-canvas" aria-label="Macro architecture diagram">
|
|
16
|
+
<div class="atlas-canvas__toolbar" role="toolbar" aria-label="Diagram controls">
|
|
17
|
+
<button type="button" data-pan-zoom="zoom-in" aria-label="Zoom in">+</button>
|
|
18
|
+
<button type="button" data-pan-zoom="zoom-out" aria-label="Zoom out">−</button>
|
|
19
|
+
<button type="button" data-pan-zoom="fit" aria-label="Reset view">Fit</button>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="atlas-canvas__viewport" data-pan-zoom-viewport>
|
|
22
|
+
<svg class="atlas-svg" viewBox="0 0 3831 521" role="img" aria-label="Project architecture atlas" data-atlas-svg="macro">
|
|
23
|
+
<defs>
|
|
24
|
+
<marker id="arrow-call" class="m-arrow m-arrow--call" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 Z" /></marker>
|
|
25
|
+
<marker id="arrow-return" class="m-arrow m-arrow--return" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 Z" /></marker>
|
|
26
|
+
<marker id="arrow-data-row" class="m-arrow m-arrow--data-row" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 Z" /></marker>
|
|
27
|
+
<marker id="arrow-failure" class="m-arrow m-arrow--failure" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 Z" /></marker>
|
|
28
|
+
</defs>
|
|
29
|
+
<g transform="translate(24,24)">
|
|
30
|
+
<g class="m-cluster" data-feature="get-invite-codes">
|
|
31
|
+
<rect class="m-cluster__bg" x="40.00" y="40.00" width="1576.00" height="393.00" rx="14" ry="14" />
|
|
32
|
+
<text class="m-cluster__title" x="828.00" y="66.00" text-anchor="middle">Get invite codes</text>
|
|
33
|
+
</g>
|
|
34
|
+
<g class="m-cluster" data-feature="invite-code-registration">
|
|
35
|
+
<rect class="m-cluster__bg" x="2017.00" y="133.00" width="1726.00" height="266.40" rx="14" ry="14" />
|
|
36
|
+
<text class="m-cluster__title" x="2880.00" y="159.00" text-anchor="middle">Invite-code registration</text>
|
|
37
|
+
</g>
|
|
38
|
+
<a class="m-node m-node--ui" href="features/get-invite-codes/web-get-invite-ui.html" data-feature="get-invite-codes" data-submodule="web-get-invite-ui" tabindex="0" aria-label="web-get-invite-ui — React page that lets a signed-in member request a new invite code. — open sub-module page">
|
|
39
|
+
<title>web-get-invite-ui — React page that lets a signed-in member request a new invite code.</title>
|
|
40
|
+
<rect x="64.00" y="166.80" width="220.00" height="126.00" rx="10" ry="10" />
|
|
41
|
+
<text class="m-node__title" x="174.00" y="196.80" text-anchor="middle">web-get-invite-ui</text>
|
|
42
|
+
<text class="m-node__kind" x="174.00" y="212.80" text-anchor="middle">UI</text>
|
|
43
|
+
<text class="m-node__role" x="174.00" y="232.80" text-anchor="middle">React page that lets a</text>
|
|
44
|
+
<text class="m-node__role" x="174.00" y="248.80" text-anchor="middle">signed-in member request a new</text>
|
|
45
|
+
<text class="m-node__role" x="174.00" y="264.80" text-anchor="middle">invite code.</text>
|
|
46
|
+
</a>
|
|
47
|
+
<a class="m-node m-node--api" href="features/get-invite-codes/public-api.html" data-feature="get-invite-codes" data-submodule="public-api" tabindex="0" aria-label="public-api — HTTP boundary for `/api/invites` POST requests. — open sub-module page">
|
|
48
|
+
<title>public-api — HTTP boundary for `/api/invites` POST requests.</title>
|
|
49
|
+
<rect x="491.00" y="174.80" width="220.00" height="110.00" rx="10" ry="10" />
|
|
50
|
+
<text class="m-node__title" x="601.00" y="204.80" text-anchor="middle">public-api</text>
|
|
51
|
+
<text class="m-node__kind" x="601.00" y="220.80" text-anchor="middle">API</text>
|
|
52
|
+
<text class="m-node__role" x="601.00" y="240.80" text-anchor="middle">HTTP boundary for</text>
|
|
53
|
+
<text class="m-node__role" x="601.00" y="256.80" text-anchor="middle">`/api/invites` POST requests.</text>
|
|
54
|
+
</a>
|
|
55
|
+
<a class="m-node m-node--service" href="features/get-invite-codes/invite-issuance-service.html" data-feature="get-invite-codes" data-submodule="invite-issuance-service" tabindex="0" aria-label="invite-issuance-service — Domain service that mints and persists a single invite row per request. — open sub-module page">
|
|
56
|
+
<title>invite-issuance-service — Domain service that mints and persists a single invite row per request.</title>
|
|
57
|
+
<rect x="925.00" y="166.80" width="226.00" height="126.00" rx="10" ry="10" />
|
|
58
|
+
<text class="m-node__title" x="1038.00" y="196.80" text-anchor="middle">invite-issuance-service</text>
|
|
59
|
+
<text class="m-node__kind" x="1038.00" y="212.80" text-anchor="middle">service</text>
|
|
60
|
+
<text class="m-node__role" x="1038.00" y="232.80" text-anchor="middle">Domain service that mints and</text>
|
|
61
|
+
<text class="m-node__role" x="1038.00" y="248.80" text-anchor="middle">persists a single invite row per</text>
|
|
62
|
+
<text class="m-node__role" x="1038.00" y="264.80" text-anchor="middle">request.</text>
|
|
63
|
+
</a>
|
|
64
|
+
<a class="m-node m-node--pure-fn" href="features/get-invite-codes/invite-code-generator.html" data-feature="get-invite-codes" data-submodule="invite-code-generator" tabindex="0" aria-label="invite-code-generator — Pure helper that turns random bytes into a printable invite code. — open sub-module page">
|
|
65
|
+
<title>invite-code-generator — Pure helper that turns random bytes into a printable invite code.</title>
|
|
66
|
+
<rect x="1372.00" y="129.00" width="220.00" height="126.00" rx="10" ry="10" />
|
|
67
|
+
<text class="m-node__title" x="1482.00" y="159.00" text-anchor="middle">invite-code-generator</text>
|
|
68
|
+
<text class="m-node__kind" x="1482.00" y="175.00" text-anchor="middle">pure function</text>
|
|
69
|
+
<text class="m-node__role" x="1482.00" y="195.00" text-anchor="middle">Pure helper that turns random</text>
|
|
70
|
+
<text class="m-node__role" x="1482.00" y="211.00" text-anchor="middle">bytes into a printable invite</text>
|
|
71
|
+
<text class="m-node__role" x="1482.00" y="227.00" text-anchor="middle">code.</text>
|
|
72
|
+
</a>
|
|
73
|
+
<a class="m-node m-node--db" href="features/get-invite-codes/postgresql.html" data-feature="get-invite-codes" data-submodule="postgresql" tabindex="0" aria-label="postgresql — Owns the `invite_codes` table (producer side of the cross-feature data row). — open sub-module page">
|
|
74
|
+
<title>postgresql — Owns the `invite_codes` table (producer side of the cross-feature data row).</title>
|
|
75
|
+
<rect x="1372.00" y="279.00" width="220.00" height="126.00" rx="10" ry="10" />
|
|
76
|
+
<text class="m-node__title" x="1482.00" y="309.00" text-anchor="middle">postgresql</text>
|
|
77
|
+
<text class="m-node__kind" x="1482.00" y="325.00" text-anchor="middle">database</text>
|
|
78
|
+
<text class="m-node__role" x="1482.00" y="345.00" text-anchor="middle">Owns the `invite_codes` table</text>
|
|
79
|
+
<text class="m-node__role" x="1482.00" y="361.00" text-anchor="middle">(producer side of the</text>
|
|
80
|
+
<text class="m-node__role" x="1482.00" y="377.00" text-anchor="middle">cross-feature data row).</text>
|
|
81
|
+
</a>
|
|
82
|
+
<a class="m-node m-node--ui" href="features/invite-code-registration/web-register-ui.html" data-feature="invite-code-registration" data-submodule="web-register-ui" tabindex="0" aria-label="web-register-ui — React page that captures email, password, and invite code. — open sub-module page">
|
|
83
|
+
<title>web-register-ui — React page that captures email, password, and invite code.</title>
|
|
84
|
+
<rect x="2041.00" y="222.00" width="220.00" height="110.00" rx="10" ry="10" />
|
|
85
|
+
<text class="m-node__title" x="2151.00" y="252.00" text-anchor="middle">web-register-ui</text>
|
|
86
|
+
<text class="m-node__kind" x="2151.00" y="268.00" text-anchor="middle">UI</text>
|
|
87
|
+
<text class="m-node__role" x="2151.00" y="288.00" text-anchor="middle">React page that captures email,</text>
|
|
88
|
+
<text class="m-node__role" x="2151.00" y="304.00" text-anchor="middle">password, and invite code.</text>
|
|
89
|
+
</a>
|
|
90
|
+
<a class="m-node m-node--api" href="features/invite-code-registration/public-api.html" data-feature="invite-code-registration" data-submodule="public-api" tabindex="0" aria-label="public-api — HTTP boundary for `/api/register` POST requests. — open sub-module page">
|
|
91
|
+
<title>public-api — HTTP boundary for `/api/register` POST requests.</title>
|
|
92
|
+
<rect x="2475.00" y="222.00" width="220.00" height="110.00" rx="10" ry="10" />
|
|
93
|
+
<text class="m-node__title" x="2585.00" y="252.00" text-anchor="middle">public-api</text>
|
|
94
|
+
<text class="m-node__kind" x="2585.00" y="268.00" text-anchor="middle">API</text>
|
|
95
|
+
<text class="m-node__role" x="2585.00" y="288.00" text-anchor="middle">HTTP boundary for</text>
|
|
96
|
+
<text class="m-node__role" x="2585.00" y="304.00" text-anchor="middle">`/api/register` POST requests.</text>
|
|
97
|
+
</a>
|
|
98
|
+
<a class="m-node m-node--service" href="features/invite-code-registration/registration-service.html" data-feature="invite-code-registration" data-submodule="registration-service" tabindex="0" aria-label="registration-service — Owns the registration transaction (consumer side of the invite_codes data row). — open sub-module page">
|
|
99
|
+
<title>registration-service — Owns the registration transaction (consumer side of the invite_codes data row).</title>
|
|
100
|
+
<rect x="2987.00" y="235.00" width="220.00" height="126.00" rx="10" ry="10" />
|
|
101
|
+
<text class="m-node__title" x="3097.00" y="265.00" text-anchor="middle">registration-service</text>
|
|
102
|
+
<text class="m-node__kind" x="3097.00" y="281.00" text-anchor="middle">service</text>
|
|
103
|
+
<text class="m-node__role" x="3097.00" y="301.00" text-anchor="middle">Owns the registration</text>
|
|
104
|
+
<text class="m-node__role" x="3097.00" y="317.00" text-anchor="middle">transaction (consumer side of</text>
|
|
105
|
+
<text class="m-node__role" x="3097.00" y="333.00" text-anchor="middle">the invite_codes data row).</text>
|
|
106
|
+
</a>
|
|
107
|
+
<a class="m-node m-node--db" href="features/invite-code-registration/postgresql.html" data-feature="invite-code-registration" data-submodule="postgresql" tabindex="0" aria-label="postgresql — Stores `users` rows and applies invite-code state transitions inside the registration tx. — open sub-module page">
|
|
108
|
+
<title>postgresql — Stores `users` rows and applies invite-code state transitions inside the registration tx.</title>
|
|
109
|
+
<rect x="3499.00" y="228.20" width="220.00" height="126.00" rx="10" ry="10" />
|
|
110
|
+
<text class="m-node__title" x="3609.00" y="258.20" text-anchor="middle">postgresql</text>
|
|
111
|
+
<text class="m-node__kind" x="3609.00" y="274.20" text-anchor="middle">database</text>
|
|
112
|
+
<text class="m-node__role" x="3609.00" y="294.20" text-anchor="middle">Stores `users` rows and applies</text>
|
|
113
|
+
<text class="m-node__role" x="3609.00" y="310.20" text-anchor="middle">invite-code state transitions</text>
|
|
114
|
+
<text class="m-node__role" x="3609.00" y="326.20" text-anchor="middle">inside the registration tx.</text>
|
|
115
|
+
</a>
|
|
116
|
+
<g class="m-edge m-edge--data-row" data-edge="cross-issuance-to-postgres-codes">
|
|
117
|
+
<path d="M1111.00,227.60 L1121.00,227.60 L1121.00,334.00 L1306.00,334.00 L1306.00,333.50 L1332.00,333.50" fill="none" marker-end="url(#arrow-data-row)" />
|
|
118
|
+
<text class="m-edge__label" x="1221.50" y="350.00" text-anchor="middle">INSERT invite_codes</text>
|
|
119
|
+
</g>
|
|
120
|
+
<g class="m-edge m-edge--data-row" data-edge="cross-postgres-codes-to-registration">
|
|
121
|
+
<path d="M1592.00,342.00 L2961.00,342.00 L2961.00,319.00 L2987.00,319.00" fill="none" marker-end="url(#arrow-data-row)" />
|
|
122
|
+
<text class="m-edge__label" x="1816.50" y="358.00" text-anchor="middle">read/consume invite_codes</text>
|
|
123
|
+
</g>
|
|
124
|
+
<g class="m-edge m-edge--call" data-edge="e-ui-api">
|
|
125
|
+
<path d="M284.00,229.80 L491.00,229.80" fill="none" marker-end="url(#arrow-call)" />
|
|
126
|
+
<text class="m-edge__label" x="387.50" y="245.80" text-anchor="middle">POST /api/invites</text>
|
|
127
|
+
</g>
|
|
128
|
+
<g class="m-edge m-edge--call" data-edge="e-api-svc">
|
|
129
|
+
<path d="M711.00,229.80 L925.00,229.80" fill="none" marker-end="url(#arrow-call)" />
|
|
130
|
+
<text class="m-edge__label" x="818.00" y="245.80" text-anchor="middle">Issue(ctx, userId)</text>
|
|
131
|
+
</g>
|
|
132
|
+
<g class="m-edge m-edge--call" data-edge="e-svc-gen">
|
|
133
|
+
<path d="M1151.00,192.00 L1372.00,192.00" fill="none" marker-end="url(#arrow-call)" />
|
|
134
|
+
<text class="m-edge__label" x="1261.50" y="208.00" text-anchor="middle">encode(rand)</text>
|
|
135
|
+
</g>
|
|
136
|
+
<g class="m-edge m-edge--call" data-edge="e-svc-db">
|
|
137
|
+
<path d="M1151.00,242.40 L1171.00,242.40 L1171.00,342.00 L1372.00,342.00" fill="none" marker-end="url(#arrow-call)" />
|
|
138
|
+
<text class="m-edge__label" x="1261.50" y="358.00" text-anchor="middle">INSERT invite_codes</text>
|
|
139
|
+
</g>
|
|
140
|
+
<g class="m-edge m-edge--return" data-edge="e-db-svc-return">
|
|
141
|
+
<path d="M1372.00,310.50 L1346.00,310.50 L1346.00,224.00 L1161.00,224.00 L1161.00,217.20 L1151.00,217.20" fill="none" marker-end="url(#arrow-return)" />
|
|
142
|
+
<text class="m-edge__label" x="1261.50" y="240.00" text-anchor="middle">rowid</text>
|
|
143
|
+
</g>
|
|
144
|
+
<g class="m-edge m-edge--call" data-edge="e-ui-api">
|
|
145
|
+
<path d="M2261.00,277.00 L2475.00,277.00" fill="none" marker-end="url(#arrow-call)" />
|
|
146
|
+
<text class="m-edge__label" x="2368.00" y="269.00" text-anchor="middle">POST /api/register</text>
|
|
147
|
+
</g>
|
|
148
|
+
<g class="m-edge m-edge--call" data-edge="e-api-svc">
|
|
149
|
+
<path d="M2695.00,277.00 L2987.00,277.00" fill="none" marker-end="url(#arrow-call)" />
|
|
150
|
+
<text class="m-edge__label" x="2841.00" y="269.00" text-anchor="middle">RegisterWithInvite(ctx, RegisterInput)</text>
|
|
151
|
+
</g>
|
|
152
|
+
<g class="m-edge m-edge--call" data-edge="e-svc-db-select">
|
|
153
|
+
<path d="M3207.00,285.40 L3473.00,285.40 L3473.00,278.60 L3499.00,278.60" fill="none" marker-end="url(#arrow-call)" />
|
|
154
|
+
<text class="m-edge__label" x="3353.00" y="301.40" text-anchor="middle">SELECT invite_codes FOR UPDATE</text>
|
|
155
|
+
</g>
|
|
156
|
+
<g class="m-edge m-edge--call" data-edge="e-svc-db-insert">
|
|
157
|
+
<path d="M3207.00,310.60 L3217.00,310.60 L3217.00,317.40 L3473.00,317.40 L3473.00,303.80 L3499.00,303.80" fill="none" marker-end="url(#arrow-call)" />
|
|
158
|
+
<text class="m-edge__label" x="3353.00" y="333.40" text-anchor="middle">INSERT users</text>
|
|
159
|
+
</g>
|
|
160
|
+
<g class="m-edge m-edge--call" data-edge="e-svc-db-update">
|
|
161
|
+
<path d="M3207.00,335.80 L3217.00,335.80 L3217.00,349.40 L3473.00,349.40 L3473.00,329.00 L3499.00,329.00" fill="none" marker-end="url(#arrow-call)" />
|
|
162
|
+
<text class="m-edge__label" x="3353.00" y="365.40" text-anchor="middle">UPDATE invite_codes.consumed_at</text>
|
|
163
|
+
</g>
|
|
164
|
+
<g class="m-edge m-edge--return" data-edge="e-db-svc-return">
|
|
165
|
+
<path d="M3499.00,253.40 L3217.00,253.40 L3217.00,260.20 L3207.00,260.20" fill="none" marker-end="url(#arrow-return)" />
|
|
166
|
+
<text class="m-edge__label" x="3353.00" y="269.40" text-anchor="middle">row | rows_affected</text>
|
|
167
|
+
</g>
|
|
168
|
+
</g>
|
|
169
|
+
</svg>
|
|
170
|
+
</div>
|
|
171
|
+
<ol class="atlas-legend" aria-label="Edge legend">
|
|
172
|
+
<li><span class="legend-swatch legend-swatch--call"></span>call</li>
|
|
173
|
+
<li><span class="legend-swatch legend-swatch--return"></span>return</li>
|
|
174
|
+
<li><span class="legend-swatch legend-swatch--data-row"></span>data-row</li>
|
|
175
|
+
<li><span class="legend-swatch legend-swatch--failure"></span>failure</li>
|
|
176
|
+
</ol>
|
|
177
|
+
</section>
|
|
178
|
+
<section class="atlas-index" aria-label="Submodule index">
|
|
179
|
+
<h2>Submodule index</h2>
|
|
180
|
+
<ul class="atlas-submodule-index">
|
|
181
|
+
<li class="atlas-submodule-index__item">
|
|
182
|
+
<a href="features/get-invite-codes/web-get-invite-ui.html">
|
|
183
|
+
<span class="atlas-submodule-index__feature">Get invite codes</span>
|
|
184
|
+
<span class="atlas-submodule-index__sub">web-get-invite-ui</span>
|
|
185
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--ui">UI</span>
|
|
186
|
+
</a>
|
|
187
|
+
<p class="atlas-submodule-index__role">React page that lets a signed-in member request a new invite code.</p>
|
|
188
|
+
</li>
|
|
189
|
+
<li class="atlas-submodule-index__item">
|
|
190
|
+
<a href="features/get-invite-codes/public-api.html">
|
|
191
|
+
<span class="atlas-submodule-index__feature">Get invite codes</span>
|
|
192
|
+
<span class="atlas-submodule-index__sub">public-api</span>
|
|
193
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--api">API</span>
|
|
194
|
+
</a>
|
|
195
|
+
<p class="atlas-submodule-index__role">HTTP boundary for `/api/invites` POST requests.</p>
|
|
196
|
+
</li>
|
|
197
|
+
<li class="atlas-submodule-index__item">
|
|
198
|
+
<a href="features/get-invite-codes/invite-issuance-service.html">
|
|
199
|
+
<span class="atlas-submodule-index__feature">Get invite codes</span>
|
|
200
|
+
<span class="atlas-submodule-index__sub">invite-issuance-service</span>
|
|
201
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--service">Service</span>
|
|
202
|
+
</a>
|
|
203
|
+
<p class="atlas-submodule-index__role">Domain service that mints and persists a single invite row per request.</p>
|
|
204
|
+
</li>
|
|
205
|
+
<li class="atlas-submodule-index__item">
|
|
206
|
+
<a href="features/get-invite-codes/invite-code-generator.html">
|
|
207
|
+
<span class="atlas-submodule-index__feature">Get invite codes</span>
|
|
208
|
+
<span class="atlas-submodule-index__sub">invite-code-generator</span>
|
|
209
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--pure-fn">Pure fn</span>
|
|
210
|
+
</a>
|
|
211
|
+
<p class="atlas-submodule-index__role">Pure helper that turns random bytes into a printable invite code.</p>
|
|
212
|
+
</li>
|
|
213
|
+
<li class="atlas-submodule-index__item">
|
|
214
|
+
<a href="features/get-invite-codes/postgresql.html">
|
|
215
|
+
<span class="atlas-submodule-index__feature">Get invite codes</span>
|
|
216
|
+
<span class="atlas-submodule-index__sub">postgresql</span>
|
|
217
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--db">DB</span>
|
|
218
|
+
</a>
|
|
219
|
+
<p class="atlas-submodule-index__role">Owns the `invite_codes` table (producer side of the cross-feature data row).</p>
|
|
220
|
+
</li>
|
|
221
|
+
<li class="atlas-submodule-index__item">
|
|
222
|
+
<a href="features/invite-code-registration/web-register-ui.html">
|
|
223
|
+
<span class="atlas-submodule-index__feature">Invite-code registration</span>
|
|
224
|
+
<span class="atlas-submodule-index__sub">web-register-ui</span>
|
|
225
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--ui">UI</span>
|
|
226
|
+
</a>
|
|
227
|
+
<p class="atlas-submodule-index__role">React page that captures email, password, and invite code.</p>
|
|
228
|
+
</li>
|
|
229
|
+
<li class="atlas-submodule-index__item">
|
|
230
|
+
<a href="features/invite-code-registration/public-api.html">
|
|
231
|
+
<span class="atlas-submodule-index__feature">Invite-code registration</span>
|
|
232
|
+
<span class="atlas-submodule-index__sub">public-api</span>
|
|
233
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--api">API</span>
|
|
234
|
+
</a>
|
|
235
|
+
<p class="atlas-submodule-index__role">HTTP boundary for `/api/register` POST requests.</p>
|
|
236
|
+
</li>
|
|
237
|
+
<li class="atlas-submodule-index__item">
|
|
238
|
+
<a href="features/invite-code-registration/registration-service.html">
|
|
239
|
+
<span class="atlas-submodule-index__feature">Invite-code registration</span>
|
|
240
|
+
<span class="atlas-submodule-index__sub">registration-service</span>
|
|
241
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--service">Service</span>
|
|
242
|
+
</a>
|
|
243
|
+
<p class="atlas-submodule-index__role">Owns the registration transaction (consumer side of the invite_codes data row).</p>
|
|
244
|
+
</li>
|
|
245
|
+
<li class="atlas-submodule-index__item">
|
|
246
|
+
<a href="features/invite-code-registration/postgresql.html">
|
|
247
|
+
<span class="atlas-submodule-index__feature">Invite-code registration</span>
|
|
248
|
+
<span class="atlas-submodule-index__sub">postgresql</span>
|
|
249
|
+
<span class="atlas-submodule-index__kind atlas-submodule-index__kind--db">DB</span>
|
|
250
|
+
</a>
|
|
251
|
+
<p class="atlas-submodule-index__role">Stores `users` rows and applies invite-code state transitions inside the registration tx.</p>
|
|
252
|
+
</li>
|
|
253
|
+
</ul>
|
|
254
|
+
</section>
|
|
255
|
+
</main>
|
|
256
|
+
<script src="assets/viewer.client.js" defer></script>
|
|
257
|
+
</body>
|
|
337
258
|
</html>
|