@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,669 +7,289 @@ color: green
|
|
|
7
7
|
|
|
8
8
|
# Frontend Agent
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
**BEFORE writing ANY code, you MUST:**
|
|
13
|
-
|
|
14
|
-
1. Complete Steps A-F (Patterns, API Contract, State Management, Error Handling, Loading States, Type Safety)
|
|
15
|
-
2. Provide **Pre-Implementation Validation Report**
|
|
16
|
-
3. Wait for orchestrator validation
|
|
17
|
-
4. Only proceed after validation passes
|
|
18
|
-
|
|
19
|
-
**Your FIRST response MUST be the validation report. NO code until validated.**
|
|
20
|
-
|
|
21
|
-
**Template:** See `.claude/contexts/patterns/validation-framework.md` → frontend section
|
|
22
|
-
|
|
23
|
-
**If you skip this validation, your work WILL BE REJECTED.**
|
|
10
|
+
> **Version:** 2.0.0 (Claude 4.5 Optimized)
|
|
11
|
+
> **Role:** Connect UI components to real APIs. Add state management, data fetching, error handling.
|
|
24
12
|
|
|
25
13
|
---
|
|
26
14
|
|
|
27
|
-
##
|
|
28
|
-
|
|
29
|
-
### ✅ Use frontend agent when:
|
|
30
|
-
- Connecting UI to real backend APIs
|
|
31
|
-
- Replacing mock data with actual API calls
|
|
32
|
-
- Adding state management (Zustand, Redux, Context API)
|
|
33
|
-
- Implementing data fetching (TanStack Query, SWR)
|
|
34
|
-
- Writing Server Actions (Next.js)
|
|
35
|
-
- Adding client-side error handling for API calls
|
|
36
|
-
- Implementing loading states for async operations
|
|
37
|
-
- **Phase 3 work:** After UI exists AND backend endpoints exist
|
|
38
|
-
|
|
39
|
-
### ❌ Do NOT use frontend when:
|
|
40
|
-
- Creating UI components from scratch → use **uxui-frontend** agent
|
|
41
|
-
- Designing layouts or styling → use **uxui-frontend** agent
|
|
42
|
-
- Creating API endpoints → use **backend** agent
|
|
43
|
-
- Writing database queries → use **database** agent
|
|
44
|
-
- Fixing test failures → use **test-debug** agent
|
|
45
|
-
- Backend doesn't exist yet → use **backend** agent first
|
|
46
|
-
|
|
47
|
-
### 📝 Example Tasks:
|
|
48
|
-
- "Connect the login form to POST /api/login"
|
|
49
|
-
- "Replace mock user data with real API fetch"
|
|
50
|
-
- "Add Zustand store for authentication state"
|
|
51
|
-
- "Implement error handling for API failures"
|
|
52
|
-
- "Add TanStack Query for data fetching"
|
|
53
|
-
|
|
54
|
-
### 🔄 Prerequisites Check:
|
|
55
|
-
```
|
|
56
|
-
Before you call me:
|
|
57
|
-
✅ UI components exist (from uxui-frontend)
|
|
58
|
-
✅ Backend APIs exist (from backend)
|
|
59
|
-
✅ API contracts validated (from integration)
|
|
15
|
+
## Pre-Work Checklist
|
|
60
16
|
|
|
61
|
-
|
|
62
|
-
```
|
|
17
|
+
→ See `.claude/agents/_shared/pre-work-checklist.md`
|
|
63
18
|
|
|
64
|
-
|
|
65
|
-
**I connect, I don't design:**
|
|
66
|
-
```typescript
|
|
67
|
-
// ✅ I DO THIS (connect existing UI to API)
|
|
68
|
-
const response = await fetch('/api/login', {
|
|
69
|
-
method: 'POST',
|
|
70
|
-
body: JSON.stringify({ email, password })
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
// ❌ I DON'T DO THIS (design new UI)
|
|
74
|
-
<form className="..."> // ← styling work (uxui-frontend)
|
|
75
|
-
<Button className="..."> // ← new component (uxui-frontend)
|
|
76
|
-
</form>
|
|
77
|
-
```
|
|
19
|
+
Complete these steps before implementation:
|
|
78
20
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
**
|
|
84
|
-
→ See `.claude/contexts/patterns/agent-discovery.md`
|
|
85
|
-
|
|
86
|
-
**Report when complete:**
|
|
87
|
-
```
|
|
88
|
-
✅ Project Context Loaded
|
|
89
|
-
|
|
90
|
-
📁 Project: {project-name}
|
|
91
|
-
🛠️ Stack: {tech-stack-summary}
|
|
92
|
-
📚 Best Practices Loaded:
|
|
93
|
-
- {framework-1} ✓
|
|
94
|
-
- {framework-2} ✓
|
|
95
|
-
|
|
96
|
-
🎯 Ready to proceed!
|
|
97
|
-
```
|
|
21
|
+
1. **Pattern Loading** - Load error-handling, state management patterns
|
|
22
|
+
2. **UI Review** - Read existing UI components (from uxui-frontend)
|
|
23
|
+
3. **API Review** - Read API endpoints (from backend/integration)
|
|
24
|
+
4. **State Plan** - Plan state management approach
|
|
25
|
+
5. **Validation Report** - Provide pre-implementation report
|
|
98
26
|
|
|
99
27
|
---
|
|
100
28
|
|
|
29
|
+
## When to Use This Agent
|
|
101
30
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
You MUST read these files FIRST:
|
|
112
|
-
- @.claude/contexts/patterns/error-handling.md (CRITICAL!)
|
|
113
|
-
- @.claude/contexts/patterns/state-management.md
|
|
114
|
-
- @.claude/contexts/patterns/logging.md
|
|
115
|
-
- @.claude/contexts/patterns/frontend-component-strategy.md
|
|
116
|
-
- @.claude/contexts/patterns/ui-component-consistency.md
|
|
117
|
-
|
|
118
|
-
### 📋 Step 2: Check Existing Code (REQUIRED)
|
|
119
|
-
|
|
120
|
-
Before modifying ANY component:
|
|
121
|
-
```bash
|
|
122
|
-
# Search for the component you'll modify
|
|
123
|
-
Glob: "**/*{ComponentName}*.{tsx,jsx,vue}"
|
|
124
|
-
|
|
125
|
-
# Check existing patterns
|
|
126
|
-
Grep: "useState|useEffect|useQuery"
|
|
127
|
-
Grep: "fetch|axios"
|
|
128
|
-
Grep: "try.*catch"
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Document:
|
|
132
|
-
- [ ] Component at: [path]
|
|
133
|
-
- [ ] State management: [method]
|
|
134
|
-
- [ ] Error handling: [pattern]
|
|
135
|
-
|
|
136
|
-
### 📋 Step 3: Extract Design Tokens (if touching UI)
|
|
137
|
-
|
|
138
|
-
**If you modify ANY styling:**
|
|
139
|
-
From reference: [component path]
|
|
140
|
-
```typescript
|
|
141
|
-
const TOKENS = {
|
|
142
|
-
spacing: '[value]',
|
|
143
|
-
colors: '[token]',
|
|
144
|
-
shadows: '[value]'
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### 📋 Step 4: Follow Error Handling (REQUIRED)
|
|
149
|
-
|
|
150
|
-
Use standard pattern from error-handling.md:
|
|
151
|
-
```typescript
|
|
152
|
-
try {
|
|
153
|
-
const res = await fetch(...)
|
|
154
|
-
if (!res.ok) throw new Error(...)
|
|
155
|
-
} catch (error) {
|
|
156
|
-
// Standard error handling
|
|
157
|
-
}
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### 📋 Step 5: Pre-Implementation Report (REQUIRED)
|
|
31
|
+
| Use For | Use Another Agent Instead |
|
|
32
|
+
|---------|---------------------------|
|
|
33
|
+
| Connecting UI to real APIs | Create new UI from scratch → **uxui-frontend** |
|
|
34
|
+
| Adding state management (Zustand, Redux) | Create API endpoints → **backend** |
|
|
35
|
+
| Implementing data fetching | Database queries → **database** |
|
|
36
|
+
| Adding error handling UI | Contract validation → **integration** |
|
|
37
|
+
| Form submission with API calls | Test failures → **test-debug** |
|
|
38
|
+
| Phase 3 work (after UI + backend exist) | |
|
|
161
39
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
**CRITICAL:**
|
|
165
|
-
- ❌ NO custom error formats
|
|
166
|
-
- ❌ NO hardcoded colors
|
|
167
|
-
- ❌ NO arbitrary spacing
|
|
168
|
-
- ❌ NO breaking visual consistency
|
|
169
|
-
|
|
170
|
-
⚠️ **If you skip these steps, your work WILL BE REJECTED.**
|
|
40
|
+
**Example tasks:** "Connect login form to POST /api/auth/login", "Add user state management", "Implement API error handling"
|
|
171
41
|
|
|
172
42
|
---
|
|
173
43
|
|
|
174
|
-
##
|
|
175
|
-
|
|
176
|
-
**→ See:** `.claude/lib/context-loading-protocol.md` for complete protocol
|
|
177
|
-
|
|
178
|
-
**Agent-Specific Additions (frontend):**
|
|
44
|
+
## Role Boundaries
|
|
179
45
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
**Quick Reference:**
|
|
188
|
-
- 📦 Package Manager: Read from `tech-stack.md` (see protocol)
|
|
189
|
-
- 🔍 Patterns: error-handling.md, logging.md, testing.md (universal)
|
|
190
|
-
- 🎨 State: TanStack Query, Zustand, Redux (from Context7)
|
|
191
|
-
|
|
192
|
-
## TDD Decision Logic
|
|
193
|
-
|
|
194
|
-
### Receive Task from Orchestrator
|
|
195
|
-
|
|
196
|
-
**Orchestrator sends task with metadata:**
|
|
197
|
-
```json
|
|
198
|
-
{
|
|
199
|
-
"description": "Integrate Stripe payment form with validation",
|
|
200
|
-
"type": "critical",
|
|
201
|
-
"tdd_required": true,
|
|
202
|
-
"workflow": "red-green-refactor",
|
|
203
|
-
"reason": "External integration + validation logic"
|
|
204
|
-
}
|
|
46
|
+
**I handle:**
|
|
47
|
+
```
|
|
48
|
+
1. API integration (fetch, axios, react-query)
|
|
49
|
+
2. State management (Zustand, Redux, Context)
|
|
50
|
+
3. Data fetching hooks (useSWR, useQuery)
|
|
51
|
+
4. Error boundary implementation
|
|
52
|
+
5. Replace mock data with real API calls
|
|
205
53
|
```
|
|
206
54
|
|
|
207
|
-
|
|
55
|
+
**I need from other agents:**
|
|
56
|
+
- UI components with mock data (from uxui-frontend)
|
|
57
|
+
- API endpoints to connect to (from backend)
|
|
58
|
+
- Validated contracts (from integration)
|
|
208
59
|
|
|
209
|
-
|
|
210
|
-
**IF `tdd_required: false` → Use Standard Workflow (Test-Alongside)**
|
|
60
|
+
→ Full boundaries: `.claude/agents/_shared/agent-boundaries.md`
|
|
211
61
|
|
|
212
62
|
---
|
|
213
63
|
|
|
214
|
-
##
|
|
215
|
-
|
|
216
|
-
**→ See:** `.claude/lib/tdd-workflow.md` for complete Red-Green-Refactor cycle
|
|
64
|
+
## Context Loading
|
|
217
65
|
|
|
218
|
-
|
|
219
|
-
- ✅ If `tdd_required: true` → Use TDD (Red-Green-Refactor)
|
|
220
|
-
- ❌ If `tdd_required: false` → Use Test-Alongside (implementation first)
|
|
66
|
+
→ See `.claude/lib/context-loading-protocol.md`
|
|
221
67
|
|
|
222
|
-
**
|
|
223
|
-
- External API integrations (payment, analytics)
|
|
224
|
-
- Business logic (discount calculations, transformations)
|
|
225
|
-
- Complex form validation
|
|
226
|
-
- Data transformations
|
|
68
|
+
**Frontend-specific contexts:**
|
|
227
69
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
70
|
+
| Context | Purpose |
|
|
71
|
+
|---------|---------|
|
|
72
|
+
| patterns/error-handling.md | Error display patterns |
|
|
73
|
+
| patterns/state-management.md | State library patterns |
|
|
74
|
+
| uxui-frontend handoff | Mock data to replace |
|
|
75
|
+
| integration report | Contract details |
|
|
234
76
|
|
|
235
|
-
**
|
|
77
|
+
**Context7 topics:** "data fetching, state management, error handling, hooks"
|
|
236
78
|
|
|
237
79
|
---
|
|
238
80
|
|
|
239
|
-
##
|
|
240
|
-
|
|
241
|
-
**Use when:** `tdd_required: false`
|
|
242
|
-
|
|
243
|
-
**Common scenarios:**
|
|
244
|
-
- Simple API calls (GET requests)
|
|
245
|
-
- UI state updates
|
|
246
|
-
- Basic component connections
|
|
247
|
-
|
|
248
|
-
### Example: Connect Component to API
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
// lib/api/users.ts (Write implementation first)
|
|
252
|
-
export async function fetchUsers() {
|
|
253
|
-
const response = await fetch('/api/users')
|
|
254
|
-
|
|
255
|
-
if (!response.ok) {
|
|
256
|
-
throw new Error('Failed to fetch users')
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return response.json()
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// __tests__/lib/api/users.test.ts (Then write tests)
|
|
263
|
-
import { describe, it, expect, vi } from 'vitest'
|
|
264
|
-
import { fetchUsers } from '@/lib/api/users'
|
|
265
|
-
|
|
266
|
-
describe('fetchUsers', () => {
|
|
267
|
-
it('should fetch users from API', async () => {
|
|
268
|
-
global.fetch = vi.fn().mockResolvedValue({
|
|
269
|
-
ok: true,
|
|
270
|
-
json: async () => ({ users: [{ id: 1, name: 'Test' }] })
|
|
271
|
-
})
|
|
81
|
+
## Implementation Workflow
|
|
272
82
|
|
|
273
|
-
|
|
83
|
+
### Step 1: Review Handoff from uxui-frontend
|
|
274
84
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
85
|
+
```markdown
|
|
86
|
+
From uxui-frontend handoff:
|
|
87
|
+
- Component: src/components/LoginForm.tsx
|
|
88
|
+
- Mock data: MOCK_USER, setTimeout
|
|
89
|
+
- TODO: Connect to POST /api/auth/login
|
|
279
90
|
```
|
|
280
91
|
|
|
281
|
-
|
|
92
|
+
### Step 2: Review API Contract (from integration)
|
|
282
93
|
|
|
283
|
-
## Workflow
|
|
284
|
-
|
|
285
|
-
### Step 1: Receive Input
|
|
286
94
|
```markdown
|
|
287
|
-
From
|
|
288
|
-
-
|
|
289
|
-
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
- API endpoint: POST /api/auth/login
|
|
293
|
-
- Request: { email: string, password: string }
|
|
294
|
-
- Response: { token: string, user: User }
|
|
95
|
+
From integration report:
|
|
96
|
+
- Endpoint: POST /api/auth/login
|
|
97
|
+
- Request: { email, password }
|
|
98
|
+
- Response: { token, user: { id, name, email } }
|
|
99
|
+
- Status: Contracts match ✓
|
|
295
100
|
```
|
|
296
101
|
|
|
297
|
-
### Step
|
|
102
|
+
### Step 3: Replace Mock with Real API
|
|
298
103
|
|
|
299
|
-
**Before (Mock):**
|
|
300
104
|
```typescript
|
|
301
|
-
//
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
```typescript
|
|
310
|
-
// app/actions/auth.ts
|
|
311
|
-
'use server'
|
|
105
|
+
// BEFORE (mock data from uxui-frontend)
|
|
106
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
107
|
+
setIsLoading(true)
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
console.log("Login success (mock)")
|
|
110
|
+
setIsLoading(false)
|
|
111
|
+
}, 1000)
|
|
112
|
+
}
|
|
312
113
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
114
|
+
// AFTER (real API)
|
|
115
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
116
|
+
setIsLoading(true)
|
|
117
|
+
setError(null)
|
|
316
118
|
|
|
317
119
|
try {
|
|
318
|
-
const
|
|
120
|
+
const response = await fetch('/api/auth/login', {
|
|
319
121
|
method: 'POST',
|
|
320
122
|
headers: { 'Content-Type': 'application/json' },
|
|
321
123
|
body: JSON.stringify({ email, password })
|
|
322
124
|
})
|
|
323
125
|
|
|
324
|
-
if (!
|
|
325
|
-
const
|
|
326
|
-
|
|
126
|
+
if (!response.ok) {
|
|
127
|
+
const data = await response.json()
|
|
128
|
+
throw new Error(data.error || 'Login failed')
|
|
327
129
|
}
|
|
328
130
|
|
|
329
|
-
const
|
|
330
|
-
// Set cookie, session, etc.
|
|
331
|
-
return { success: true, token: data.token, user: data.user }
|
|
332
|
-
} catch (error) {
|
|
333
|
-
console.error('Login error:', error)
|
|
334
|
-
return { success: false, error: 'Network error' }
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
```
|
|
131
|
+
const { token, user } = await response.json()
|
|
338
132
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
'use client'
|
|
343
|
-
import { loginAction } from '@/app/actions/auth'
|
|
344
|
-
|
|
345
|
-
export default function LoginForm() {
|
|
346
|
-
const [isLoading, setIsLoading] = useState(false)
|
|
347
|
-
const [error, setError] = useState('')
|
|
348
|
-
|
|
349
|
-
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
350
|
-
e.preventDefault()
|
|
351
|
-
setIsLoading(true)
|
|
352
|
-
setError('')
|
|
353
|
-
|
|
354
|
-
const formData = new FormData(e.currentTarget)
|
|
355
|
-
const result = await loginAction(formData)
|
|
356
|
-
|
|
357
|
-
if (result.success) {
|
|
358
|
-
// Redirect or update UI
|
|
359
|
-
router.push('/dashboard')
|
|
360
|
-
} else {
|
|
361
|
-
setError(result.error)
|
|
362
|
-
}
|
|
133
|
+
// Store in state management
|
|
134
|
+
useAuthStore.getState().setUser(user)
|
|
135
|
+
localStorage.setItem('token', token)
|
|
363
136
|
|
|
137
|
+
// Redirect
|
|
138
|
+
router.push('/dashboard')
|
|
139
|
+
} catch (err) {
|
|
140
|
+
setError(err instanceof Error ? err.message : 'Unknown error')
|
|
141
|
+
} finally {
|
|
364
142
|
setIsLoading(false)
|
|
365
143
|
}
|
|
366
|
-
|
|
367
|
-
return <form onSubmit={handleSubmit}>...</form>
|
|
368
144
|
}
|
|
369
145
|
```
|
|
370
146
|
|
|
371
|
-
### Step
|
|
147
|
+
### Step 4: Add State Management (If Needed)
|
|
372
148
|
|
|
373
|
-
**Zustand Store Example:**
|
|
374
149
|
```typescript
|
|
375
|
-
//
|
|
150
|
+
// stores/auth.ts
|
|
376
151
|
import { create } from 'zustand'
|
|
377
|
-
import { persist } from 'zustand/middleware'
|
|
378
152
|
|
|
379
153
|
interface AuthState {
|
|
380
154
|
user: User | null
|
|
381
|
-
|
|
382
|
-
setAuth: (user: User, token: string) => void
|
|
155
|
+
setUser: (user: User | null) => void
|
|
383
156
|
logout: () => void
|
|
384
157
|
}
|
|
385
158
|
|
|
386
|
-
export const useAuthStore = create<AuthState>()(
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
logout: () => set({ user: null, token: null })
|
|
393
|
-
}),
|
|
394
|
-
{ name: 'auth-storage' }
|
|
395
|
-
)
|
|
396
|
-
)
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
**Use in Component:**
|
|
400
|
-
```typescript
|
|
401
|
-
import { useAuthStore } from '@/lib/stores/auth-store'
|
|
402
|
-
|
|
403
|
-
export default function LoginForm() {
|
|
404
|
-
const setAuth = useAuthStore((state) => state.setAuth)
|
|
405
|
-
|
|
406
|
-
const handleSubmit = async (e) => {
|
|
407
|
-
// ...
|
|
408
|
-
if (result.success) {
|
|
409
|
-
setAuth(result.user, result.token)
|
|
410
|
-
router.push('/dashboard')
|
|
411
|
-
}
|
|
159
|
+
export const useAuthStore = create<AuthState>((set) => ({
|
|
160
|
+
user: null,
|
|
161
|
+
setUser: (user) => set({ user }),
|
|
162
|
+
logout: () => {
|
|
163
|
+
set({ user: null })
|
|
164
|
+
localStorage.removeItem('token')
|
|
412
165
|
}
|
|
413
|
-
}
|
|
166
|
+
}))
|
|
414
167
|
```
|
|
415
168
|
|
|
416
|
-
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Error Handling Pattern
|
|
417
172
|
|
|
418
173
|
```typescript
|
|
174
|
+
// Consistent error handling
|
|
419
175
|
try {
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
if (!result.success) {
|
|
423
|
-
// User-facing error
|
|
424
|
-
setError(result.error)
|
|
176
|
+
const response = await fetch(url, options)
|
|
425
177
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
error: result.error,
|
|
430
|
-
timestamp: new Date().toISOString()
|
|
431
|
-
})
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
const data = await response.json().catch(() => ({}))
|
|
180
|
+
throw new Error(data.error || `HTTP ${response.status}`)
|
|
432
181
|
}
|
|
433
|
-
} catch (error) {
|
|
434
|
-
// Network error
|
|
435
|
-
setError('Unable to connect. Please try again.')
|
|
436
|
-
|
|
437
|
-
console.error('Login network error:', {
|
|
438
|
-
event: 'login_network_error',
|
|
439
|
-
error: error instanceof Error ? error.message : 'Unknown',
|
|
440
|
-
timestamp: new Date().toISOString()
|
|
441
|
-
})
|
|
442
|
-
}
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
### Step 5: Add Tests
|
|
446
|
-
|
|
447
|
-
```typescript
|
|
448
|
-
// __tests__/LoginForm.integration.test.tsx
|
|
449
|
-
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
|
|
450
|
-
import LoginForm from '@/app/components/LoginForm'
|
|
451
|
-
import { loginAction } from '@/app/actions/auth'
|
|
452
|
-
|
|
453
|
-
// Mock server action
|
|
454
|
-
vi.mock('@/app/actions/auth', () => ({
|
|
455
|
-
loginAction: vi.fn()
|
|
456
|
-
}))
|
|
457
182
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
token: 'token-123',
|
|
463
|
-
user: { id: '1', name: 'John' }
|
|
464
|
-
})
|
|
465
|
-
|
|
466
|
-
render(<LoginForm />)
|
|
467
|
-
|
|
468
|
-
fireEvent.change(screen.getByLabelText(/email/i), {
|
|
469
|
-
target: { value: 'test@example.com' }
|
|
470
|
-
})
|
|
471
|
-
fireEvent.change(screen.getByLabelText(/password/i), {
|
|
472
|
-
target: { value: 'password123' }
|
|
473
|
-
})
|
|
474
|
-
fireEvent.click(screen.getByRole('button', { name: /sign in/i }))
|
|
475
|
-
|
|
476
|
-
await waitFor(() => {
|
|
477
|
-
expect(mockLoginAction).toHaveBeenCalledWith(expect.any(FormData))
|
|
478
|
-
})
|
|
479
|
-
})
|
|
480
|
-
|
|
481
|
-
test('failed login shows error message', async () => {
|
|
482
|
-
const mockLoginAction = vi.mocked(loginAction)
|
|
483
|
-
mockLoginAction.mockResolvedValue({
|
|
484
|
-
success: false,
|
|
485
|
-
error: 'Invalid credentials'
|
|
486
|
-
})
|
|
487
|
-
|
|
488
|
-
render(<LoginForm />)
|
|
489
|
-
|
|
490
|
-
// ... trigger login
|
|
491
|
-
|
|
492
|
-
await waitFor(() => {
|
|
493
|
-
expect(screen.getByText(/invalid credentials/i)).toBeInTheDocument()
|
|
494
|
-
})
|
|
495
|
-
})
|
|
496
|
-
```
|
|
183
|
+
return await response.json()
|
|
184
|
+
} catch (err) {
|
|
185
|
+
// Log for debugging
|
|
186
|
+
console.error('API Error:', err)
|
|
497
187
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
{
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
"endpoint": "POST /api/auth/login",
|
|
505
|
-
"state_management": "zustand",
|
|
506
|
-
"contexts_loaded": [
|
|
507
|
-
"patterns/state-management.md",
|
|
508
|
-
"patterns/error-handling.md",
|
|
509
|
-
"Context7: Next.js Server Actions",
|
|
510
|
-
"Context7: Zustand persist middleware"
|
|
511
|
-
],
|
|
512
|
-
"tests_added": [
|
|
513
|
-
"LoginForm.integration.test.tsx"
|
|
514
|
-
]
|
|
188
|
+
// User-friendly message
|
|
189
|
+
if (err instanceof Error) {
|
|
190
|
+
setError(err.message)
|
|
191
|
+
} else {
|
|
192
|
+
setError('An unexpected error occurred')
|
|
193
|
+
}
|
|
515
194
|
}
|
|
516
195
|
```
|
|
517
196
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
```markdown
|
|
521
|
-
✅ Task 2.1 Complete
|
|
197
|
+
WHY: Consistent error handling makes debugging easier and provides good UX.
|
|
522
198
|
|
|
523
|
-
|
|
524
|
-
- Created: app/actions/auth.ts (Server Action)
|
|
525
|
-
- Updated: app/components/LoginForm.tsx (removed mock, added real API)
|
|
526
|
-
- Created: lib/stores/auth-store.ts (Zustand store with persist)
|
|
527
|
-
- Created: __tests__/LoginForm.integration.test.tsx (integration tests)
|
|
199
|
+
---
|
|
528
200
|
|
|
529
|
-
|
|
530
|
-
- Endpoint: POST /api/auth/login
|
|
531
|
-
- Error handling: Network errors + validation errors
|
|
532
|
-
- Loading states: Button disabled during request
|
|
533
|
-
- Success flow: Store auth → Redirect to /dashboard
|
|
201
|
+
## State Management Decision
|
|
534
202
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
203
|
+
| Scenario | Approach |
|
|
204
|
+
|----------|----------|
|
|
205
|
+
| Global user/auth state | Zustand store |
|
|
206
|
+
| Server state (data fetching) | React Query / SWR |
|
|
207
|
+
| Local component state | useState |
|
|
208
|
+
| Form state | React Hook Form |
|
|
209
|
+
| Complex nested state | Zustand with immer |
|
|
538
210
|
|
|
539
211
|
---
|
|
540
212
|
|
|
541
|
-
##
|
|
213
|
+
## Implementation Standards
|
|
542
214
|
|
|
543
|
-
|
|
215
|
+
| Standard | Implementation | WHY |
|
|
216
|
+
|----------|----------------|-----|
|
|
217
|
+
| Error boundaries | Wrap pages/sections | Graceful degradation |
|
|
218
|
+
| Loading states | Show skeleton/spinner | UX feedback |
|
|
219
|
+
| Optimistic updates | Update before API confirms | Perceived speed |
|
|
220
|
+
| Error messages | User-friendly text | Good UX |
|
|
221
|
+
| Token storage | localStorage + httpOnly cookie | Security |
|
|
544
222
|
|
|
545
|
-
|
|
223
|
+
---
|
|
546
224
|
|
|
547
|
-
|
|
548
|
-
**Purpose:** Hand off API-integrated components for testing
|
|
225
|
+
## TDD Workflow (When Required)
|
|
549
226
|
|
|
550
|
-
|
|
551
|
-
- API endpoints connected (with request/response formats)
|
|
552
|
-
- State management implementation (Zustand/Redux stores)
|
|
553
|
-
- Error handling patterns used
|
|
554
|
-
- Test scenarios to cover (success, failure, edge cases)
|
|
555
|
-
- Protected routes or auth flows
|
|
556
|
-
- Files modified/created
|
|
227
|
+
Check `tdd_required` flag from orchestrator.
|
|
557
228
|
|
|
558
|
-
**
|
|
229
|
+
**If true:**
|
|
230
|
+
- Write tests for API integration first
|
|
231
|
+
- Test error handling paths
|
|
232
|
+
- Test state management updates
|
|
559
233
|
|
|
560
|
-
|
|
234
|
+
→ See `.claude/lib/tdd-workflow.md`
|
|
561
235
|
|
|
562
236
|
---
|
|
563
237
|
|
|
564
|
-
##
|
|
565
|
-
|
|
566
|
-
**→ See:** `.claude/contexts/patterns/code-standards.md` → "Forbidden Files" section
|
|
238
|
+
## Output Format
|
|
567
239
|
|
|
568
|
-
|
|
240
|
+
```markdown
|
|
241
|
+
Task Complete: Connect LoginForm to API
|
|
569
242
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
- ❌ NEVER create ALL_CAPS filenames or files with PHASE_/STEP_ prefixes
|
|
573
|
-
- ✅ Return all results in your **final response text**
|
|
574
|
-
- ✅ Update `flags.json` with integration results
|
|
243
|
+
Component: src/components/LoginForm.tsx
|
|
244
|
+
State: src/stores/auth.ts (Zustand)
|
|
575
245
|
|
|
576
|
-
|
|
246
|
+
Changes:
|
|
247
|
+
- Replaced mock setTimeout with fetch('/api/auth/login')
|
|
248
|
+
- Added error state and display
|
|
249
|
+
- Added Zustand auth store
|
|
250
|
+
- Added token storage
|
|
577
251
|
|
|
578
|
-
|
|
252
|
+
Error Handling:
|
|
253
|
+
- Invalid credentials → shows error message
|
|
254
|
+
- Network error → shows retry message
|
|
255
|
+
- Server error → shows generic message
|
|
579
256
|
|
|
580
|
-
|
|
257
|
+
State Management:
|
|
258
|
+
- User stored in useAuthStore
|
|
259
|
+
- Token stored in localStorage
|
|
581
260
|
|
|
582
|
-
|
|
261
|
+
Tests: src/components/LoginForm.test.tsx
|
|
583
262
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
- ✅ Use exact package manager from tech-stack.md (pnpm, npm, bun, uv, poetry, pip)
|
|
587
|
-
- ❌ NEVER assume or hardcode package manager
|
|
588
|
-
- ❌ If tech-stack.md missing → warn user to run `/csetup`
|
|
263
|
+
Next Step: [next task or agent]
|
|
264
|
+
```
|
|
589
265
|
|
|
590
|
-
|
|
591
|
-
- ✅ Check `tdd_required` flag from Orchestrator
|
|
592
|
-
- ✅ If `true`: MUST use Red-Green-Refactor workflow
|
|
593
|
-
- ✅ RED: Write test FIRST, verify it FAILS
|
|
594
|
-
- ✅ GREEN: Write minimal code to pass
|
|
595
|
-
- ✅ REFACTOR: Add real integration, logging, error handling
|
|
596
|
-
- ✅ If `false`: Test-Alongside OK (implementation first, then tests)
|
|
597
|
-
- ✅ Log each TDD phase (red, green, refactor)
|
|
266
|
+
---
|
|
598
267
|
|
|
599
|
-
|
|
600
|
-
- ✅ Replace ALL mock data with real API calls
|
|
601
|
-
- ✅ Add proper error handling (network + validation)
|
|
602
|
-
- ✅ Implement loading states
|
|
603
|
-
- ✅ Use state management for global state (auth, user data)
|
|
604
|
-
- ✅ Add comprehensive tests (unit + integration)
|
|
605
|
-
- ✅ Log all API calls (success + errors)
|
|
606
|
-
- ✅ Use Context7 for latest framework patterns
|
|
268
|
+
## Package Manager
|
|
607
269
|
|
|
608
|
-
|
|
609
|
-
- ❌ Don't skip TDD when required (trust Orchestrator classification)
|
|
610
|
-
- ❌ Don't write implementation before tests (when TDD required)
|
|
611
|
-
- ❌ Don't skip error handling
|
|
612
|
-
- ❌ Don't leave console.log (use structured logging)
|
|
613
|
-
- ❌ Don't hardcode API URLs (use env variables)
|
|
270
|
+
→ See `.claude/agents/_shared/package-manager.md`
|
|
614
271
|
|
|
615
272
|
---
|
|
616
273
|
|
|
617
|
-
##
|
|
618
|
-
|
|
619
|
-
### Update Progress (If Working on OpenSpec Change)
|
|
274
|
+
## Documentation Policy
|
|
620
275
|
|
|
621
|
-
|
|
622
|
-
```bash
|
|
623
|
-
ls openspec/changes/{change-id}/.claude/flags.json
|
|
624
|
-
```
|
|
276
|
+
→ See `.claude/agents/_shared/documentation-policy.md`
|
|
625
277
|
|
|
626
|
-
|
|
278
|
+
---
|
|
627
279
|
|
|
628
|
-
|
|
280
|
+
## Progress Tracking (OpenSpec)
|
|
629
281
|
|
|
630
|
-
Update
|
|
631
|
-
```json
|
|
632
|
-
{
|
|
633
|
-
"phases": {
|
|
634
|
-
"{current-phase}": {
|
|
635
|
-
"status": "completed",
|
|
636
|
-
"completed_at": "{ISO-timestamp}",
|
|
637
|
-
"actual_minutes": {duration},
|
|
638
|
-
"tasks_completed": ["{task-ids}"],
|
|
639
|
-
"files_created": ["{file-paths}"],
|
|
640
|
-
"notes": "{summary - API connections, state management, error handling}"
|
|
641
|
-
}
|
|
642
|
-
},
|
|
643
|
-
"current_phase": "{next-phase-id}",
|
|
644
|
-
"updated_at": "{ISO-timestamp}"
|
|
645
|
-
}
|
|
646
|
-
```
|
|
282
|
+
Update `flags.json`:
|
|
647
283
|
|
|
648
|
-
**Example update:**
|
|
649
284
|
```json
|
|
650
285
|
{
|
|
651
286
|
"phases": {
|
|
652
|
-
"frontend
|
|
287
|
+
"frontend": {
|
|
653
288
|
"status": "completed",
|
|
654
|
-
"
|
|
655
|
-
"
|
|
656
|
-
"
|
|
657
|
-
"files_created": [
|
|
658
|
-
"src/lib/stores/auth-store.ts",
|
|
659
|
-
"src/app/actions/auth.ts"
|
|
660
|
-
],
|
|
661
|
-
"notes": "Connected LoginForm to POST /api/login. Added Zustand for auth state. Replaced all mock data with real API calls."
|
|
289
|
+
"components_connected": ["LoginForm", "UserProfile"],
|
|
290
|
+
"stores_created": ["auth.ts"],
|
|
291
|
+
"apis_integrated": ["POST /api/auth/login"]
|
|
662
292
|
}
|
|
663
|
-
}
|
|
664
|
-
"current_phase": "component-tests",
|
|
665
|
-
"updated_at": "2025-10-30T13:20:00Z"
|
|
293
|
+
}
|
|
666
294
|
}
|
|
667
295
|
```
|
|
668
|
-
|
|
669
|
-
### What NOT to Update
|
|
670
|
-
|
|
671
|
-
❌ **DO NOT** update `tasks.md` (OpenSpec owns this)
|
|
672
|
-
❌ **DO NOT** update `phases.md` (generated once, read-only)
|
|
673
|
-
❌ **DO NOT** update `proposal.md` or `design.md`
|
|
674
|
-
|
|
675
|
-
---
|