@polymorphism-tech/morph-spec 4.6.0 → 4.7.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 (239) hide show
  1. package/README.md +394 -700
  2. package/docs/ARCHITECTURE.md +331 -0
  3. package/docs/CHEATSHEET.md +221 -0
  4. package/docs/COMMAND-FLOWS.md +368 -0
  5. package/docs/QUICKSTART.md +212 -0
  6. package/docs/examples/order-management/contracts.cs +84 -0
  7. package/docs/examples/order-management/proposal.md +24 -0
  8. package/docs/examples/order-management/spec.md +162 -0
  9. package/docs/plans/2026-02-23-ddd-architecture-refactor.md +1153 -0
  10. package/docs/plans/2026-02-23-ddd-nextsteps.md +682 -0
  11. package/docs/plans/2026-02-23-infra-architect-refactor.md +437 -0
  12. package/docs/plans/2026-02-23-nextjs-code-review-design.md +156 -0
  13. package/docs/plans/2026-02-23-nextjs-code-review-impl.md +1254 -0
  14. package/docs/plans/2026-02-23-nextjs-standards-design.md +149 -0
  15. package/docs/plans/2026-02-23-nextjs-standards-impl.md +1846 -0
  16. package/framework/agents/README.md +14 -14
  17. package/framework/agents/architecture/standards-architect.md +159 -159
  18. package/framework/agents/frontend/nextjs-expert.md +87 -127
  19. package/framework/agents/infrastructure/azure-architect.md +147 -147
  20. package/framework/agents/infrastructure/infra-architect.md +45 -0
  21. package/framework/agents.json +1145 -278
  22. package/framework/rules/frontend-standards.md +0 -3
  23. package/framework/rules/nextjs-standards.md +17 -0
  24. package/framework/skills/level-0-meta/code-review-nextjs/SKILL.md +147 -0
  25. package/framework/skills/level-0-meta/code-review-nextjs/references/review-example-nextjs.md +254 -0
  26. package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +3 -3
  27. package/framework/skills/level-1-workflows/phase-design/SKILL.md +45 -9
  28. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +38 -0
  29. package/framework/standards/STANDARDS.json +121 -0
  30. package/framework/standards/architecture/ddd/bounded-contexts.md +105 -0
  31. package/framework/standards/architecture/ddd/complexity-levels.md +108 -0
  32. package/framework/standards/architecture/ddd/ubiquitous-language.md +58 -0
  33. package/framework/standards/frontend/nextjs/app-router.md +123 -0
  34. package/framework/standards/frontend/nextjs/components.md +132 -0
  35. package/framework/standards/frontend/nextjs/data-fetching.md +126 -0
  36. package/framework/standards/frontend/nextjs/forms.md +128 -0
  37. package/framework/standards/frontend/nextjs/naming-conventions.md +67 -0
  38. package/framework/standards/frontend/nextjs/project-structure.md +102 -0
  39. package/framework/standards/frontend/nextjs/state-management.md +72 -0
  40. package/framework/standards/frontend/nextjs/testing.md +111 -0
  41. package/framework/templates/REGISTRY.json +538 -142
  42. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +69 -0
  43. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +86 -0
  44. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +41 -0
  45. package/framework/templates/docs/spec.md +49 -0
  46. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -0
  47. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -0
  48. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -0
  49. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -0
  50. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -0
  51. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -0
  52. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -0
  53. package/framework/templates/project-structure/dotnet-ddd.md +70 -0
  54. package/framework/workflows/docs/enforcement-pipeline.md +2 -1
  55. package/package.json +1 -1
  56. package/scripts/scan-nextjs.mjs +169 -0
  57. package/src/commands/project/doctor.js +52 -1
  58. package/src/commands/project/init.js +15 -1
  59. package/src/commands/project/update.js +6 -1
  60. package/src/lib/standards/standards-context-injector.js +5 -0
  61. package/src/lib/validators/nextjs/index.js +6 -0
  62. package/src/lib/validators/nextjs/next-component-validator.js +181 -0
  63. package/src/lib/validators/validation-runner.js +5 -0
  64. package/src/utils/agents-installer.js +14 -2
  65. package/.morph/.morphversion +0 -5
  66. package/.morph/analytics/threads-log.jsonl +0 -6
  67. package/.morph/config/config.json +0 -8
  68. package/.morph/framework/agents.json +0 -948
  69. package/.morph/framework/standards/STANDARDS.json +0 -812
  70. package/.morph/framework/standards/ai-agents/blazor-ui.md +0 -364
  71. package/.morph/framework/standards/ai-agents/production.md +0 -415
  72. package/.morph/framework/standards/ai-agents/setup.md +0 -418
  73. package/.morph/framework/standards/ai-agents/team-orchestration.md +0 -479
  74. package/.morph/framework/standards/ai-agents/workflows.md +0 -354
  75. package/.morph/framework/standards/architecture/ddd/aggregates.md +0 -120
  76. package/.morph/framework/standards/architecture/ddd/entities.md +0 -99
  77. package/.morph/framework/standards/architecture/ddd/value-objects.md +0 -124
  78. package/.morph/framework/standards/backend/api/minimal-api.md +0 -494
  79. package/.morph/framework/standards/backend/api/rest.md +0 -492
  80. package/.morph/framework/standards/backend/api/validation.md +0 -88
  81. package/.morph/framework/standards/backend/authentication/passkeys.md +0 -428
  82. package/.morph/framework/standards/backend/database/ef-core.md +0 -199
  83. package/.morph/framework/standards/backend/database/migrations.md +0 -393
  84. package/.morph/framework/standards/backend/database/postgresql/database.md +0 -352
  85. package/.morph/framework/standards/backend/database/repository-patterns.md +0 -528
  86. package/.morph/framework/standards/backend/database/vector-search-rag.md +0 -541
  87. package/.morph/framework/standards/backend/dotnet/async.md +0 -366
  88. package/.morph/framework/standards/backend/dotnet/core.md +0 -117
  89. package/.morph/framework/standards/backend/dotnet/di.md +0 -439
  90. package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  91. package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +0 -216
  92. package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
  93. package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -350
  94. package/.morph/framework/standards/backend/integrations/resend/resend-email.md +0 -385
  95. package/.morph/framework/standards/context/analytics.md +0 -96
  96. package/.morph/framework/standards/context/bundles.md +0 -110
  97. package/.morph/framework/standards/context/priming.md +0 -78
  98. package/.morph/framework/standards/core/architecture.md +0 -185
  99. package/.morph/framework/standards/core/coding.md +0 -214
  100. package/.morph/framework/standards/core/git-branching-strategy.md +0 -403
  101. package/.morph/framework/standards/core/git.md +0 -185
  102. package/.morph/framework/standards/core/testing.md +0 -295
  103. package/.morph/framework/standards/data/nosql/blob-storage.md +0 -102
  104. package/.morph/framework/standards/data/nosql/cache/redis.md +0 -97
  105. package/.morph/framework/standards/data/nosql/cosmos-db.md +0 -118
  106. package/.morph/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  107. package/.morph/framework/standards/data/vector-search/rag-chunking.md +0 -104
  108. package/.morph/framework/standards/frontend/blazor/design-checklist.md +0 -222
  109. package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  110. package/.morph/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  111. package/.morph/framework/standards/frontend/blazor/html-conversion.md +0 -184
  112. package/.morph/framework/standards/frontend/blazor/lifecycle.md +0 -195
  113. package/.morph/framework/standards/frontend/blazor/pitfalls.md +0 -198
  114. package/.morph/framework/standards/frontend/blazor/state.md +0 -191
  115. package/.morph/framework/standards/frontend/design-system/animations.md +0 -151
  116. package/.morph/framework/standards/frontend/design-system/naming.md +0 -64
  117. package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +0 -215
  118. package/.morph/framework/standards/infrastructure/azure/azure.md +0 -624
  119. package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  120. package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  121. package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  122. package/.morph/framework/standards/infrastructure/azure/services/functions.md +0 -486
  123. package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  124. package/.morph/framework/standards/infrastructure/azure/services/storage.md +0 -407
  125. package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +0 -196
  126. package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +0 -252
  127. package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
  128. package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
  129. package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
  130. package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
  131. package/.morph/framework/standards/integration/api/graphql.md +0 -91
  132. package/.morph/framework/standards/integration/api/grpc.md +0 -114
  133. package/.morph/framework/standards/integration/api/rest-design.md +0 -95
  134. package/.morph/framework/standards/integration/event-driven/cqrs.md +0 -101
  135. package/.morph/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  136. package/.morph/framework/standards/integration/event-driven/service-bus.md +0 -95
  137. package/.morph/framework/standards/integration/mcp/mcp-tools.md +0 -384
  138. package/.morph/framework/standards/observability/logging.md +0 -131
  139. package/.morph/framework/standards/observability/metrics.md +0 -121
  140. package/.morph/framework/standards/observability/monitoring.md +0 -114
  141. package/.morph/framework/standards/observability/tracing.md +0 -132
  142. package/.morph/framework/standards/workflows/parallel-execution.md +0 -112
  143. package/.morph/framework/standards/workflows/thread-management.md +0 -113
  144. package/.morph/framework/templates/.idea/morph-templates.xml +0 -92
  145. package/.morph/framework/templates/.vscode/morph-templates.code-snippets +0 -186
  146. package/.morph/framework/templates/IDE-SNIPPETS.md +0 -266
  147. package/.morph/framework/templates/README.md +0 -814
  148. package/.morph/framework/templates/REGISTRY.json +0 -1492
  149. package/.morph/framework/templates/code/dotnet/backend/repository.cs +0 -141
  150. package/.morph/framework/templates/code/dotnet/backend/service.cs +0 -139
  151. package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  152. package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  153. package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  154. package/.morph/framework/templates/code/dotnet/contracts/README.md +0 -74
  155. package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  156. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
  157. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
  158. package/.morph/framework/templates/code/dotnet/database/migration.cs +0 -83
  159. package/.morph/framework/templates/code/dotnet/frontend/component.razor +0 -239
  160. package/.morph/framework/templates/code/dotnet/jobs/agent.cs +0 -163
  161. package/.morph/framework/templates/code/dotnet/jobs/job.cs +0 -171
  162. package/.morph/framework/templates/code/dotnet/test.cs +0 -239
  163. package/.morph/framework/templates/code/sql/rls-policy.sql +0 -57
  164. package/.morph/framework/templates/code/sql/supabase-migration.sql +0 -100
  165. package/.morph/framework/templates/code/sql/supabase-migration.template.sql +0 -113
  166. package/.morph/framework/templates/code/typescript/contracts.ts +0 -168
  167. package/.morph/framework/templates/context/CONTEXT-FEATURE.md +0 -276
  168. package/.morph/framework/templates/context/CONTEXT.md +0 -181
  169. package/.morph/framework/templates/docs/clarifications.md +0 -253
  170. package/.morph/framework/templates/docs/onboarding.md +0 -123
  171. package/.morph/framework/templates/docs/proposal.md +0 -182
  172. package/.morph/framework/templates/docs/schema-analysis.md +0 -119
  173. package/.morph/framework/templates/docs/spec.md +0 -149
  174. package/.morph/framework/templates/docs/ui-components.md +0 -124
  175. package/.morph/framework/templates/docs/ui-design-system.md +0 -76
  176. package/.morph/framework/templates/docs/ui-flows.md +0 -167
  177. package/.morph/framework/templates/docs/ui-mockups.md +0 -98
  178. package/.morph/framework/templates/docs/user-stories.md +0 -34
  179. package/.morph/framework/templates/examples/design-system-examples.md +0 -357
  180. package/.morph/framework/templates/examples/spec-examples.md +0 -90
  181. package/.morph/framework/templates/feature/decisions.md +0 -187
  182. package/.morph/framework/templates/feature/recap.md +0 -146
  183. package/.morph/framework/templates/feature/tasks.md +0 -199
  184. package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  185. package/.morph/framework/templates/infrastructure/azure/README.md +0 -286
  186. package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  187. package/.morph/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  188. package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  189. package/.morph/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  190. package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  191. package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  192. package/.morph/framework/templates/infrastructure/azure/deploy.sh +0 -208
  193. package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  194. package/.morph/framework/templates/infrastructure/azure/main.bicep +0 -189
  195. package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  196. package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  197. package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  198. package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  199. package/.morph/framework/templates/infrastructure/azure/storage.bicep +0 -106
  200. package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +0 -58
  201. package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +0 -67
  202. package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +0 -38
  203. package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +0 -48
  204. package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +0 -54
  205. package/.morph/framework/templates/infrastructure/github/README.md +0 -593
  206. package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  207. package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -45
  208. package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +0 -27
  209. package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  210. package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
  211. package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -59
  212. package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -39
  213. package/.morph/framework/templates/integrations/asaas-client.cs +0 -387
  214. package/.morph/framework/templates/integrations/asaas-webhook.cs +0 -351
  215. package/.morph/framework/templates/integrations/azure-identity-config.cs +0 -288
  216. package/.morph/framework/templates/integrations/clerk-config.cs +0 -258
  217. package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +0 -76
  218. package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +0 -100
  219. package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
  220. package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
  221. package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
  222. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
  223. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
  224. package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +0 -90
  225. package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +0 -126
  226. package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +0 -43
  227. package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +0 -107
  228. package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +0 -95
  229. package/.morph/framework/templates/saas/subscription.cs +0 -347
  230. package/.morph/framework/templates/saas/tenant.cs +0 -338
  231. package/.morph/framework/templates/state.template.json +0 -17
  232. package/.morph/framework/templates/ui/FluentDesignTheme.cs +0 -149
  233. package/.morph/framework/templates/ui/MudTheme.cs +0 -281
  234. package/.morph/framework/templates/ui/design-system.css +0 -226
  235. package/.morph/logs/tool-failures.log +0 -7
  236. package/.morph/memory/pre-compact-2026-02-23T15-43-03-521Z.json +0 -16
  237. package/.morph/state.json +0 -48
  238. package/framework/templates/code/dotnet/contracts/contracts.cs +0 -217
  239. package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +0 -172
@@ -1,494 +0,0 @@
1
- # Minimal API Standards - .NET
2
-
3
- > **Scope:** universal
4
- > **Layer:** 0 (always load)
5
- > **Keywords:** minimal api, dotnet, asp.net, endpoint, mapget, mappost
6
- > **Load When:** always
7
-
8
- Patterns and best practices for .NET Minimal API endpoints.
9
-
10
- ---
11
-
12
- ## Route Handler Structure
13
-
14
- ### File Organization
15
-
16
- ```
17
- app/api/
18
- auth/
19
- login/
20
- route.ts # POST /api/auth/login
21
- logout/
22
- route.ts # POST /api/auth/logout
23
- users/
24
- route.ts # GET /api/users, POST /api/users
25
- [id]/
26
- route.ts # GET /api/users/:id, PATCH /api/users/:id
27
- ```
28
-
29
- ### HTTP Methods
30
-
31
- ```typescript
32
- // app/api/users/route.ts
33
- import { NextRequest, NextResponse } from 'next/server'
34
-
35
- // GET /api/users
36
- export async function GET(request: NextRequest) {
37
- const searchParams = request.nextUrl.searchParams
38
- const limit = searchParams.get('limit') || '10'
39
-
40
- // Fetch users
41
- return NextResponse.json({ users: [] })
42
- }
43
-
44
- // POST /api/users
45
- export async function POST(request: NextRequest) {
46
- const body = await request.json()
47
-
48
- // Create user
49
- return NextResponse.json({ user: {} }, { status: 201 })
50
- }
51
- ```
52
-
53
- ### Dynamic Routes
54
-
55
- ```typescript
56
- // app/api/users/[id]/route.ts
57
- interface RouteParams {
58
- params: { id: string }
59
- }
60
-
61
- export async function GET(
62
- request: NextRequest,
63
- { params }: RouteParams
64
- ) {
65
- const userId = params.id
66
-
67
- // Fetch user by ID
68
- return NextResponse.json({ user: {} })
69
- }
70
-
71
- export async function PATCH(
72
- request: NextRequest,
73
- { params }: RouteParams
74
- ) {
75
- const userId = params.id
76
- const updates = await request.json()
77
-
78
- // Update user
79
- return NextResponse.json({ user: {} })
80
- }
81
-
82
- export async function DELETE(
83
- request: NextRequest,
84
- { params }: RouteParams
85
- ) {
86
- const userId = params.id
87
-
88
- // Delete user
89
- return NextResponse.json(null, { status: 204 })
90
- }
91
- ```
92
-
93
- ---
94
-
95
- ## Request Handling
96
-
97
- ### Query Parameters
98
-
99
- ```typescript
100
- export async function GET(request: NextRequest) {
101
- const searchParams = request.nextUrl.searchParams
102
- const page = parseInt(searchParams.get('page') || '1')
103
- const limit = parseInt(searchParams.get('limit') || '10')
104
- const sort = searchParams.get('sort') || 'created_at'
105
-
106
- // Use query params
107
- }
108
- ```
109
-
110
- ### Request Body Validation (Zod)
111
-
112
- ```typescript
113
- import { z } from 'zod'
114
-
115
- const createUserSchema = z.object({
116
- name: z.string().min(1, 'Name is required'),
117
- email: z.string().email('Invalid email'),
118
- age: z.number().int().positive().optional()
119
- })
120
-
121
- export async function POST(request: NextRequest) {
122
- try {
123
- const body = await request.json()
124
- const validatedData = createUserSchema.parse(body)
125
-
126
- // Proceed with validated data
127
- return NextResponse.json({ user: validatedData }, { status: 201 })
128
- } catch (error) {
129
- if (error instanceof z.ZodError) {
130
- return NextResponse.json(
131
- { error: 'Validation failed', details: error.errors },
132
- { status: 400 }
133
- )
134
- }
135
- throw error
136
- }
137
- }
138
- ```
139
-
140
- ### Headers
141
-
142
- ```typescript
143
- export async function GET(request: NextRequest) {
144
- const authHeader = request.headers.get('authorization')
145
- const contentType = request.headers.get('content-type')
146
-
147
- // Set response headers
148
- return NextResponse.json(
149
- { data: {} },
150
- {
151
- headers: {
152
- 'Cache-Control': 'max-age=3600',
153
- 'X-Custom-Header': 'value'
154
- }
155
- }
156
- )
157
- }
158
- ```
159
-
160
- ---
161
-
162
- ## Response Patterns
163
-
164
- ### Success Responses
165
-
166
- ```typescript
167
- // 200 OK - Successful GET
168
- return NextResponse.json({ users: [] })
169
-
170
- // 201 Created - Successful POST
171
- return NextResponse.json({ user: {} }, { status: 201 })
172
-
173
- // 204 No Content - Successful DELETE
174
- return new NextResponse(null, { status: 204 })
175
- ```
176
-
177
- ### Error Responses
178
-
179
- ```typescript
180
- // 400 Bad Request
181
- return NextResponse.json(
182
- { error: 'Invalid input', details: errors },
183
- { status: 400 }
184
- )
185
-
186
- // 401 Unauthorized
187
- return NextResponse.json(
188
- { error: 'Authentication required' },
189
- { status: 401 }
190
- )
191
-
192
- // 403 Forbidden
193
- return NextResponse.json(
194
- { error: 'Insufficient permissions' },
195
- { status: 403 }
196
- )
197
-
198
- // 404 Not Found
199
- return NextResponse.json(
200
- { error: 'Resource not found' },
201
- { status: 404 }
202
- )
203
-
204
- // 500 Internal Server Error
205
- return NextResponse.json(
206
- { error: 'Internal server error' },
207
- { status: 500 }
208
- )
209
- ```
210
-
211
- ---
212
-
213
- ## Authentication & Authorization
214
-
215
- ### Middleware-based Auth
216
-
217
- ```typescript
218
- // middleware.ts
219
- import { createMiddlewareClient } from '@/lib/supabase/middleware'
220
- import { NextResponse } from 'next/server'
221
-
222
- export async function middleware(request: NextRequest) {
223
- const res = NextResponse.next()
224
- const supabase = createMiddlewareClient(request, res)
225
-
226
- const { data: { session } } = await supabase.auth.getSession()
227
-
228
- // Protected API routes
229
- if (request.nextUrl.pathname.startsWith('/api/protected') && !session) {
230
- return NextResponse.json(
231
- { error: 'Unauthorized' },
232
- { status: 401 }
233
- )
234
- }
235
-
236
- return res
237
- }
238
- ```
239
-
240
- ### Route-level Auth
241
-
242
- ```typescript
243
- import { createRouteHandlerClient } from '@/lib/supabase/server'
244
-
245
- export async function GET(request: NextRequest) {
246
- const supabase = createRouteHandlerClient()
247
- const { data: { session } } = await supabase.auth.getSession()
248
-
249
- if (!session) {
250
- return NextResponse.json(
251
- { error: 'Unauthorized' },
252
- { status: 401 }
253
- )
254
- }
255
-
256
- // Proceed with authenticated request
257
- const { data: profile } = await supabase
258
- .from('profiles')
259
- .select('*')
260
- .eq('user_id', session.user.id)
261
- .single()
262
-
263
- return NextResponse.json({ profile })
264
- }
265
- ```
266
-
267
- ### Role-based Authorization
268
-
269
- ```typescript
270
- const ADMIN_ROLES = ['admin', 'super_admin']
271
-
272
- export async function DELETE(
273
- request: NextRequest,
274
- { params }: { params: { id: string } }
275
- ) {
276
- const supabase = createRouteHandlerClient()
277
- const { data: { session } } = await supabase.auth.getSession()
278
-
279
- if (!session) {
280
- return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
281
- }
282
-
283
- // Check user role
284
- const { data: profile } = await supabase
285
- .from('profiles')
286
- .select('role')
287
- .eq('user_id', session.user.id)
288
- .single()
289
-
290
- if (!profile || !ADMIN_ROLES.includes(profile.role)) {
291
- return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
292
- }
293
-
294
- // Proceed with admin-only operation
295
- }
296
- ```
297
-
298
- ---
299
-
300
- ## Error Handling
301
-
302
- ### Centralized Error Handler
303
-
304
- ```typescript
305
- // lib/api/errorHandler.ts
306
- import { NextResponse } from 'next/server'
307
- import { PostgrestError } from '@supabase/supabase-js'
308
- import { z } from 'zod'
309
-
310
- export function handleApiError(error: unknown) {
311
- console.error('API Error:', error)
312
-
313
- // Zod validation errors
314
- if (error instanceof z.ZodError) {
315
- return NextResponse.json(
316
- { error: 'Validation failed', details: error.errors },
317
- { status: 400 }
318
- )
319
- }
320
-
321
- // Supabase errors
322
- if (isPostgrestError(error)) {
323
- return NextResponse.json(
324
- { error: error.message, code: error.code },
325
- { status: 400 }
326
- )
327
- }
328
-
329
- // Default error
330
- return NextResponse.json(
331
- { error: 'Internal server error' },
332
- { status: 500 }
333
- )
334
- }
335
-
336
- function isPostgrestError(error: unknown): error is PostgrestError {
337
- return (error as PostgrestError).code !== undefined
338
- }
339
- ```
340
-
341
- ### Usage
342
-
343
- ```typescript
344
- import { handleApiError } from '@/lib/api/errorHandler'
345
-
346
- export async function POST(request: NextRequest) {
347
- try {
348
- // API logic
349
- return NextResponse.json({ success: true })
350
- } catch (error) {
351
- return handleApiError(error)
352
- }
353
- }
354
- ```
355
-
356
- ---
357
-
358
- ## Supabase Integration
359
-
360
- ### Database Operations
361
-
362
- ```typescript
363
- import { createRouteHandlerClient } from '@/lib/supabase/server'
364
-
365
- export async function GET(request: NextRequest) {
366
- const supabase = createRouteHandlerClient()
367
-
368
- const { data: users, error } = await supabase
369
- .from('users')
370
- .select('id, name, email')
371
- .order('created_at', { ascending: false })
372
- .limit(10)
373
-
374
- if (error) {
375
- return NextResponse.json({ error: error.message }, { status: 500 })
376
- }
377
-
378
- return NextResponse.json({ users })
379
- }
380
- ```
381
-
382
- ### Row Level Security (RLS)
383
-
384
- ```typescript
385
- // Supabase automatically enforces RLS based on authenticated user
386
- export async function GET(request: NextRequest) {
387
- const supabase = createRouteHandlerClient()
388
-
389
- // Only returns rows the authenticated user can access
390
- const { data: documents } = await supabase
391
- .from('documents')
392
- .select('*')
393
-
394
- return NextResponse.json({ documents })
395
- }
396
- ```
397
-
398
- ---
399
-
400
- ## Caching
401
-
402
- ### Static Data (ISR)
403
-
404
- ```typescript
405
- export async function GET() {
406
- const data = await fetchStaticData()
407
-
408
- return NextResponse.json(
409
- { data },
410
- {
411
- headers: {
412
- 'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400'
413
- }
414
- }
415
- )
416
- }
417
- ```
418
-
419
- ### Opt-out of Caching
420
-
421
- ```typescript
422
- export const dynamic = 'force-dynamic' // Opt out of caching
423
- export const revalidate = 0 // Disable ISR
424
-
425
- export async function GET() {
426
- // Always fetch fresh data
427
- return NextResponse.json({ data: [] })
428
- }
429
- ```
430
-
431
- ---
432
-
433
- ## CORS Configuration
434
-
435
- ```typescript
436
- // app/api/public/route.ts
437
- export async function GET(request: NextRequest) {
438
- const response = NextResponse.json({ data: [] })
439
-
440
- // Allow CORS
441
- response.headers.set('Access-Control-Allow-Origin', '*')
442
- response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
443
- response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization')
444
-
445
- return response
446
- }
447
-
448
- export async function OPTIONS() {
449
- return new NextResponse(null, {
450
- status: 204,
451
- headers: {
452
- 'Access-Control-Allow-Origin': '*',
453
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
454
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization'
455
- }
456
- })
457
- }
458
- ```
459
-
460
- ---
461
-
462
- ## Testing API Routes
463
-
464
- ```typescript
465
- import { describe, it, expect } from 'vitest'
466
- import { GET, POST } from './route'
467
-
468
- describe('/api/users', () => {
469
- it('should return users list', async () => {
470
- const request = new Request('http://localhost:3000/api/users')
471
- const response = await GET(request)
472
- const data = await response.json()
473
-
474
- expect(response.status).toBe(200)
475
- expect(Array.isArray(data.users)).toBe(true)
476
- })
477
-
478
- it('should create a new user', async () => {
479
- const request = new Request('http://localhost:3000/api/users', {
480
- method: 'POST',
481
- body: JSON.stringify({ name: 'John', email: 'john@example.com' })
482
- })
483
- const response = await POST(request)
484
- const data = await response.json()
485
-
486
- expect(response.status).toBe(201)
487
- expect(data.user).toBeDefined()
488
- })
489
- })
490
- ```
491
-
492
- ---
493
-
494
- *API Routes Standards - MORPH-SPEC by Polymorphism Tech*