@hustle-together/api-dev-tools 3.12.3 → 4.5.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/.claude/adr-requests/.gitkeep +10 -0
- package/.claude/agents/adr-researcher.md +109 -0
- package/.claude/agents/visual-analyzer.md +183 -0
- package/.claude/api-dev-state.json +7 -463
- package/.claude/documentation-audit.json +114 -0
- package/.claude/registry.json +289 -0
- package/.claude/settings.json +45 -1
- package/.claude/workflow-logs/None.json +49 -0
- package/.claude/workflow-logs/session-20251230-143727.json +106 -0
- package/.skills/adr-deep-research/SKILL.md +351 -0
- package/.skills/api-create/SKILL.md +116 -17
- package/.skills/api-research/SKILL.md +130 -0
- package/.skills/docs-sync/SKILL.md +260 -0
- package/.skills/docs-update/SKILL.md +205 -0
- package/.skills/hustle-brand/SKILL.md +368 -0
- package/.skills/hustle-build/SKILL.md +786 -0
- package/.skills/hustle-build-review/SKILL.md +518 -0
- package/.skills/parallel-spawn/SKILL.md +212 -0
- package/.skills/ralph-continue/SKILL.md +151 -0
- package/.skills/ralph-loop/SKILL.md +341 -0
- package/.skills/ralph-status/SKILL.md +87 -0
- package/.skills/refactor/SKILL.md +59 -0
- package/.skills/shadcn/SKILL.md +522 -0
- package/.skills/test-all/SKILL.md +210 -0
- package/.skills/test-builds/SKILL.md +208 -0
- package/.skills/test-debug/SKILL.md +212 -0
- package/.skills/test-e2e/SKILL.md +168 -0
- package/.skills/test-review/SKILL.md +707 -0
- package/.skills/test-unit/SKILL.md +143 -0
- package/.skills/test-visual/SKILL.md +301 -0
- package/.skills/token-report/SKILL.md +132 -0
- package/CHANGELOG.md +575 -0
- package/README.md +426 -56
- package/bin/cli.js +1538 -88
- package/commands/hustle-api-create.md +22 -0
- package/commands/hustle-build.md +259 -0
- package/commands/hustle-combine.md +81 -2
- package/commands/hustle-ui-create-page.md +84 -2
- package/commands/hustle-ui-create.md +82 -2
- package/hooks/__pycache__/api-workflow-check.cpython-314.pyc +0 -0
- package/hooks/__pycache__/auto-answer.cpython-314.pyc +0 -0
- package/hooks/__pycache__/cache-research.cpython-314.pyc +0 -0
- package/hooks/__pycache__/check-api-routes.cpython-314.pyc +0 -0
- package/hooks/__pycache__/check-playwright-setup.cpython-314.pyc +0 -0
- package/hooks/__pycache__/check-storybook-setup.cpython-314.pyc +0 -0
- package/hooks/__pycache__/check-update.cpython-314.pyc +0 -0
- package/hooks/__pycache__/completion-promise-detector.cpython-314.pyc +0 -0
- package/hooks/__pycache__/context-capacity-warning.cpython-314.pyc +0 -0
- package/hooks/__pycache__/detect-interruption.cpython-314.pyc +0 -0
- package/hooks/__pycache__/docs-update-check.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-a11y-audit.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-brand-guide.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-component-type-confirm.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-deep-research.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-disambiguation.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-documentation.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-dry-run.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-environment.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-external-research.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-freshness.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-interview.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-page-components.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-page-data-schema.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-questions-sourced.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-refactor.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-research.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-schema-from-interview.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-schema.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-scope.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-tdd-red.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-ui-disambiguation.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-ui-interview.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-verify.cpython-314.pyc +0 -0
- package/hooks/__pycache__/generate-adr-options.cpython-314.pyc +0 -0
- package/hooks/__pycache__/generate-manifest-entry.cpython-314.pyc +0 -0
- package/hooks/__pycache__/hook_utils.cpython-314.pyc +0 -0
- package/hooks/__pycache__/notify-input-needed.cpython-314.pyc +0 -0
- package/hooks/__pycache__/notify-phase-complete.cpython-314.pyc +0 -0
- package/hooks/__pycache__/ntfy-on-question.cpython-314.pyc +0 -0
- package/hooks/__pycache__/orchestrator-completion.cpython-314.pyc +0 -0
- package/hooks/__pycache__/orchestrator-handoff.cpython-314.pyc +0 -0
- package/hooks/__pycache__/orchestrator-session-startup.cpython-314.pyc +0 -0
- package/hooks/__pycache__/parallel-orchestrator.cpython-314.pyc +0 -0
- package/hooks/__pycache__/periodic-reground.cpython-314.pyc +0 -0
- package/hooks/__pycache__/project-document-prompt.cpython-314.pyc +0 -0
- package/hooks/__pycache__/remote-question-proxy.cpython-314.pyc +0 -0
- package/hooks/__pycache__/remote-question-server.cpython-314.pyc +0 -0
- package/hooks/__pycache__/run-code-review.cpython-314.pyc +0 -0
- package/hooks/__pycache__/run-visual-qa.cpython-314.pyc +0 -0
- package/hooks/__pycache__/session-logger.cpython-314.pyc +0 -0
- package/hooks/__pycache__/session-startup.cpython-314.pyc +0 -0
- package/hooks/__pycache__/track-scope-coverage.cpython-314.pyc +0 -0
- package/hooks/__pycache__/track-token-usage.cpython-314.pyc +0 -0
- package/hooks/__pycache__/track-tool-use.cpython-314.pyc +0 -0
- package/hooks/__pycache__/update-adr-decision.cpython-314.pyc +0 -0
- package/hooks/__pycache__/update-api-showcase.cpython-314.pyc +0 -0
- package/hooks/__pycache__/update-registry.cpython-314.pyc +0 -0
- package/hooks/__pycache__/update-ui-showcase.cpython-314.pyc +0 -0
- package/hooks/__pycache__/verify-after-green.cpython-314.pyc +0 -0
- package/hooks/__pycache__/verify-implementation.cpython-314.pyc +0 -0
- package/hooks/api-workflow-check.py +34 -0
- package/hooks/auto-answer.py +305 -0
- package/hooks/check-update.py +132 -0
- package/hooks/completion-promise-detector.py +293 -0
- package/hooks/context-capacity-warning.py +171 -0
- package/hooks/docs-update-check.py +120 -0
- package/hooks/enforce-dry-run.py +134 -0
- package/hooks/enforce-external-research.py +25 -0
- package/hooks/enforce-interview.py +20 -0
- package/hooks/generate-adr-options.py +282 -0
- package/hooks/hook_utils.py +609 -0
- package/hooks/lib/__pycache__/__init__.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/greptile.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/ntfy.cpython-314.pyc +0 -0
- package/hooks/ntfy-on-question.py +240 -0
- package/hooks/orchestrator-completion.py +313 -0
- package/hooks/orchestrator-handoff.py +267 -0
- package/hooks/orchestrator-session-startup.py +146 -0
- package/hooks/parallel-orchestrator.py +451 -0
- package/hooks/periodic-reground.py +270 -67
- package/hooks/project-document-prompt.py +302 -0
- package/hooks/remote-question-proxy.py +284 -0
- package/hooks/remote-question-server.py +1224 -0
- package/hooks/run-code-review.py +176 -29
- package/hooks/run-visual-qa.py +338 -0
- package/hooks/session-logger.py +27 -1
- package/hooks/session-startup.py +113 -0
- package/hooks/update-adr-decision.py +236 -0
- package/hooks/update-api-showcase.py +13 -1
- package/hooks/update-testing-checklist.py +195 -0
- package/hooks/update-ui-showcase.py +13 -1
- package/package.json +7 -3
- package/scripts/extract-schema-docs.cjs +322 -0
- package/templates/.skills/hustle-interview/SKILL.md +174 -0
- package/templates/CLAUDE-SECTION.md +89 -64
- package/templates/adr-viewer/_components/ADRViewer.tsx +326 -0
- package/templates/api-dev-state.json +33 -1
- package/templates/api-showcase/_components/APIModal.tsx +100 -8
- package/templates/api-showcase/_components/APIShowcase.tsx +36 -4
- package/templates/api-showcase/_components/APITester.tsx +367 -58
- package/templates/brand-page/page.tsx +645 -0
- package/templates/component/Component.visual.spec.ts +30 -24
- package/templates/docs/page.tsx +230 -0
- package/templates/eslint-plugin-zod-schema/index.js +446 -0
- package/templates/eslint-plugin-zod-schema/package.json +26 -0
- package/templates/github-workflows/security.yml +274 -0
- package/templates/hustle-build-defaults.json +136 -0
- package/templates/hustle-dev-dashboard/page.tsx +365 -0
- package/templates/page/page.e2e.test.ts +30 -26
- package/templates/performance-budgets.json +63 -5
- package/templates/playwright-report/page.tsx +258 -0
- package/templates/registry.json +279 -3
- package/templates/review-dashboard/page.tsx +510 -0
- package/templates/settings.json +155 -7
- package/templates/test-results/page.tsx +237 -0
- package/templates/typedoc.json +19 -0
- package/templates/ui-showcase/_components/UIShowcase.tsx +48 -1
- package/templates/ui-showcase/_components/VisualTestingDashboard.tsx +579 -0
- package/templates/ui-showcase/page.tsx +1 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Playwright Report Page
|
|
7
|
+
*
|
|
8
|
+
* Shows Playwright E2E test results or instructions to run tests.
|
|
9
|
+
* Links to the HTML report when available.
|
|
10
|
+
*
|
|
11
|
+
* Created with Hustle API Dev Tools (v3.12.12)
|
|
12
|
+
*/
|
|
13
|
+
export default function PlaywrightReportPage() {
|
|
14
|
+
// In a real implementation, check if playwright-report/ exists
|
|
15
|
+
const hasReport = false;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className="min-h-screen bg-white dark:bg-gray-950">
|
|
19
|
+
{/* Header */}
|
|
20
|
+
<header className="border-b-4 border-black bg-[#BA0C2F] px-6 py-8 dark:border-gray-600">
|
|
21
|
+
<div className="mx-auto max-w-4xl">
|
|
22
|
+
<div className="flex items-center gap-2">
|
|
23
|
+
<Link
|
|
24
|
+
href="/hustle-dev-dashboard"
|
|
25
|
+
className="text-white/80 hover:text-white"
|
|
26
|
+
>
|
|
27
|
+
Dashboard
|
|
28
|
+
</Link>
|
|
29
|
+
<span className="text-white/60">/</span>
|
|
30
|
+
<span className="text-white">Playwright</span>
|
|
31
|
+
</div>
|
|
32
|
+
<h1 className="mt-2 text-3xl font-black text-white">
|
|
33
|
+
PLAYWRIGHT REPORTS
|
|
34
|
+
</h1>
|
|
35
|
+
<p className="mt-2 text-white/80">End-to-end test results</p>
|
|
36
|
+
</div>
|
|
37
|
+
</header>
|
|
38
|
+
|
|
39
|
+
{/* Main Content */}
|
|
40
|
+
<main className="mx-auto max-w-4xl px-6 py-8">
|
|
41
|
+
{hasReport ? <ReportContent /> : <EmptyState />}
|
|
42
|
+
</main>
|
|
43
|
+
|
|
44
|
+
{/* Footer */}
|
|
45
|
+
<footer className="border-t-2 border-black px-6 py-4 dark:border-gray-600">
|
|
46
|
+
<div className="mx-auto max-w-4xl text-center text-sm text-gray-600 dark:text-gray-400">
|
|
47
|
+
Built with{" "}
|
|
48
|
+
<a
|
|
49
|
+
href="https://github.com/hustle-together/api-dev-tools"
|
|
50
|
+
className="font-bold text-[#BA0C2F] hover:underline"
|
|
51
|
+
>
|
|
52
|
+
Hustle API Dev Tools
|
|
53
|
+
</a>
|
|
54
|
+
</div>
|
|
55
|
+
</footer>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function ReportContent() {
|
|
61
|
+
return (
|
|
62
|
+
<div className="space-y-6">
|
|
63
|
+
<div className="border-2 border-black p-6 dark:border-gray-600">
|
|
64
|
+
<h2 className="mb-4 text-xl font-bold text-black dark:text-white">
|
|
65
|
+
View Report
|
|
66
|
+
</h2>
|
|
67
|
+
<p className="mb-4 text-gray-600 dark:text-gray-400">
|
|
68
|
+
Playwright has generated an HTML report. Click below to view it:
|
|
69
|
+
</p>
|
|
70
|
+
<a
|
|
71
|
+
href="/playwright-report/index.html"
|
|
72
|
+
target="_blank"
|
|
73
|
+
rel="noopener noreferrer"
|
|
74
|
+
className="inline-block rounded bg-[#BA0C2F] px-6 py-3 font-bold text-white transition-colors hover:bg-[#8a0923]"
|
|
75
|
+
>
|
|
76
|
+
Open HTML Report
|
|
77
|
+
</a>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function EmptyState() {
|
|
84
|
+
return (
|
|
85
|
+
<div className="space-y-6">
|
|
86
|
+
{/* Status Card */}
|
|
87
|
+
<div className="border-2 border-black p-6 dark:border-gray-600">
|
|
88
|
+
<div className="flex items-center gap-3">
|
|
89
|
+
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-gray-100 text-2xl dark:bg-gray-800">
|
|
90
|
+
0
|
|
91
|
+
</div>
|
|
92
|
+
<div>
|
|
93
|
+
<h2 className="text-xl font-bold text-black dark:text-white">
|
|
94
|
+
No Playwright Reports
|
|
95
|
+
</h2>
|
|
96
|
+
<p className="text-gray-600 dark:text-gray-400">
|
|
97
|
+
Run E2E tests to generate a report
|
|
98
|
+
</p>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
{/* Instructions */}
|
|
104
|
+
<div className="border-2 border-black bg-gray-50 p-6 dark:border-gray-600 dark:bg-gray-900">
|
|
105
|
+
<h3 className="mb-4 font-bold text-black dark:text-white">
|
|
106
|
+
Run E2E Tests
|
|
107
|
+
</h3>
|
|
108
|
+
<div className="space-y-4">
|
|
109
|
+
<Step
|
|
110
|
+
number={1}
|
|
111
|
+
title="Run All E2E Tests"
|
|
112
|
+
command="pnpm test:e2e"
|
|
113
|
+
description="Runs all Playwright tests and generates a report"
|
|
114
|
+
/>
|
|
115
|
+
<Step
|
|
116
|
+
number={2}
|
|
117
|
+
title="Run with UI"
|
|
118
|
+
command="pnpm playwright test --ui"
|
|
119
|
+
description="Opens Playwright's interactive test runner"
|
|
120
|
+
/>
|
|
121
|
+
<Step
|
|
122
|
+
number={3}
|
|
123
|
+
title="View Report"
|
|
124
|
+
command="pnpm playwright show-report"
|
|
125
|
+
description="Opens the HTML report in your browser"
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
{/* Available Commands */}
|
|
131
|
+
<div className="border-2 border-black p-6 dark:border-gray-600">
|
|
132
|
+
<h3 className="mb-4 font-bold text-black dark:text-white">
|
|
133
|
+
Playwright Commands
|
|
134
|
+
</h3>
|
|
135
|
+
<div className="space-y-3">
|
|
136
|
+
<CommandItem
|
|
137
|
+
command="pnpm test:e2e"
|
|
138
|
+
description="Run all E2E tests"
|
|
139
|
+
/>
|
|
140
|
+
<CommandItem
|
|
141
|
+
command="pnpm playwright test --ui"
|
|
142
|
+
description="Interactive test runner"
|
|
143
|
+
/>
|
|
144
|
+
<CommandItem
|
|
145
|
+
command="pnpm playwright test --headed"
|
|
146
|
+
description="Run with visible browser"
|
|
147
|
+
/>
|
|
148
|
+
<CommandItem
|
|
149
|
+
command="pnpm playwright show-report"
|
|
150
|
+
description="Open HTML report"
|
|
151
|
+
/>
|
|
152
|
+
<CommandItem
|
|
153
|
+
command="pnpm playwright codegen"
|
|
154
|
+
description="Generate tests by recording"
|
|
155
|
+
/>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
{/* Test Types */}
|
|
160
|
+
<div className="border-2 border-black bg-gray-50 p-6 dark:border-gray-600 dark:bg-gray-900">
|
|
161
|
+
<h3 className="mb-4 font-bold text-black dark:text-white">
|
|
162
|
+
E2E Test Types
|
|
163
|
+
</h3>
|
|
164
|
+
<div className="grid gap-4 sm:grid-cols-2">
|
|
165
|
+
<TestTypeCard
|
|
166
|
+
icon="🖥️"
|
|
167
|
+
title="Page Tests"
|
|
168
|
+
description="Full page navigation and interaction tests"
|
|
169
|
+
pattern="*.e2e.test.ts"
|
|
170
|
+
/>
|
|
171
|
+
<TestTypeCard
|
|
172
|
+
icon="📸"
|
|
173
|
+
title="Visual Tests"
|
|
174
|
+
description="Screenshot comparison for UI changes"
|
|
175
|
+
pattern="*.visual.spec.ts"
|
|
176
|
+
/>
|
|
177
|
+
<TestTypeCard
|
|
178
|
+
icon="♿"
|
|
179
|
+
title="Accessibility"
|
|
180
|
+
description="WCAG compliance and a11y checks"
|
|
181
|
+
pattern="*.a11y.spec.ts"
|
|
182
|
+
/>
|
|
183
|
+
<TestTypeCard
|
|
184
|
+
icon="📱"
|
|
185
|
+
title="Responsive"
|
|
186
|
+
description="Mobile, tablet, and desktop viewports"
|
|
187
|
+
pattern="--project=mobile"
|
|
188
|
+
/>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function Step({
|
|
196
|
+
number,
|
|
197
|
+
title,
|
|
198
|
+
command,
|
|
199
|
+
description,
|
|
200
|
+
}: {
|
|
201
|
+
number: number;
|
|
202
|
+
title: string;
|
|
203
|
+
command: string;
|
|
204
|
+
description: string;
|
|
205
|
+
}) {
|
|
206
|
+
return (
|
|
207
|
+
<div className="flex gap-4">
|
|
208
|
+
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-[#BA0C2F] text-sm font-bold text-white">
|
|
209
|
+
{number}
|
|
210
|
+
</div>
|
|
211
|
+
<div>
|
|
212
|
+
<p className="font-medium text-black dark:text-white">{title}</p>
|
|
213
|
+
<code className="mt-1 block rounded bg-white px-3 py-1 font-mono text-sm text-[#BA0C2F] dark:bg-gray-800">
|
|
214
|
+
{command}
|
|
215
|
+
</code>
|
|
216
|
+
<p className="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
|
217
|
+
{description}
|
|
218
|
+
</p>
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function CommandItem({
|
|
225
|
+
command,
|
|
226
|
+
description,
|
|
227
|
+
}: {
|
|
228
|
+
command: string;
|
|
229
|
+
description: string;
|
|
230
|
+
}) {
|
|
231
|
+
return (
|
|
232
|
+
<div className="flex items-center justify-between rounded bg-white px-4 py-2 dark:bg-gray-800">
|
|
233
|
+
<code className="font-mono text-[#BA0C2F]">{command}</code>
|
|
234
|
+
<span className="text-sm text-gray-500">{description}</span>
|
|
235
|
+
</div>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function TestTypeCard({
|
|
240
|
+
icon,
|
|
241
|
+
title,
|
|
242
|
+
description,
|
|
243
|
+
pattern,
|
|
244
|
+
}: {
|
|
245
|
+
icon: string;
|
|
246
|
+
title: string;
|
|
247
|
+
description: string;
|
|
248
|
+
pattern: string;
|
|
249
|
+
}) {
|
|
250
|
+
return (
|
|
251
|
+
<div className="rounded border border-gray-200 bg-white p-4 dark:border-gray-700 dark:bg-gray-800">
|
|
252
|
+
<div className="mb-2 text-2xl">{icon}</div>
|
|
253
|
+
<h4 className="font-medium text-black dark:text-white">{title}</h4>
|
|
254
|
+
<p className="text-sm text-gray-600 dark:text-gray-400">{description}</p>
|
|
255
|
+
<code className="mt-2 block text-xs text-[#BA0C2F]">{pattern}</code>
|
|
256
|
+
</div>
|
|
257
|
+
);
|
|
258
|
+
}
|
package/templates/registry.json
CHANGED
|
@@ -1,7 +1,96 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.5.0",
|
|
3
3
|
"updated_at": "",
|
|
4
|
-
"description": "Central registry tracking all APIs, components, and
|
|
4
|
+
"description": "Central registry tracking all APIs, components, pages, hooks, utilities, types, routes, environment variables, external services, ADRs, and brand guide created through Hustle Dev Tools",
|
|
5
|
+
|
|
6
|
+
"adrs": {
|
|
7
|
+
"_description": "Architecture Decision Records - significant decisions with context and reasoning. Created during research, updated during interview.",
|
|
8
|
+
"_example": {
|
|
9
|
+
"0001-database-choice": {
|
|
10
|
+
"number": 1,
|
|
11
|
+
"title": "Database Choice",
|
|
12
|
+
"status": "accepted",
|
|
13
|
+
"date": "2025-12-30",
|
|
14
|
+
"phase": "interview",
|
|
15
|
+
"endpoint": "todo-app",
|
|
16
|
+
"category": "database",
|
|
17
|
+
"decision": "supabase",
|
|
18
|
+
"options_considered": ["supabase", "firebase", "postgres"],
|
|
19
|
+
"file": ".claude/adrs/0001-database-choice.md",
|
|
20
|
+
"decided_at": "2025-12-30T10:15:00Z"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"brand_guide": {
|
|
26
|
+
"_description": "Brand guide configuration tracking. Single source of truth for all UI styling decisions.",
|
|
27
|
+
"created_at": null,
|
|
28
|
+
"last_updated": null,
|
|
29
|
+
"version": 0,
|
|
30
|
+
"interview_completed": false,
|
|
31
|
+
"file": ".claude/BRAND_GUIDE.md",
|
|
32
|
+
"brand_page": "src/app/brand/page.tsx",
|
|
33
|
+
"theme_file": "src/lib/theme.ts",
|
|
34
|
+
"sections": {
|
|
35
|
+
"colors": false,
|
|
36
|
+
"typography": false,
|
|
37
|
+
"spacing": false,
|
|
38
|
+
"animations": false,
|
|
39
|
+
"voice": false,
|
|
40
|
+
"custom_elements": false
|
|
41
|
+
},
|
|
42
|
+
"custom_elements": [],
|
|
43
|
+
"_custom_elements_options": [
|
|
44
|
+
"terminal-animation",
|
|
45
|
+
"gradient-text",
|
|
46
|
+
"typing-effect",
|
|
47
|
+
"parallax-scroll",
|
|
48
|
+
"particle-background",
|
|
49
|
+
"three-js-scene",
|
|
50
|
+
"gsap-animations",
|
|
51
|
+
"lottie-animations",
|
|
52
|
+
"glassmorphism",
|
|
53
|
+
"neumorphism"
|
|
54
|
+
],
|
|
55
|
+
"voice": {
|
|
56
|
+
"tone": null,
|
|
57
|
+
"_tone_options": ["professional", "friendly", "technical", "playful", "custom"],
|
|
58
|
+
"terminology": {},
|
|
59
|
+
"dos": [],
|
|
60
|
+
"donts": []
|
|
61
|
+
},
|
|
62
|
+
"colors": {
|
|
63
|
+
"primary": null,
|
|
64
|
+
"secondary": null,
|
|
65
|
+
"accent": null,
|
|
66
|
+
"background": null,
|
|
67
|
+
"foreground": null,
|
|
68
|
+
"muted": null,
|
|
69
|
+
"destructive": null,
|
|
70
|
+
"gradients": []
|
|
71
|
+
},
|
|
72
|
+
"typography": {
|
|
73
|
+
"font_sans": null,
|
|
74
|
+
"font_mono": null,
|
|
75
|
+
"font_heading": null,
|
|
76
|
+
"scale": "default"
|
|
77
|
+
},
|
|
78
|
+
"motion": {
|
|
79
|
+
"style": null,
|
|
80
|
+
"_style_options": ["snappy", "smooth", "bouncy", "minimal", "none"],
|
|
81
|
+
"duration_fast": "150ms",
|
|
82
|
+
"duration_normal": "300ms",
|
|
83
|
+
"duration_slow": "500ms",
|
|
84
|
+
"easing": "ease-out",
|
|
85
|
+
"library": null,
|
|
86
|
+
"_library_options": ["css", "framer-motion", "gsap", "none"]
|
|
87
|
+
},
|
|
88
|
+
"shadcn": {
|
|
89
|
+
"initialized": false,
|
|
90
|
+
"components_installed": [],
|
|
91
|
+
"theme_configured": false
|
|
92
|
+
}
|
|
93
|
+
},
|
|
5
94
|
|
|
6
95
|
"apis": {},
|
|
7
96
|
|
|
@@ -9,5 +98,192 @@
|
|
|
9
98
|
|
|
10
99
|
"pages": {},
|
|
11
100
|
|
|
12
|
-
"combined": {}
|
|
101
|
+
"combined": {},
|
|
102
|
+
|
|
103
|
+
"routes": {
|
|
104
|
+
"_description": "All application routes - API routes, page routes, middleware. Enables dead route detection and navigation planning.",
|
|
105
|
+
"_example": {
|
|
106
|
+
"/api/users": {
|
|
107
|
+
"file": "src/app/api/users/route.ts",
|
|
108
|
+
"methods": ["GET", "POST"],
|
|
109
|
+
"auth_required": true,
|
|
110
|
+
"rate_limited": true,
|
|
111
|
+
"description": "User CRUD operations"
|
|
112
|
+
},
|
|
113
|
+
"/api/users/[id]": {
|
|
114
|
+
"file": "src/app/api/users/[id]/route.ts",
|
|
115
|
+
"methods": ["GET", "PUT", "DELETE"],
|
|
116
|
+
"auth_required": true,
|
|
117
|
+
"params": ["id"],
|
|
118
|
+
"description": "Single user operations"
|
|
119
|
+
},
|
|
120
|
+
"/dashboard": {
|
|
121
|
+
"file": "src/app/dashboard/page.tsx",
|
|
122
|
+
"type": "page",
|
|
123
|
+
"auth_required": true,
|
|
124
|
+
"layout": "src/app/dashboard/layout.tsx"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
"env_vars": {
|
|
130
|
+
"_description": "Environment variables required by the application. Enables /api-env validation and deployment checklists.",
|
|
131
|
+
"_example": {
|
|
132
|
+
"DATABASE_URL": {
|
|
133
|
+
"required": true,
|
|
134
|
+
"description": "PostgreSQL connection string",
|
|
135
|
+
"used_by": ["prisma", "src/lib/db.ts"],
|
|
136
|
+
"format": "postgresql://user:pass@host:5432/db",
|
|
137
|
+
"sensitive": true
|
|
138
|
+
},
|
|
139
|
+
"NEXT_PUBLIC_API_URL": {
|
|
140
|
+
"required": true,
|
|
141
|
+
"description": "Public API base URL",
|
|
142
|
+
"used_by": ["src/lib/api-client.ts"],
|
|
143
|
+
"public": true,
|
|
144
|
+
"sensitive": false
|
|
145
|
+
},
|
|
146
|
+
"STRIPE_SECRET_KEY": {
|
|
147
|
+
"required": false,
|
|
148
|
+
"description": "Stripe API secret key",
|
|
149
|
+
"used_by": ["src/app/api/payments/route.ts"],
|
|
150
|
+
"sensitive": true,
|
|
151
|
+
"docs": "https://stripe.com/docs/keys"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
"services": {
|
|
157
|
+
"_description": "External services and APIs the application depends on. Enables dependency tracking and outage awareness.",
|
|
158
|
+
"_example": {
|
|
159
|
+
"stripe": {
|
|
160
|
+
"name": "Stripe",
|
|
161
|
+
"type": "payment",
|
|
162
|
+
"sdk": "@stripe/stripe-js",
|
|
163
|
+
"env_vars": ["STRIPE_SECRET_KEY", "STRIPE_PUBLISHABLE_KEY", "STRIPE_WEBHOOK_SECRET"],
|
|
164
|
+
"endpoints_used": ["/v1/customers", "/v1/subscriptions", "/v1/checkout/sessions"],
|
|
165
|
+
"webhooks": ["/api/webhooks/stripe"],
|
|
166
|
+
"docs": "https://stripe.com/docs/api",
|
|
167
|
+
"status_page": "https://status.stripe.com"
|
|
168
|
+
},
|
|
169
|
+
"supabase": {
|
|
170
|
+
"name": "Supabase",
|
|
171
|
+
"type": "database",
|
|
172
|
+
"sdk": "@supabase/supabase-js",
|
|
173
|
+
"env_vars": ["SUPABASE_URL", "SUPABASE_ANON_KEY", "SUPABASE_SERVICE_KEY"],
|
|
174
|
+
"features_used": ["auth", "database", "storage"],
|
|
175
|
+
"docs": "https://supabase.com/docs",
|
|
176
|
+
"status_page": "https://status.supabase.com"
|
|
177
|
+
},
|
|
178
|
+
"openai": {
|
|
179
|
+
"name": "OpenAI",
|
|
180
|
+
"type": "ai",
|
|
181
|
+
"sdk": "openai",
|
|
182
|
+
"env_vars": ["OPENAI_API_KEY"],
|
|
183
|
+
"models_used": ["gpt-4", "gpt-3.5-turbo"],
|
|
184
|
+
"docs": "https://platform.openai.com/docs",
|
|
185
|
+
"status_page": "https://status.openai.com"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
"webhooks": {
|
|
191
|
+
"_description": "Incoming webhook endpoints and their configurations. Critical for security auditing.",
|
|
192
|
+
"_example": {
|
|
193
|
+
"/api/webhooks/stripe": {
|
|
194
|
+
"file": "src/app/api/webhooks/stripe/route.ts",
|
|
195
|
+
"service": "stripe",
|
|
196
|
+
"signature_header": "stripe-signature",
|
|
197
|
+
"signature_secret_env": "STRIPE_WEBHOOK_SECRET",
|
|
198
|
+
"events_handled": ["checkout.session.completed", "customer.subscription.updated"],
|
|
199
|
+
"idempotency": true
|
|
200
|
+
},
|
|
201
|
+
"/api/webhooks/github": {
|
|
202
|
+
"file": "src/app/api/webhooks/github/route.ts",
|
|
203
|
+
"service": "github",
|
|
204
|
+
"signature_header": "x-hub-signature-256",
|
|
205
|
+
"signature_secret_env": "GITHUB_WEBHOOK_SECRET",
|
|
206
|
+
"events_handled": ["push", "pull_request"]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
"hooks": {
|
|
212
|
+
"_description": "Custom React hooks - tracked to prevent duplication and enable reuse",
|
|
213
|
+
"_example": {
|
|
214
|
+
"useAuth": {
|
|
215
|
+
"file": "src/hooks/useAuth.ts",
|
|
216
|
+
"returns": "{ user: User | null, login: Function, logout: Function }",
|
|
217
|
+
"description": "Authentication hook with login/logout methods"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
"utils": {
|
|
223
|
+
"_description": "Utility functions - tracked to prevent duplication",
|
|
224
|
+
"_example": {
|
|
225
|
+
"formatCurrency": {
|
|
226
|
+
"file": "src/lib/utils/format.ts",
|
|
227
|
+
"signature": "(amount: number, currency?: string) => string",
|
|
228
|
+
"description": "Format number as currency with locale support"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
"types": {
|
|
234
|
+
"_description": "Shared TypeScript types - tracked for schema consistency",
|
|
235
|
+
"_example": {
|
|
236
|
+
"User": {
|
|
237
|
+
"file": "src/types/user.ts",
|
|
238
|
+
"definition": "{ id: string, email: string, name: string }",
|
|
239
|
+
"used_by": ["useAuth", "UserProfile", "api/users"]
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
"providers": {
|
|
245
|
+
"_description": "React Context providers - tracked to show app structure",
|
|
246
|
+
"_example": {
|
|
247
|
+
"AuthProvider": {
|
|
248
|
+
"file": "src/providers/AuthProvider.tsx",
|
|
249
|
+
"context": "AuthContext",
|
|
250
|
+
"provides": "{ user, login, logout }",
|
|
251
|
+
"wraps": "entire app"
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
"orchestrator_defaults": {
|
|
257
|
+
"description": "Shared decisions from /hustle-build orchestrator interviews - applied to all sub-workflows",
|
|
258
|
+
"error_handling": {
|
|
259
|
+
"style": null,
|
|
260
|
+
"options": ["try-catch-rethrow", "error-boundary", "result-type", "error-codes"]
|
|
261
|
+
},
|
|
262
|
+
"authentication": {
|
|
263
|
+
"method": null,
|
|
264
|
+
"options": ["jwt", "session", "api-key", "oauth", "none"]
|
|
265
|
+
},
|
|
266
|
+
"logging": {
|
|
267
|
+
"level": null,
|
|
268
|
+
"options": ["verbose", "standard", "minimal", "none"]
|
|
269
|
+
},
|
|
270
|
+
"api_versioning": {
|
|
271
|
+
"strategy": null,
|
|
272
|
+
"options": ["url-prefix", "header", "query-param", "none"]
|
|
273
|
+
},
|
|
274
|
+
"testing": {
|
|
275
|
+
"coverage_threshold": null,
|
|
276
|
+
"visual_viewports": ["mobile-portrait", "mobile-notch", "mobile-landscape", "tablet-portrait", "tablet-landscape", "small-desktop", "desktop"]
|
|
277
|
+
},
|
|
278
|
+
"styling": {
|
|
279
|
+
"approach": null,
|
|
280
|
+
"options": ["tailwind", "css-modules", "styled-components", "emotion", "vanilla"]
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
|
|
284
|
+
"visual_test_results": {
|
|
285
|
+
"description": "Results from /test-visual runs - populated by visual-analyzer agent",
|
|
286
|
+
"last_run": null,
|
|
287
|
+
"elements": {}
|
|
288
|
+
}
|
|
13
289
|
}
|