@qazuor/claude-code-config 0.1.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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1248 -0
  3. package/dist/bin.cjs +11886 -0
  4. package/dist/bin.cjs.map +1 -0
  5. package/dist/bin.d.cts +1 -0
  6. package/dist/bin.d.ts +1 -0
  7. package/dist/bin.js +11869 -0
  8. package/dist/bin.js.map +1 -0
  9. package/dist/index.cjs +3887 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.cts +1325 -0
  12. package/dist/index.d.ts +1325 -0
  13. package/dist/index.js +3835 -0
  14. package/dist/index.js.map +1 -0
  15. package/package.json +86 -0
  16. package/templates/.log/notifications.log +1775 -0
  17. package/templates/agents/README.md +164 -0
  18. package/templates/agents/_registry.json +443 -0
  19. package/templates/agents/design/content-writer.md +353 -0
  20. package/templates/agents/design/ux-ui-designer.md +382 -0
  21. package/templates/agents/engineering/astro-engineer.md +293 -0
  22. package/templates/agents/engineering/db-drizzle-engineer.md +360 -0
  23. package/templates/agents/engineering/express-engineer.md +316 -0
  24. package/templates/agents/engineering/fastify-engineer.md +399 -0
  25. package/templates/agents/engineering/hono-engineer.md +263 -0
  26. package/templates/agents/engineering/mongoose-engineer.md +473 -0
  27. package/templates/agents/engineering/nestjs-engineer.md +429 -0
  28. package/templates/agents/engineering/nextjs-engineer.md +451 -0
  29. package/templates/agents/engineering/node-typescript-engineer.md +347 -0
  30. package/templates/agents/engineering/prisma-engineer.md +432 -0
  31. package/templates/agents/engineering/react-senior-dev.md +394 -0
  32. package/templates/agents/engineering/tanstack-start-engineer.md +447 -0
  33. package/templates/agents/engineering/tech-lead.md +269 -0
  34. package/templates/agents/product/product-functional.md +329 -0
  35. package/templates/agents/product/product-technical.md +578 -0
  36. package/templates/agents/quality/debugger.md +514 -0
  37. package/templates/agents/quality/qa-engineer.md +390 -0
  38. package/templates/agents/specialized/enrichment-agent.md +277 -0
  39. package/templates/agents/specialized/i18n-specialist.md +322 -0
  40. package/templates/agents/specialized/seo-ai-specialist.md +387 -0
  41. package/templates/agents/specialized/tech-writer.md +300 -0
  42. package/templates/code-style/.editorconfig +27 -0
  43. package/templates/code-style/.prettierignore +25 -0
  44. package/templates/code-style/.prettierrc +12 -0
  45. package/templates/code-style/biome.json +78 -0
  46. package/templates/code-style/commitlint.config.js +44 -0
  47. package/templates/commands/README.md +175 -0
  48. package/templates/commands/_registry.json +420 -0
  49. package/templates/commands/add-new-entity.md +211 -0
  50. package/templates/commands/audit/accessibility-audit.md +360 -0
  51. package/templates/commands/audit/performance-audit.md +290 -0
  52. package/templates/commands/audit/security-audit.md +231 -0
  53. package/templates/commands/code-check.md +127 -0
  54. package/templates/commands/five-why.md +225 -0
  55. package/templates/commands/formatting/format-markdown.md +197 -0
  56. package/templates/commands/git/commit.md +247 -0
  57. package/templates/commands/meta/create-agent.md +257 -0
  58. package/templates/commands/meta/create-command.md +312 -0
  59. package/templates/commands/meta/create-skill.md +321 -0
  60. package/templates/commands/meta/help.md +318 -0
  61. package/templates/commands/planning/check-completed-tasks.md +224 -0
  62. package/templates/commands/planning/cleanup-issues.md +248 -0
  63. package/templates/commands/planning/planning-cleanup.md +251 -0
  64. package/templates/commands/planning/sync-planning-github.md +133 -0
  65. package/templates/commands/planning/sync-todos-github.md +203 -0
  66. package/templates/commands/quality-check.md +211 -0
  67. package/templates/commands/run-tests.md +159 -0
  68. package/templates/commands/start-feature-plan.md +232 -0
  69. package/templates/commands/start-refactor-plan.md +244 -0
  70. package/templates/commands/sync-planning.md +176 -0
  71. package/templates/commands/update-docs.md +242 -0
  72. package/templates/docs/CHECKPOINT-SYSTEM.md +504 -0
  73. package/templates/docs/INDEX.md +677 -0
  74. package/templates/docs/RECOMMENDED-HOOKS.md +415 -0
  75. package/templates/docs/_registry.json +329 -0
  76. package/templates/docs/diagrams/README.md +220 -0
  77. package/templates/docs/diagrams/agent-hierarchy.mmd +55 -0
  78. package/templates/docs/diagrams/documentation-map.mmd +61 -0
  79. package/templates/docs/diagrams/tools-relationship.mmd +55 -0
  80. package/templates/docs/diagrams/workflow-decision-tree.mmd +38 -0
  81. package/templates/docs/doc-sync.md +533 -0
  82. package/templates/docs/examples/end-to-end-workflow.md +1505 -0
  83. package/templates/docs/glossary.md +495 -0
  84. package/templates/docs/guides/mockup-prompt-engineering.md +644 -0
  85. package/templates/docs/guides/mockup-setup.md +737 -0
  86. package/templates/docs/learnings/README.md +250 -0
  87. package/templates/docs/learnings/common-architectural-patterns.md +123 -0
  88. package/templates/docs/learnings/common-mistakes-to-avoid.md +149 -0
  89. package/templates/docs/learnings/markdown-formatting-standards.md +104 -0
  90. package/templates/docs/learnings/monorepo-command-execution.md +64 -0
  91. package/templates/docs/learnings/optimization-tips.md +146 -0
  92. package/templates/docs/learnings/planning-linear-sync-workflow.md +70 -0
  93. package/templates/docs/learnings/shell-compatibility-fish.md +46 -0
  94. package/templates/docs/learnings/test-organization-structure.md +68 -0
  95. package/templates/docs/mcp-installation.md +613 -0
  96. package/templates/docs/mcp-servers.md +989 -0
  97. package/templates/docs/notification-installation.md +570 -0
  98. package/templates/docs/quick-start.md +354 -0
  99. package/templates/docs/standards/architecture-patterns.md +1064 -0
  100. package/templates/docs/standards/atomic-commits.md +513 -0
  101. package/templates/docs/standards/code-standards.md +993 -0
  102. package/templates/docs/standards/design-standards.md +656 -0
  103. package/templates/docs/standards/documentation-standards.md +1160 -0
  104. package/templates/docs/standards/testing-standards.md +969 -0
  105. package/templates/docs/system-maintenance.md +604 -0
  106. package/templates/docs/templates/PDR-template.md +561 -0
  107. package/templates/docs/templates/TODOs-template.md +534 -0
  108. package/templates/docs/templates/tech-analysis-template.md +800 -0
  109. package/templates/docs/workflows/README.md +519 -0
  110. package/templates/docs/workflows/atomic-task-protocol.md +955 -0
  111. package/templates/docs/workflows/decision-tree.md +482 -0
  112. package/templates/docs/workflows/edge-cases.md +856 -0
  113. package/templates/docs/workflows/phase-1-planning.md +957 -0
  114. package/templates/docs/workflows/phase-2-implementation.md +896 -0
  115. package/templates/docs/workflows/phase-3-validation.md +792 -0
  116. package/templates/docs/workflows/phase-4-finalization.md +927 -0
  117. package/templates/docs/workflows/quick-fix-protocol.md +505 -0
  118. package/templates/docs/workflows/task-atomization.md +537 -0
  119. package/templates/docs/workflows/task-completion-protocol.md +448 -0
  120. package/templates/hooks/on-notification.sh +28 -0
  121. package/templates/schemas/checkpoint.schema.json +97 -0
  122. package/templates/schemas/code-registry.schema.json +84 -0
  123. package/templates/schemas/pdr.schema.json +314 -0
  124. package/templates/schemas/problems.schema.json +55 -0
  125. package/templates/schemas/tech-analysis.schema.json +404 -0
  126. package/templates/schemas/telemetry.schema.json +298 -0
  127. package/templates/schemas/todos.schema.json +234 -0
  128. package/templates/schemas/workflows.schema.json +69 -0
  129. package/templates/scripts/add-changelogs.sh +105 -0
  130. package/templates/scripts/generate-code-registry.ts +270 -0
  131. package/templates/scripts/health-check.sh +343 -0
  132. package/templates/scripts/sync-registry.sh +40 -0
  133. package/templates/scripts/telemetry-report.ts +36 -0
  134. package/templates/scripts/validate-docs.sh +224 -0
  135. package/templates/scripts/validate-registry.sh +225 -0
  136. package/templates/scripts/validate-schemas.ts +283 -0
  137. package/templates/scripts/validate-structure.sh +165 -0
  138. package/templates/scripts/worktree-cleanup.sh +81 -0
  139. package/templates/scripts/worktree-create.sh +63 -0
  140. package/templates/sessions/planning/.gitkeep +0 -0
  141. package/templates/sessions/planning/archived/.gitkeep +0 -0
  142. package/templates/settings.json +202 -0
  143. package/templates/settings.local.json +138 -0
  144. package/templates/skills/README.md +197 -0
  145. package/templates/skills/_registry.json +473 -0
  146. package/templates/skills/audit/accessibility-audit.md +309 -0
  147. package/templates/skills/audit/performance-audit.md +257 -0
  148. package/templates/skills/audit/security-audit.md +217 -0
  149. package/templates/skills/auth/nextauth-patterns.md +308 -0
  150. package/templates/skills/brand-guidelines.md +240 -0
  151. package/templates/skills/documentation/markdown-formatter.md +302 -0
  152. package/templates/skills/git/git-commit-helper.md +321 -0
  153. package/templates/skills/i18n/i18n-patterns.md +251 -0
  154. package/templates/skills/patterns/error-handling-patterns.md +242 -0
  155. package/templates/skills/patterns/tdd-methodology.md +342 -0
  156. package/templates/skills/qa/qa-criteria-validator.md +383 -0
  157. package/templates/skills/qa/web-app-testing.md +398 -0
  158. package/templates/skills/react/react-hook-form-patterns.md +359 -0
  159. package/templates/skills/state/redux-toolkit-patterns.md +272 -0
  160. package/templates/skills/state/tanstack-query-patterns.md +299 -0
  161. package/templates/skills/state/zustand-patterns.md +301 -0
  162. package/templates/skills/tech/mermaid-diagram-specialist.md +195 -0
  163. package/templates/skills/tech/shadcn-specialist.md +252 -0
  164. package/templates/skills/tech/vercel-specialist.md +297 -0
  165. package/templates/skills/testing/api-app-testing.md +254 -0
  166. package/templates/skills/testing/performance-testing.md +275 -0
  167. package/templates/skills/testing/security-testing.md +348 -0
  168. package/templates/skills/utils/add-memory.md +295 -0
  169. package/templates/skills/utils/json-data-auditor.md +283 -0
  170. package/templates/skills/utils/pdf-creator-editor.md +342 -0
  171. package/templates/tools/format-markdown.sh +185 -0
@@ -0,0 +1,1505 @@
1
+ # End-to-End Workflow Example
2
+
3
+ **Feature:** User Favorites for Entitys
4
+
5
+ This document shows a complete workflow from feature request to deployment, following the **Level 3: Feature Planning** protocol with all 4 phases.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Context](#context)
10
+ - [Phase 1: Planning](#phase-1-planning)
11
+ - [Phase 2: Implementation](#phase-2-implementation)
12
+ - [Phase 3: Validation](#phase-3-validation)
13
+ - [Phase 4: Finalization](#phase-4-finalization)
14
+ - [Results](#results)
15
+
16
+ ---
17
+
18
+ ## Context
19
+
20
+ ### Feature Request
21
+
22
+ **From:** Product Manager
23
+ **Date:** 2025-11-01
24
+ **Priority:** High
25
+
26
+ > "We need to allow users to save their favorite entitys for quick access later. Users should be able to add/remove favorites and see a list of their saved entitys. This should work for both logged-in users (persisted) and guest users (session-based)."
27
+
28
+ ### Initial Assessment
29
+
30
+ - **Workflow Level:** Level 3 (Feature Planning - 4 Phases)
31
+ - **Estimated Duration:** 3-5 days
32
+ - **Complexity:** Medium
33
+ - **Risk:** Low-Medium
34
+ - **Reason for Level 3:**
35
+ - Database changes required (favorites table)
36
+ - Multiple layers affected (DB, Service, API, Frontend)
37
+ - New business logic (favorites management)
38
+ - Authentication considerations
39
+ - Session management for guests
40
+
41
+ ---
42
+
43
+ ## Phase 1: Planning
44
+
45
+ **Duration:** 4-6 hours
46
+ **Participants:** product-functional, product-technical, ux-ui-designer, tech-lead
47
+
48
+ ### Step 1: Start Planning Session
49
+
50
+ ```bash
51
+ # Create planning session
52
+ mkdir -p .claude/sessions/planning/active/P-007-user-favorites
53
+ cd .claude/sessions/planning/active/P-007-user-favorites
54
+ ```
55
+
56
+ ### Step 2: Product Functional Analysis
57
+
58
+ **Agent:** product-functional
59
+
60
+ **Output:** `PDR.md` (Product Design Requirements)
61
+
62
+ <details>
63
+ <summary>PDR.md (Click to expand)</summary>
64
+
65
+ ```markdown
66
+ # PDR: User Favorites for Entitys
67
+
68
+ **Feature ID:** F-007
69
+ **Priority:** High
70
+ **Status:** Planning
71
+ **Created:** 2025-11-01
72
+
73
+ ## Overview
74
+
75
+ Allow users to save favorite entitys for quick access and future reference.
76
+
77
+ ## User Stories
78
+
79
+ ### US-001: Add to Favorites (Logged User)
80
+
81
+ **As a** logged-in user
82
+ **I want** to mark entitys as favorites
83
+ **So that** I can easily find them later
84
+
85
+ **Acceptance Criteria:**
86
+
87
+ - [ ] Heart icon appears on entity cards
88
+ - [ ] Clicking heart adds/removes from favorites
89
+ - [ ] Visual feedback shows favorite state (filled vs outline)
90
+ - [ ] Favorites persist across sessions
91
+ - [ ] Maximum 50 favorites per user
92
+
93
+ ### US-002: View Favorites List
94
+
95
+ **As a** logged-in user
96
+ **I want** to see all my favorite entitys
97
+ **So that** I can quickly access properties I'm interested in
98
+
99
+ **Acceptance Criteria:**
100
+
101
+ - [ ] Dedicated "Favorites" page accessible from navigation
102
+ - [ ] Shows all favorited entitys
103
+ - [ ] Displays same info as search results (image, title, price, rating)
104
+ - [ ] Empty state shown when no favorites
105
+ - [ ] Can remove favorites from this page
106
+ - [ ] Results are paginated (20 per page)
107
+
108
+ ### US-003: Guest User Favorites
109
+
110
+ **As a** guest user
111
+ **I want** to save favorites during my session
112
+ **So that** I can compare properties before deciding to register
113
+
114
+ **Acceptance Criteria:**
115
+
116
+ - [ ] Favorites stored in session/localStorage
117
+ - [ ] Same UI/UX as logged users
118
+ - [ ] Prompt to register when trying to exceed 5 favorites
119
+ - [ ] Clear message that favorites will be lost on logout
120
+ - [ ] Option to migrate favorites on registration
121
+
122
+ ## Mockups
123
+
124
+ ### Entity Card with Favorite Button
125
+
126
+ ```
127
+
128
+ ┌─────────────────────────────┐
129
+ │ [Image] ♡ /❤️ │
130
+ │ │
131
+ │ Beach House Villa │
132
+ │ ⭐ 4.8 (120) │
133
+ │ $150/night │
134
+ └─────────────────────────────┘
135
+
136
+ ```
137
+
138
+ ### Favorites Page
139
+
140
+ ```
141
+
142
+ ┌─────────────────────────────────────────┐
143
+ │ My Favorites (12) │
144
+ ├─────────────────────────────────────────┤
145
+ │ ┌───────────┐ │
146
+ │ │ [Image] │ Beach Villa ❤️ Remove │
147
+ │ └───────────┘ $150/night ⭐ 4.8 │
148
+ │ │
149
+ │ ┌───────────┐ │
150
+ │ │ [Image] │ City Apartment ❤️ Remove│
151
+ │ └───────────┘ $80/night ⭐ 4.5 │
152
+ └─────────────────────────────────────────┘
153
+
154
+ ```
155
+
156
+ ## Functional Requirements
157
+
158
+ ### FR-001: Favorite Management
159
+
160
+ - Users can add/remove favorites
161
+ - System prevents duplicates
162
+ - Favorites associated with user ID
163
+ - Soft delete (mark as inactive instead of DELETE)
164
+
165
+ ### FR-002: Limits
166
+
167
+ - Logged users: max 50 favorites
168
+ - Guest users: max 5 favorites
169
+ - Clear error messages when limits reached
170
+
171
+ ### FR-003: Performance
172
+
173
+ - Favorites list loads < 500ms
174
+ - Add/remove operations < 200ms
175
+ - Optimistic UI updates
176
+
177
+ ## Non-Functional Requirements
178
+
179
+ ### NFR-001: Scalability
180
+
181
+ - Support up to 100,000 users with favorites
182
+ - Efficient queries (proper indexing)
183
+
184
+ ### NFR-002: Data Integrity
185
+
186
+ - No orphaned favorites
187
+ - CASCADE delete when user deleted
188
+ - CASCADE update when entity deleted
189
+
190
+ ### NFR-003: Security
191
+
192
+ - Users can only see/modify their own favorites
193
+ - Rate limiting on favorite operations (max 10/minute)
194
+
195
+ ## Out of Scope
196
+
197
+ - Sharing favorites with other users
198
+ - Organizing favorites into lists/categories
199
+ - Email notifications for price changes on favorites
200
+ - Collaborative favorites (multiple users)
201
+
202
+ ## Dependencies
203
+
204
+ - User authentication system (Clerk)
205
+ - Entity service (existing)
206
+
207
+ ## Risks
208
+
209
+ | Risk | Impact | Mitigation |
210
+ |------|--------|------------|
211
+ | Performance degradation with large favorites lists | Medium | Implement pagination, caching |
212
+ | Guest favorites lost | Low | Clear messaging, migration flow |
213
+ | Favorite spam/abuse | Low | Rate limiting, max limits |
214
+
215
+ ## Success Metrics
216
+
217
+ - 40%+ users add at least one favorite within first week
218
+ - < 1% error rate on favorite operations
219
+ - Average 8 favorites per active user
220
+ ```
221
+
222
+ </details>
223
+
224
+ ### Step 3: UX/UI Design
225
+
226
+ **Agent:** ux-ui-designer
227
+
228
+ **Output:** Design specs in `PDR.md` (mockups section)
229
+
230
+ **Key Decisions:**
231
+
232
+ - Heart icon for consistency with booking platforms
233
+ - Filled heart (❤️) for favorited, outline (♡) for not favorited
234
+ - Optimistic UI: instant visual feedback, revert on error
235
+ - Toast notifications for add/remove confirmations
236
+
237
+ ### Step 4: Technical Analysis
238
+
239
+ **Agent:** product-technical
240
+
241
+ **Output:** `tech-analysis.md`
242
+
243
+ <details>
244
+ <summary>tech-analysis.md (Click to expand)</summary>
245
+
246
+ ```markdown
247
+ # Technical Analysis: User Favorites
248
+
249
+ **Feature ID:** F-007
250
+ **Complexity:** Medium
251
+ **Estimated Effort:** 20-24 hours
252
+
253
+ ## Architecture Impact
254
+
255
+ ### Database Layer
256
+
257
+ **New Table:** `favorites`
258
+
259
+ ```sql
260
+ CREATE TABLE favorites (
261
+ id TEXT PRIMARY KEY,
262
+ user_id TEXT NOT NULL,
263
+ entity_id TEXT NOT NULL,
264
+ created_at TIMESTAMP DEFAULT NOW(),
265
+ is_active BOOLEAN DEFAULT TRUE,
266
+
267
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
268
+ FOREIGN KEY (entity_id) REFERENCES entitys(id) ON DELETE CASCADE,
269
+ UNIQUE (user_id, entity_id)
270
+ );
271
+
272
+ CREATE INDEX idx_favorites_user ON favorites(user_id, is_active);
273
+ CREATE INDEX idx_favorites_entity ON favorites(entity_id);
274
+ ```
275
+
276
+ ### Service Layer
277
+
278
+ **New Service:** `FavoriteService extends BaseCrudService`
279
+
280
+ Methods:
281
+
282
+ - `addFavorite({ userId, entityId })` - Add favorite
283
+ - `removeFavorite({ userId, entityId })` - Remove favorite (soft delete)
284
+ - `getFavorites({ userId, pagination })` - Get user's favorites
285
+ - `isFavorite({ userId, entityId })` - Check if favorited
286
+ - `getFavoriteCount({ userId })` - Get count for limit checking
287
+
288
+ ### API Layer
289
+
290
+ **New Routes:** `/api/favorites`
291
+
292
+ - `POST /favorites` - Add favorite
293
+ - `DELETE /favorites/:entityId` - Remove favorite
294
+ - `GET /favorites` - List user's favorites
295
+ - `GET /favorites/check/:entityId` - Check if favorited
296
+
297
+ ### Frontend (Web)
298
+
299
+ **Components:**
300
+
301
+ - `FavoriteButton.tsx` - Heart icon toggle
302
+ - `FavoritesList.tsx` - Favorites page
303
+ - `FavoritesEmpty.tsx` - Empty state
304
+
305
+ **State Management:**
306
+
307
+ - TanStack Query for server state
308
+ - Optimistic updates for add/remove
309
+
310
+ ### Frontend (Admin)
311
+
312
+ **No changes required** - Admin doesn't need favorites feature
313
+
314
+ ## Technology Stack
315
+
316
+ | Layer | Technology |
317
+ |-------|------------|
318
+ | Database | PostgreSQL + Drizzle ORM |
319
+ | Validation | Zod schemas |
320
+ | API | Hono |
321
+ | Frontend | Astro + React 19 |
322
+ | State | TanStack Query |
323
+ | Auth | Clerk |
324
+
325
+ ## Data Flow
326
+
327
+ ```
328
+ User clicks heart
329
+
330
+ Optimistic UI update (instant feedback)
331
+
332
+ POST /api/favorites
333
+
334
+ Auth middleware validates user
335
+
336
+ Zod validates payload
337
+
338
+ FavoriteService.addFavorite()
339
+
340
+ Check user favorites count < limit
341
+
342
+ FavoriteModel.create()
343
+
344
+ Return success
345
+
346
+ TanStack Query revalidates
347
+
348
+ UI stays updated (or reverts on error)
349
+ ```
350
+
351
+ ## Security Considerations
352
+
353
+ ### Authentication
354
+
355
+ - All endpoints require authentication
356
+ - User can only access their own favorites
357
+
358
+ ### Authorization
359
+
360
+ - Verify userId from JWT matches request
361
+ - No admin-specific permissions needed
362
+
363
+ ### Rate Limiting
364
+
365
+ - Max 10 operations/minute per user
366
+ - Prevents abuse/spam
367
+
368
+ ### Input Validation
369
+
370
+ ```typescript
371
+ addFavoriteSchema = z.object({
372
+ entityId: z.string().uuid(),
373
+ });
374
+
375
+ // userId comes from authenticated session
376
+ ```
377
+
378
+ ## Performance Optimization
379
+
380
+ ### Database
381
+
382
+ - Composite index on `(user_id, is_active)` for fast user lookups
383
+ - Soft deletes preserve data while keeping queries fast
384
+ - UNIQUE constraint prevents duplicates
385
+
386
+ ### API
387
+
388
+ - Pagination for favorites list (20 per page)
389
+ - Response caching with short TTL (1 minute)
390
+
391
+ ### Frontend
392
+
393
+ - Optimistic updates for instant feedback
394
+ - Prefetch favorites count on page load
395
+ - Debounce favorite toggle (prevent double-clicks)
396
+
397
+ ## Testing Strategy
398
+
399
+ ### Unit Tests
400
+
401
+ - FavoriteModel CRUD operations
402
+ - FavoriteService business logic
403
+ - Limit enforcement
404
+ - Duplicate prevention
405
+
406
+ ### Integration Tests
407
+
408
+ - API endpoints with authentication
409
+ - Database constraints
410
+ - Cascading deletes
411
+
412
+ ### E2E Tests
413
+
414
+ - Add favorite from search results
415
+ - Remove favorite from favorites page
416
+ - Guest user flow
417
+ - Limit enforcement UI
418
+
419
+ **Coverage Target:** 90%+ for all layers
420
+
421
+ ## Error Handling
422
+
423
+ | Scenario | Response | HTTP Code |
424
+ |----------|----------|-----------|
425
+ | Entity not found | "Entity not found" | 404 |
426
+ | Already favorited | No-op (idempotent) | 200 |
427
+ | Limit reached | "Maximum favorites reached (50)" | 400 |
428
+ | Unauthorized | "Authentication required" | 401 |
429
+ | Rate limit exceeded | "Too many requests" | 429 |
430
+
431
+ ## Rollout Plan
432
+
433
+ ### Phase 1: Backend (Day 1-2)
434
+
435
+ 1. Database migration
436
+ 2. Models and services
437
+ 3. API endpoints
438
+ 4. Unit + integration tests
439
+
440
+ ### Phase 2: Frontend (Day 3-4)
441
+
442
+ 1. React components
443
+ 2. TanStack Query integration
444
+ 3. Optimistic updates
445
+ 4. E2E tests
446
+
447
+ ### Phase 3: Polish (Day 5)
448
+
449
+ 1. Edge case handling
450
+ 2. Error messages
451
+ 3. Loading states
452
+ 4. Documentation
453
+
454
+ ## Risks & Mitigation
455
+
456
+ | Risk | Probability | Impact | Mitigation |
457
+ |------|-------------|--------|------------|
458
+ | Performance issues with large lists | Low | Medium | Pagination + indexing |
459
+ | Race conditions on toggle | Medium | Low | Optimistic updates + debouncing |
460
+ | Guest migration complexity | Low | Low | Simple: prompt to login |
461
+
462
+ ## Dependencies
463
+
464
+ - `@repo/db` - Database models
465
+ - `@repo/schemas` - Validation schemas
466
+ - `@repo/service-core` - Business logic
467
+ - `apps/api` - API routes
468
+ - `apps/web` - Frontend UI
469
+ - `@clerk/nextjs` - Authentication
470
+
471
+ ## Acceptance Criteria
472
+
473
+ - [ ] All user stories met
474
+ - [ ] 90%+ test coverage
475
+ - [ ] Performance targets met (< 500ms list, < 200ms toggle)
476
+ - [ ] Security audit passed
477
+ - [ ] Accessibility WCAG 2.1 AA compliant
478
+ - [ ] Documentation complete
479
+
480
+ ```
481
+
482
+ </details>
483
+
484
+ ### Step 5: Task Breakdown
485
+
486
+ **Agent:** product-technical
487
+
488
+ **Output:** `TODOs.md`
489
+
490
+ <details>
491
+ <summary>TODOs.md (Click to expand)</summary>
492
+
493
+ ```markdown
494
+ # TODOs: User Favorites Feature
495
+
496
+ **Feature ID:** F-007
497
+ **Session:** P-007-user-favorites
498
+
499
+ ## Phase 2: Implementation
500
+
501
+ ### PB-001: Database Schema & Migration
502
+
503
+ - **Description**: Create favorites table with indexes
504
+ - **Assignee**: @db-engineer
505
+ - **Estimated**: 2 hours
506
+ - **Dependencies**: None
507
+ - **Acceptance**:
508
+ - [ ] Migration file created
509
+ - [ ] Table with all fields
510
+ - [ ] Foreign keys configured
511
+ - [ ] Indexes created
512
+ - [ ] Migration tested (up/down)
513
+
514
+ ### PB-002: Zod Validation Schemas
515
+
516
+ - **Description**: Create Zod schemas for favorite operations
517
+ - **Assignee**: @node-typescript-engineer
518
+ - **Estimated**: 1 hour
519
+ - **Dependencies**: None
520
+ - **Acceptance**:
521
+ - [ ] `createFavoriteSchema`
522
+ - [ ] `getFavoritesSchema` (pagination)
523
+ - [ ] Types exported via `z.infer`
524
+ - [ ] Unit tests for schemas
525
+
526
+ ### PB-003: Favorite Model
527
+
528
+ - **Description**: Implement FavoriteModel extending BaseModel
529
+ - **Assignee**: @db-engineer
530
+ - **Estimated**: 3 hours
531
+ - **Dependencies**: PB-001
532
+ - **Acceptance**:
533
+ - [ ] Model class extends BaseModel
534
+ - [ ] CRUD methods implemented
535
+ - [ ] Soft delete support
536
+ - [ ] 90%+ test coverage
537
+ - [ ] JSDoc documentation
538
+
539
+ ### PB-004: Favorite Service
540
+
541
+ - **Description**: Business logic for favorites management
542
+ - **Assignee**: @node-typescript-engineer
543
+ - **Estimated**: 4 hours
544
+ - **Dependencies**: PB-002, PB-003
545
+ - **Acceptance**:
546
+ - [ ] Service extends BaseCrudService
547
+ - [ ] `addFavorite()` with limit checking
548
+ - [ ] `removeFavorite()` (soft delete)
549
+ - [ ] `getFavorites()` with pagination
550
+ - [ ] `isFavorite()` check
551
+ - [ ] `getFavoriteCount()` for limits
552
+ - [ ] Error handling
553
+ - [ ] 90%+ test coverage
554
+
555
+ ### PB-005: API Routes
556
+
557
+ - **Description**: Hono endpoints for favorites
558
+ - **Assignee**: @hono-engineer
559
+ - **Estimated**: 3 hours
560
+ - **Dependencies**: PB-004
561
+ - **Acceptance**:
562
+ - [ ] POST /api/favorites
563
+ - [ ] DELETE /api/favorites/:entityId
564
+ - [ ] GET /api/favorites (paginated)
565
+ - [ ] GET /api/favorites/check/:entityId
566
+ - [ ] Zod validation middleware
567
+ - [ ] Authentication middleware
568
+ - [ ] Rate limiting (10/min)
569
+ - [ ] Integration tests
570
+ - [ ] API documentation
571
+
572
+ ### PB-006: React Components
573
+
574
+ - **Description**: UI components for favorites
575
+ - **Assignee**: @react-senior-dev
576
+ - **Estimated**: 4 hours
577
+ - **Dependencies**: PB-005
578
+ - **Acceptance**:
579
+ - [ ] `FavoriteButton` component
580
+ - [ ] `FavoritesList` component
581
+ - [ ] `FavoritesEmpty` component
582
+ - [ ] Accessible (ARIA labels)
583
+ - [ ] Responsive design
584
+ - [ ] Unit tests
585
+ - [ ] Storybook stories
586
+
587
+ ### PB-007: TanStack Query Integration
588
+
589
+ - **Description**: Server state management for favorites
590
+ - **Assignee**: @astro-engineer
591
+ - **Estimated**: 3 hours
592
+ - **Dependencies**: PB-005, PB-006
593
+ - **Acceptance**:
594
+ - [ ] Query hooks for favorites
595
+ - [ ] Mutation hooks (add/remove)
596
+ - [ ] Optimistic updates
597
+ - [ ] Cache invalidation
598
+ - [ ] Error handling
599
+ - [ ] Loading states
600
+
601
+ ### PB-008: Favorites Page
602
+
603
+ - **Description**: Dedicated page for favorites list
604
+ - **Assignee**: @astro-engineer
605
+ - **Estimated**: 3 hours
606
+ - **Dependencies**: PB-007
607
+ - **Acceptance**:
608
+ - [ ] `/favorites` route
609
+ - [ ] Server-side rendering
610
+ - [ ] Pagination
611
+ - [ ] Empty state
612
+ - [ ] Remove functionality
613
+ - [ ] Responsive design
614
+ - [ ] SEO meta tags
615
+
616
+ ## Phase 3: Validation
617
+
618
+ ### PB-009: E2E Testing
619
+
620
+ - **Description**: End-to-end tests for favorites flow
621
+ - **Assignee**: @qa-engineer
622
+ - **Estimated**: 3 hours
623
+ - **Dependencies**: PB-008
624
+ - **Acceptance**:
625
+ - [ ] Test: Add favorite from search
626
+ - [ ] Test: Remove from favorites page
627
+ - [ ] Test: Limit enforcement (50)
628
+ - [ ] Test: Guest user flow
629
+ - [ ] Test: Authentication required
630
+ - [ ] All tests pass
631
+
632
+ ### PB-010: Quality Check
633
+
634
+ - **Description**: Run comprehensive quality checks
635
+ - **Assignee**: @tech-lead
636
+ - **Estimated**: 2 hours
637
+ - **Dependencies**: PB-009
638
+ - **Acceptance**:
639
+ - [ ] Code review passed
640
+ - [ ] 90%+ test coverage
641
+ - [ ] No lint errors
642
+ - [ ] No type errors
643
+ - [ ] Performance benchmarks met
644
+ - [ ] Security audit passed
645
+ - [ ] Accessibility audit passed
646
+
647
+ ## Phase 4: Finalization
648
+
649
+ ### PB-011: API Documentation
650
+
651
+ - **Description**: Document favorites API endpoints
652
+ - **Assignee**: @tech-writer
653
+ - **Estimated**: 2 hours
654
+ - **Dependencies**: PB-010
655
+ - **Acceptance**:
656
+ - [ ] OpenAPI/Swagger docs
657
+ - [ ] Request/response examples
658
+ - [ ] Error codes documented
659
+ - [ ] Rate limits documented
660
+
661
+ ### PB-012: User Documentation
662
+
663
+ - **Description**: User-facing documentation
664
+ - **Assignee**: @tech-writer
665
+ - **Estimated**: 1 hour
666
+ - **Dependencies**: PB-010
667
+ - **Acceptance**:
668
+ - [ ] Feature guide created
669
+ - [ ] Screenshots added
670
+ - [ ] FAQ section
671
+
672
+ ### PB-013: CHANGELOG Update
673
+
674
+ - **Description**: Add feature to changelog
675
+ - **Assignee**: @tech-writer
676
+ - **Estimated**: 0.5 hours
677
+ - **Dependencies**: PB-011, PB-012
678
+ - **Acceptance**:
679
+ - [ ] Entry in CHANGELOG.md
680
+ - [ ] Follows Keep a Changelog format
681
+ - [ ] Links to documentation
682
+
683
+ ## Summary
684
+
685
+ - **Total Tasks**: 13
686
+ - **Total Estimated**: 31.5 hours
687
+ - **Backend**: 10 hours (PB-001 to PB-003)
688
+ - **API**: 3 hours (PB-005)
689
+ - **Frontend**: 10 hours (PB-006 to PB-008)
690
+ - **QA**: 5 hours (PB-009 to PB-010)
691
+ - **Docs**: 3.5 hours (PB-011 to PB-013)
692
+ ```
693
+
694
+ </details>
695
+
696
+ ### Step 6: Planning Approval
697
+
698
+ **Participants:** User + tech-lead
699
+
700
+ **Review:**
701
+
702
+ - PDR approved ✅
703
+ - Technical approach validated ✅
704
+ - Task breakdown realistic ✅
705
+ - Risks acceptable ✅
706
+
707
+ **Decision:** Proceed to implementation
708
+
709
+ ---
710
+
711
+ ## Phase 2: Implementation
712
+
713
+ **Duration:** 3-4 days
714
+ **Methodology:** TDD (Red → Green → Refactor)
715
+
716
+ ### Day 1: Backend Foundation
717
+
718
+ #### PB-001: Database Schema
719
+
720
+ **Agent:** db-engineer
721
+
722
+ ```bash
723
+ # Create migration file
724
+ pnpm db:generate
725
+
726
+ # Migration: 0007_add_favorites.sql
727
+ ```
728
+
729
+ ```sql
730
+ CREATE TABLE favorites (
731
+ id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
732
+ user_id TEXT NOT NULL,
733
+ entity_id TEXT NOT NULL,
734
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
735
+ is_active BOOLEAN DEFAULT TRUE,
736
+
737
+ CONSTRAINT fk_favorites_user
738
+ FOREIGN KEY (user_id)
739
+ REFERENCES users(id)
740
+ ON DELETE CASCADE,
741
+
742
+ CONSTRAINT fk_favorites_entity
743
+ FOREIGN KEY (entity_id)
744
+ REFERENCES entitys(id)
745
+ ON DELETE CASCADE,
746
+
747
+ CONSTRAINT unique_user_entity
748
+ UNIQUE (user_id, entity_id)
749
+ );
750
+
751
+ CREATE INDEX idx_favorites_user_active
752
+ ON favorites(user_id, is_active)
753
+ WHERE is_active = TRUE;
754
+
755
+ CREATE INDEX idx_favorites_entity
756
+ ON favorites(entity_id);
757
+ ```
758
+
759
+ **Commit:**
760
+
761
+ ```bash
762
+ git add packages/db/drizzle/migrations/0007_add_favorites.sql
763
+ git commit -m "feat(db): add favorites table schema [PB-001]"
764
+ ```
765
+
766
+ #### PB-002: Validation Schemas
767
+
768
+ **Agent:** node-typescript-engineer
769
+
770
+ ```typescript
771
+ // packages/schemas/src/favorite.schema.ts
772
+ import { z } from 'zod';
773
+
774
+ export const createFavoriteSchema = z.object({
775
+ entityId: z.string().uuid(),
776
+ });
777
+
778
+ export const getFavoritesSchema = z.object({
779
+ page: z.coerce.number().int().min(1).default(1),
780
+ limit: z.coerce.number().int().min(1).max(100).default(20),
781
+ });
782
+
783
+ export const checkFavoriteSchema = z.object({
784
+ entityId: z.string().uuid(),
785
+ });
786
+
787
+ // Types
788
+ export type CreateFavorite = z.infer<typeof createFavoriteSchema>;
789
+ export type GetFavorites = z.infer<typeof getFavoritesSchema>;
790
+ export type CheckFavorite = z.infer<typeof checkFavoriteSchema>;
791
+ ```
792
+
793
+ **Tests:**
794
+
795
+ ```typescript
796
+ // packages/schemas/test/favorite.schema.test.ts
797
+ describe('Favorite Schemas', () => {
798
+ it('should validate create favorite schema', () => {
799
+ const valid = createFavoriteSchema.parse({
800
+ entityId: '123e4567-e89b-12d3-a456-426614174000',
801
+ });
802
+
803
+ expect(valid.entityId).toBeDefined();
804
+ });
805
+
806
+ // ... more tests
807
+ });
808
+ ```
809
+
810
+ **Commit:**
811
+
812
+ ```bash
813
+ git add packages/schemas/src/favorite.schema.ts
814
+ git add packages/schemas/test/favorite.schema.test.ts
815
+ git commit -m "feat(schemas): add favorite validation schemas [PB-002]"
816
+ ```
817
+
818
+ #### PB-003: Favorite Model (TDD)
819
+
820
+ **Agent:** db-engineer
821
+
822
+ **Red Phase:**
823
+
824
+ ```typescript
825
+ // packages/db/test/models/favorite.model.test.ts
826
+ describe('FavoriteModel', () => {
827
+ it('should create favorite', async () => {
828
+ const result = await favoriteModel.create({
829
+ userId: testUser.id,
830
+ entityId: testEntity.id,
831
+ });
832
+
833
+ expect(result.success).toBe(true);
834
+ expect(result.data?.userId).toBe(testUser.id);
835
+ });
836
+
837
+ // ... tests fail (model doesn't exist)
838
+ });
839
+ ```
840
+
841
+ **Green Phase:**
842
+
843
+ ```typescript
844
+ // packages/db/src/models/favorite.model.ts
845
+ import { BaseModel } from './base.model';
846
+ import type { Favorite } from '../schemas/favorite';
847
+
848
+ export class FavoriteModel extends BaseModel<Favorite> {
849
+ protected table = favoritesTable;
850
+ protected entityName = 'favorite';
851
+
852
+ async findByUser(userId: string): Promise<Favorite[]> {
853
+ return this.db
854
+ .select()
855
+ .from(this.table)
856
+ .where(
857
+ and(
858
+ eq(this.table.userId, userId),
859
+ eq(this.table.isActive, true)
860
+ )
861
+ );
862
+ }
863
+
864
+ async softDelete(id: string): Promise<void> {
865
+ await this.db
866
+ .update(this.table)
867
+ .set({ isActive: false })
868
+ .where(eq(this.table.id, id));
869
+ }
870
+ }
871
+ ```
872
+
873
+ **Refactor Phase:**
874
+
875
+ - Extract common queries
876
+ - Add JSDoc
877
+ - Optimize indexes usage
878
+
879
+ **Commit:**
880
+
881
+ ```bash
882
+ git add packages/db/src/models/favorite.model.ts
883
+ git add packages/db/test/models/favorite.model.test.ts
884
+ git commit -m "feat(db): implement favorite model with tests [PB-003]"
885
+ ```
886
+
887
+ ### Day 2: Service & API
888
+
889
+ #### PB-004: Favorite Service (TDD)
890
+
891
+ **Agent:** node-typescript-engineer
892
+
893
+ ```typescript
894
+ // packages/service-core/src/favorite.service.ts
895
+ export class FavoriteService extends BaseCrudService<
896
+ Favorite,
897
+ FavoriteModel,
898
+ CreateFavorite,
899
+ never, // No update
900
+ GetFavorites
901
+ > {
902
+ private readonly MAX_FAVORITES = 50;
903
+
904
+ async addFavorite(input: {
905
+ userId: string;
906
+ entityId: string;
907
+ }): Promise<Result<Favorite>> {
908
+ // Check limit
909
+ const count = await this.getFavoriteCount({ userId: input.userId });
910
+ if (count >= this.MAX_FAVORITES) {
911
+ return {
912
+ success: false,
913
+ error: {
914
+ code: ServiceErrorCode.VALIDATION_ERROR,
915
+ message: `Maximum favorites reached (${this.MAX_FAVORITES})`,
916
+ },
917
+ };
918
+ }
919
+
920
+ // Check if exists (idempotent)
921
+ const existing = await this.model.findOne({
922
+ userId: input.userId,
923
+ entityId: input.entityId,
924
+ });
925
+
926
+ if (existing) {
927
+ return { success: true, data: existing };
928
+ }
929
+
930
+ // Create
931
+ return this.model.create({
932
+ userId: input.userId,
933
+ entityId: input.entityId,
934
+ });
935
+ }
936
+
937
+ // ... other methods
938
+ }
939
+ ```
940
+
941
+ **Commit:**
942
+
943
+ ```bash
944
+ git add packages/service-core/src/favorite.service.ts
945
+ git add packages/service-core/test/favorite.service.test.ts
946
+ git commit -m "feat(service): add favorite CRUD service [PB-004]"
947
+ ```
948
+
949
+ #### PB-005: API Routes
950
+
951
+ **Agent:** hono-engineer
952
+
953
+ ```typescript
954
+ // apps/api/src/routes/favorites.ts
955
+ import { Hono } from 'hono';
956
+ import { zValidator } from '@hono/zod-validator';
957
+ import { requireAuth } from '../middleware/auth';
958
+ import { rateLimit } from '../middleware/rate-limit';
959
+
960
+ const app = new Hono();
961
+
962
+ app.use('*', requireAuth());
963
+ app.use('*', rateLimit({ max: 10, window: '1m' }));
964
+
965
+ // Add favorite
966
+ app.post(
967
+ '/',
968
+ zValidator('json', createFavoriteSchema),
969
+ async (c) => {
970
+ const { entityId } = c.req.valid('json');
971
+ const userId = c.get('userId');
972
+
973
+ const service = new FavoriteService(c.get('ctx'));
974
+ const result = await service.addFavorite({ userId, entityId });
975
+
976
+ if (!result.success) {
977
+ return c.json(result.error, 400);
978
+ }
979
+
980
+ return c.json(result.data, 201);
981
+ }
982
+ );
983
+
984
+ // Remove favorite
985
+ app.delete('/:entityId', async (c) => {
986
+ const entityId = c.req.param('entityId');
987
+ const userId = c.get('userId');
988
+
989
+ const service = new FavoriteService(c.get('ctx'));
990
+ const result = await service.removeFavorite({ userId, entityId });
991
+
992
+ if (!result.success) {
993
+ return c.json(result.error, 400);
994
+ }
995
+
996
+ return c.json({ success: true }, 200);
997
+ });
998
+
999
+ // List favorites (paginated)
1000
+ app.get(
1001
+ '/',
1002
+ zValidator('query', getFavoritesSchema),
1003
+ async (c) => {
1004
+ const { page, limit } = c.req.valid('query');
1005
+ const userId = c.get('userId');
1006
+
1007
+ const service = new FavoriteService(c.get('ctx'));
1008
+ const result = await service.getFavorites({
1009
+ userId,
1010
+ page,
1011
+ limit,
1012
+ });
1013
+
1014
+ if (!result.success) {
1015
+ return c.json(result.error, 400);
1016
+ }
1017
+
1018
+ return c.json(result.data);
1019
+ }
1020
+ );
1021
+
1022
+ export default app;
1023
+ ```
1024
+
1025
+ **Commit:**
1026
+
1027
+ ```bash
1028
+ git add apps/api/src/routes/favorites.ts
1029
+ git add apps/api/test/routes/favorites.test.ts
1030
+ git commit -m "feat(api): add favorite endpoints with auth & rate limiting [PB-005]"
1031
+ ```
1032
+
1033
+ ### Day 3-4: Frontend
1034
+
1035
+ #### PB-006: React Components
1036
+
1037
+ **Agent:** react-senior-dev
1038
+
1039
+ ```tsx
1040
+ // apps/web/src/components/FavoriteButton.tsx
1041
+ import { useState } from 'react';
1042
+ import { HeartIcon } from '@heroicons/react/24/outline';
1043
+ import { HeartIcon as HeartSolidIcon } from '@heroicons/react/24/solid';
1044
+
1045
+ interface FavoriteButtonProps {
1046
+ entityId: string;
1047
+ initialIsFavorite: boolean;
1048
+ onToggle: (isFavorite: boolean) => Promise<void>;
1049
+ }
1050
+
1051
+ export function FavoriteButton({
1052
+ entityId,
1053
+ initialIsFavorite,
1054
+ onToggle,
1055
+ }: FavoriteButtonProps) {
1056
+ const [isFavorite, setIsFavorite] = useState(initialIsFavorite);
1057
+ const [isLoading, setIsLoading] = useState(false);
1058
+
1059
+ const handleClick = async (e: React.MouseEvent) => {
1060
+ e.preventDefault(); // Don't navigate if in a link
1061
+
1062
+ setIsLoading(true);
1063
+ const newState = !isFavorite;
1064
+
1065
+ // Optimistic update
1066
+ setIsFavorite(newState);
1067
+
1068
+ try {
1069
+ await onToggle(newState);
1070
+ } catch (error) {
1071
+ // Revert on error
1072
+ setIsFavorite(!newState);
1073
+ console.error('Failed to toggle favorite:', error);
1074
+ } finally {
1075
+ setIsLoading(false);
1076
+ }
1077
+ };
1078
+
1079
+ return (
1080
+ <button
1081
+ onClick={handleClick}
1082
+ disabled={isLoading}
1083
+ className="favorite-button"
1084
+ aria-label={isFavorite ? 'Remove from favorites' : 'Add to favorites'}
1085
+ aria-pressed={isFavorite}
1086
+ >
1087
+ {isFavorite ? (
1088
+ <HeartSolidIcon className="w-6 h-6 text-red-500" />
1089
+ ) : (
1090
+ <HeartIcon className="w-6 h-6 text-gray-400 hover:text-red-500" />
1091
+ )}
1092
+ </button>
1093
+ );
1094
+ }
1095
+ ```
1096
+
1097
+ **Commit:**
1098
+
1099
+ ```bash
1100
+ git add apps/web/src/components/FavoriteButton.tsx
1101
+ git add apps/web/test/components/FavoriteButton.test.tsx
1102
+ git commit -m "feat(web): add favorite button component with optimistic updates [PB-006]"
1103
+ ```
1104
+
1105
+ #### PB-007: TanStack Query Integration
1106
+
1107
+ **Agent:** astro-engineer
1108
+
1109
+ ```typescript
1110
+ // apps/web/src/hooks/useFavorites.ts
1111
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
1112
+
1113
+ export function useFavorites() {
1114
+ const queryClient = useQueryClient();
1115
+
1116
+ const { data: favorites, isLoading } = useQuery({
1117
+ queryKey: ['favorites'],
1118
+ queryFn: async () => {
1119
+ const res = await fetch('/api/favorites');
1120
+ if (!res.ok) throw new Error('Failed to fetch favorites');
1121
+ return res.json();
1122
+ },
1123
+ });
1124
+
1125
+ const addFavorite = useMutation({
1126
+ mutationFn: async (entityId: string) => {
1127
+ const res = await fetch('/api/favorites', {
1128
+ method: 'POST',
1129
+ headers: { 'Content-Type': 'application/json' },
1130
+ body: JSON.stringify({ entityId }),
1131
+ });
1132
+ if (!res.ok) throw new Error('Failed to add favorite');
1133
+ return res.json();
1134
+ },
1135
+ // Optimistic update
1136
+ onMutate: async (entityId) => {
1137
+ await queryClient.cancelQueries({ queryKey: ['favorites'] });
1138
+ const previous = queryClient.getQueryData(['favorites']);
1139
+
1140
+ queryClient.setQueryData(['favorites'], (old: any) => ({
1141
+ ...old,
1142
+ items: [...(old?.items || []), { entityId }],
1143
+ }));
1144
+
1145
+ return { previous };
1146
+ },
1147
+ // Revert on error
1148
+ onError: (err, variables, context) => {
1149
+ if (context?.previous) {
1150
+ queryClient.setQueryData(['favorites'], context.previous);
1151
+ }
1152
+ },
1153
+ // Refetch on success
1154
+ onSettled: () => {
1155
+ queryClient.invalidateQueries({ queryKey: ['favorites'] });
1156
+ },
1157
+ });
1158
+
1159
+ return {
1160
+ favorites: favorites?.items || [],
1161
+ isLoading,
1162
+ addFavorite: addFavorite.mutate,
1163
+ removeFavorite: removeFavorite.mutate,
1164
+ };
1165
+ }
1166
+ ```
1167
+
1168
+ **Commit:**
1169
+
1170
+ ```bash
1171
+ git add apps/web/src/hooks/useFavorites.ts
1172
+ git commit -m "feat(web): add TanStack Query hooks for favorites [PB-007]"
1173
+ ```
1174
+
1175
+ #### PB-008: Favorites Page
1176
+
1177
+ **Agent:** astro-engineer
1178
+
1179
+ ```astro
1180
+ ---
1181
+ // apps/web/src/pages/favorites.astro
1182
+ import Layout from '../layouts/Layout.astro';
1183
+ import { FavoritesList } from '../components/FavoritesList';
1184
+ ---
1185
+
1186
+ <Layout title="My Favorites | Project">
1187
+ <main class="container mx-auto px-4 py-8">
1188
+ <h1 class="text-3xl font-bold mb-6">My Favorites</h1>
1189
+
1190
+ <FavoritesList client:load />
1191
+ </main>
1192
+ </Layout>
1193
+ ```
1194
+
1195
+ **Commit:**
1196
+
1197
+ ```bash
1198
+ git add apps/web/src/pages/favorites.astro
1199
+ git add apps/web/src/components/FavoritesList.tsx
1200
+ git commit -m "feat(web): add favorites page with SSR [PB-008]"
1201
+ ```
1202
+
1203
+ ---
1204
+
1205
+ ## Phase 3: Validation
1206
+
1207
+ **Duration:** 1 day
1208
+
1209
+ ### PB-009: E2E Testing
1210
+
1211
+ **Agent:** qa-engineer
1212
+
1213
+ ```typescript
1214
+ // apps/web/e2e/favorites.spec.ts
1215
+ import { test, expect } from '@playwright/test';
1216
+
1217
+ test.describe('Favorites Feature', () => {
1218
+ test('should add favorite from search results', async ({ page }) => {
1219
+ await page.goto('/search');
1220
+
1221
+ // Click first favorite button
1222
+ const favoriteBtn = page.locator('[aria-label="Add to favorites"]').first();
1223
+ await favoriteBtn.click();
1224
+
1225
+ // Should show filled heart
1226
+ await expect(favoriteBtn).toHaveAttribute('aria-pressed', 'true');
1227
+
1228
+ // Should show toast notification
1229
+ await expect(page.locator('text=Added to favorites')).toBeVisible();
1230
+ });
1231
+
1232
+ test('should remove favorite from favorites page', async ({ page }) => {
1233
+ await page.goto('/favorites');
1234
+
1235
+ const removeBtn = page.locator('[aria-label="Remove from favorites"]').first();
1236
+ await removeBtn.click();
1237
+
1238
+ await expect(page.locator('text=Removed from favorites')).toBeVisible();
1239
+ });
1240
+
1241
+ test('should enforce 50 favorites limit', async ({ page }) => {
1242
+ // Add 50 favorites...
1243
+ // Try to add 51st
1244
+ await page.goto('/entity/123');
1245
+ await page.locator('[aria-label="Add to favorites"]').click();
1246
+
1247
+ await expect(page.locator('text=Maximum favorites reached')).toBeVisible();
1248
+ });
1249
+ });
1250
+ ```
1251
+
1252
+ **Commit:**
1253
+
1254
+ ```bash
1255
+ git add apps/web/e2e/favorites.spec.ts
1256
+ git commit -m "test(e2e): add favorites feature tests [PB-009]"
1257
+ ```
1258
+
1259
+ ### PB-010: Quality Check
1260
+
1261
+ **Agent:** tech-lead
1262
+
1263
+ ```bash
1264
+ # Run all checks
1265
+ pnpm typecheck # ✅ No errors
1266
+ pnpm lint # ✅ No errors
1267
+ pnpm test:coverage # ✅ 94% coverage
1268
+
1269
+ # Run quality check command
1270
+ pnpm quality-check
1271
+ ```
1272
+
1273
+ **Results:**
1274
+
1275
+ - ✅ Code review: All patterns followed
1276
+ - ✅ Test coverage: 94% (exceeds 90% minimum)
1277
+ - ✅ Performance: All endpoints < 200ms
1278
+ - ✅ Security: Auth enforced, rate limiting active
1279
+ - ✅ Accessibility: WCAG 2.1 AA compliant
1280
+
1281
+ **Approval:** Ready for finalization
1282
+
1283
+ ---
1284
+
1285
+ ## Phase 4: Finalization
1286
+
1287
+ **Duration:** 0.5 day
1288
+
1289
+ ### PB-011: API Documentation
1290
+
1291
+ **Agent:** tech-writer
1292
+
1293
+ ```yaml
1294
+ # docs/api/favorites.yml
1295
+ paths:
1296
+ /api/favorites:
1297
+ post:
1298
+ summary: Add favorite
1299
+ security:
1300
+ - bearerAuth: []
1301
+ requestBody:
1302
+ content:
1303
+ application/json:
1304
+ schema:
1305
+ type: object
1306
+ properties:
1307
+ entityId:
1308
+ type: string
1309
+ format: uuid
1310
+ responses:
1311
+ 201:
1312
+ description: Favorite added
1313
+ 400:
1314
+ description: Limit reached or invalid request
1315
+ 401:
1316
+ description: Unauthorized
1317
+ ```
1318
+
1319
+ **Commit:**
1320
+
1321
+ ```bash
1322
+ git add docs/api/favorites.yml
1323
+ git commit -m "docs(api): add favorites endpoint documentation [PB-011]"
1324
+ ```
1325
+
1326
+ ### PB-012: User Documentation
1327
+
1328
+ **Agent:** tech-writer
1329
+
1330
+ ```markdown
1331
+ # docs/features/favorites.md
1332
+
1333
+ ## User Favorites
1334
+
1335
+ Save your favorite entitys for quick access later.
1336
+
1337
+ ### How to Use
1338
+
1339
+ 1. **Add Favorite**: Click the heart icon (♡) on any entity card
1340
+ 2. **View Favorites**: Navigate to "Favorites" from the menu
1341
+ 3. **Remove Favorite**: Click the filled heart (❤️) to remove
1342
+
1343
+ ### Limits
1344
+
1345
+ - **Logged Users**: Up to 50 favorites
1346
+ - **Guest Users**: Up to 5 favorites (lost on logout)
1347
+
1348
+ ### FAQs
1349
+
1350
+ **Q: Can I share my favorites?**
1351
+ A: Not yet, but this feature is planned for a future release.
1352
+ ```
1353
+
1354
+ **Commit:**
1355
+
1356
+ ```bash
1357
+ git add docs/features/favorites.md
1358
+ git commit -m "docs(features): add user guide for favorites [PB-012]"
1359
+ ```
1360
+
1361
+ ### PB-013: CHANGELOG Update
1362
+
1363
+ **Agent:** tech-writer
1364
+
1365
+ ```markdown
1366
+ # CHANGELOG.md
1367
+
1368
+ ## [Unreleased]
1369
+
1370
+ ### Added
1371
+
1372
+ - **User Favorites** - Users can now save favorite entitys
1373
+ - Add/remove favorites with heart icon
1374
+ - Dedicated favorites page with pagination
1375
+ - Max 50 favorites per logged user, 5 for guests
1376
+ - Optimistic UI updates for instant feedback
1377
+ - Rate limiting to prevent abuse (10 operations/min)
1378
+ - See [Favorites Guide](docs/features/favorites.md) for details
1379
+ ```
1380
+
1381
+ **Commit:**
1382
+
1383
+ ```bash
1384
+ git add CHANGELOG.md
1385
+ git commit -m "docs(changelog): add favorites feature entry [PB-013]"
1386
+ ```
1387
+
1388
+ ---
1389
+
1390
+ ## Results
1391
+
1392
+ ### Metrics
1393
+
1394
+ - **Total Duration:** 4.5 days (36 hours actual vs 31.5 estimated)
1395
+ - **Commits:** 13 atomic commits (one per task)
1396
+ - **Test Coverage:** 94% (exceeded 90% target)
1397
+ - **Performance:**
1398
+ - Add favorite: 150ms avg
1399
+ - List favorites: 380ms avg
1400
+ - Both under targets ✅
1401
+
1402
+ ### Deliverables
1403
+
1404
+ ✅ Database migration
1405
+ ✅ Backend services
1406
+ ✅ API endpoints
1407
+ ✅ Frontend components
1408
+ ✅ Favorites page
1409
+ ✅ E2E tests
1410
+ ✅ Documentation
1411
+ ✅ CHANGELOG update
1412
+
1413
+ ### Pull Request
1414
+
1415
+ ```bash
1416
+ # Create PR
1417
+ gh pr create \
1418
+ --title "feat: user favorites for entitys [F-007]" \
1419
+ --body "$(cat <<'EOF'
1420
+ ## Summary
1421
+
1422
+ Implements user favorites feature allowing users to save and manage favorite entitys.
1423
+
1424
+ ## Changes
1425
+
1426
+ - Database: `favorites` table with indexes
1427
+ - Backend: FavoriteService, FavoriteModel
1428
+ - API: 4 new endpoints with auth & rate limiting
1429
+ - Frontend: FavoriteButton, FavoritesList components
1430
+ - Tests: 94% coverage (Unit + Integration + E2E)
1431
+
1432
+ ## Testing
1433
+
1434
+ - [x] All tests pass
1435
+ - [x] Manual testing completed
1436
+ - [x] E2E tests pass
1437
+ - [x] Performance benchmarks met
1438
+
1439
+ ## Documentation
1440
+
1441
+ - [x] API docs updated
1442
+ - [x] User guide created
1443
+ - [x] CHANGELOG updated
1444
+
1445
+ ## Related
1446
+
1447
+ - Planning Session: P-007
1448
+ - Feature ID: F-007
1449
+ - Tasks: PB-001 to PB-013
1450
+
1451
+ ## Screenshots
1452
+
1453
+ (Screenshots of favorite button and favorites page)
1454
+ EOF
1455
+ )"
1456
+ ```
1457
+
1458
+ ### Deployment
1459
+
1460
+ ```bash
1461
+ # After PR approval and merge
1462
+ git checkout main
1463
+ git pull
1464
+
1465
+ # Vercel auto-deploys from main branch
1466
+ # Migration runs automatically on deploy
1467
+
1468
+ # Verify deployment
1469
+ curl -f https://example.com/health || exit 1
1470
+ ```
1471
+
1472
+ ### Success Metrics (1 week after launch)
1473
+
1474
+ - ✅ 42% users added at least one favorite
1475
+ - ✅ 0.3% error rate (below 1% target)
1476
+ - ✅ Average 9 favorites per active user
1477
+
1478
+ ---
1479
+
1480
+ ## Lessons Learned
1481
+
1482
+ ### What Went Well
1483
+
1484
+ 1. **TDD Approach** - Caught bugs early, tests gave confidence
1485
+ 2. **Atomic Commits** - Easy to review, clear history
1486
+ 3. **Optimistic UI** - Great user experience
1487
+ 4. **Planning Phase** - Clear requirements avoided scope creep
1488
+
1489
+ ### Challenges
1490
+
1491
+ 1. **Optimistic Updates** - Needed careful error handling
1492
+ 2. **Rate Limiting** - Initial implementation too strict, relaxed to 10/min
1493
+ 3. **Guest Migration** - Decided to keep simple (just prompt to login)
1494
+
1495
+ ### Would Do Differently
1496
+
1497
+ - Add analytics events from the start (added in hotfix)
1498
+ - Include performance monitoring from day 1
1499
+ - More edge case testing for concurrent operations
1500
+
1501
+ ---
1502
+
1503
+ *End of Example*
1504
+
1505
+ This example demonstrates a complete workflow following all standards, protocols, and best practices from the Project project.