@corbat-tech/coding-standards-mcp 1.0.3 → 2.0.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.
- package/README.md +233 -337
- package/dist/agent.d.ts +5 -6
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +95 -217
- package/dist/agent.js.map +1 -1
- package/dist/analysis/code-analyzer.d.ts +44 -0
- package/dist/analysis/code-analyzer.d.ts.map +1 -0
- package/dist/analysis/code-analyzer.js +528 -0
- package/dist/analysis/code-analyzer.js.map +1 -0
- package/dist/errors.d.ts +58 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +112 -0
- package/dist/errors.js.map +1 -0
- package/dist/guardrails.d.ts +35 -0
- package/dist/guardrails.d.ts.map +1 -0
- package/dist/guardrails.js +303 -0
- package/dist/guardrails.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +36 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +63 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.d.ts +40 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +97 -0
- package/dist/metrics.js.map +1 -0
- package/dist/profiles.d.ts +1 -1
- package/dist/profiles.d.ts.map +1 -1
- package/dist/profiles.js +239 -108
- package/dist/profiles.js.map +1 -1
- package/dist/prompts.js +1 -1
- package/dist/prompts.js.map +1 -1
- package/dist/tools/definitions.d.ts +143 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +229 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/handlers/get-context.d.ts +12 -0
- package/dist/tools/handlers/get-context.d.ts.map +1 -0
- package/dist/tools/handlers/get-context.js +233 -0
- package/dist/tools/handlers/get-context.js.map +1 -0
- package/dist/tools/handlers/health.d.ts +11 -0
- package/dist/tools/handlers/health.d.ts.map +1 -0
- package/dist/tools/handlers/health.js +57 -0
- package/dist/tools/handlers/health.js.map +1 -0
- package/dist/tools/handlers/index.d.ts +12 -0
- package/dist/tools/handlers/index.d.ts.map +1 -0
- package/dist/tools/handlers/index.js +12 -0
- package/dist/tools/handlers/index.js.map +1 -0
- package/dist/tools/handlers/init.d.ts +12 -0
- package/dist/tools/handlers/init.d.ts.map +1 -0
- package/dist/tools/handlers/init.js +102 -0
- package/dist/tools/handlers/init.js.map +1 -0
- package/dist/tools/handlers/profiles.d.ts +11 -0
- package/dist/tools/handlers/profiles.d.ts.map +1 -0
- package/dist/tools/handlers/profiles.js +25 -0
- package/dist/tools/handlers/profiles.js.map +1 -0
- package/dist/tools/handlers/search.d.ts +12 -0
- package/dist/tools/handlers/search.d.ts.map +1 -0
- package/dist/tools/handlers/search.js +58 -0
- package/dist/tools/handlers/search.js.map +1 -0
- package/dist/tools/handlers/validate.d.ts +15 -0
- package/dist/tools/handlers/validate.d.ts.map +1 -0
- package/dist/tools/handlers/validate.js +71 -0
- package/dist/tools/handlers/validate.js.map +1 -0
- package/dist/tools/handlers/verify.d.ts +38 -0
- package/dist/tools/handlers/verify.d.ts.map +1 -0
- package/dist/tools/handlers/verify.js +172 -0
- package/dist/tools/handlers/verify.js.map +1 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +75 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/schemas.d.ts +29 -0
- package/dist/tools/schemas.d.ts.map +1 -0
- package/dist/tools/schemas.js +20 -0
- package/dist/tools/schemas.js.map +1 -0
- package/dist/tools.js +2 -2
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +141 -71
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +92 -40
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/profiles/examples/microservice-kafka.yaml +122 -0
- package/profiles/examples/startup-fast.yaml +67 -0
- package/profiles/examples/strict-enterprise.yaml +62 -0
- package/profiles/templates/angular.yaml +614 -0
- package/profiles/templates/csharp-dotnet.yaml +529 -0
- package/profiles/templates/flutter.yaml +547 -0
- package/profiles/templates/go.yaml +1276 -0
- package/profiles/templates/java-spring-backend.yaml +326 -0
- package/profiles/templates/kotlin-spring.yaml +417 -0
- package/profiles/templates/nextjs.yaml +536 -0
- package/profiles/templates/nodejs.yaml +594 -0
- package/profiles/templates/python.yaml +546 -0
- package/profiles/templates/react.yaml +456 -0
- package/profiles/templates/rust.yaml +508 -0
- package/profiles/templates/vue.yaml +483 -0
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# CORBAT MCP - Next.js Profile
|
|
3
|
+
# ============================================================================
|
|
4
|
+
# Production-ready standards for Next.js full-stack applications.
|
|
5
|
+
# Based on Next.js 14+ App Router, Server Components, and React best practices.
|
|
6
|
+
# ============================================================================
|
|
7
|
+
|
|
8
|
+
name: "Next.js Full-Stack Standards"
|
|
9
|
+
description: "Production-ready standards for Next.js with App Router, Server Components, Server Actions, and TypeScript"
|
|
10
|
+
|
|
11
|
+
# ----------------------------------------------------------------------------
|
|
12
|
+
# ARCHITECTURE
|
|
13
|
+
# ----------------------------------------------------------------------------
|
|
14
|
+
architecture:
|
|
15
|
+
type: feature-based
|
|
16
|
+
enforceLayerDependencies: true
|
|
17
|
+
layers:
|
|
18
|
+
- name: app
|
|
19
|
+
description: "Next.js App Router. Contains routes, layouts, pages, and API routes."
|
|
20
|
+
allowedDependencies:
|
|
21
|
+
- features
|
|
22
|
+
- shared
|
|
23
|
+
- lib
|
|
24
|
+
directories:
|
|
25
|
+
- "app"
|
|
26
|
+
- "app/(routes)"
|
|
27
|
+
- "app/api"
|
|
28
|
+
|
|
29
|
+
- name: features
|
|
30
|
+
description: "Feature modules. Each feature contains its own components, hooks, and server actions."
|
|
31
|
+
allowedDependencies:
|
|
32
|
+
- shared
|
|
33
|
+
- lib
|
|
34
|
+
directories:
|
|
35
|
+
- "features"
|
|
36
|
+
- "features/*/components"
|
|
37
|
+
- "features/*/actions"
|
|
38
|
+
- "features/*/hooks"
|
|
39
|
+
|
|
40
|
+
- name: shared
|
|
41
|
+
description: "Shared components, hooks, and utilities used across features."
|
|
42
|
+
allowedDependencies:
|
|
43
|
+
- lib
|
|
44
|
+
directories:
|
|
45
|
+
- "components"
|
|
46
|
+
- "hooks"
|
|
47
|
+
- "utils"
|
|
48
|
+
|
|
49
|
+
- name: lib
|
|
50
|
+
description: "Core utilities, configurations, and type definitions."
|
|
51
|
+
allowedDependencies: []
|
|
52
|
+
directories:
|
|
53
|
+
- "lib"
|
|
54
|
+
- "types"
|
|
55
|
+
- "config"
|
|
56
|
+
|
|
57
|
+
# ----------------------------------------------------------------------------
|
|
58
|
+
# NEXT.JS FEATURES
|
|
59
|
+
# ----------------------------------------------------------------------------
|
|
60
|
+
nextjsFeatures:
|
|
61
|
+
version: "14+"
|
|
62
|
+
appRouter:
|
|
63
|
+
required: true
|
|
64
|
+
features:
|
|
65
|
+
- "Server Components (default)"
|
|
66
|
+
- "Client Components ('use client')"
|
|
67
|
+
- "Server Actions ('use server')"
|
|
68
|
+
- "Parallel Routes"
|
|
69
|
+
- "Intercepting Routes"
|
|
70
|
+
- "Route Groups"
|
|
71
|
+
|
|
72
|
+
serverComponents:
|
|
73
|
+
default: true
|
|
74
|
+
benefits:
|
|
75
|
+
- "Zero client-side JavaScript for server components"
|
|
76
|
+
- "Direct database access"
|
|
77
|
+
- "Secure server-only code"
|
|
78
|
+
- "Automatic code splitting"
|
|
79
|
+
patterns:
|
|
80
|
+
dataFetching: "async components"
|
|
81
|
+
streaming: "Suspense boundaries"
|
|
82
|
+
example: |
|
|
83
|
+
// app/orders/page.tsx (Server Component)
|
|
84
|
+
export default async function OrdersPage() {
|
|
85
|
+
const orders = await getOrders(); // Direct DB call
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<Suspense fallback={<OrdersSkeleton />}>
|
|
89
|
+
<OrderList orders={orders} />
|
|
90
|
+
</Suspense>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
clientComponents:
|
|
95
|
+
directive: "'use client'"
|
|
96
|
+
useFor:
|
|
97
|
+
- "Interactive UI (onClick, onChange)"
|
|
98
|
+
- "Browser APIs (localStorage, window)"
|
|
99
|
+
- "React hooks (useState, useEffect)"
|
|
100
|
+
- "Third-party client libraries"
|
|
101
|
+
avoidFor:
|
|
102
|
+
- "Data fetching"
|
|
103
|
+
- "Database access"
|
|
104
|
+
- "Server-only secrets"
|
|
105
|
+
example: |
|
|
106
|
+
'use client';
|
|
107
|
+
|
|
108
|
+
export function AddToCartButton({ productId }: { productId: string }) {
|
|
109
|
+
const [isPending, startTransition] = useTransition();
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<button
|
|
113
|
+
onClick={() => startTransition(() => addToCart(productId))}
|
|
114
|
+
disabled={isPending}
|
|
115
|
+
>
|
|
116
|
+
{isPending ? 'Adding...' : 'Add to Cart'}
|
|
117
|
+
</button>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
serverActions:
|
|
122
|
+
directive: "'use server'"
|
|
123
|
+
patterns:
|
|
124
|
+
formActions: true
|
|
125
|
+
mutations: true
|
|
126
|
+
revalidation: true
|
|
127
|
+
example: |
|
|
128
|
+
'use server';
|
|
129
|
+
|
|
130
|
+
export async function createOrder(formData: FormData) {
|
|
131
|
+
const validatedData = orderSchema.parse({
|
|
132
|
+
customerId: formData.get('customerId'),
|
|
133
|
+
items: JSON.parse(formData.get('items') as string),
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const order = await db.order.create({ data: validatedData });
|
|
137
|
+
|
|
138
|
+
revalidatePath('/orders');
|
|
139
|
+
redirect(`/orders/${order.id}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# ----------------------------------------------------------------------------
|
|
143
|
+
# RENDERING STRATEGIES
|
|
144
|
+
# ----------------------------------------------------------------------------
|
|
145
|
+
rendering:
|
|
146
|
+
strategies:
|
|
147
|
+
static:
|
|
148
|
+
description: "Pre-rendered at build time"
|
|
149
|
+
useFor: "Marketing pages, blog posts"
|
|
150
|
+
example: "export const dynamic = 'force-static'"
|
|
151
|
+
|
|
152
|
+
dynamic:
|
|
153
|
+
description: "Rendered on each request"
|
|
154
|
+
useFor: "User-specific content, real-time data"
|
|
155
|
+
example: "export const dynamic = 'force-dynamic'"
|
|
156
|
+
|
|
157
|
+
streaming:
|
|
158
|
+
description: "Progressive rendering with Suspense"
|
|
159
|
+
useFor: "Complex pages with multiple data sources"
|
|
160
|
+
|
|
161
|
+
isr:
|
|
162
|
+
description: "Incremental Static Regeneration"
|
|
163
|
+
useFor: "Content that updates periodically"
|
|
164
|
+
example: "export const revalidate = 3600 // 1 hour"
|
|
165
|
+
|
|
166
|
+
caching:
|
|
167
|
+
fetch:
|
|
168
|
+
default: "cache: 'force-cache'"
|
|
169
|
+
revalidate: "next: { revalidate: seconds }"
|
|
170
|
+
noStore: "cache: 'no-store'"
|
|
171
|
+
routeSegment:
|
|
172
|
+
- "export const revalidate = 60"
|
|
173
|
+
- "export const dynamic = 'force-dynamic'"
|
|
174
|
+
|
|
175
|
+
# ----------------------------------------------------------------------------
|
|
176
|
+
# CODE QUALITY
|
|
177
|
+
# ----------------------------------------------------------------------------
|
|
178
|
+
codeQuality:
|
|
179
|
+
maxMethodLines: 30
|
|
180
|
+
maxClassLines: 200
|
|
181
|
+
maxFileLines: 300
|
|
182
|
+
maxMethodParameters: 4
|
|
183
|
+
maxCyclomaticComplexity: 10
|
|
184
|
+
requireDocumentation: true
|
|
185
|
+
requireTests: true
|
|
186
|
+
minimumTestCoverage: 70
|
|
187
|
+
|
|
188
|
+
principles:
|
|
189
|
+
- "Server Components by default"
|
|
190
|
+
- "Minimize 'use client' directives"
|
|
191
|
+
- "Colocate data fetching with components"
|
|
192
|
+
- "Use Server Actions for mutations"
|
|
193
|
+
- "Leverage built-in optimizations"
|
|
194
|
+
- "Progressive enhancement"
|
|
195
|
+
|
|
196
|
+
linting:
|
|
197
|
+
eslint:
|
|
198
|
+
extends:
|
|
199
|
+
- "next/core-web-vitals"
|
|
200
|
+
- "next/typescript"
|
|
201
|
+
rules:
|
|
202
|
+
- "@next/next/no-img-element"
|
|
203
|
+
- "@next/next/no-html-link-for-pages"
|
|
204
|
+
|
|
205
|
+
# ----------------------------------------------------------------------------
|
|
206
|
+
# NAMING CONVENTIONS
|
|
207
|
+
# ----------------------------------------------------------------------------
|
|
208
|
+
naming:
|
|
209
|
+
general:
|
|
210
|
+
component: PascalCase
|
|
211
|
+
hook: useCamelCase
|
|
212
|
+
serverAction: camelCase
|
|
213
|
+
utility: camelCase
|
|
214
|
+
constant: SCREAMING_SNAKE_CASE
|
|
215
|
+
type: PascalCase
|
|
216
|
+
file: kebab-case.tsx
|
|
217
|
+
|
|
218
|
+
nextjsConventions:
|
|
219
|
+
page: "page.tsx"
|
|
220
|
+
layout: "layout.tsx"
|
|
221
|
+
loading: "loading.tsx"
|
|
222
|
+
error: "error.tsx"
|
|
223
|
+
notFound: "not-found.tsx"
|
|
224
|
+
template: "template.tsx"
|
|
225
|
+
routeHandler: "route.ts"
|
|
226
|
+
middleware: "middleware.ts"
|
|
227
|
+
|
|
228
|
+
suffixes:
|
|
229
|
+
component: ""
|
|
230
|
+
clientComponent: ""
|
|
231
|
+
serverAction: "Action"
|
|
232
|
+
hook: ""
|
|
233
|
+
schema: "Schema"
|
|
234
|
+
type: ""
|
|
235
|
+
|
|
236
|
+
directories:
|
|
237
|
+
routeGroups: "(group-name)"
|
|
238
|
+
parallelRoutes: "@slot-name"
|
|
239
|
+
interceptingRoutes: "(.)route, (..)route"
|
|
240
|
+
|
|
241
|
+
# ----------------------------------------------------------------------------
|
|
242
|
+
# DATA FETCHING
|
|
243
|
+
# ----------------------------------------------------------------------------
|
|
244
|
+
dataFetching:
|
|
245
|
+
serverSide:
|
|
246
|
+
patterns:
|
|
247
|
+
- "async Server Components"
|
|
248
|
+
- "Server Actions"
|
|
249
|
+
- "Route Handlers"
|
|
250
|
+
example: |
|
|
251
|
+
// Fetch in Server Component
|
|
252
|
+
async function ProductPage({ params }: { params: { id: string } }) {
|
|
253
|
+
const product = await getProduct(params.id);
|
|
254
|
+
return <ProductDetails product={product} />;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
clientSide:
|
|
258
|
+
patterns:
|
|
259
|
+
- "TanStack Query (React Query)"
|
|
260
|
+
- "SWR"
|
|
261
|
+
useFor:
|
|
262
|
+
- "Real-time updates"
|
|
263
|
+
- "Optimistic updates"
|
|
264
|
+
- "Infinite scrolling"
|
|
265
|
+
example: |
|
|
266
|
+
'use client';
|
|
267
|
+
|
|
268
|
+
function useOrders() {
|
|
269
|
+
return useQuery({
|
|
270
|
+
queryKey: ['orders'],
|
|
271
|
+
queryFn: () => fetch('/api/orders').then(res => res.json()),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
validation:
|
|
276
|
+
library: "Zod"
|
|
277
|
+
patterns:
|
|
278
|
+
- "Schema validation for forms"
|
|
279
|
+
- "API input validation"
|
|
280
|
+
- "Type inference"
|
|
281
|
+
example: |
|
|
282
|
+
const orderSchema = z.object({
|
|
283
|
+
customerId: z.string().uuid(),
|
|
284
|
+
items: z.array(orderItemSchema).min(1),
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
type CreateOrderInput = z.infer<typeof orderSchema>;
|
|
288
|
+
|
|
289
|
+
# ----------------------------------------------------------------------------
|
|
290
|
+
# TESTING
|
|
291
|
+
# ----------------------------------------------------------------------------
|
|
292
|
+
testing:
|
|
293
|
+
framework: "Vitest"
|
|
294
|
+
componentTesting: "React Testing Library"
|
|
295
|
+
e2e: "Playwright"
|
|
296
|
+
|
|
297
|
+
types:
|
|
298
|
+
unit:
|
|
299
|
+
location: "__tests__/*.test.ts"
|
|
300
|
+
coverage: 70
|
|
301
|
+
patterns:
|
|
302
|
+
- "Test utilities and helpers"
|
|
303
|
+
- "Test Server Actions"
|
|
304
|
+
- "Test data transformations"
|
|
305
|
+
|
|
306
|
+
component:
|
|
307
|
+
location: "__tests__/*.test.tsx"
|
|
308
|
+
patterns:
|
|
309
|
+
- "Test user interactions"
|
|
310
|
+
- "Test accessibility"
|
|
311
|
+
- "Mock Server Components"
|
|
312
|
+
example: |
|
|
313
|
+
import { render, screen } from '@testing-library/react';
|
|
314
|
+
import userEvent from '@testing-library/user-event';
|
|
315
|
+
|
|
316
|
+
test('should add item to cart', async () => {
|
|
317
|
+
const user = userEvent.setup();
|
|
318
|
+
render(<AddToCartButton productId="123" />);
|
|
319
|
+
|
|
320
|
+
await user.click(screen.getByRole('button', { name: /add to cart/i }));
|
|
321
|
+
|
|
322
|
+
expect(screen.getByText(/adding/i)).toBeInTheDocument();
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
e2e:
|
|
326
|
+
location: "e2e/*.spec.ts"
|
|
327
|
+
patterns:
|
|
328
|
+
- "Critical user flows"
|
|
329
|
+
- "Cross-page interactions"
|
|
330
|
+
example: |
|
|
331
|
+
test('should complete checkout flow', async ({ page }) => {
|
|
332
|
+
await page.goto('/products');
|
|
333
|
+
await page.click('[data-testid="add-to-cart"]');
|
|
334
|
+
await page.goto('/cart');
|
|
335
|
+
await page.click('[data-testid="checkout"]');
|
|
336
|
+
|
|
337
|
+
await expect(page.locator('[data-testid="order-confirmation"]'))
|
|
338
|
+
.toBeVisible();
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
# ----------------------------------------------------------------------------
|
|
342
|
+
# PERFORMANCE
|
|
343
|
+
# ----------------------------------------------------------------------------
|
|
344
|
+
performance:
|
|
345
|
+
coreWebVitals:
|
|
346
|
+
LCP: "< 2.5s"
|
|
347
|
+
FID: "< 100ms"
|
|
348
|
+
CLS: "< 0.1"
|
|
349
|
+
INP: "< 200ms"
|
|
350
|
+
|
|
351
|
+
optimizations:
|
|
352
|
+
images:
|
|
353
|
+
component: "next/image"
|
|
354
|
+
features:
|
|
355
|
+
- "Automatic optimization"
|
|
356
|
+
- "Lazy loading"
|
|
357
|
+
- "Responsive images"
|
|
358
|
+
- "AVIF/WebP format"
|
|
359
|
+
|
|
360
|
+
fonts:
|
|
361
|
+
component: "next/font"
|
|
362
|
+
features:
|
|
363
|
+
- "Zero layout shift"
|
|
364
|
+
- "Self-hosted fonts"
|
|
365
|
+
- "Automatic subsetting"
|
|
366
|
+
|
|
367
|
+
scripts:
|
|
368
|
+
component: "next/script"
|
|
369
|
+
strategies:
|
|
370
|
+
- "beforeInteractive"
|
|
371
|
+
- "afterInteractive"
|
|
372
|
+
- "lazyOnload"
|
|
373
|
+
|
|
374
|
+
bundling:
|
|
375
|
+
- "Dynamic imports"
|
|
376
|
+
- "Route-based code splitting"
|
|
377
|
+
- "Tree shaking"
|
|
378
|
+
|
|
379
|
+
# ----------------------------------------------------------------------------
|
|
380
|
+
# PROJECT STRUCTURE
|
|
381
|
+
# ----------------------------------------------------------------------------
|
|
382
|
+
projectStructure:
|
|
383
|
+
approach: "Feature-colocation"
|
|
384
|
+
|
|
385
|
+
example: |
|
|
386
|
+
app/
|
|
387
|
+
├── (marketing)/
|
|
388
|
+
│ ├── page.tsx
|
|
389
|
+
│ └── about/page.tsx
|
|
390
|
+
├── (app)/
|
|
391
|
+
│ ├── layout.tsx
|
|
392
|
+
│ ├── dashboard/
|
|
393
|
+
│ │ ├── page.tsx
|
|
394
|
+
│ │ ├── loading.tsx
|
|
395
|
+
│ │ └── error.tsx
|
|
396
|
+
│ └── orders/
|
|
397
|
+
│ ├── page.tsx
|
|
398
|
+
│ ├── [id]/page.tsx
|
|
399
|
+
│ └── actions.ts
|
|
400
|
+
├── api/
|
|
401
|
+
│ └── webhooks/route.ts
|
|
402
|
+
└── layout.tsx
|
|
403
|
+
features/
|
|
404
|
+
├── orders/
|
|
405
|
+
│ ├── components/
|
|
406
|
+
│ ├── actions/
|
|
407
|
+
│ ├── hooks/
|
|
408
|
+
│ └── types.ts
|
|
409
|
+
└── auth/
|
|
410
|
+
components/
|
|
411
|
+
├── ui/
|
|
412
|
+
└── layout/
|
|
413
|
+
lib/
|
|
414
|
+
├── db.ts
|
|
415
|
+
├── auth.ts
|
|
416
|
+
└── utils.ts
|
|
417
|
+
|
|
418
|
+
# ----------------------------------------------------------------------------
|
|
419
|
+
# DATABASE
|
|
420
|
+
# ----------------------------------------------------------------------------
|
|
421
|
+
database:
|
|
422
|
+
orm: "Prisma or Drizzle"
|
|
423
|
+
|
|
424
|
+
prisma:
|
|
425
|
+
patterns:
|
|
426
|
+
- "Schema-first development"
|
|
427
|
+
- "Type-safe queries"
|
|
428
|
+
- "Migrations"
|
|
429
|
+
example: |
|
|
430
|
+
// lib/db.ts
|
|
431
|
+
import { PrismaClient } from '@prisma/client';
|
|
432
|
+
|
|
433
|
+
const globalForPrisma = globalThis as unknown as {
|
|
434
|
+
prisma: PrismaClient | undefined;
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
export const db = globalForPrisma.prisma ?? new PrismaClient();
|
|
438
|
+
|
|
439
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
440
|
+
globalForPrisma.prisma = db;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
drizzle:
|
|
444
|
+
patterns:
|
|
445
|
+
- "SQL-like queries"
|
|
446
|
+
- "Edge runtime compatible"
|
|
447
|
+
- "Lightweight"
|
|
448
|
+
|
|
449
|
+
# ----------------------------------------------------------------------------
|
|
450
|
+
# AUTHENTICATION
|
|
451
|
+
# ----------------------------------------------------------------------------
|
|
452
|
+
authentication:
|
|
453
|
+
library: "NextAuth.js (Auth.js)"
|
|
454
|
+
|
|
455
|
+
patterns:
|
|
456
|
+
middleware: true
|
|
457
|
+
serverSession: true
|
|
458
|
+
clientSession: true
|
|
459
|
+
example: |
|
|
460
|
+
// middleware.ts
|
|
461
|
+
export { auth as middleware } from '@/lib/auth';
|
|
462
|
+
|
|
463
|
+
export const config = {
|
|
464
|
+
matcher: ['/dashboard/:path*', '/api/:path*'],
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
// Server Component
|
|
468
|
+
async function DashboardPage() {
|
|
469
|
+
const session = await auth();
|
|
470
|
+
if (!session) redirect('/login');
|
|
471
|
+
return <Dashboard user={session.user} />;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
# ----------------------------------------------------------------------------
|
|
475
|
+
# ERROR HANDLING
|
|
476
|
+
# ----------------------------------------------------------------------------
|
|
477
|
+
errorHandling:
|
|
478
|
+
patterns:
|
|
479
|
+
errorBoundary: "error.tsx"
|
|
480
|
+
notFound: "not-found.tsx"
|
|
481
|
+
serverActions: "try-catch with typed errors"
|
|
482
|
+
|
|
483
|
+
example: |
|
|
484
|
+
// app/orders/error.tsx
|
|
485
|
+
'use client';
|
|
486
|
+
|
|
487
|
+
export default function OrderError({
|
|
488
|
+
error,
|
|
489
|
+
reset,
|
|
490
|
+
}: {
|
|
491
|
+
error: Error & { digest?: string };
|
|
492
|
+
reset: () => void;
|
|
493
|
+
}) {
|
|
494
|
+
return (
|
|
495
|
+
<div>
|
|
496
|
+
<h2>Something went wrong!</h2>
|
|
497
|
+
<button onClick={reset}>Try again</button>
|
|
498
|
+
</div>
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
# ----------------------------------------------------------------------------
|
|
503
|
+
# TECHNOLOGIES
|
|
504
|
+
# ----------------------------------------------------------------------------
|
|
505
|
+
technologies:
|
|
506
|
+
- name: nextjs
|
|
507
|
+
version: "14+"
|
|
508
|
+
specificRules:
|
|
509
|
+
useAppRouter: true
|
|
510
|
+
useServerComponents: true
|
|
511
|
+
useServerActions: true
|
|
512
|
+
useImageOptimization: true
|
|
513
|
+
useFontOptimization: true
|
|
514
|
+
|
|
515
|
+
- name: react
|
|
516
|
+
version: "18+"
|
|
517
|
+
specificRules:
|
|
518
|
+
useFunctionalComponents: true
|
|
519
|
+
useHooks: true
|
|
520
|
+
useSuspense: true
|
|
521
|
+
useTransitions: true
|
|
522
|
+
|
|
523
|
+
- name: typescript
|
|
524
|
+
version: "5+"
|
|
525
|
+
specificRules:
|
|
526
|
+
strict: true
|
|
527
|
+
noImplicitAny: true
|
|
528
|
+
strictNullChecks: true
|
|
529
|
+
|
|
530
|
+
- name: testing
|
|
531
|
+
specificRules:
|
|
532
|
+
useVitest: true
|
|
533
|
+
useReactTestingLibrary: true
|
|
534
|
+
usePlaywright: true
|
|
535
|
+
testServerActions: true
|
|
536
|
+
testAccessibility: true
|