@dtlabs/ai-toolkit 0.10.0 → 0.11.0
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 +79 -0
- package/bin/cli.js +1178 -64
- package/docs/installation.md +74 -8
- package/docs/reference.md +60 -12
- package/lib/asset-catalog.js +52 -0
- package/package.json +9 -2
- package/{.claude → src/claude}/agents/install-toolkit.md +30 -103
- package/{.claude → src/claude}/workflows/am-phase1.js +9 -12
- package/{.claude → src/claude}/workflows/pm-phase2.js +2 -2
- package/.claude/.ai-toolkit-version +0 -1
- package/.claude/scripts/.gitkeep +0 -0
- package/.claude/scripts/tests/fixtures/ac-table-format.md +0 -48
- package/.claude/scripts/tests/fixtures/test-feature/TEST-001-Work-Breakdown.json +0 -234
- package/.claude/scripts/tests/fixtures/test-feature/TEST-001-semantic-output.json +0 -4
- package/.claude/scripts/tests/fixtures/test-feature/feature.md +0 -45
- package/.claude/scripts/tests/fixtures/wb-invalid-bad-domain.json +0 -39
- package/.claude/scripts/tests/fixtures/wb-invalid-cycle.json +0 -61
- package/.claude/scripts/tests/fixtures/wb-invalid-duplicate-id.json +0 -72
- package/.claude/scripts/tests/fixtures/wb-invalid-missing-field.json +0 -38
- package/.claude/scripts/tests/fixtures/wb-valid.json +0 -189
- package/.claude/scripts/tests/helpers/buildWaves.js +0 -21
- package/.claude/scripts/tests/helpers/pm-phase2-flow.js +0 -29
- package/.claude/scripts/tests/helpers/pm-phase2-gate2.js +0 -55
- package/.claude/scripts/tests/helpers/pm-phase2-ledger.js +0 -108
- package/.claude/scripts/tests/installer.scripts-distribution.test.js +0 -131
- package/.claude/scripts/tests/pm-phase2.gate2-payload.test.js +0 -353
- package/.claude/scripts/tests/pm-phase2.ledger-transitions.test.js +0 -346
- package/.claude/scripts/tests/pm-phase2.orchestration-flow.test.js +0 -276
- package/.claude/scripts/tests/verify-us-01-t03.js +0 -288
- package/.claude/scripts/tests/verify-us-03-t04.js +0 -262
- package/.claude/scripts/tests/wb-render.checks-md-csv-deps.test.js +0 -337
- package/.claude/scripts/tests/wb-render.checks-sanitize-commit-paths.test.js +0 -352
- package/.claude/scripts/tests/wb-render.regression-pm-phase3-csv.test.js +0 -219
- package/.claude/scripts/tests/wb-validate.checks-1-7.test.js +0 -330
- package/.claude/scripts/tests/wb-validate.checks-11.test.js +0 -166
- package/.claude/scripts/tests/wb-validate.checks-12-14.test.js +0 -222
- package/.claude/scripts/tests/wb-validate.checks-15-18.test.js +0 -359
- package/.claude/scripts/tests/wb-validate.checks-19-21.test.js +0 -362
- package/.claude/scripts/tests/wb-validate.checks-22-23-report.test.js +0 -297
- package/.claude/scripts/tests/wb-validate.checks-8-10.test.js +0 -243
- package/.claude/settings.json +0 -5
- /package/{.claude → src/claude}/agents/concurrency-safety-assessment.md +0 -0
- /package/{.claude → src/claude}/agents/define-feature.md +0 -0
- /package/{.claude → src/claude}/agents/dependency-injection-refactoring.md +0 -0
- /package/{.claude → src/claude}/agents/dependency-supply-chain-security.md +0 -0
- /package/{.claude → src/claude}/agents/developer-backend.md +0 -0
- /package/{.claude → src/claude}/agents/developer-frontend.md +0 -0
- /package/{.claude → src/claude}/agents/developer-testing.md +0 -0
- /package/{.claude → src/claude}/agents/domain-model-refactoring.md +0 -0
- /package/{.claude → src/claude}/agents/generate-requirements.md +0 -0
- /package/{.claude → src/claude}/agents/generate-tech-spec.md +0 -0
- /package/{.claude → src/claude}/agents/generate-work-breakdown.md +0 -0
- /package/{.claude → src/claude}/agents/generic-software-assessment.md +0 -0
- /package/{.claude → src/claude}/agents/god-class-decomposition.md +0 -0
- /package/{.claude → src/claude}/agents/init-agents-md.md +0 -0
- /package/{.claude → src/claude}/agents/intervention-documentation-standard.md +0 -0
- /package/{.claude → src/claude}/agents/layered-architecture-assessment.md +0 -0
- /package/{.claude → src/claude}/agents/review-solution.md +0 -0
- /package/{.claude → src/claude}/agents/security-hardening.md +0 -0
- /package/{.claude → src/claude}/agents/validate-feature-docs.md +0 -0
- /package/{.claude → src/claude}/agents/validate-work-breakdown-semantic.md +0 -0
- /package/{.claude → src/claude}/commands/assessment-status.md +0 -0
- /package/{.claude → src/claude}/commands/check-docs.md +0 -0
- /package/{.claude → src/claude}/commands/check-interventions.md +0 -0
- /package/{.claude → src/claude}/commands/feature-status.md +0 -0
- /package/{.claude → src/claude}/commands/next-intervention.md +0 -0
- /package/{.claude → src/claude}/commands/next-task.md +0 -0
- /package/{.claude → src/claude}/commands/pr-description.md +0 -0
- /package/{.claude → src/claude}/scripts/wb-render.js +0 -0
- /package/{.claude → src/claude}/scripts/wb-validate.js +0 -0
- /package/{.claude → src/claude}/skills/assess-codebase/SKILL.md +0 -0
- /package/{.claude → src/claude}/skills/define-feature/SKILL.md +0 -0
- /package/{.claude → src/claude}/skills/hi-gaia/SKILL.md +0 -0
- /package/{.claude → src/claude}/skills/implement-feature/SKILL.md +0 -0
- /package/{.claude → src/claude}/skills/init-agents/SKILL.md +0 -0
- /package/{.claude → src/claude}/skills/install-toolkit/SKILL.md +0 -0
- /package/{.claude → src/claude}/workflows/am-phase2.js +0 -0
- /package/{.claude → src/claude}/workflows/pm-phase1.js +0 -0
- /package/{.claude → src/claude}/workflows/pm-phase3.js +0 -0
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 2,
|
|
3
|
-
"feature": "TEST-001",
|
|
4
|
-
"phases": [
|
|
5
|
-
{
|
|
6
|
-
"id": "INFRA",
|
|
7
|
-
"type": "infrastructure",
|
|
8
|
-
"title": "Shared infrastructure setup for JWT authentication",
|
|
9
|
-
"commit": { "type": "feat", "subject": "shared infrastructure for JWT auth" },
|
|
10
|
-
"tasks": [
|
|
11
|
-
{
|
|
12
|
-
"id": "INFRA-TASK-DB-01",
|
|
13
|
-
"title": "Register database context and User entity",
|
|
14
|
-
"outcome": "User entity is mapped in the database context; schema includes users table with id, email, passwordHash columns",
|
|
15
|
-
"domain": "DB",
|
|
16
|
-
"agentType": "developer-database",
|
|
17
|
-
"dependsOn": [],
|
|
18
|
-
"acceptanceCriteria": [],
|
|
19
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
20
|
-
"estimate": { "agentMinutes": 8, "tokens": 18000 },
|
|
21
|
-
"outputCount": 1,
|
|
22
|
-
"groupingRationale": null,
|
|
23
|
-
"commit": { "type": "feat", "subject": "add User entity and database context registration" }
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"id": "INFRA-TASK-DB-02",
|
|
27
|
-
"title": "Create RefreshToken entity and migration",
|
|
28
|
-
"outcome": "RefreshToken entity is mapped; migration creates refresh_tokens table with token, userId, expiresAt columns",
|
|
29
|
-
"domain": "DB",
|
|
30
|
-
"agentType": "developer-database",
|
|
31
|
-
"dependsOn": ["INFRA-TASK-DB-01"],
|
|
32
|
-
"acceptanceCriteria": [],
|
|
33
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
34
|
-
"estimate": { "agentMinutes": 8, "tokens": 18000 },
|
|
35
|
-
"outputCount": 1,
|
|
36
|
-
"groupingRationale": null,
|
|
37
|
-
"commit": { "type": "feat", "subject": "add RefreshToken entity and migration" }
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"id": "INFRA-TASK-BE-01",
|
|
41
|
-
"title": "Configure JWT signing secret and token expiry constants",
|
|
42
|
-
"outcome": "JWT_SECRET, ACCESS_TOKEN_EXPIRY (15m), and REFRESH_TOKEN_EXPIRY (7d) constants are loaded from environment variables and exported",
|
|
43
|
-
"domain": "BE",
|
|
44
|
-
"agentType": "developer-backend",
|
|
45
|
-
"dependsOn": [],
|
|
46
|
-
"acceptanceCriteria": [],
|
|
47
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
48
|
-
"estimate": { "agentMinutes": 5, "tokens": 10000 },
|
|
49
|
-
"outputCount": 1,
|
|
50
|
-
"groupingRationale": null,
|
|
51
|
-
"commit": { "type": "feat", "subject": "add JWT signing secret and expiry config constants" }
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"id": "INFRA-TASK-BE-02",
|
|
55
|
-
"title": "Implement JwtService — sign and verify helpers",
|
|
56
|
-
"outcome": "JwtService class exists with signAccessToken(userId) and verifyToken(token) methods; uses INFRA-TASK-BE-01 constants",
|
|
57
|
-
"domain": "BE",
|
|
58
|
-
"agentType": "developer-backend",
|
|
59
|
-
"dependsOn": ["INFRA-TASK-BE-01"],
|
|
60
|
-
"acceptanceCriteria": [],
|
|
61
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
62
|
-
"estimate": { "agentMinutes": 10, "tokens": 22000 },
|
|
63
|
-
"outputCount": 1,
|
|
64
|
-
"groupingRationale": null,
|
|
65
|
-
"commit": { "type": "feat", "subject": "add JwtService sign and verify helpers" }
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"id": "INFRA-TASK-BE-03",
|
|
69
|
-
"title": "Implement PasswordService — hash and compare helpers",
|
|
70
|
-
"outcome": "PasswordService class exists with hashPassword(plain) and comparePassword(plain, hash) methods using bcrypt",
|
|
71
|
-
"domain": "BE",
|
|
72
|
-
"agentType": "developer-backend",
|
|
73
|
-
"dependsOn": [],
|
|
74
|
-
"acceptanceCriteria": [],
|
|
75
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
76
|
-
"estimate": { "agentMinutes": 8, "tokens": 15000 },
|
|
77
|
-
"outputCount": 1,
|
|
78
|
-
"groupingRationale": null,
|
|
79
|
-
"commit": { "type": "feat", "subject": "add PasswordService bcrypt helpers" }
|
|
80
|
-
}
|
|
81
|
-
]
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
"id": "US-01",
|
|
85
|
-
"type": "user-story",
|
|
86
|
-
"title": "As an anonymous user, I want to register with email and password, so that I can access the system",
|
|
87
|
-
"commit": { "type": "feat", "subject": "implement US-01 user registration" },
|
|
88
|
-
"tasks": [
|
|
89
|
-
{
|
|
90
|
-
"id": "US-01-TASK-BE-01",
|
|
91
|
-
"title": "Implement RegisterUserService",
|
|
92
|
-
"outcome": "RegisterUserService class exists with register(email, password) method; validates uniqueness, hashes password via PasswordService, persists User, returns user id and email",
|
|
93
|
-
"domain": "BE",
|
|
94
|
-
"agentType": "developer-backend",
|
|
95
|
-
"dependsOn": ["INFRA-TASK-DB-01", "INFRA-TASK-BE-03"],
|
|
96
|
-
"acceptanceCriteria": ["AC-01", "AC-02", "AC-03"],
|
|
97
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
98
|
-
"estimate": { "agentMinutes": 13, "tokens": 30000 },
|
|
99
|
-
"outputCount": 1,
|
|
100
|
-
"groupingRationale": null,
|
|
101
|
-
"commit": { "type": "feat", "subject": "add RegisterUserService with uniqueness and hash validation" }
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"id": "US-01-TASK-BE-02",
|
|
105
|
-
"title": "Implement POST /auth/register endpoint",
|
|
106
|
-
"outcome": "POST /auth/register controller action exists; validates request body (email, password), delegates to RegisterUserService, returns 201 on success or 409 on duplicate email",
|
|
107
|
-
"domain": "BE",
|
|
108
|
-
"agentType": "developer-backend",
|
|
109
|
-
"dependsOn": ["US-01-TASK-BE-01"],
|
|
110
|
-
"acceptanceCriteria": ["AC-01", "AC-02"],
|
|
111
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
112
|
-
"estimate": { "agentMinutes": 10, "tokens": 22000 },
|
|
113
|
-
"outputCount": 1,
|
|
114
|
-
"groupingRationale": null,
|
|
115
|
-
"commit": { "type": "feat", "subject": "add POST /auth/register endpoint" }
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
"id": "US-01-TASK-TEST-01",
|
|
119
|
-
"title": "Tests: user registration — success, duplicate email, password hashing",
|
|
120
|
-
"outcome": "Jest test suite for RegisterUserService and POST /auth/register covering 201 success, 409 conflict, and bcrypt hash verification",
|
|
121
|
-
"domain": "TEST",
|
|
122
|
-
"agentType": "developer-testing",
|
|
123
|
-
"dependsOn": ["US-01-TASK-BE-01", "US-01-TASK-BE-02"],
|
|
124
|
-
"acceptanceCriteria": ["AC-01", "AC-02", "AC-03"],
|
|
125
|
-
"verification": { "commands": ["npx jest --testPathPattern=register"] },
|
|
126
|
-
"estimate": { "agentMinutes": 15, "tokens": 35000 },
|
|
127
|
-
"outputCount": 1,
|
|
128
|
-
"groupingRationale": null,
|
|
129
|
-
"commit": { "type": "test", "subject": "add registration unit and integration tests" }
|
|
130
|
-
}
|
|
131
|
-
]
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
"id": "US-02",
|
|
135
|
-
"type": "user-story",
|
|
136
|
-
"title": "As a registered user, I want to log in with my credentials, so that I receive JWT access and refresh tokens",
|
|
137
|
-
"commit": { "type": "feat", "subject": "implement US-02 user login" },
|
|
138
|
-
"tasks": [
|
|
139
|
-
{
|
|
140
|
-
"id": "US-02-TASK-BE-01",
|
|
141
|
-
"title": "Implement LoginService",
|
|
142
|
-
"outcome": "LoginService class exists with login(email, password) method; validates credentials via PasswordService, signs access and refresh tokens via JwtService, persists RefreshToken, returns both tokens",
|
|
143
|
-
"domain": "BE",
|
|
144
|
-
"agentType": "developer-backend",
|
|
145
|
-
"dependsOn": ["INFRA-TASK-DB-01", "INFRA-TASK-DB-02", "INFRA-TASK-BE-02", "INFRA-TASK-BE-03"],
|
|
146
|
-
"acceptanceCriteria": ["AC-04", "AC-05"],
|
|
147
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
148
|
-
"estimate": { "agentMinutes": 14, "tokens": 32000 },
|
|
149
|
-
"outputCount": 1,
|
|
150
|
-
"groupingRationale": null,
|
|
151
|
-
"commit": { "type": "feat", "subject": "add LoginService with credential validation and token issuance" }
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
"id": "US-02-TASK-BE-02",
|
|
155
|
-
"title": "Implement POST /auth/login endpoint",
|
|
156
|
-
"outcome": "POST /auth/login controller action exists; validates request body, delegates to LoginService, returns 200 with accessToken and refreshToken or 401 on invalid credentials",
|
|
157
|
-
"domain": "BE",
|
|
158
|
-
"agentType": "developer-backend",
|
|
159
|
-
"dependsOn": ["US-02-TASK-BE-01"],
|
|
160
|
-
"acceptanceCriteria": ["AC-04", "AC-05"],
|
|
161
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
162
|
-
"estimate": { "agentMinutes": 9, "tokens": 20000 },
|
|
163
|
-
"outputCount": 1,
|
|
164
|
-
"groupingRationale": null,
|
|
165
|
-
"commit": { "type": "feat", "subject": "add POST /auth/login endpoint" }
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
"id": "US-02-TASK-TEST-01",
|
|
169
|
-
"title": "Tests: user login — success, invalid password, unknown email",
|
|
170
|
-
"outcome": "Jest test suite for LoginService and POST /auth/login covering 200 with tokens, 401 on bad password, and 401 on unknown email",
|
|
171
|
-
"domain": "TEST",
|
|
172
|
-
"agentType": "developer-testing",
|
|
173
|
-
"dependsOn": ["US-02-TASK-BE-01", "US-02-TASK-BE-02"],
|
|
174
|
-
"acceptanceCriteria": ["AC-04", "AC-05"],
|
|
175
|
-
"verification": { "commands": ["npx jest --testPathPattern=login"] },
|
|
176
|
-
"estimate": { "agentMinutes": 14, "tokens": 32000 },
|
|
177
|
-
"outputCount": 1,
|
|
178
|
-
"groupingRationale": null,
|
|
179
|
-
"commit": { "type": "test", "subject": "add login unit and integration tests" }
|
|
180
|
-
}
|
|
181
|
-
]
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
"id": "US-03",
|
|
185
|
-
"type": "user-story",
|
|
186
|
-
"title": "As an authenticated client, I want to refresh my access token, so that I stay logged in without re-entering credentials",
|
|
187
|
-
"commit": { "type": "feat", "subject": "implement US-03 token refresh" },
|
|
188
|
-
"tasks": [
|
|
189
|
-
{
|
|
190
|
-
"id": "US-03-TASK-BE-01",
|
|
191
|
-
"title": "Implement TokenRefreshService",
|
|
192
|
-
"outcome": "TokenRefreshService class exists with refresh(refreshToken) method; validates token via JwtService, invalidates old RefreshToken, issues new access and refresh tokens, persists new RefreshToken",
|
|
193
|
-
"domain": "BE",
|
|
194
|
-
"agentType": "developer-backend",
|
|
195
|
-
"dependsOn": ["INFRA-TASK-DB-02", "INFRA-TASK-BE-02"],
|
|
196
|
-
"acceptanceCriteria": ["AC-06", "AC-07"],
|
|
197
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
198
|
-
"estimate": { "agentMinutes": 13, "tokens": 30000 },
|
|
199
|
-
"outputCount": 1,
|
|
200
|
-
"groupingRationale": null,
|
|
201
|
-
"commit": { "type": "feat", "subject": "add TokenRefreshService with rotation logic" }
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
"id": "US-03-TASK-BE-02",
|
|
205
|
-
"title": "Implement POST /auth/refresh endpoint",
|
|
206
|
-
"outcome": "POST /auth/refresh controller action exists; validates request body, delegates to TokenRefreshService, returns 200 with new accessToken and refreshToken or 401 on invalid/expired token",
|
|
207
|
-
"domain": "BE",
|
|
208
|
-
"agentType": "developer-backend",
|
|
209
|
-
"dependsOn": ["US-03-TASK-BE-01"],
|
|
210
|
-
"acceptanceCriteria": ["AC-06", "AC-07"],
|
|
211
|
-
"verification": { "commands": ["npx tsc --noEmit"] },
|
|
212
|
-
"estimate": { "agentMinutes": 9, "tokens": 20000 },
|
|
213
|
-
"outputCount": 1,
|
|
214
|
-
"groupingRationale": null,
|
|
215
|
-
"commit": { "type": "feat", "subject": "add POST /auth/refresh endpoint" }
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
"id": "US-03-TASK-TEST-01",
|
|
219
|
-
"title": "Tests: token refresh — success with rotation, expired token, reuse of invalidated token",
|
|
220
|
-
"outcome": "Jest test suite for TokenRefreshService and POST /auth/refresh covering 200 with rotated tokens, 401 on expired token, and 401 on reuse of already-invalidated token",
|
|
221
|
-
"domain": "TEST",
|
|
222
|
-
"agentType": "developer-testing",
|
|
223
|
-
"dependsOn": ["US-03-TASK-BE-01", "US-03-TASK-BE-02"],
|
|
224
|
-
"acceptanceCriteria": ["AC-06", "AC-07"],
|
|
225
|
-
"verification": { "commands": ["npx jest --testPathPattern=refresh"] },
|
|
226
|
-
"estimate": { "agentMinutes": 15, "tokens": 35000 },
|
|
227
|
-
"outputCount": 1,
|
|
228
|
-
"groupingRationale": null,
|
|
229
|
-
"commit": { "type": "test", "subject": "add token refresh unit and integration tests" }
|
|
230
|
-
}
|
|
231
|
-
]
|
|
232
|
-
}
|
|
233
|
-
]
|
|
234
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Feature: TEST-001 — JWT Authentication
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Add user authentication to the API using JSON Web Tokens (JWT). Users register with an email and password, log in to receive a signed access token, and present that token on protected endpoints. A token refresh flow is also supported.
|
|
6
|
-
|
|
7
|
-
## Goals
|
|
8
|
-
|
|
9
|
-
- Allow new users to register with a unique email address and a hashed password.
|
|
10
|
-
- Allow registered users to log in and receive a short-lived JWT access token and a long-lived refresh token.
|
|
11
|
-
- Allow clients to exchange a valid refresh token for a new access token without re-entering credentials.
|
|
12
|
-
- Protect designated API routes so that only requests bearing a valid JWT are accepted.
|
|
13
|
-
|
|
14
|
-
## Non-Goals
|
|
15
|
-
|
|
16
|
-
- OAuth / social login is out of scope.
|
|
17
|
-
- Role-based access control beyond "authenticated vs. anonymous" is out of scope.
|
|
18
|
-
|
|
19
|
-
## Actors
|
|
20
|
-
|
|
21
|
-
- **Anonymous user** — not yet authenticated; may register or log in.
|
|
22
|
-
- **Authenticated user** — holds a valid JWT; may call protected endpoints and refresh tokens.
|
|
23
|
-
|
|
24
|
-
## Use Cases
|
|
25
|
-
|
|
26
|
-
### UC-01: User Registration
|
|
27
|
-
An anonymous user submits an email and password. The system validates the input, checks the email is not already taken, hashes the password, persists a new user record, and returns a 201 response.
|
|
28
|
-
|
|
29
|
-
### UC-02: User Login
|
|
30
|
-
A registered user submits their email and password. The system validates credentials, signs a JWT access token (15-minute expiry) and a refresh token (7-day expiry), persists the refresh token, and returns both tokens.
|
|
31
|
-
|
|
32
|
-
### UC-03: Token Refresh
|
|
33
|
-
An authenticated client presents a valid refresh token. The system validates the token, rotates it (invalidates the old one, issues a new one), and returns a fresh access token and new refresh token.
|
|
34
|
-
|
|
35
|
-
## Acceptance Criteria
|
|
36
|
-
|
|
37
|
-
| ID | Priority | User Story | Description |
|
|
38
|
-
|-------|----------|-----------|-------------|
|
|
39
|
-
| AC-01 | Must | US-01 | POST /auth/register returns 201 with user id and email on valid input |
|
|
40
|
-
| AC-02 | Must | US-01 | POST /auth/register returns 409 when email already exists |
|
|
41
|
-
| AC-03 | Must | US-01 | Passwords are stored as bcrypt hashes; plain text is never persisted |
|
|
42
|
-
| AC-04 | Must | US-02 | POST /auth/login returns 200 with accessToken and refreshToken on valid credentials |
|
|
43
|
-
| AC-05 | Must | US-02 | POST /auth/login returns 401 on invalid credentials |
|
|
44
|
-
| AC-06 | Must | US-03 | POST /auth/refresh returns 200 with a new accessToken and rotated refreshToken |
|
|
45
|
-
| AC-07 | Must | US-03 | POST /auth/refresh returns 401 when refresh token is expired or invalid |
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 2,
|
|
3
|
-
"feature": "FTR-014",
|
|
4
|
-
"phases": [
|
|
5
|
-
{
|
|
6
|
-
"id": "INFRA",
|
|
7
|
-
"type": "infrastructure",
|
|
8
|
-
"title": "Shared infrastructure setup",
|
|
9
|
-
"commit": {
|
|
10
|
-
"type": "feat",
|
|
11
|
-
"subject": "add shared infrastructure"
|
|
12
|
-
},
|
|
13
|
-
"tasks": [
|
|
14
|
-
{
|
|
15
|
-
"id": "INFRA-TASK-INFRA-01",
|
|
16
|
-
"title": "Create scripts directory",
|
|
17
|
-
"outcome": "The .claude/scripts directory exists",
|
|
18
|
-
"domain": "BACKEND",
|
|
19
|
-
"agentType": "developer-backend",
|
|
20
|
-
"dependsOn": [],
|
|
21
|
-
"acceptanceCriteria": [],
|
|
22
|
-
"verification": {
|
|
23
|
-
"commands": ["ls .claude/scripts"]
|
|
24
|
-
},
|
|
25
|
-
"estimate": {
|
|
26
|
-
"agentMinutes": 5,
|
|
27
|
-
"tokens": 8000
|
|
28
|
-
},
|
|
29
|
-
"outputCount": 1,
|
|
30
|
-
"groupingRationale": null,
|
|
31
|
-
"commit": {
|
|
32
|
-
"type": "feat",
|
|
33
|
-
"subject": "create .claude/scripts directory"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
}
|
|
38
|
-
]
|
|
39
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 2,
|
|
3
|
-
"feature": "FTR-014",
|
|
4
|
-
"phases": [
|
|
5
|
-
{
|
|
6
|
-
"id": "INFRA",
|
|
7
|
-
"type": "infrastructure",
|
|
8
|
-
"title": "Shared infrastructure setup",
|
|
9
|
-
"commit": {
|
|
10
|
-
"type": "feat",
|
|
11
|
-
"subject": "add shared infrastructure"
|
|
12
|
-
},
|
|
13
|
-
"tasks": [
|
|
14
|
-
{
|
|
15
|
-
"id": "INFRA-TASK-INFRA-01",
|
|
16
|
-
"title": "Task A — depends on Task B (forms a cycle)",
|
|
17
|
-
"outcome": "Task A exists and triggers task_cycle_detected when validated",
|
|
18
|
-
"domain": "INFRA",
|
|
19
|
-
"agentType": "developer-backend",
|
|
20
|
-
"dependsOn": ["INFRA-TASK-INFRA-02"],
|
|
21
|
-
"acceptanceCriteria": [],
|
|
22
|
-
"verification": {
|
|
23
|
-
"commands": ["npm test"]
|
|
24
|
-
},
|
|
25
|
-
"estimate": {
|
|
26
|
-
"agentMinutes": 5,
|
|
27
|
-
"tokens": 8000
|
|
28
|
-
},
|
|
29
|
-
"outputCount": 1,
|
|
30
|
-
"groupingRationale": null,
|
|
31
|
-
"commit": {
|
|
32
|
-
"type": "feat",
|
|
33
|
-
"subject": "add task A"
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"id": "INFRA-TASK-INFRA-02",
|
|
38
|
-
"title": "Task B — depends on Task A (forms a cycle)",
|
|
39
|
-
"outcome": "Task B exists and triggers task_cycle_detected when validated",
|
|
40
|
-
"domain": "INFRA",
|
|
41
|
-
"agentType": "developer-backend",
|
|
42
|
-
"dependsOn": ["INFRA-TASK-INFRA-01"],
|
|
43
|
-
"acceptanceCriteria": [],
|
|
44
|
-
"verification": {
|
|
45
|
-
"commands": ["npm test"]
|
|
46
|
-
},
|
|
47
|
-
"estimate": {
|
|
48
|
-
"agentMinutes": 5,
|
|
49
|
-
"tokens": 8000
|
|
50
|
-
},
|
|
51
|
-
"outputCount": 1,
|
|
52
|
-
"groupingRationale": null,
|
|
53
|
-
"commit": {
|
|
54
|
-
"type": "feat",
|
|
55
|
-
"subject": "add task B"
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
]
|
|
59
|
-
}
|
|
60
|
-
]
|
|
61
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 2,
|
|
3
|
-
"feature": "FTR-014",
|
|
4
|
-
"phases": [
|
|
5
|
-
{
|
|
6
|
-
"id": "INFRA",
|
|
7
|
-
"type": "infrastructure",
|
|
8
|
-
"title": "Shared infrastructure setup",
|
|
9
|
-
"commit": {
|
|
10
|
-
"type": "feat",
|
|
11
|
-
"subject": "add shared infrastructure"
|
|
12
|
-
},
|
|
13
|
-
"tasks": [
|
|
14
|
-
{
|
|
15
|
-
"id": "INFRA-TASK-INFRA-01",
|
|
16
|
-
"title": "Create scripts directory",
|
|
17
|
-
"outcome": "The .claude/scripts directory exists",
|
|
18
|
-
"domain": "INFRA",
|
|
19
|
-
"agentType": "developer-backend",
|
|
20
|
-
"dependsOn": [],
|
|
21
|
-
"acceptanceCriteria": [],
|
|
22
|
-
"verification": {
|
|
23
|
-
"commands": ["ls .claude/scripts"]
|
|
24
|
-
},
|
|
25
|
-
"estimate": {
|
|
26
|
-
"agentMinutes": 5,
|
|
27
|
-
"tokens": 8000
|
|
28
|
-
},
|
|
29
|
-
"outputCount": 1,
|
|
30
|
-
"groupingRationale": null,
|
|
31
|
-
"commit": {
|
|
32
|
-
"type": "feat",
|
|
33
|
-
"subject": "create .claude/scripts directory"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"id": "US-01",
|
|
40
|
-
"type": "user-story",
|
|
41
|
-
"title": "Implement validator entry point",
|
|
42
|
-
"commit": {
|
|
43
|
-
"type": "feat",
|
|
44
|
-
"subject": "implement validator entry point"
|
|
45
|
-
},
|
|
46
|
-
"tasks": [
|
|
47
|
-
{
|
|
48
|
-
"id": "INFRA-TASK-INFRA-01",
|
|
49
|
-
"title": "Duplicate task ID — same as INFRA-TASK-INFRA-01 above",
|
|
50
|
-
"outcome": "This task intentionally reuses INFRA-TASK-INFRA-01 to trigger unique_id_violation",
|
|
51
|
-
"domain": "BE",
|
|
52
|
-
"agentType": "developer-backend",
|
|
53
|
-
"dependsOn": [],
|
|
54
|
-
"acceptanceCriteria": [],
|
|
55
|
-
"verification": {
|
|
56
|
-
"commands": ["npm test"]
|
|
57
|
-
},
|
|
58
|
-
"estimate": {
|
|
59
|
-
"agentMinutes": 8,
|
|
60
|
-
"tokens": 12000
|
|
61
|
-
},
|
|
62
|
-
"outputCount": 1,
|
|
63
|
-
"groupingRationale": null,
|
|
64
|
-
"commit": {
|
|
65
|
-
"type": "feat",
|
|
66
|
-
"subject": "add duplicate task"
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
]
|
|
70
|
-
}
|
|
71
|
-
]
|
|
72
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 2,
|
|
3
|
-
"feature": "FTR-014",
|
|
4
|
-
"phases": [
|
|
5
|
-
{
|
|
6
|
-
"id": "INFRA",
|
|
7
|
-
"type": "infrastructure",
|
|
8
|
-
"title": "Shared infrastructure setup",
|
|
9
|
-
"commit": {
|
|
10
|
-
"type": "feat",
|
|
11
|
-
"subject": "add shared infrastructure"
|
|
12
|
-
},
|
|
13
|
-
"tasks": [
|
|
14
|
-
{
|
|
15
|
-
"id": "INFRA-TASK-INFRA-01",
|
|
16
|
-
"title": "Create scripts directory",
|
|
17
|
-
"domain": "INFRA",
|
|
18
|
-
"agentType": "developer-backend",
|
|
19
|
-
"dependsOn": [],
|
|
20
|
-
"acceptanceCriteria": [],
|
|
21
|
-
"verification": {
|
|
22
|
-
"commands": ["ls .claude/scripts"]
|
|
23
|
-
},
|
|
24
|
-
"estimate": {
|
|
25
|
-
"agentMinutes": 5,
|
|
26
|
-
"tokens": 8000
|
|
27
|
-
},
|
|
28
|
-
"outputCount": 1,
|
|
29
|
-
"groupingRationale": null,
|
|
30
|
-
"commit": {
|
|
31
|
-
"type": "feat",
|
|
32
|
-
"subject": "create .claude/scripts directory"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
]
|
|
38
|
-
}
|