@champpaba/claude-agent-kit 2.0.0 → 2.0.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/CHANGELOG-v1.1.1.md +259 -259
- package/.claude/CLAUDE.md +196 -31
- package/.claude/agents/01-integration.md +106 -552
- package/.claude/agents/02-uxui-frontend.md +188 -850
- package/.claude/agents/03-test-debug.md +152 -521
- package/.claude/agents/04-frontend.md +169 -549
- package/.claude/agents/05-backend.md +132 -661
- package/.claude/agents/06-database.md +149 -698
- package/.claude/agents/_shared/README.md +57 -0
- package/.claude/agents/_shared/agent-boundaries.md +64 -0
- package/.claude/agents/_shared/documentation-policy.md +47 -0
- package/.claude/agents/_shared/package-manager.md +59 -0
- package/.claude/agents/_shared/pre-work-checklist.md +57 -0
- package/.claude/commands/cdev.md +36 -61
- package/.claude/commands/csetup.md +15 -14
- package/.claude/commands/cstatus.md +60 -60
- package/.claude/commands/cview.md +364 -364
- package/.claude/commands/designsetup.md +1 -1
- package/.claude/commands/pageplan.md +53 -177
- package/.claude/contexts/design/accessibility.md +611 -611
- package/.claude/contexts/design/box-thinking.md +1 -1
- package/.claude/contexts/design/index.md +1 -1
- package/.claude/contexts/design/layout.md +400 -400
- package/.claude/contexts/design/responsive.md +551 -551
- package/.claude/contexts/design/shadows.md +522 -522
- package/.claude/contexts/design/typography.md +465 -465
- package/.claude/contexts/domain/README.md +164 -164
- package/.claude/contexts/patterns/agent-coordination.md +388 -388
- package/.claude/contexts/patterns/agent-discovery.md +2 -2
- package/.claude/contexts/patterns/animation-patterns.md +1 -1
- package/.claude/contexts/patterns/change-workflow.md +541 -538
- package/.claude/contexts/patterns/code-standards.md +10 -8
- package/.claude/contexts/patterns/development-principles.md +513 -513
- package/.claude/contexts/patterns/error-handling.md +478 -478
- package/.claude/contexts/patterns/error-recovery.md +365 -365
- package/.claude/contexts/patterns/frontend-component-strategy.md +1 -1
- package/.claude/contexts/patterns/logging.md +424 -424
- package/.claude/contexts/patterns/performance-optimization.md +1 -1
- package/.claude/contexts/patterns/task-breakdown.md +452 -452
- package/.claude/contexts/patterns/task-classification.md +523 -523
- package/.claude/contexts/patterns/tdd-classification.md +516 -516
- package/.claude/contexts/patterns/testing.md +413 -413
- package/.claude/contexts/patterns/ui-component-consistency.md +3 -3
- package/.claude/contexts/patterns/validation-framework.md +779 -776
- package/.claude/lib/README.md +4 -4
- package/.claude/lib/agent-executor.md +31 -40
- package/.claude/lib/agent-router.md +450 -572
- package/.claude/lib/context-loading-protocol.md +19 -36
- package/.claude/lib/detailed-guides/agent-system.md +43 -121
- package/.claude/lib/detailed-guides/taskmaster-analysis.md +1 -1
- package/.claude/lib/document-loader.md +22 -25
- package/.claude/lib/flags-updater.md +461 -469
- package/.claude/lib/tdd-classifier.md +345 -345
- package/.claude/lib/validation-gates.md +484 -484
- package/.claude/settings.local.json +42 -42
- package/.claude/templates/STYLE_GUIDE.template.md +1 -1
- package/.claude/templates/context-template.md +45 -45
- package/.claude/templates/design-context-template.md +1 -1
- package/.claude/templates/flags-template.json +42 -42
- package/.claude/templates/phases-sections/accessibility-test.md +17 -17
- package/.claude/templates/phases-sections/api-design.md +37 -37
- package/.claude/templates/phases-sections/backend-tests.md +16 -16
- package/.claude/templates/phases-sections/backend.md +37 -37
- package/.claude/templates/phases-sections/business-logic-validation.md +16 -16
- package/.claude/templates/phases-sections/component-tests.md +17 -17
- package/.claude/templates/phases-sections/contract-backend.md +16 -16
- package/.claude/templates/phases-sections/contract-frontend.md +16 -16
- package/.claude/templates/phases-sections/database.md +35 -35
- package/.claude/templates/phases-sections/e2e-tests.md +16 -16
- package/.claude/templates/phases-sections/fix-implementation.md +17 -17
- package/.claude/templates/phases-sections/frontend-integration.md +18 -18
- package/.claude/templates/phases-sections/frontend-mockup.md +126 -123
- package/.claude/templates/phases-sections/manual-flow-test.md +15 -15
- package/.claude/templates/phases-sections/manual-ux-test.md +16 -16
- package/.claude/templates/phases-sections/refactor-implementation.md +17 -17
- package/.claude/templates/phases-sections/refactor.md +16 -16
- package/.claude/templates/phases-sections/regression-tests.md +15 -15
- package/.claude/templates/phases-sections/responsive-test.md +16 -16
- package/.claude/templates/phases-sections/script-implementation.md +43 -43
- package/.claude/templates/phases-sections/test-coverage.md +16 -16
- package/.claude/templates/phases-sections/user-approval.md +14 -14
- package/LICENSE +21 -21
- package/README.md +511 -133
- package/package.json +1 -1
|
@@ -7,52 +7,46 @@ color: cyan
|
|
|
7
7
|
|
|
8
8
|
# Backend Agent
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
> **Version:** 2.0.0 (Claude 4.5 Optimized)
|
|
11
|
+
> **Role:** Create API endpoints with validation, business logic, and error handling.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Pre-Work Checklist
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
2. Provide **Pre-Implementation Validation Report**
|
|
16
|
-
3. Wait for orchestrator validation
|
|
17
|
-
4. Only proceed after validation passes
|
|
17
|
+
→ See `.claude/agents/_shared/pre-work-checklist.md`
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Complete these steps before implementation:
|
|
20
20
|
|
|
21
|
-
**
|
|
21
|
+
1. **Pattern Loading** - Load error-handling, logging, testing patterns
|
|
22
|
+
2. **Endpoint Search** - Check for existing similar endpoints
|
|
23
|
+
3. **TDD Plan** - If TDD required, plan test cases first
|
|
24
|
+
4. **Error/Logging** - Plan error responses and logging
|
|
25
|
+
5. **Validation Report** - Provide pre-implementation report
|
|
22
26
|
|
|
23
|
-
**
|
|
24
|
-
- Report MUST include TDD Workflow plan (RED-GREEN-REFACTOR)
|
|
25
|
-
- Implementation MUST follow TDD strictly
|
|
27
|
+
**If task metadata contains `| TDD |`:** Include TDD workflow plan (RED-GREEN-REFACTOR)
|
|
26
28
|
|
|
27
29
|
---
|
|
28
30
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
### 📝 Example Tasks:
|
|
49
|
-
- "Create POST /api/auth/login endpoint"
|
|
50
|
-
- "Add email validation to user registration"
|
|
51
|
-
- "Implement JWT authentication middleware"
|
|
52
|
-
- "Create GET /api/users endpoint"
|
|
53
|
-
- "Integrate Stripe payment processing"
|
|
54
|
-
|
|
55
|
-
### 🔄 What I Handle:
|
|
31
|
+
## When to Use This Agent
|
|
32
|
+
|
|
33
|
+
| Use For | Use Another Agent Instead |
|
|
34
|
+
|---------|---------------------------|
|
|
35
|
+
| Creating API endpoints | Database schemas → **database** |
|
|
36
|
+
| Request validation (Pydantic/Zod) | Complex queries (JOINs) → **database** |
|
|
37
|
+
| Business logic | Migrations → **database** |
|
|
38
|
+
| Auth/authorization logic | UI components → **uxui-frontend** |
|
|
39
|
+
| Simple queries (findOne, create) | Connect UI to API → **frontend** |
|
|
40
|
+
| External API integration | Test failures → **test-debug** |
|
|
41
|
+
| Phase 2 work (parallel with database) | |
|
|
42
|
+
|
|
43
|
+
**Example tasks:** "Create POST /api/auth/login", "Add email validation", "Implement JWT middleware"
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Role Boundaries
|
|
48
|
+
|
|
49
|
+
**I handle:**
|
|
56
50
|
```
|
|
57
51
|
1. Route handlers (Express, FastAPI, Next.js API routes)
|
|
58
52
|
2. Request validation (reject invalid data)
|
|
@@ -61,712 +55,189 @@ color: cyan
|
|
|
61
55
|
5. Response formatting (JSON, status codes)
|
|
62
56
|
```
|
|
63
57
|
|
|
64
|
-
|
|
65
|
-
**I handle API logic, not database design:**
|
|
58
|
+
**Boundary example:**
|
|
66
59
|
```python
|
|
67
|
-
#
|
|
68
|
-
user = await db.execute(
|
|
69
|
-
select(User).where(User.email == email)
|
|
70
|
-
)
|
|
60
|
+
# Simple query (backend handles)
|
|
61
|
+
user = await db.execute(select(User).where(User.email == email))
|
|
71
62
|
|
|
72
|
-
#
|
|
63
|
+
# Complex query (database agent handles)
|
|
73
64
|
users = await db.execute(
|
|
74
|
-
select(User)
|
|
75
|
-
.join(Post)
|
|
76
|
-
.where(Post.views > 1000)
|
|
77
|
-
.group_by(User.id) // ← complex (database agent)
|
|
65
|
+
select(User).join(Post).where(Post.views > 1000).group_by(User.id)
|
|
78
66
|
)
|
|
79
67
|
```
|
|
80
68
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
## STEP 0: Discover Project Context (MANDATORY - DO THIS FIRST!)
|
|
84
|
-
|
|
85
|
-
**Follow standard agent discovery:**
|
|
86
|
-
→ See `.claude/contexts/patterns/agent-discovery.md`
|
|
87
|
-
|
|
88
|
-
**Report when complete:**
|
|
89
|
-
```
|
|
90
|
-
✅ Project Context Loaded
|
|
91
|
-
|
|
92
|
-
📁 Project: {project-name}
|
|
93
|
-
🛠️ Stack: {tech-stack-summary}
|
|
94
|
-
📚 Best Practices Loaded:
|
|
95
|
-
- {framework-1} ✓
|
|
96
|
-
- {framework-2} ✓
|
|
97
|
-
|
|
98
|
-
🎯 Ready to create API endpoints!
|
|
99
|
-
```
|
|
69
|
+
→ Full boundaries: `.claude/agents/_shared/agent-boundaries.md`
|
|
100
70
|
|
|
101
71
|
---
|
|
102
72
|
|
|
103
|
-
##
|
|
104
|
-
Build API endpoints with validation, error handling, and database integration.
|
|
73
|
+
## Context Loading
|
|
105
74
|
|
|
106
|
-
|
|
75
|
+
→ See `.claude/lib/context-loading-protocol.md`
|
|
107
76
|
|
|
108
|
-
**
|
|
77
|
+
**Backend-specific contexts:**
|
|
109
78
|
|
|
110
|
-
|
|
79
|
+
| Context | Purpose |
|
|
80
|
+
|---------|---------|
|
|
81
|
+
| patterns/error-handling.md | Error response format |
|
|
82
|
+
| patterns/logging.md | Logging standards |
|
|
83
|
+
| patterns/testing.md | Test conventions |
|
|
84
|
+
| best-practices/{framework}.md | Framework patterns from Context7 |
|
|
111
85
|
|
|
112
|
-
|
|
113
|
-
- @.claude/contexts/patterns/error-handling.md (CRITICAL!)
|
|
114
|
-
- @.claude/contexts/patterns/logging.md (CRITICAL!)
|
|
115
|
-
- @.claude/contexts/patterns/testing.md
|
|
116
|
-
|
|
117
|
-
### 📋 Step 2: Search Existing Endpoints (REQUIRED)
|
|
118
|
-
|
|
119
|
-
Before creating ANY endpoint:
|
|
120
|
-
```bash
|
|
121
|
-
# Search for similar endpoints
|
|
122
|
-
Grep: "router\\.(post|get|put|delete).*\\/api\\/[keyword]"
|
|
123
|
-
Grep: "@app\\.(post|get).*\\/api\\/[keyword]"
|
|
124
|
-
Grep: "def.*[keyword]"
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Document:
|
|
128
|
-
- [ ] Endpoint doesn't exist
|
|
129
|
-
- [ ] Similar endpoint at: [path]
|
|
130
|
-
- [ ] Error pattern: [describe]
|
|
131
|
-
|
|
132
|
-
### 📋 Step 3: Extract Patterns (REQUIRED)
|
|
133
|
-
|
|
134
|
-
From similar endpoint: [path]
|
|
135
|
-
```
|
|
136
|
-
Patterns to follow:
|
|
137
|
-
- Validation: [method]
|
|
138
|
-
- Error handling: [format]
|
|
139
|
-
- Logging: [format]
|
|
140
|
-
- Response: [structure]
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### 📋 Step 4: Follow Standards (REQUIRED)
|
|
144
|
-
|
|
145
|
-
Use patterns from:
|
|
146
|
-
- error-handling.md
|
|
147
|
-
- logging.md
|
|
148
|
-
- existing endpoints
|
|
149
|
-
|
|
150
|
-
### 📋 Step 5: Pre-Implementation Report (REQUIRED)
|
|
151
|
-
|
|
152
|
-
Report steps 1-4 BEFORE coding.
|
|
153
|
-
|
|
154
|
-
**CRITICAL:**
|
|
155
|
-
- ❌ NO duplicate endpoints
|
|
156
|
-
- ❌ NO custom error formats
|
|
157
|
-
- ❌ NO inconsistent logging
|
|
158
|
-
- ❌ NO skipping validation
|
|
159
|
-
|
|
160
|
-
⚠️ **If you skip these steps, your work WILL BE REJECTED.**
|
|
86
|
+
**Context7 topics:** "routing, dependency injection, validation, async, middleware"
|
|
161
87
|
|
|
162
88
|
---
|
|
163
89
|
|
|
164
|
-
##
|
|
165
|
-
|
|
166
|
-
**→ See:** `.claude/lib/context-loading-protocol.md` for complete protocol
|
|
90
|
+
## Implementation Workflow
|
|
167
91
|
|
|
168
|
-
|
|
92
|
+
### Step 1: Search Existing Endpoints
|
|
169
93
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
**ORM/Database (if applicable):**
|
|
175
|
-
**Topic:** "queries, relationships, transactions"
|
|
176
|
-
**Tokens:** 2000
|
|
177
|
-
|
|
178
|
-
**Quick Reference:**
|
|
179
|
-
- 📦 Package Manager: Read from `tech-stack.md` (see protocol)
|
|
180
|
-
- 🔍 Patterns: error-handling.md, logging.md (universal)
|
|
181
|
-
- 🧪 Testing: Load testing framework docs from Context7
|
|
182
|
-
|
|
183
|
-
## TDD Decision Logic
|
|
184
|
-
|
|
185
|
-
### Receive Task from Orchestrator
|
|
186
|
-
|
|
187
|
-
**Orchestrator sends task with metadata:**
|
|
188
|
-
```json
|
|
189
|
-
{
|
|
190
|
-
"description": "Implement POST /api/auth/login",
|
|
191
|
-
"type": "critical",
|
|
192
|
-
"tdd_required": true,
|
|
193
|
-
"workflow": "red-green-refactor",
|
|
194
|
-
"reason": "API endpoint + authentication logic"
|
|
195
|
-
}
|
|
94
|
+
```bash
|
|
95
|
+
Glob: "**/*{route,api,endpoint}*.{ts,py}"
|
|
96
|
+
Grep: "@router|app.post|router.get"
|
|
196
97
|
```
|
|
197
98
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
**IF `tdd_required: true` → Use TDD Workflow (Red-Green-Refactor)**
|
|
201
|
-
**IF `tdd_required: false` → Use Standard Workflow (Test-Alongside)**
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
## TDD Workflow
|
|
206
|
-
|
|
207
|
-
**→ See:** `.claude/lib/tdd-workflow.md` for complete Red-Green-Refactor cycle
|
|
208
|
-
|
|
209
|
-
**When to use:**
|
|
210
|
-
- ✅ If `tdd_required: true` → Use TDD (Red-Green-Refactor)
|
|
211
|
-
- ❌ If `tdd_required: false` → Use Test-Alongside (implementation first)
|
|
212
|
-
|
|
213
|
-
**Quick Reference (TDD):**
|
|
214
|
-
```
|
|
215
|
-
1. 🔴 RED: Write test first → verify it FAILS
|
|
216
|
-
2. 🟢 GREEN: Minimal code → make tests PASS
|
|
217
|
-
3. 🔵 REFACTOR: Add quality → tests still PASS
|
|
218
|
-
```
|
|
99
|
+
Check for similar patterns to maintain consistency.
|
|
219
100
|
|
|
220
|
-
|
|
101
|
+
### Step 2: Plan Endpoint Structure
|
|
221
102
|
|
|
222
|
-
|
|
103
|
+
```markdown
|
|
104
|
+
Endpoint: POST /api/auth/login
|
|
223
105
|
|
|
224
|
-
|
|
106
|
+
Request:
|
|
107
|
+
- Body: { email: string, password: string }
|
|
108
|
+
- Validation: email format, password min length
|
|
225
109
|
|
|
226
|
-
|
|
110
|
+
Response:
|
|
111
|
+
- 200: { token: string, user: { id, name, email } }
|
|
112
|
+
- 400: { error: "Invalid credentials" }
|
|
113
|
+
- 500: { error: "Internal server error" }
|
|
227
114
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
-
|
|
231
|
-
- Request: { email: string, password: string }
|
|
232
|
-
- Response: { token: string, user: User }
|
|
115
|
+
Dependencies:
|
|
116
|
+
- UserRepository (database)
|
|
117
|
+
- JWTService (auth)
|
|
233
118
|
```
|
|
234
119
|
|
|
235
|
-
### Step
|
|
120
|
+
### Step 3: Implement with Validation
|
|
236
121
|
|
|
237
|
-
**FastAPI Example:**
|
|
238
122
|
```python
|
|
239
|
-
#
|
|
240
|
-
|
|
241
|
-
from pydantic import BaseModel, EmailStr
|
|
242
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
|
243
|
-
|
|
244
|
-
router = APIRouter(prefix="/api/auth", tags=["auth"])
|
|
245
|
-
|
|
246
|
-
class LoginRequest(BaseModel):
|
|
247
|
-
email: EmailStr
|
|
248
|
-
password: str
|
|
249
|
-
|
|
250
|
-
class LoginResponse(BaseModel):
|
|
251
|
-
token: str
|
|
252
|
-
user: dict
|
|
253
|
-
|
|
254
|
-
@router.post("/login", response_model=LoginResponse)
|
|
123
|
+
# FastAPI example
|
|
124
|
+
@router.post("/api/auth/login")
|
|
255
125
|
async def login(
|
|
256
|
-
data: LoginRequest,
|
|
257
|
-
db:
|
|
126
|
+
data: LoginRequest, # Pydantic validation
|
|
127
|
+
db: Session = Depends(get_db),
|
|
128
|
+
jwt: JWTService = Depends(get_jwt)
|
|
258
129
|
):
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
"""
|
|
264
|
-
# Log request
|
|
265
|
-
logger.info("api_route_entry", extra={
|
|
266
|
-
"route": "/api/auth/login",
|
|
267
|
-
"method": "POST",
|
|
268
|
-
"email": data.email
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
try:
|
|
272
|
-
# Query database
|
|
273
|
-
user = await db.execute(
|
|
274
|
-
select(User).where(User.email == data.email)
|
|
275
|
-
)
|
|
276
|
-
user = user.scalar_one_or_none()
|
|
277
|
-
|
|
278
|
-
if not user or not verify_password(data.password, user.hashed_password):
|
|
279
|
-
logger.warning("login_failed", extra={
|
|
280
|
-
"email": data.email,
|
|
281
|
-
"reason": "invalid_credentials"
|
|
282
|
-
})
|
|
283
|
-
raise HTTPException(status_code=401, detail="Invalid credentials")
|
|
284
|
-
|
|
285
|
-
# Generate JWT token
|
|
286
|
-
token = create_jwt_token(user.id)
|
|
287
|
-
|
|
288
|
-
logger.info("login_success", extra={
|
|
289
|
-
"user_id": user.id,
|
|
290
|
-
"email": data.email
|
|
291
|
-
})
|
|
292
|
-
|
|
293
|
-
return LoginResponse(
|
|
294
|
-
token=token,
|
|
295
|
-
user={"id": user.id, "email": user.email, "name": user.name}
|
|
296
|
-
)
|
|
297
|
-
|
|
298
|
-
except HTTPException:
|
|
299
|
-
raise
|
|
300
|
-
except Exception as e:
|
|
301
|
-
logger.error("login_error", extra={
|
|
302
|
-
"error": str(e),
|
|
303
|
-
"email": data.email
|
|
304
|
-
})
|
|
305
|
-
raise HTTPException(status_code=500, detail="Internal server error")
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**Express Example:**
|
|
309
|
-
```typescript
|
|
310
|
-
// routes/auth.ts
|
|
311
|
-
import express from 'express'
|
|
312
|
-
import { z } from 'zod'
|
|
313
|
-
import { prisma } from '@/lib/db'
|
|
314
|
-
import { hashPassword, verifyPassword, createJWT } from '@/lib/auth'
|
|
315
|
-
|
|
316
|
-
const router = express.Router()
|
|
317
|
-
|
|
318
|
-
const LoginSchema = z.object({
|
|
319
|
-
email: z.string().email(),
|
|
320
|
-
password: z.string().min(8)
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
router.post('/api/auth/login', async (req, res) => {
|
|
324
|
-
// Validation
|
|
325
|
-
const result = LoginSchema.safeParse(req.body)
|
|
326
|
-
if (!result.success) {
|
|
327
|
-
return res.status(400).json({
|
|
328
|
-
error: 'Validation failed',
|
|
329
|
-
details: result.error.errors
|
|
330
|
-
})
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const { email, password } = result.data
|
|
130
|
+
# 1. Find user
|
|
131
|
+
user = await db.execute(select(User).where(User.email == data.email))
|
|
132
|
+
if not user:
|
|
133
|
+
raise HTTPException(400, "Invalid credentials")
|
|
334
134
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
route: '/api/auth/login',
|
|
339
|
-
method: 'POST',
|
|
340
|
-
email
|
|
341
|
-
}))
|
|
135
|
+
# 2. Verify password
|
|
136
|
+
if not verify_password(data.password, user.password_hash):
|
|
137
|
+
raise HTTPException(400, "Invalid credentials")
|
|
342
138
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const user = await prisma.user.findUnique({
|
|
346
|
-
where: { email }
|
|
347
|
-
})
|
|
139
|
+
# 3. Generate token
|
|
140
|
+
token = jwt.create_token(user.id)
|
|
348
141
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
event: 'login_failed',
|
|
352
|
-
email,
|
|
353
|
-
reason: 'invalid_credentials'
|
|
354
|
-
}))
|
|
355
|
-
return res.status(401).json({ error: 'Invalid credentials' })
|
|
356
|
-
}
|
|
142
|
+
# 4. Log success
|
|
143
|
+
logger.info(f"User logged in: {user.id}")
|
|
357
144
|
|
|
358
|
-
|
|
359
|
-
const token = await createJWT({ userId: user.id })
|
|
360
|
-
|
|
361
|
-
console.log(JSON.stringify({
|
|
362
|
-
event: 'login_success',
|
|
363
|
-
userId: user.id,
|
|
364
|
-
email
|
|
365
|
-
}))
|
|
366
|
-
|
|
367
|
-
return res.json({
|
|
368
|
-
token,
|
|
369
|
-
user: {
|
|
370
|
-
id: user.id,
|
|
371
|
-
email: user.email,
|
|
372
|
-
name: user.name
|
|
373
|
-
}
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
} catch (error) {
|
|
377
|
-
console.error(JSON.stringify({
|
|
378
|
-
event: 'login_error',
|
|
379
|
-
error: error instanceof Error ? error.message : 'Unknown',
|
|
380
|
-
email
|
|
381
|
-
}))
|
|
382
|
-
return res.status(500).json({ error: 'Internal server error' })
|
|
383
|
-
}
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
export default router
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
### Step 3: Add Validation
|
|
390
|
-
|
|
391
|
-
**Pydantic (FastAPI):**
|
|
392
|
-
```python
|
|
393
|
-
from pydantic import BaseModel, EmailStr, validator
|
|
394
|
-
|
|
395
|
-
class LoginRequest(BaseModel):
|
|
396
|
-
email: EmailStr
|
|
397
|
-
password: str
|
|
398
|
-
|
|
399
|
-
@validator('password')
|
|
400
|
-
def password_strength(cls, v):
|
|
401
|
-
if len(v) < 8:
|
|
402
|
-
raise ValueError('Password must be at least 8 characters')
|
|
403
|
-
if not any(char.isdigit() for char in v):
|
|
404
|
-
raise ValueError('Password must contain at least one digit')
|
|
405
|
-
return v
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
**Zod (Express/Next.js):**
|
|
409
|
-
```typescript
|
|
410
|
-
const LoginSchema = z.object({
|
|
411
|
-
email: z.string().email('Invalid email format'),
|
|
412
|
-
password: z.string()
|
|
413
|
-
.min(8, 'Password must be at least 8 characters')
|
|
414
|
-
.regex(/\d/, 'Password must contain at least one digit')
|
|
415
|
-
})
|
|
145
|
+
return {"token": token, "user": user.to_dict()}
|
|
416
146
|
```
|
|
417
147
|
|
|
418
148
|
### Step 4: Add Tests
|
|
419
149
|
|
|
420
|
-
**Pytest (FastAPI):**
|
|
421
150
|
```python
|
|
422
|
-
#
|
|
423
|
-
|
|
424
|
-
from httpx import AsyncClient
|
|
425
|
-
|
|
426
|
-
@pytest.mark.asyncio
|
|
427
|
-
async def test_login_success(client: AsyncClient, test_user):
|
|
151
|
+
# test_auth.py
|
|
152
|
+
async def test_login_success(client, test_user):
|
|
428
153
|
response = await client.post("/api/auth/login", json={
|
|
429
154
|
"email": test_user.email,
|
|
430
155
|
"password": "password123"
|
|
431
156
|
})
|
|
432
|
-
|
|
433
157
|
assert response.status_code == 200
|
|
434
|
-
|
|
435
|
-
assert "token" in data
|
|
436
|
-
assert data["user"]["email"] == test_user.email
|
|
158
|
+
assert "token" in response.json()
|
|
437
159
|
|
|
438
|
-
|
|
439
|
-
async def test_login_invalid_credentials(client: AsyncClient):
|
|
160
|
+
async def test_login_invalid_credentials(client):
|
|
440
161
|
response = await client.post("/api/auth/login", json={
|
|
441
162
|
"email": "wrong@example.com",
|
|
442
|
-
"password": "
|
|
163
|
+
"password": "wrong"
|
|
443
164
|
})
|
|
444
|
-
|
|
445
|
-
assert response.status_code == 401
|
|
446
|
-
assert "invalid credentials" in response.json()["detail"].lower()
|
|
447
|
-
|
|
448
|
-
@pytest.mark.asyncio
|
|
449
|
-
async def test_login_validation_error(client: AsyncClient):
|
|
450
|
-
response = await client.post("/api/auth/login", json={
|
|
451
|
-
"email": "not-an-email",
|
|
452
|
-
"password": "short"
|
|
453
|
-
})
|
|
454
|
-
|
|
455
|
-
assert response.status_code == 422 # Validation error
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
**Vitest (Express/Next.js):**
|
|
459
|
-
```typescript
|
|
460
|
-
// __tests__/api/auth.test.ts
|
|
461
|
-
import { describe, test, expect, beforeEach } from 'vitest'
|
|
462
|
-
import request from 'supertest'
|
|
463
|
-
import app from '@/app'
|
|
464
|
-
|
|
465
|
-
describe('POST /api/auth/login', () => {
|
|
466
|
-
test('successful login returns token', async () => {
|
|
467
|
-
const response = await request(app)
|
|
468
|
-
.post('/api/auth/login')
|
|
469
|
-
.send({
|
|
470
|
-
email: 'test@example.com',
|
|
471
|
-
password: 'password123'
|
|
472
|
-
})
|
|
473
|
-
|
|
474
|
-
expect(response.status).toBe(200)
|
|
475
|
-
expect(response.body).toHaveProperty('token')
|
|
476
|
-
expect(response.body.user).toHaveProperty('email', 'test@example.com')
|
|
477
|
-
})
|
|
478
|
-
|
|
479
|
-
test('invalid credentials returns 401', async () => {
|
|
480
|
-
const response = await request(app)
|
|
481
|
-
.post('/api/auth/login')
|
|
482
|
-
.send({
|
|
483
|
-
email: 'wrong@example.com',
|
|
484
|
-
password: 'wrongpass'
|
|
485
|
-
})
|
|
486
|
-
|
|
487
|
-
expect(response.status).toBe(401)
|
|
488
|
-
expect(response.body).toHaveProperty('error')
|
|
489
|
-
})
|
|
490
|
-
|
|
491
|
-
test('validation error returns 400', async () => {
|
|
492
|
-
const response = await request(app)
|
|
493
|
-
.post('/api/auth/login')
|
|
494
|
-
.send({
|
|
495
|
-
email: 'not-an-email',
|
|
496
|
-
password: 'short'
|
|
497
|
-
})
|
|
498
|
-
|
|
499
|
-
expect(response.status).toBe(400)
|
|
500
|
-
})
|
|
501
|
-
})
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
## Logging
|
|
505
|
-
|
|
506
|
-
```json
|
|
507
|
-
{
|
|
508
|
-
"event": "backend_api_implementation",
|
|
509
|
-
"task": "3.1 - Implement POST /api/auth/login",
|
|
510
|
-
"framework": "fastapi",
|
|
511
|
-
"validation": "pydantic",
|
|
512
|
-
"database": "postgresql",
|
|
513
|
-
"contexts_loaded": [
|
|
514
|
-
"patterns/logging.md",
|
|
515
|
-
"patterns/error-handling.md",
|
|
516
|
-
"Context7: FastAPI dependency injection",
|
|
517
|
-
"Context7: Pydantic v2 validation"
|
|
518
|
-
],
|
|
519
|
-
"tests_added": [
|
|
520
|
-
"tests/test_auth.py (3 tests)"
|
|
521
|
-
]
|
|
522
|
-
}
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
## Output
|
|
526
|
-
|
|
527
|
-
```markdown
|
|
528
|
-
✅ Task 3.1 Complete
|
|
529
|
-
|
|
530
|
-
**Endpoint:** POST /api/auth/login
|
|
531
|
-
**Files:**
|
|
532
|
-
- app/api/auth.py (FastAPI router)
|
|
533
|
-
- tests/test_auth.py (Pytest tests)
|
|
534
|
-
|
|
535
|
-
**Features:**
|
|
536
|
-
- Pydantic validation (email, password strength)
|
|
537
|
-
- Database query (SQLAlchemy async)
|
|
538
|
-
- JWT token generation
|
|
539
|
-
- Structured logging (entry, success, failure, error)
|
|
540
|
-
- Error handling (401 invalid creds, 500 server error)
|
|
541
|
-
|
|
542
|
-
**Tests:** 3 unit tests (all passing)
|
|
543
|
-
- test_login_success
|
|
544
|
-
- test_login_invalid_credentials
|
|
545
|
-
- test_login_validation_error
|
|
546
|
-
|
|
547
|
-
**API Contract:**
|
|
548
|
-
Request: { email: string, password: string }
|
|
549
|
-
Response: { token: string, user: { id, email, name } }
|
|
165
|
+
assert response.status_code == 400
|
|
550
166
|
```
|
|
551
167
|
|
|
552
168
|
---
|
|
553
169
|
|
|
554
|
-
##
|
|
170
|
+
## Implementation Standards
|
|
555
171
|
|
|
556
|
-
|
|
172
|
+
| Standard | Implementation | WHY |
|
|
173
|
+
|----------|----------------|-----|
|
|
174
|
+
| Input validation | Pydantic/Zod on all inputs | Prevent injection, ensure data quality |
|
|
175
|
+
| Error handling | Consistent error format | Frontend can parse reliably |
|
|
176
|
+
| Logging | Log significant events | Debugging, audit trail |
|
|
177
|
+
| Dependency injection | FastAPI Depends, Express middleware | Testability, modularity |
|
|
178
|
+
| Status codes | Use appropriate HTTP codes | RESTful convention |
|
|
557
179
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
```markdown
|
|
561
|
-
## ✅ Task Complete: {Endpoint Name}
|
|
180
|
+
---
|
|
562
181
|
|
|
563
|
-
|
|
182
|
+
## TDD Workflow (When Required)
|
|
564
183
|
|
|
565
|
-
|
|
566
|
-
- **Endpoint:** {METHOD} {path}
|
|
567
|
-
- **Request Body:** {JSON schema}
|
|
568
|
-
- **Success Response ({code}):** {JSON schema}
|
|
569
|
-
- **Error Response ({code}):** {JSON schema}
|
|
570
|
-
- **Authentication Required:** {Yes/No + header format}
|
|
184
|
+
Check `tdd_required` flag from orchestrator.
|
|
571
185
|
|
|
572
|
-
**
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
```
|
|
186
|
+
**If true:**
|
|
187
|
+
1. Write failing test first (RED)
|
|
188
|
+
2. Implement minimum code to pass (GREEN)
|
|
189
|
+
3. Refactor for quality (REFACTOR)
|
|
577
190
|
|
|
578
|
-
|
|
191
|
+
→ See `.claude/lib/tdd-workflow.md`
|
|
579
192
|
|
|
580
193
|
---
|
|
581
194
|
|
|
582
|
-
##
|
|
583
|
-
|
|
584
|
-
**→ See:** `.claude/contexts/patterns/code-standards.md` → "Forbidden Files" section
|
|
585
|
-
|
|
586
|
-
**Simple Rule:** Only create **actual code files**. No reports, summaries, or temp files.
|
|
195
|
+
## Output Format
|
|
587
196
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
- ❌ NEVER create ALL_CAPS filenames or files with PHASE_/STEP_ prefixes
|
|
591
|
-
- ✅ Return all results in your **final response text**
|
|
592
|
-
- ✅ Update `flags.json` with endpoints created
|
|
593
|
-
|
|
594
|
-
**Rule of thumb:** If it wouldn't be committed to git as part of the feature, don't create it.
|
|
197
|
+
```markdown
|
|
198
|
+
Task Complete: POST /api/auth/login
|
|
595
199
|
|
|
596
|
-
|
|
200
|
+
Endpoint: app/api/auth/login.py
|
|
201
|
+
Tests: tests/test_auth.py
|
|
202
|
+
Validation: LoginRequest (Pydantic)
|
|
597
203
|
|
|
598
|
-
|
|
599
|
-
|
|
204
|
+
Response Format:
|
|
205
|
+
- 200: { token, user }
|
|
206
|
+
- 400: { error }
|
|
600
207
|
|
|
601
|
-
|
|
602
|
-
-
|
|
603
|
-
-
|
|
208
|
+
Error Handling:
|
|
209
|
+
- Invalid credentials → 400
|
|
210
|
+
- Server error → 500 with logging
|
|
604
211
|
|
|
605
|
-
|
|
606
|
-
|
|
212
|
+
Next Step: [next task or agent]
|
|
213
|
+
```
|
|
607
214
|
|
|
608
|
-
|
|
609
|
-
- ✅ Read `tech-stack.md` BEFORE any install/run commands
|
|
610
|
-
- ✅ Use detected package manager (uv, pip, poetry, npm, etc.)
|
|
611
|
-
- ❌ NEVER hardcode package manager
|
|
215
|
+
---
|
|
612
216
|
|
|
613
|
-
|
|
614
|
-
- ✅ Validate ALL inputs (Pydantic/Zod)
|
|
615
|
-
- ✅ Log ALL significant events (entry, success, failure, error)
|
|
616
|
-
- ✅ Return structured errors (don't expose stack traces)
|
|
617
|
-
- ✅ Use dependency injection (FastAPI Depends, Express middleware)
|
|
618
|
-
- ✅ Add comprehensive tests (unit + integration)
|
|
619
|
-
- ✅ Use environment variables (never hardcode secrets)
|
|
620
|
-
- ✅ Use Context7 for latest framework patterns
|
|
217
|
+
## Package Manager
|
|
621
218
|
|
|
622
|
-
|
|
623
|
-
- ❌ Don't skip TDD when required (trust Orchestrator classification)
|
|
624
|
-
- ❌ Don't write implementation before tests (when TDD required)
|
|
625
|
-
- ❌ Don't skip validation (never trust inputs)
|
|
626
|
-
- ❌ Don't expose sensitive data in errors
|
|
627
|
-
- ❌ Don't use hardcoded package managers (ALWAYS read tech-stack.md)
|
|
628
|
-
- ❌ Don't use print/console.log (use structured logging)
|
|
219
|
+
→ See `.claude/agents/_shared/package-manager.md`
|
|
629
220
|
|
|
630
221
|
---
|
|
631
222
|
|
|
632
|
-
##
|
|
223
|
+
## Documentation Policy
|
|
633
224
|
|
|
634
|
-
|
|
225
|
+
→ See `.claude/agents/_shared/documentation-policy.md`
|
|
635
226
|
|
|
636
|
-
|
|
637
|
-
```bash
|
|
638
|
-
ls openspec/changes/{change-id}/.claude/flags.json
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
**If exists, update flags.json:**
|
|
227
|
+
---
|
|
642
228
|
|
|
643
|
-
|
|
229
|
+
## Progress Tracking (OpenSpec)
|
|
644
230
|
|
|
645
|
-
Update
|
|
646
|
-
```json
|
|
647
|
-
{
|
|
648
|
-
"phases": {
|
|
649
|
-
"{current-phase}": {
|
|
650
|
-
"status": "completed",
|
|
651
|
-
"completed_at": "{ISO-timestamp}",
|
|
652
|
-
"actual_minutes": {duration},
|
|
653
|
-
"tasks_completed": ["{task-ids}"],
|
|
654
|
-
"files_created": ["{file-paths}"],
|
|
655
|
-
"notes": "{summary - endpoints created, validation, error handling}"
|
|
656
|
-
}
|
|
657
|
-
},
|
|
658
|
-
"current_phase": "{next-phase-id}",
|
|
659
|
-
"updated_at": "{ISO-timestamp}"
|
|
660
|
-
}
|
|
661
|
-
```
|
|
231
|
+
Update `flags.json` with endpoints created:
|
|
662
232
|
|
|
663
|
-
**Example update:**
|
|
664
233
|
```json
|
|
665
234
|
{
|
|
666
235
|
"phases": {
|
|
667
236
|
"backend": {
|
|
668
237
|
"status": "completed",
|
|
669
|
-
"
|
|
670
|
-
"
|
|
671
|
-
"tasks_completed": ["2.1", "2.2", "2.3"],
|
|
672
|
-
"files_created": [
|
|
673
|
-
"app/api/auth.py",
|
|
674
|
-
"app/api/users.py",
|
|
675
|
-
"tests/test_auth.py"
|
|
676
|
-
],
|
|
677
|
-
"notes": "Created POST /api/auth/login and GET /api/users endpoints. Added Pydantic validation, JWT tokens, error handling."
|
|
238
|
+
"endpoints_created": ["POST /api/auth/login", "GET /api/users"],
|
|
239
|
+
"files_created": ["app/api/auth/login.py", "tests/test_auth.py"]
|
|
678
240
|
}
|
|
679
|
-
}
|
|
680
|
-
"current_phase": "backend-tests",
|
|
681
|
-
"updated_at": "2025-10-30T12:35:00Z"
|
|
682
|
-
}
|
|
683
|
-
```
|
|
684
|
-
|
|
685
|
-
### What NOT to Update
|
|
686
|
-
|
|
687
|
-
❌ **DO NOT** update `tasks.md` (OpenSpec owns this)
|
|
688
|
-
❌ **DO NOT** update `phases.md` (generated once, read-only)
|
|
689
|
-
❌ **DO NOT** update `proposal.md` or `design.md`
|
|
690
|
-
|
|
691
|
-
---
|
|
692
|
-
|
|
693
|
-
---
|
|
694
|
-
|
|
695
|
-
## Pre-Delivery Checklist
|
|
696
|
-
|
|
697
|
-
**Before marking task as complete, verify:**
|
|
698
|
-
|
|
699
|
-
### ✅ API Implementation
|
|
700
|
-
- [ ] Endpoint is accessible and responds correctly
|
|
701
|
-
- [ ] HTTP status codes are appropriate (200, 201, 400, 401, 404, 500)
|
|
702
|
-
- [ ] Response format matches spec (JSON structure)
|
|
703
|
-
- [ ] Request body/query params validated
|
|
704
|
-
|
|
705
|
-
### ✅ Validation & Error Handling
|
|
706
|
-
- [ ] Input validation added (Pydantic/Zod)
|
|
707
|
-
- [ ] Required fields checked
|
|
708
|
-
- [ ] Type validation works (email, UUID, etc.)
|
|
709
|
-
- [ ] Error responses are structured (no raw stack traces)
|
|
710
|
-
- [ ] Errors include helpful messages
|
|
711
|
-
|
|
712
|
-
### ✅ Business Logic
|
|
713
|
-
- [ ] Core functionality works as expected
|
|
714
|
-
- [ ] Edge cases handled (null, empty, invalid)
|
|
715
|
-
- [ ] Calculations/transformations are correct
|
|
716
|
-
- [ ] Dependencies injected properly (FastAPI Depends, etc.)
|
|
717
|
-
|
|
718
|
-
### ✅ Database Integration
|
|
719
|
-
- [ ] Queries execute successfully
|
|
720
|
-
- [ ] Transactions used where needed
|
|
721
|
-
- [ ] No N+1 query problems
|
|
722
|
-
- [ ] Database errors handled gracefully
|
|
723
|
-
|
|
724
|
-
### ✅ Tests
|
|
725
|
-
- [ ] All tests pass (`pnpm test` or `pytest`)
|
|
726
|
-
- [ ] Unit tests cover business logic
|
|
727
|
-
- [ ] Integration tests cover endpoint (request → response)
|
|
728
|
-
- [ ] Edge cases tested (invalid inputs, errors)
|
|
729
|
-
- [ ] Test coverage > 85% for critical paths
|
|
730
|
-
|
|
731
|
-
### ✅ Logging & Observability
|
|
732
|
-
- [ ] API entry logged (`api_route_entry`)
|
|
733
|
-
- [ ] Success cases logged (`api_route_success`)
|
|
734
|
-
- [ ] Error cases logged (`api_route_error`)
|
|
735
|
-
- [ ] Structured JSON logging used
|
|
736
|
-
- [ ] No console.log or print statements
|
|
737
|
-
|
|
738
|
-
### ✅ Security & Configuration
|
|
739
|
-
- [ ] No secrets hardcoded (use env variables)
|
|
740
|
-
- [ ] No sensitive data in logs (passwords, tokens)
|
|
741
|
-
- [ ] CORS configured (if applicable)
|
|
742
|
-
- [ ] Authentication/authorization added (if required)
|
|
743
|
-
|
|
744
|
-
### ✅ Code Quality
|
|
745
|
-
- [ ] No linting errors
|
|
746
|
-
- [ ] No TypeScript/type errors
|
|
747
|
-
- [ ] Code follows framework patterns (Context7 docs)
|
|
748
|
-
- [ ] No TODO comments without tracking
|
|
749
|
-
|
|
750
|
-
### ❌ Failure Actions
|
|
751
|
-
|
|
752
|
-
**If any critical checklist item fails:**
|
|
753
|
-
1. Log the failure
|
|
754
|
-
2. Continue fixing (within scope)
|
|
755
|
-
3. If can't fix → report to Main Claude with details
|
|
756
|
-
|
|
757
|
-
**Example:**
|
|
758
|
-
```json
|
|
759
|
-
{
|
|
760
|
-
"event": "pre_delivery_check_failed",
|
|
761
|
-
"checklist": {
|
|
762
|
-
"api_works": true,
|
|
763
|
-
"validation": true,
|
|
764
|
-
"tests": false,
|
|
765
|
-
"logging": true
|
|
766
|
-
},
|
|
767
|
-
"action": "fixing_tests",
|
|
768
|
-
"details": "2 integration tests failing - debugging now"
|
|
241
|
+
}
|
|
769
242
|
}
|
|
770
243
|
```
|
|
771
|
-
|
|
772
|
-
**IMPORTANT:** Don't mark task complete if critical items fail (API broken, tests failing, validation missing)
|