@polymorphism-tech/morph-spec 7.0.0 → 7.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.
- package/README.md +367 -367
- package/framework/agents.json +132 -127
- package/framework/rubrics/backend.json +41 -36
- package/framework/rules/ai-agents-standards.md +45 -15
- package/framework/rules/neon-standards.md +25 -26
- package/framework/standards/STANDARDS.json +1729 -1133
- package/framework/standards/ai-agents/agent-session.md +160 -0
- package/framework/standards/ai-agents/batching.md +193 -0
- package/framework/standards/ai-agents/context-providers.md +188 -0
- package/framework/standards/ai-agents/mcp-server.md +250 -0
- package/framework/standards/ai-agents/mcp-tools.md +197 -0
- package/framework/standards/ai-agents/middleware-patterns.md +207 -0
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -0
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -0
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -0
- package/framework/standards/ai-agents/modalities-vision.md +201 -0
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -0
- package/framework/standards/ai-agents/production.md +114 -258
- package/framework/standards/ai-agents/prompts-in-db.md +214 -0
- package/framework/standards/ai-agents/providers/model-registry.md +158 -0
- package/framework/standards/ai-agents/rag-custom-pgvector.md +243 -0
- package/framework/standards/ai-agents/service-tier-flex.md +135 -0
- package/framework/standards/ai-agents/setup.md +142 -316
- package/framework/standards/ai-agents/structured-output.md +249 -0
- package/framework/standards/ai-agents/sweet-spot.md +109 -0
- package/framework/standards/ai-agents/workflows.md +114 -284
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +433 -429
- package/framework/standards/backend/api/validation.md +92 -88
- package/framework/standards/backend/database/postgresql/database.md +336 -332
- package/framework/standards/backend/database/vector-search-rag.md +599 -541
- package/framework/standards/backend/dotnet/fluent-validation-vsa.md +4 -0
- package/framework/standards/backend/dotnet/result-pattern.md +4 -0
- package/framework/standards/backend/dotnet/scalar-ui.md +176 -172
- package/framework/standards/backend/dotnet/scrutor.md +4 -0
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +278 -274
- package/framework/standards/backend/integrations/asaas/asaas-api.md +260 -216
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +354 -350
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +30 -19
- package/framework/standards/backend/integrations/resend/resend-email.md +400 -385
- package/framework/standards/data/nosql/cache/redis.md +106 -97
- package/framework/standards/data/nosql/cosmos-db.md +127 -118
- package/framework/standards/data/vector-search/rag-chunking.md +113 -104
- package/framework/standards/frontend/design-system/ai-image-generation.md +4 -0
- package/framework/standards/frontend/design-system/animations.md +164 -160
- package/framework/standards/frontend/design-system/naming.md +68 -64
- package/framework/standards/frontend/gsap/gsap-core.md +14 -8
- package/framework/standards/frontend/gsap/gsap-plugins.md +26 -21
- package/framework/standards/frontend/gsap/gsap-scrolltrigger.md +9 -7
- package/framework/standards/frontend/nextjs/app-router.md +127 -123
- package/framework/standards/frontend/nextjs/components.md +136 -132
- package/framework/standards/frontend/nextjs/data-fetching.md +130 -126
- package/framework/standards/frontend/nextjs/forms.md +134 -128
- package/framework/standards/frontend/nextjs/motion-patterns.md +328 -322
- package/framework/standards/frontend/nextjs/naming-conventions.md +71 -67
- package/framework/standards/frontend/nextjs/nextjs-patterns.md +229 -225
- package/framework/standards/frontend/nextjs/project-structure.md +106 -102
- package/framework/standards/frontend/nextjs/state-management.md +76 -72
- package/framework/standards/frontend/nextjs/testing.md +115 -111
- package/framework/standards/infrastructure/docker/easypanel-deploy.md +196 -192
- package/framework/standards/infrastructure/neon/neon-pgrag.md +6 -2
- package/framework/standards/infrastructure/neon/neon-pgvector.md +4 -0
- package/framework/standards/infrastructure/neon/neon-setup.md +5 -1
- package/framework/standards/integration/mcp/mcp-tools.md +471 -462
- package/framework/templates/REGISTRY.json +1745 -1239
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -0
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -0
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -0
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -0
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -0
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -0
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -0
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -0
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -0
- package/package.json +89 -83
- package/src/core/templates/template-registry.js +289 -256
- package/src/lib/generators/context-generator.js +516 -518
- package/src/lib/generators/scaffold-generator.js +23 -26
- package/framework/standards/infrastructure/neon/neon-semantic-kernel.md +0 -310
- package/framework/templates/integrations/semantic-kernel-neon.cs +0 -125
|
@@ -1,64 +1,68 @@
|
|
|
1
|
-
# CSS Naming Convention
|
|
2
|
-
|
|
3
|
-
> **Scope:** universal
|
|
4
|
-
> **Layer:** 0 (always load)
|
|
5
|
-
> **Keywords:** css, bem, naming, class names, conventions
|
|
6
|
-
> **Load When:** always
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
# CSS Naming Convention
|
|
2
|
+
|
|
3
|
+
> **Scope:** universal
|
|
4
|
+
> **Layer:** 0 (always load)
|
|
5
|
+
> **Keywords:** css, bem, naming, class names, conventions
|
|
6
|
+
> **Load When:** always
|
|
7
|
+
|
|
8
|
+
**Verified against:** CSS (BEM + custom properties — language-level, no framework). Last-verified: 2026-05-20.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Principles
|
|
13
|
+
|
|
14
|
+
1. **Page prefix** — Prevents conflicts
|
|
15
|
+
2. **BEM for components** — Clear hierarchy
|
|
16
|
+
3. **Namespaced variables** — No library collisions
|
|
17
|
+
4. **State suffixes** — Consistent modifiers
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Page Prefixes
|
|
22
|
+
|
|
23
|
+
| Page | Example |
|
|
24
|
+
|------|---------|
|
|
25
|
+
| Home | `.home-hero`, `.home-features` |
|
|
26
|
+
| Checkout | `.checkout-form`, `.checkout-summary` |
|
|
27
|
+
| Dashboard | `.dashboard-stats`, `.dashboard-chart` |
|
|
28
|
+
| Auth | `.auth-form`, `.auth-social-buttons` |
|
|
29
|
+
|
|
30
|
+
## BEM for Reusable Components
|
|
31
|
+
|
|
32
|
+
```css
|
|
33
|
+
.card { } /* Block */
|
|
34
|
+
.card__header { } /* Element */
|
|
35
|
+
.card__body { }
|
|
36
|
+
.card--featured { } /* Modifier */
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Rule:** BEM for reusable components. Page prefix for page-specific elements.
|
|
40
|
+
|
|
41
|
+
## CSS Variables with Namespace
|
|
42
|
+
|
|
43
|
+
```css
|
|
44
|
+
:root {
|
|
45
|
+
--app-primary: #007bff;
|
|
46
|
+
--app-spacing-md: 1rem;
|
|
47
|
+
--app-font-heading: 'Segoe UI', sans-serif;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## State Suffixes
|
|
52
|
+
|
|
53
|
+
| State | Suffix |
|
|
54
|
+
|-------|--------|
|
|
55
|
+
| Active | `--active` |
|
|
56
|
+
| Disabled | `--disabled` |
|
|
57
|
+
| Loading | `--loading` |
|
|
58
|
+
| Error | `--error` |
|
|
59
|
+
|
|
60
|
+
```css
|
|
61
|
+
.button { }
|
|
62
|
+
.button--active { }
|
|
63
|
+
.button--disabled { }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
*MORPH-SPEC by Polymorphism Tech*
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
---
|
|
2
|
-
scope: frontend-nextjs-ui
|
|
3
|
-
layer: 3
|
|
4
|
-
keywords: gsap, animation, timeline, tween, useGSAP, greensock, transform
|
|
5
|
-
load_when: gsap-animator active
|
|
6
|
-
---
|
|
7
|
-
|
|
8
1
|
# GSAP Core & React Integration
|
|
9
2
|
|
|
3
|
+
> **Scope:** frontend-nextjs-ui
|
|
4
|
+
> **Layer:** 3
|
|
5
|
+
> **Keywords:** gsap, animation, timeline, tween, useGSAP, greensock, transform
|
|
6
|
+
> **Load When:** gsap-animator active
|
|
7
|
+
|
|
8
|
+
**Verified against:** GSAP 3.13 + @gsap/react. Last-verified: 2026-05-20.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
10
12
|
Reference guide for implementing animations in Next.js projects using GSAP and the official @gsap/react bindings. Covers core APIs, React integration via useGSAP, timeline sequencing, utility functions, performance, accessibility, and the decision boundary with Framer Motion.
|
|
11
13
|
|
|
12
14
|
---
|
|
@@ -33,7 +35,11 @@ Reference guide for implementing animations in Next.js projects using GSAP and t
|
|
|
33
35
|
npm install gsap @gsap/react
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
Since the Webflow acquisition, **GSAP and every plugin are free for commercial
|
|
39
|
+
use**. The public `gsap` package includes Flip, Observer, ScrollToPlugin, and the
|
|
40
|
+
formerly-premium plugins (SplitText, MorphSVG, DrawSVG, MotionPath, Draggable,
|
|
41
|
+
InertiaPlugin) — no Club GreenSock membership or private registry needed. See
|
|
42
|
+
`gsap-plugins.md` for the per-plugin API.
|
|
37
43
|
|
|
38
44
|
### Plugin Registration
|
|
39
45
|
|
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
---
|
|
2
|
-
scope: frontend-nextjs-gsap
|
|
3
|
-
layer: 3
|
|
4
|
-
keywords: flip, splittext, morphsvg, drawsvg, motionpath, draggable, observer, scrollto, gsap-plugins
|
|
5
|
-
load_when: gsap-animator active
|
|
6
|
-
---
|
|
7
|
-
|
|
8
1
|
# GSAP Plugins
|
|
9
2
|
|
|
10
|
-
|
|
3
|
+
> **Scope:** frontend-nextjs-gsap
|
|
4
|
+
> **Layer:** 3
|
|
5
|
+
> **Keywords:** flip, splittext, morphsvg, drawsvg, motionpath, draggable, observer, scrollto, gsap-plugins
|
|
6
|
+
> **Load When:** gsap-animator active
|
|
11
7
|
|
|
12
|
-
|
|
8
|
+
**Verified against:** GSAP 3.13 + @gsap/react. Last-verified: 2026-05-20.
|
|
9
|
+
|
|
10
|
+
---
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
Reference guide for GSAP's plugin ecosystem in Next.js. Covers the full plugin set — Flip, Observer, ScrollToPlugin, SplitText, MorphSVG, DrawSVG, MotionPath, Draggable, InertiaPlugin.
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
## Plugin Registration & Licensing
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
Since the Webflow acquisition, **GSAP and every plugin are free for commercial
|
|
17
|
+
use** — no Club GreenSock membership, no license key, no auth token, no private
|
|
18
|
+
registry. The formerly-premium plugins (SplitText, MorphSVG, DrawSVG, MotionPath,
|
|
19
|
+
Draggable, InertiaPlugin, ScrambleText, CustomEase, CustomWiggle, CustomBounce,
|
|
20
|
+
Physics2D, PhysicsProps) now ship in the public `gsap` package alongside Flip,
|
|
21
|
+
Observer, and ScrollToPlugin.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
```bash
|
|
24
|
+
# Everything — core + all plugins — installs from the public package
|
|
25
|
+
npm install gsap @gsap/react
|
|
24
26
|
```
|
|
25
27
|
|
|
28
|
+
> Disregard any older instruction to install `gsap@npm:@gsap/shockingly` or
|
|
29
|
+
> configure a private npm registry — that path is obsolete.
|
|
30
|
+
|
|
26
31
|
Registration pattern (do ONCE at app init):
|
|
27
32
|
|
|
28
33
|
```typescript
|
|
@@ -70,7 +75,7 @@ function FilterableGrid({ items, filter }: { items: Item[]; filter: string }) {
|
|
|
70
75
|
|
|
71
76
|
Use cases: filterable grids, list reordering, expanding cards, shared element transitions.
|
|
72
77
|
|
|
73
|
-
## SplitText
|
|
78
|
+
## SplitText
|
|
74
79
|
|
|
75
80
|
Split text into chars, words, or lines for staggered reveals:
|
|
76
81
|
|
|
@@ -101,7 +106,7 @@ Key points:
|
|
|
101
106
|
- The split creates `<div>` wrappers -- this affects layout. Test carefully.
|
|
102
107
|
- useGSAP automatically reverts the split on unmount
|
|
103
108
|
|
|
104
|
-
## MorphSVG
|
|
109
|
+
## MorphSVG
|
|
105
110
|
|
|
106
111
|
Morph between SVG shapes:
|
|
107
112
|
|
|
@@ -125,7 +130,7 @@ Rules:
|
|
|
125
130
|
- Match point counts for smoother morphs
|
|
126
131
|
- `type: "rotational"` is smoother for most shapes
|
|
127
132
|
|
|
128
|
-
## DrawSVG
|
|
133
|
+
## DrawSVG
|
|
129
134
|
|
|
130
135
|
Animate SVG stroke drawing:
|
|
131
136
|
|
|
@@ -151,7 +156,7 @@ gsap.from(paths, {
|
|
|
151
156
|
|
|
152
157
|
Requires SVG elements with visible `stroke` and `stroke-width`. Does not work on `fill`.
|
|
153
158
|
|
|
154
|
-
## MotionPath
|
|
159
|
+
## MotionPath
|
|
155
160
|
|
|
156
161
|
Animate elements along SVG paths:
|
|
157
162
|
|
|
@@ -192,7 +197,7 @@ gsap.to(window, {
|
|
|
192
197
|
});
|
|
193
198
|
```
|
|
194
199
|
|
|
195
|
-
## Draggable
|
|
200
|
+
## Draggable
|
|
196
201
|
|
|
197
202
|
Make elements draggable with optional physics:
|
|
198
203
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
---
|
|
2
|
-
scope: frontend-nextjs-gsap
|
|
3
|
-
layer: 3
|
|
4
|
-
keywords: scrolltrigger, scroll-animation, pinning, scrubbing, parallax, scroll-driven, gsap
|
|
5
|
-
load_when: gsap-animator active
|
|
6
|
-
---
|
|
7
|
-
|
|
8
1
|
# GSAP ScrollTrigger — Next.js
|
|
9
2
|
|
|
3
|
+
> **Scope:** frontend-nextjs-gsap
|
|
4
|
+
> **Layer:** 3
|
|
5
|
+
> **Keywords:** scrolltrigger, scroll-animation, pinning, scrubbing, parallax, scroll-driven, gsap
|
|
6
|
+
> **Load When:** gsap-animator active
|
|
7
|
+
|
|
8
|
+
**Verified against:** GSAP 3.13 ScrollTrigger + @gsap/react. Last-verified: 2026-05-20.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
10
12
|
Reference guide for implementing scroll-driven animations in Next.js projects using GSAP ScrollTrigger. Covers plugin setup, scrubbing, pinning, batch processing, responsive breakpoints, SSR considerations, and mandatory cleanup patterns.
|
|
11
13
|
|
|
12
14
|
---
|
|
@@ -1,123 +1,127 @@
|
|
|
1
|
-
# Next.js App Router Standard
|
|
2
|
-
|
|
3
|
-
> **Scope:** frontend/nextjs/app-router
|
|
4
|
-
> **Layer:** 2 (on keyword)
|
|
5
|
-
> **Keywords:** next.js, app router, server component, client component, page, layout, route
|
|
6
|
-
> **Load When:** editing files in `app/` or `features/` directories
|
|
7
|
-
|
|
8
|
-
Next.js
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- ALWAYS
|
|
17
|
-
- ALWAYS
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
|
26
|
-
|
|
27
|
-
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
├──
|
|
49
|
-
│
|
|
50
|
-
│
|
|
51
|
-
│
|
|
52
|
-
|
|
53
|
-
│
|
|
54
|
-
│
|
|
55
|
-
│
|
|
56
|
-
│
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
|
67
|
-
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
1
|
+
# Next.js App Router Standard
|
|
2
|
+
|
|
3
|
+
> **Scope:** frontend/nextjs/app-router
|
|
4
|
+
> **Layer:** 2 (on keyword)
|
|
5
|
+
> **Keywords:** next.js, app router, server component, client component, page, layout, route
|
|
6
|
+
> **Load When:** editing files in `app/` or `features/` directories
|
|
7
|
+
|
|
8
|
+
**Verified against:** Next.js 15. Last-verified: 2026-05-20.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Next.js App Router with TypeScript strict mode. Server Components by default, Client Components only when interactivity is required.
|
|
13
|
+
|
|
14
|
+
## Core Rules
|
|
15
|
+
|
|
16
|
+
- ALWAYS default to Server Components — add `'use client'` only when needed
|
|
17
|
+
- ALWAYS keep `app/` directory for routing only — no business logic in page files
|
|
18
|
+
- NEVER put data fetching in Client Components when a Server Component can do it
|
|
19
|
+
- NEVER use `useEffect` to fetch data — use Server Components or TanStack Query
|
|
20
|
+
- ALWAYS co-locate loading/error UI: `loading.tsx`, `error.tsx` next to `page.tsx`
|
|
21
|
+
- ALWAYS use TypeScript — no `.js` or `.jsx` files in the project
|
|
22
|
+
|
|
23
|
+
## Server vs Client Components
|
|
24
|
+
|
|
25
|
+
| Use Server Component | Use Client Component |
|
|
26
|
+
|---------------------|---------------------|
|
|
27
|
+
| Fetching from .NET API on load | onClick, onChange, form submit |
|
|
28
|
+
| Rendering static or user-specific data | useState, useEffect, useRef |
|
|
29
|
+
| Accessing backend environment variables | Browser APIs (localStorage, geolocation) |
|
|
30
|
+
| SEO-critical content | TanStack Query hooks |
|
|
31
|
+
| No interactivity needed | shadcn/ui interactive components |
|
|
32
|
+
|
|
33
|
+
## Decision Tree
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Does this component need user interaction (click, input, hover state)?
|
|
37
|
+
YES → 'use client'
|
|
38
|
+
NO → Does it fetch data?
|
|
39
|
+
YES → Server Component (fetch directly)
|
|
40
|
+
NO → Server Component (static)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## App Directory Structure
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
src/app/
|
|
47
|
+
├── (auth)/
|
|
48
|
+
│ ├── login/
|
|
49
|
+
│ │ └── page.tsx # Server Component — renders login form
|
|
50
|
+
│ └── register/
|
|
51
|
+
│ └── page.tsx
|
|
52
|
+
├── (dashboard)/
|
|
53
|
+
│ ├── layout.tsx # Shared layout for dashboard routes
|
|
54
|
+
│ ├── page.tsx # Dashboard home
|
|
55
|
+
│ └── users/
|
|
56
|
+
│ ├── page.tsx # User list (Server Component)
|
|
57
|
+
│ ├── [id]/
|
|
58
|
+
│ │ └── page.tsx # User detail
|
|
59
|
+
│ ├── loading.tsx # Suspense fallback
|
|
60
|
+
│ └── error.tsx # Error boundary
|
|
61
|
+
└── layout.tsx # Root layout — providers, fonts, metadata
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## File Conventions
|
|
65
|
+
|
|
66
|
+
| File | Purpose | Type |
|
|
67
|
+
|------|---------|------|
|
|
68
|
+
| `page.tsx` | Route segment UI | Server Component (default) |
|
|
69
|
+
| `layout.tsx` | Shared UI wrapper | Server Component |
|
|
70
|
+
| `loading.tsx` | Suspense fallback | Server Component |
|
|
71
|
+
| `error.tsx` | Error boundary | **Must be Client Component** |
|
|
72
|
+
| `not-found.tsx` | 404 page | Server Component |
|
|
73
|
+
| `route.ts` | API route (avoid — use .NET API) | — |
|
|
74
|
+
|
|
75
|
+
## Server Component Data Fetch Pattern
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
// app/(dashboard)/users/page.tsx
|
|
79
|
+
import { UserList } from '@/features/users/components/user-list';
|
|
80
|
+
|
|
81
|
+
async function getUsers(): Promise<User[]> {
|
|
82
|
+
const res = await fetch(`${process.env.API_URL}/api/users`, {
|
|
83
|
+
next: { revalidate: 60 },
|
|
84
|
+
});
|
|
85
|
+
if (!res.ok) throw new Error('Failed to fetch users');
|
|
86
|
+
return res.json();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default async function UsersPage() {
|
|
90
|
+
const users = await getUsers();
|
|
91
|
+
return <UserList initialUsers={users} />;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Root Layout — Required Providers
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
// app/layout.tsx
|
|
99
|
+
import { QueryProvider } from '@/lib/query-client';
|
|
100
|
+
import { Toaster } from '@/components/ui/sonner';
|
|
101
|
+
|
|
102
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
103
|
+
return (
|
|
104
|
+
<html lang="pt-BR">
|
|
105
|
+
<body>
|
|
106
|
+
<QueryProvider>
|
|
107
|
+
{children}
|
|
108
|
+
<Toaster />
|
|
109
|
+
</QueryProvider>
|
|
110
|
+
</body>
|
|
111
|
+
</html>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Common Mistakes
|
|
117
|
+
|
|
118
|
+
| Wrong | Right | Why |
|
|
119
|
+
|-------|-------|-----|
|
|
120
|
+
| `'use client'` on every component | Only add when needed | Kills SSR benefits, bloats JS bundle |
|
|
121
|
+
| `useEffect(() => { fetch(...) }, [])` | Server Component fetch or TanStack Query | Two renders, no caching, no SSR |
|
|
122
|
+
| Business logic in `page.tsx` | Move to `features/` | pages are routes, not controllers |
|
|
123
|
+
| `fetch` without error handling | Always check `res.ok` | Silent failures in production |
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
*MORPH-SPEC by Polymorphism Tech*
|