proagents 1.6.17 → 1.6.18

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 (168) hide show
  1. package/.claude/settings.local.json +169 -0
  2. package/COMMANDS.md +595 -0
  3. package/README.md +13 -23
  4. package/package.json +2 -7
  5. package/.proagents/ai-models/README.md +0 -141
  6. package/.proagents/ai-models/cost-management.md +0 -362
  7. package/.proagents/ai-models/fallbacks.md +0 -342
  8. package/.proagents/ai-models/model-config.md +0 -318
  9. package/.proagents/ai-models/task-routing.md +0 -503
  10. package/.proagents/ai-training/README.md +0 -155
  11. package/.proagents/ai-training/continuous-learning.md +0 -413
  12. package/.proagents/ai-training/domain-knowledge.md +0 -378
  13. package/.proagents/ai-training/pattern-learning.md +0 -455
  14. package/.proagents/ai-training/training-data.md +0 -337
  15. package/.proagents/ai-training/user-preferences.md +0 -346
  16. package/.proagents/approval-workflows/README.md +0 -146
  17. package/.proagents/approval-workflows/approval-config.md +0 -332
  18. package/.proagents/approval-workflows/approval-stages.md +0 -503
  19. package/.proagents/approval-workflows/emergency-bypass.md +0 -351
  20. package/.proagents/approval-workflows/examples.md +0 -859
  21. package/.proagents/approval-workflows/notifications.md +0 -320
  22. package/.proagents/compliance/README.md +0 -206
  23. package/.proagents/compliance/access-control.md +0 -310
  24. package/.proagents/compliance/audit-logging.md +0 -444
  25. package/.proagents/compliance/compliance-frameworks.md +0 -429
  26. package/.proagents/compliance/reports.md +0 -491
  27. package/.proagents/compliance/retention-policies.md +0 -454
  28. package/.proagents/config-versioning/README.md +0 -120
  29. package/.proagents/config-versioning/changelog.md +0 -300
  30. package/.proagents/config-versioning/rollback.md +0 -283
  31. package/.proagents/config-versioning/versioning.md +0 -330
  32. package/.proagents/contract-testing/README.md +0 -223
  33. package/.proagents/contract-testing/contract-testing.md +0 -614
  34. package/.proagents/contract-testing/pact-integration.md +0 -507
  35. package/.proagents/contract-testing/schema-validation.md +0 -565
  36. package/.proagents/dependency-management/README.md +0 -140
  37. package/.proagents/dependency-management/automation.md +0 -363
  38. package/.proagents/dependency-management/compatibility.md +0 -319
  39. package/.proagents/dependency-management/security-scanning.md +0 -413
  40. package/.proagents/dependency-management/update-policies.md +0 -374
  41. package/.proagents/disaster-recovery/README.md +0 -247
  42. package/.proagents/disaster-recovery/automation.md +0 -366
  43. package/.proagents/disaster-recovery/backup-recovery.md +0 -571
  44. package/.proagents/disaster-recovery/incident-response.md +0 -565
  45. package/.proagents/disaster-recovery/rollback-procedures.md +0 -499
  46. package/.proagents/disaster-recovery/runbooks.md +0 -603
  47. package/.proagents/disaster-recovery/scenarios.md +0 -892
  48. package/.proagents/disaster-recovery/testing.md +0 -438
  49. package/.proagents/environments/README.md +0 -244
  50. package/.proagents/environments/configuration.md +0 -437
  51. package/.proagents/environments/promotion.md +0 -434
  52. package/.proagents/environments/setup.md +0 -420
  53. package/.proagents/examples/README.md +0 -55
  54. package/.proagents/examples/backend-nodejs/README.md +0 -188
  55. package/.proagents/examples/backend-nodejs/complete-conversation.md +0 -601
  56. package/.proagents/examples/backend-nodejs/proagents.config.yaml +0 -415
  57. package/.proagents/examples/backend-nodejs/workflow-example.md +0 -909
  58. package/.proagents/examples/fullstack-nextjs/README.md +0 -155
  59. package/.proagents/examples/fullstack-nextjs/complete-conversation.md +0 -604
  60. package/.proagents/examples/fullstack-nextjs/proagents.config.yaml +0 -287
  61. package/.proagents/examples/fullstack-nextjs/workflow-example.md +0 -553
  62. package/.proagents/examples/mobile-react-native/README.md +0 -171
  63. package/.proagents/examples/mobile-react-native/complete-conversation.md +0 -825
  64. package/.proagents/examples/mobile-react-native/proagents.config.yaml +0 -330
  65. package/.proagents/examples/mobile-react-native/workflow-example.md +0 -723
  66. package/.proagents/examples/web-frontend-react/README.md +0 -125
  67. package/.proagents/examples/web-frontend-react/complete-conversation.md +0 -556
  68. package/.proagents/examples/web-frontend-react/proagents.config.yaml +0 -183
  69. package/.proagents/examples/web-frontend-react/workflow-example.md +0 -603
  70. package/.proagents/existing-projects/README.md +0 -65
  71. package/.proagents/existing-projects/challenges.md +0 -861
  72. package/.proagents/existing-projects/coexistence-mode.md +0 -483
  73. package/.proagents/existing-projects/compatibility-assessment.md +0 -541
  74. package/.proagents/existing-projects/gradual-adoption.md +0 -515
  75. package/.proagents/existing-projects/migration-strategies.md +0 -788
  76. package/.proagents/existing-projects/pattern-reconciliation.md +0 -489
  77. package/.proagents/existing-projects/team-onboarding.md +0 -617
  78. package/.proagents/existing-projects/technical-debt-handling.md +0 -644
  79. package/.proagents/feature-flags/README.md +0 -263
  80. package/.proagents/feature-flags/ab-testing.md +0 -413
  81. package/.proagents/feature-flags/configuration.md +0 -420
  82. package/.proagents/feature-flags/kill-switches.md +0 -444
  83. package/.proagents/feature-flags/rollout-strategies.md +0 -392
  84. package/.proagents/history.log +0 -12
  85. package/.proagents/i18n/README.md +0 -133
  86. package/.proagents/i18n/extraction.md +0 -433
  87. package/.proagents/i18n/tms-integration.md +0 -332
  88. package/.proagents/i18n/translation-workflow.md +0 -413
  89. package/.proagents/i18n/validation.md +0 -355
  90. package/.proagents/logging/README.md +0 -276
  91. package/.proagents/logging/aggregation.md +0 -475
  92. package/.proagents/logging/log-levels.md +0 -376
  93. package/.proagents/logging/sensitive-data.md +0 -423
  94. package/.proagents/logging/structured-logging.md +0 -406
  95. package/.proagents/metrics/README.md +0 -69
  96. package/.proagents/metrics/code-quality-kpis.md +0 -461
  97. package/.proagents/metrics/deployment-metrics.md +0 -517
  98. package/.proagents/metrics/developer-productivity.md +0 -368
  99. package/.proagents/metrics/learning-effectiveness.md +0 -478
  100. package/.proagents/migrations/README.md +0 -77
  101. package/.proagents/migrations/from-claude-projects.md +0 -313
  102. package/.proagents/migrations/from-cursor-rules.md +0 -345
  103. package/.proagents/migrations/from-custom-workflows.md +0 -410
  104. package/.proagents/monitoring/README.md +0 -308
  105. package/.proagents/monitoring/alerting.md +0 -449
  106. package/.proagents/monitoring/dashboards.md +0 -454
  107. package/.proagents/monitoring/health-checks.md +0 -436
  108. package/.proagents/monitoring/metrics.md +0 -434
  109. package/.proagents/multi-project/README.md +0 -170
  110. package/.proagents/multi-project/coordinated-deploy.md +0 -510
  111. package/.proagents/multi-project/cross-project-deps.md +0 -395
  112. package/.proagents/multi-project/unified-changelog.md +0 -477
  113. package/.proagents/multi-project/walkthroughs/monorepo-setup.md +0 -787
  114. package/.proagents/multi-project/workspace-config.md +0 -408
  115. package/.proagents/notifications/README.md +0 -151
  116. package/.proagents/notifications/channels.md +0 -457
  117. package/.proagents/notifications/preferences.md +0 -415
  118. package/.proagents/notifications/routing.md +0 -449
  119. package/.proagents/notifications/scheduling.md +0 -425
  120. package/.proagents/notifications/templates.md +0 -446
  121. package/.proagents/offline-mode/README.md +0 -145
  122. package/.proagents/offline-mode/caching.md +0 -344
  123. package/.proagents/offline-mode/offline-operations.md +0 -312
  124. package/.proagents/offline-mode/queue-specifications.md +0 -679
  125. package/.proagents/offline-mode/sync.md +0 -475
  126. package/.proagents/parallel-features/README.md +0 -85
  127. package/.proagents/parallel-features/conflict-detection.md +0 -226
  128. package/.proagents/parallel-features/dependency-management.md +0 -392
  129. package/.proagents/parallel-features/merge-coordination.md +0 -506
  130. package/.proagents/parallel-features/tracking-system.md +0 -416
  131. package/.proagents/performance/README.md +0 -59
  132. package/.proagents/performance/bundle-analysis.md +0 -375
  133. package/.proagents/performance/load-testing.md +0 -563
  134. package/.proagents/performance/runtime-metrics.md +0 -489
  135. package/.proagents/performance/web-vitals.md +0 -425
  136. package/.proagents/plugins/README.md +0 -139
  137. package/.proagents/plugins/creating-plugins.md +0 -504
  138. package/.proagents/plugins/plugin-api.md +0 -467
  139. package/.proagents/plugins/plugin-registry.md +0 -276
  140. package/.proagents/reporting/README.md +0 -158
  141. package/.proagents/reporting/dashboards.md +0 -366
  142. package/.proagents/reporting/exports.md +0 -524
  143. package/.proagents/reporting/quality-metrics.md +0 -385
  144. package/.proagents/reporting/templates/README.md +0 -56
  145. package/.proagents/reporting/templates/dashboard-config.json +0 -187
  146. package/.proagents/reporting/templates/metrics-queries.md +0 -427
  147. package/.proagents/reporting/templates/react-dashboard.tsx +0 -544
  148. package/.proagents/reporting/templates/widgets.md +0 -451
  149. package/.proagents/reporting/velocity-metrics.md +0 -340
  150. package/.proagents/reverse-engineering/README.md +0 -151
  151. package/.proagents/reverse-engineering/architecture-extraction.md +0 -325
  152. package/.proagents/reverse-engineering/code-analysis.md +0 -377
  153. package/.proagents/reverse-engineering/dependency-mapping.md +0 -567
  154. package/.proagents/reverse-engineering/diagram-generation.md +0 -586
  155. package/.proagents/reverse-engineering/documentation-generation.md +0 -468
  156. package/.proagents/reverse-engineering/pattern-detection.md +0 -569
  157. package/.proagents/reverse-engineering/quality-assessment.md +0 -733
  158. package/.proagents/secrets/README.md +0 -278
  159. package/.proagents/secrets/access-control.md +0 -443
  160. package/.proagents/secrets/rotation.md +0 -403
  161. package/.proagents/secrets/scanning.md +0 -487
  162. package/.proagents/secrets/storage.md +0 -394
  163. package/.proagents/webhooks/README.md +0 -126
  164. package/.proagents/webhooks/endpoints.md +0 -298
  165. package/.proagents/webhooks/events.md +0 -316
  166. package/.proagents/webhooks/payloads.md +0 -325
  167. package/.proagents/webhooks/reliability.md +0 -363
  168. package/.proagents/webhooks/security.md +0 -380
@@ -1,604 +0,0 @@
1
- # Complete Conversation: Next.js Settings Feature
2
-
3
- A full walkthrough of building a settings page with API in a Next.js application.
4
-
5
- ---
6
-
7
- ## Feature Request
8
-
9
- **User:** I need to add a user settings page where users can update their profile, change notification preferences, and manage their account. It should have an API backend.
10
-
11
- ---
12
-
13
- ## Phase 0: Initialization
14
-
15
- **AI:** I'll help you build a comprehensive settings feature. Let me start by analyzing your existing codebase.
16
-
17
- ```
18
- Starting ProAgents workflow...
19
- Mode: Full Workflow
20
- Feature: User Settings Page with API
21
- Branch: feature/user-settings
22
- ```
23
-
24
- ---
25
-
26
- ## Phase 1: Codebase Analysis
27
-
28
- **AI:** I've analyzed your Next.js project. Here's what I found:
29
-
30
- ### Project Structure
31
- ```
32
- app/
33
- ├── (auth)/
34
- │ ├── dashboard/
35
- │ │ └── page.tsx
36
- │ └── layout.tsx
37
- ├── api/
38
- │ └── users/
39
- │ └── route.ts
40
- ├── layout.tsx
41
- └── page.tsx
42
- lib/
43
- ├── db.ts # Prisma client
44
- ├── auth.ts # NextAuth config
45
- └── validations/
46
- └── user.ts # Zod schemas
47
- components/
48
- ├── ui/ # shadcn/ui components
49
- └── forms/
50
- prisma/
51
- └── schema.prisma
52
- ```
53
-
54
- ### Patterns Detected
55
- - **Framework:** Next.js 14 with App Router
56
- - **Database:** Prisma with PostgreSQL
57
- - **Auth:** NextAuth.js with JWT strategy
58
- - **UI:** shadcn/ui components with Tailwind
59
- - **Validation:** Zod schemas
60
- - **State:** React Query for server state
61
-
62
- ### Existing Conventions
63
- - API routes use typed request/response
64
- - Forms use react-hook-form with Zod
65
- - All routes under `(auth)` require authentication
66
-
67
- **Checkpoint: Analysis Complete**
68
- Do you want to proceed with these patterns? [Yes/Modify]
69
-
70
- **User:** Yes, proceed.
71
-
72
- ---
73
-
74
- ## Phase 2: Requirements
75
-
76
- **AI:** Let me clarify the requirements for the settings feature.
77
-
78
- ### Feature Requirements
79
-
80
- **1. Profile Settings**
81
- - Update display name
82
- - Update avatar (upload)
83
- - Update bio/description
84
-
85
- **2. Notification Preferences**
86
- - Email notifications toggle
87
- - Push notifications toggle
88
- - Notification frequency (immediate/daily/weekly)
89
-
90
- **3. Account Settings**
91
- - Change email (with verification)
92
- - Change password
93
- - Delete account (with confirmation)
94
-
95
- ### Technical Requirements
96
- - All operations require authentication
97
- - Form validation with Zod
98
- - Optimistic updates where appropriate
99
- - Proper error handling
100
-
101
- **User:** Looks good, but also add a timezone selector in profile settings.
102
-
103
- **AI:** Added timezone selector to profile settings.
104
-
105
- ---
106
-
107
- ## Phase 3: Design
108
-
109
- **AI:** Based on your existing UI patterns, here's the design specification:
110
-
111
- ### Page Layout
112
- ```
113
- /settings
114
- ├── /settings/profile # Profile settings
115
- ├── /settings/notifications # Notification preferences
116
- └── /settings/account # Account management
117
- ```
118
-
119
- ### Component Structure
120
- ```tsx
121
- // Settings layout with sidebar navigation
122
- <SettingsLayout>
123
- <SettingsSidebar />
124
- <SettingsContent>
125
- {children}
126
- </SettingsContent>
127
- </SettingsLayout>
128
- ```
129
-
130
- ### UI Components (using existing shadcn/ui)
131
- - Card for each settings section
132
- - Form with Input, Select, Switch components
133
- - Button for actions
134
- - AlertDialog for destructive actions
135
- - Toast for feedback
136
-
137
- **Checkpoint: Design Complete**
138
- Ready to proceed with implementation? [Yes/Modify]
139
-
140
- **User:** Yes.
141
-
142
- ---
143
-
144
- ## Phase 4: Implementation Plan
145
-
146
- **AI:** Here's the implementation plan:
147
-
148
- ### Database Changes
149
- ```prisma
150
- // Add to schema.prisma
151
- model UserSettings {
152
- id String @id @default(cuid())
153
- userId String @unique
154
- user User @relation(fields: [userId], references: [id])
155
- timezone String @default("UTC")
156
- emailNotifications Boolean @default(true)
157
- pushNotifications Boolean @default(false)
158
- notificationFrequency String @default("immediate")
159
- createdAt DateTime @default(now())
160
- updatedAt DateTime @updatedAt
161
- }
162
- ```
163
-
164
- ### Files to Create
165
- 1. `prisma/migrations/xxx_add_user_settings.sql`
166
- 2. `lib/validations/settings.ts` - Zod schemas
167
- 3. `app/api/settings/route.ts` - GET/PATCH settings
168
- 4. `app/api/settings/password/route.ts` - Change password
169
- 5. `app/api/settings/account/route.ts` - Delete account
170
- 6. `app/(auth)/settings/layout.tsx` - Settings layout
171
- 7. `app/(auth)/settings/page.tsx` - Redirect to profile
172
- 8. `app/(auth)/settings/profile/page.tsx`
173
- 9. `app/(auth)/settings/notifications/page.tsx`
174
- 10. `app/(auth)/settings/account/page.tsx`
175
- 11. `components/settings/SettingsSidebar.tsx`
176
- 12. `components/settings/ProfileForm.tsx`
177
- 13. `components/settings/NotificationsForm.tsx`
178
- 14. `components/settings/AccountSettings.tsx`
179
-
180
- ### Implementation Order
181
- 1. Database schema + migration
182
- 2. Validation schemas
183
- 3. API routes
184
- 4. Layout and navigation
185
- 5. Individual settings pages
186
- 6. Forms and components
187
-
188
- ---
189
-
190
- ## Phase 5: Implementation
191
-
192
- **AI:** Starting implementation. Creating branch `feature/user-settings`.
193
-
194
- ### Step 1: Database Schema
195
-
196
- ```prisma
197
- // prisma/schema.prisma - additions
198
- model UserSettings {
199
- id String @id @default(cuid())
200
- userId String @unique
201
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
202
- timezone String @default("UTC")
203
- emailNotifications Boolean @default(true)
204
- pushNotifications Boolean @default(false)
205
- notificationFrequency String @default("immediate")
206
- createdAt DateTime @default(now())
207
- updatedAt DateTime @updatedAt
208
- }
209
- ```
210
-
211
- ```bash
212
- npx prisma migrate dev --name add_user_settings
213
- ```
214
-
215
- ### Step 2: Validation Schemas
216
-
217
- ```typescript
218
- // lib/validations/settings.ts
219
- import { z } from 'zod';
220
-
221
- export const profileSchema = z.object({
222
- name: z.string().min(2).max(50),
223
- bio: z.string().max(500).optional(),
224
- timezone: z.string(),
225
- });
226
-
227
- export const notificationsSchema = z.object({
228
- emailNotifications: z.boolean(),
229
- pushNotifications: z.boolean(),
230
- notificationFrequency: z.enum(['immediate', 'daily', 'weekly']),
231
- });
232
-
233
- export const passwordSchema = z.object({
234
- currentPassword: z.string().min(8),
235
- newPassword: z.string().min(8),
236
- confirmPassword: z.string().min(8),
237
- }).refine((data) => data.newPassword === data.confirmPassword, {
238
- message: "Passwords don't match",
239
- path: ["confirmPassword"],
240
- });
241
-
242
- export const deleteAccountSchema = z.object({
243
- confirmation: z.literal('DELETE'),
244
- });
245
- ```
246
-
247
- ### Step 3: API Routes
248
-
249
- ```typescript
250
- // app/api/settings/route.ts
251
- import { NextRequest, NextResponse } from 'next/server';
252
- import { getServerSession } from 'next-auth';
253
- import { authOptions } from '@/lib/auth';
254
- import { db } from '@/lib/db';
255
- import { profileSchema, notificationsSchema } from '@/lib/validations/settings';
256
-
257
- export async function GET(req: NextRequest) {
258
- try {
259
- const session = await getServerSession(authOptions);
260
- if (!session?.user?.id) {
261
- return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
262
- }
263
-
264
- const settings = await db.userSettings.findUnique({
265
- where: { userId: session.user.id },
266
- });
267
-
268
- // Create default settings if none exist
269
- if (!settings) {
270
- const newSettings = await db.userSettings.create({
271
- data: { userId: session.user.id },
272
- });
273
- return NextResponse.json({ data: newSettings });
274
- }
275
-
276
- return NextResponse.json({ data: settings });
277
- } catch (error) {
278
- return NextResponse.json({ error: 'Failed to fetch settings' }, { status: 500 });
279
- }
280
- }
281
-
282
- export async function PATCH(req: NextRequest) {
283
- try {
284
- const session = await getServerSession(authOptions);
285
- if (!session?.user?.id) {
286
- return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
287
- }
288
-
289
- const body = await req.json();
290
- const { type, ...data } = body;
291
-
292
- let validatedData;
293
- if (type === 'profile') {
294
- validatedData = profileSchema.parse(data);
295
- await db.user.update({
296
- where: { id: session.user.id },
297
- data: { name: validatedData.name },
298
- });
299
- } else if (type === 'notifications') {
300
- validatedData = notificationsSchema.parse(data);
301
- }
302
-
303
- const settings = await db.userSettings.upsert({
304
- where: { userId: session.user.id },
305
- update: validatedData,
306
- create: { userId: session.user.id, ...validatedData },
307
- });
308
-
309
- return NextResponse.json({ data: settings });
310
- } catch (error) {
311
- if (error instanceof z.ZodError) {
312
- return NextResponse.json({ error: error.errors }, { status: 400 });
313
- }
314
- return NextResponse.json({ error: 'Failed to update settings' }, { status: 500 });
315
- }
316
- }
317
- ```
318
-
319
- ### Step 4: Settings Layout
320
-
321
- ```tsx
322
- // app/(auth)/settings/layout.tsx
323
- import { SettingsSidebar } from '@/components/settings/SettingsSidebar';
324
-
325
- export default function SettingsLayout({
326
- children,
327
- }: {
328
- children: React.ReactNode;
329
- }) {
330
- return (
331
- <div className="container max-w-6xl py-8">
332
- <h1 className="text-3xl font-bold mb-8">Settings</h1>
333
- <div className="flex gap-8">
334
- <SettingsSidebar />
335
- <div className="flex-1">{children}</div>
336
- </div>
337
- </div>
338
- );
339
- }
340
- ```
341
-
342
- ### Step 5: Profile Page
343
-
344
- ```tsx
345
- // app/(auth)/settings/profile/page.tsx
346
- import { ProfileForm } from '@/components/settings/ProfileForm';
347
- import { getServerSession } from 'next-auth';
348
- import { authOptions } from '@/lib/auth';
349
- import { db } from '@/lib/db';
350
-
351
- export default async function ProfileSettingsPage() {
352
- const session = await getServerSession(authOptions);
353
- const user = await db.user.findUnique({
354
- where: { id: session?.user?.id },
355
- include: { settings: true },
356
- });
357
-
358
- return (
359
- <div className="space-y-6">
360
- <div>
361
- <h2 className="text-xl font-semibold">Profile</h2>
362
- <p className="text-muted-foreground">
363
- Manage your public profile information.
364
- </p>
365
- </div>
366
- <ProfileForm user={user} />
367
- </div>
368
- );
369
- }
370
- ```
371
-
372
- [Implementation continues for all components...]
373
-
374
- ---
375
-
376
- ## Phase 6: Testing
377
-
378
- **AI:** Creating tests for the settings feature.
379
-
380
- ### API Route Tests
381
-
382
- ```typescript
383
- // __tests__/api/settings.test.ts
384
- import { describe, it, expect, beforeEach, vi } from 'vitest';
385
- import { GET, PATCH } from '@/app/api/settings/route';
386
- import { NextRequest } from 'next/server';
387
-
388
- vi.mock('next-auth', () => ({
389
- getServerSession: vi.fn(),
390
- }));
391
-
392
- vi.mock('@/lib/db', () => ({
393
- db: {
394
- userSettings: {
395
- findUnique: vi.fn(),
396
- create: vi.fn(),
397
- upsert: vi.fn(),
398
- },
399
- user: {
400
- update: vi.fn(),
401
- },
402
- },
403
- }));
404
-
405
- describe('Settings API', () => {
406
- describe('GET /api/settings', () => {
407
- it('returns 401 when not authenticated', async () => {
408
- const { getServerSession } = await import('next-auth');
409
- vi.mocked(getServerSession).mockResolvedValue(null);
410
-
411
- const req = new NextRequest('http://localhost/api/settings');
412
- const res = await GET(req);
413
-
414
- expect(res.status).toBe(401);
415
- });
416
-
417
- it('returns user settings when authenticated', async () => {
418
- const { getServerSession } = await import('next-auth');
419
- vi.mocked(getServerSession).mockResolvedValue({
420
- user: { id: 'user-1' },
421
- });
422
-
423
- const { db } = await import('@/lib/db');
424
- vi.mocked(db.userSettings.findUnique).mockResolvedValue({
425
- id: 'settings-1',
426
- userId: 'user-1',
427
- timezone: 'America/New_York',
428
- emailNotifications: true,
429
- pushNotifications: false,
430
- notificationFrequency: 'daily',
431
- });
432
-
433
- const req = new NextRequest('http://localhost/api/settings');
434
- const res = await GET(req);
435
- const data = await res.json();
436
-
437
- expect(res.status).toBe(200);
438
- expect(data.data.timezone).toBe('America/New_York');
439
- });
440
- });
441
-
442
- describe('PATCH /api/settings', () => {
443
- it('validates notification settings', async () => {
444
- const { getServerSession } = await import('next-auth');
445
- vi.mocked(getServerSession).mockResolvedValue({
446
- user: { id: 'user-1' },
447
- });
448
-
449
- const req = new NextRequest('http://localhost/api/settings', {
450
- method: 'PATCH',
451
- body: JSON.stringify({
452
- type: 'notifications',
453
- emailNotifications: 'invalid', // Should be boolean
454
- }),
455
- });
456
-
457
- const res = await PATCH(req);
458
- expect(res.status).toBe(400);
459
- });
460
- });
461
- });
462
- ```
463
-
464
- ### Component Tests
465
-
466
- ```typescript
467
- // __tests__/components/ProfileForm.test.tsx
468
- import { describe, it, expect } from 'vitest';
469
- import { render, screen } from '@testing-library/react';
470
- import userEvent from '@testing-library/user-event';
471
- import { ProfileForm } from '@/components/settings/ProfileForm';
472
-
473
- describe('ProfileForm', () => {
474
- const mockUser = {
475
- id: 'user-1',
476
- name: 'John Doe',
477
- email: 'john@example.com',
478
- settings: {
479
- timezone: 'UTC',
480
- },
481
- };
482
-
483
- it('renders with user data', () => {
484
- render(<ProfileForm user={mockUser} />);
485
-
486
- expect(screen.getByDisplayValue('John Doe')).toBeInTheDocument();
487
- expect(screen.getByDisplayValue('UTC')).toBeInTheDocument();
488
- });
489
-
490
- it('validates required fields', async () => {
491
- render(<ProfileForm user={mockUser} />);
492
-
493
- const nameInput = screen.getByLabelText(/name/i);
494
- await userEvent.clear(nameInput);
495
- await userEvent.click(screen.getByRole('button', { name: /save/i }));
496
-
497
- expect(screen.getByText(/name is required/i)).toBeInTheDocument();
498
- });
499
- });
500
- ```
501
-
502
- ### E2E Tests
503
-
504
- ```typescript
505
- // e2e/settings.spec.ts
506
- import { test, expect } from '@playwright/test';
507
-
508
- test.describe('Settings Page', () => {
509
- test.beforeEach(async ({ page }) => {
510
- // Login before each test
511
- await page.goto('/login');
512
- await page.fill('[name="email"]', 'test@example.com');
513
- await page.fill('[name="password"]', 'password123');
514
- await page.click('button[type="submit"]');
515
- await page.waitForURL('/dashboard');
516
- });
517
-
518
- test('can update profile settings', async ({ page }) => {
519
- await page.goto('/settings/profile');
520
-
521
- await page.fill('[name="name"]', 'Updated Name');
522
- await page.click('button:has-text("Save")');
523
-
524
- await expect(page.locator('.toast')).toContainText('Settings saved');
525
- });
526
-
527
- test('can toggle notification preferences', async ({ page }) => {
528
- await page.goto('/settings/notifications');
529
-
530
- const emailToggle = page.locator('[name="emailNotifications"]');
531
- await emailToggle.click();
532
- await page.click('button:has-text("Save")');
533
-
534
- await expect(page.locator('.toast')).toContainText('Settings saved');
535
- });
536
- });
537
- ```
538
-
539
- **Test Results:**
540
- ```
541
- ✓ API tests: 12 passed
542
- ✓ Component tests: 8 passed
543
- ✓ E2E tests: 5 passed
544
- Coverage: 87%
545
- ```
546
-
547
- ---
548
-
549
- ## Phase 7: Documentation
550
-
551
- **AI:** Creating documentation for the settings feature.
552
-
553
- ### API Documentation
554
-
555
- ```markdown
556
- ## Settings API
557
-
558
- ### GET /api/settings
559
- Returns the current user's settings.
560
-
561
- **Response:**
562
- - 200: Settings object
563
- - 401: Unauthorized
564
-
565
- ### PATCH /api/settings
566
- Updates user settings.
567
-
568
- **Body:**
569
- - type: "profile" | "notifications"
570
- - ...fields based on type
571
-
572
- **Response:**
573
- - 200: Updated settings
574
- - 400: Validation error
575
- - 401: Unauthorized
576
- ```
577
-
578
- ---
579
-
580
- ## Phase 8: Deployment Preparation
581
-
582
- **AI:** Pre-deployment checklist:
583
-
584
- - [x] All tests passing
585
- - [x] Database migration ready
586
- - [x] Environment variables documented
587
- - [x] No hardcoded secrets
588
- - [x] Error handling complete
589
- - [x] Loading states implemented
590
- - [x] Mobile responsive
591
-
592
- **Ready for deployment.**
593
-
594
- ---
595
-
596
- ## Summary
597
-
598
- **Feature Complete:** User Settings Page with API
599
-
600
- **Files Created:** 15
601
- **Tests Added:** 25
602
- **Coverage:** 87%
603
-
604
- **PR Ready:** `feature/user-settings` → `main`