create-genia-os 2.1.0 → 2.2.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 +154 -106
- package/bin/index.js +240 -240
- package/package.json +42 -37
- package/template/.claude/CLAUDE.md +215 -215
- package/template/.claude/agent-memory/analyst/MEMORY.md +20 -20
- package/template/.claude/agent-memory/architect/MEMORY.md +20 -20
- package/template/.claude/agent-memory/dev/MEMORY.md +20 -20
- package/template/.claude/agent-memory/devops/MEMORY.md +20 -20
- package/template/.claude/agent-memory/pm/MEMORY.md +20 -20
- package/template/.claude/agent-memory/po/MEMORY.md +20 -20
- package/template/.claude/agent-memory/qa/MEMORY.md +20 -20
- package/template/.claude/agent-memory/reviewer/MEMORY.md +20 -20
- package/template/.claude/agent-memory/sm/MEMORY.md +20 -20
- package/template/.claude/hooks/enforce-git-push-authority.py +70 -70
- package/template/.claude/hooks/metrics-tracker.cjs +65 -0
- package/template/.claude/hooks/precompact-session-digest.cjs +87 -87
- package/template/.claude/hooks/sql-governance.py +65 -65
- package/template/.claude/hooks/synapse-engine.cjs +122 -122
- package/template/.claude/hooks/write-path-validation.py +59 -59
- package/template/.claude/rules/agent-authority.md +39 -39
- package/template/.claude/rules/agent-handoff.md +71 -71
- package/template/.claude/rules/agent-memory.md +61 -61
- package/template/.claude/rules/ids-principles.md +52 -52
- package/template/.claude/rules/mcp-usage.md +49 -49
- package/template/.claude/rules/new-project.md +157 -0
- package/template/.claude/rules/story-lifecycle.md +87 -87
- package/template/.claude/rules/workflow-execution.md +68 -68
- package/template/.claude/settings.json +58 -58
- package/template/.claude/settings.local.json +14 -14
- package/template/.genia/CONSTITUTION.md +129 -129
- package/template/.genia/contexts/api-patterns.md +134 -134
- package/template/.genia/contexts/nextjs-react.md +210 -210
- package/template/.genia/contexts/projeto.md +18 -18
- package/template/.genia/contexts/supabase.md +152 -152
- package/template/.genia/contexts/whatsapp-cloud.md +176 -176
- package/template/.genia/core-config.yaml +192 -192
- package/template/.genia/development/agents/analyst.md +138 -138
- package/template/.genia/development/agents/architect.md +171 -171
- package/template/.genia/development/agents/dev.md +160 -160
- package/template/.genia/development/agents/devops.md +200 -200
- package/template/.genia/development/agents/pm.md +142 -142
- package/template/.genia/development/agents/po.md +165 -165
- package/template/.genia/development/agents/qa.md +183 -183
- package/template/.genia/development/agents/reviewer.md +198 -198
- package/template/.genia/development/agents/sm.md +230 -230
- package/template/.genia/development/checklists/architecture-review.md +189 -189
- package/template/.genia/development/checklists/pre-commit.md +205 -205
- package/template/.genia/development/checklists/pre-deploy.md +230 -230
- package/template/.genia/development/checklists/qa-gate.md +216 -216
- package/template/.genia/development/checklists/story-dod.md +155 -155
- package/template/.genia/development/tasks/code-review.md +197 -197
- package/template/.genia/development/tasks/criar-prd.md +170 -170
- package/template/.genia/development/tasks/criar-spec.md +188 -188
- package/template/.genia/development/tasks/criar-story.md +185 -185
- package/template/.genia/development/tasks/debug-sistematico.md +230 -230
- package/template/.genia/development/tasks/dev-implement.md +199 -199
- package/template/.genia/development/tasks/qa-review.md +224 -224
- package/template/.genia/development/workflows/brownfield.md +178 -178
- package/template/.genia/development/workflows/delivery.md +208 -208
- package/template/.genia/development/workflows/development.md +189 -189
- package/template/.genia/development/workflows/greenfield.md +166 -166
- package/template/.genia/development/workflows/planning.md +167 -167
- package/template/.genia/development/workflows/qa-loop.md +179 -179
- package/template/.genia/development/workflows/spec-pipeline.md +192 -192
- package/template/.genia/development/workflows/story-development-cycle.md +252 -252
- package/template/.genia/guidelines/clean-code.md +98 -98
- package/template/.genia/guidelines/testing.md +176 -176
- package/template/.genia/skills/design/canvas-design.md +109 -109
- package/template/.genia/skills/design/frontend-design.md +140 -140
- package/template/.genia/skills/dev/mcp-builder.md +172 -172
- package/template/.genia/skills/dev/webapp-testing.md +150 -150
- package/template/.genia/skills/documents/docx.md +153 -153
- package/template/.genia/skills/documents/pdf.md +134 -134
- package/template/.genia/skills/documents/pptx.md +118 -118
- package/template/.genia/skills/documents/xlsx.md +140 -140
- package/template/.synapse/agent-analyst +8 -8
- package/template/.synapse/agent-architect +8 -8
- package/template/.synapse/agent-dev +8 -8
- package/template/.synapse/agent-devops +8 -8
- package/template/.synapse/agent-pm +8 -8
- package/template/.synapse/agent-po +7 -7
- package/template/.synapse/agent-qa +8 -8
- package/template/.synapse/agent-reviewer +7 -7
- package/template/.synapse/agent-sm +7 -7
- package/template/.synapse/constitution +7 -7
- package/template/.synapse/context +8 -8
- package/template/.synapse/global +8 -8
- package/template/.synapse/manifest +14 -14
- package/template/README.md +53 -53
|
@@ -1,134 +1,134 @@
|
|
|
1
|
-
# Contexto: API Patterns
|
|
2
|
-
|
|
3
|
-
> Principios de design de API e tomada de decisao.
|
|
4
|
-
|
|
5
|
-
## Mapa de Conteudo
|
|
6
|
-
|
|
7
|
-
| Topico | Quando Usar |
|
|
8
|
-
|--------|-------------|
|
|
9
|
-
| REST vs GraphQL vs tRPC | Escolher tipo de API |
|
|
10
|
-
| Resource naming, HTTP methods | Design REST |
|
|
11
|
-
| Envelope pattern, error format | Estrutura de resposta |
|
|
12
|
-
| Schema design | GraphQL |
|
|
13
|
-
| Type safety | TS fullstack |
|
|
14
|
-
|
|
15
|
-
## Arvore de Decisao: Escolher Tipo de API
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
Projeto → TypeScript monorepo?
|
|
19
|
-
├── Sim → tRPC (type safety end-to-end)
|
|
20
|
-
│
|
|
21
|
-
└── Nao → Clientes diversos?
|
|
22
|
-
├── Sim → REST (universal, cacheable)
|
|
23
|
-
│
|
|
24
|
-
└── Nao → Queries complexas?
|
|
25
|
-
├── Sim → GraphQL (flexivel, self-documenting)
|
|
26
|
-
└── Nao → REST (simples, padrao da industria)
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## REST Design
|
|
30
|
-
|
|
31
|
-
### Naming de Recursos
|
|
32
|
-
```
|
|
33
|
-
GET /users # Lista
|
|
34
|
-
GET /users/{id} # Detalhe
|
|
35
|
-
POST /users # Criar
|
|
36
|
-
PUT /users/{id} # Atualizar (completo)
|
|
37
|
-
PATCH /users/{id} # Atualizar (parcial)
|
|
38
|
-
DELETE /users/{id} # Remover
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Status Codes
|
|
42
|
-
| Code | Uso |
|
|
43
|
-
|------|-----|
|
|
44
|
-
| 200 | OK - Sucesso |
|
|
45
|
-
| 201 | Created - Recurso criado |
|
|
46
|
-
| 204 | No Content - Deletado |
|
|
47
|
-
| 400 | Bad Request - Input invalido |
|
|
48
|
-
| 401 | Unauthorized - Nao autenticado |
|
|
49
|
-
| 403 | Forbidden - Sem permissao |
|
|
50
|
-
| 404 | Not Found - Recurso nao existe |
|
|
51
|
-
| 422 | Unprocessable - Validacao falhou |
|
|
52
|
-
| 500 | Internal Error - Erro do servidor |
|
|
53
|
-
|
|
54
|
-
## Formato de Resposta
|
|
55
|
-
|
|
56
|
-
### Sucesso
|
|
57
|
-
```json
|
|
58
|
-
{
|
|
59
|
-
"data": { ... },
|
|
60
|
-
"meta": {
|
|
61
|
-
"pagination": { "page": 1, "total": 100 }
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Erro
|
|
67
|
-
```json
|
|
68
|
-
{
|
|
69
|
-
"error": {
|
|
70
|
-
"code": "VALIDATION_ERROR",
|
|
71
|
-
"message": "Email invalido",
|
|
72
|
-
"details": [
|
|
73
|
-
{ "field": "email", "message": "Formato invalido" }
|
|
74
|
-
]
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Paginacao
|
|
80
|
-
|
|
81
|
-
### Offset-based
|
|
82
|
-
```
|
|
83
|
-
GET /users?page=2&limit=20
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Cursor-based (recomendado para grandes volumes)
|
|
87
|
-
```
|
|
88
|
-
GET /users?cursor=abc123&limit=20
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Versionamento
|
|
92
|
-
|
|
93
|
-
| Metodo | Exemplo | Uso |
|
|
94
|
-
|--------|---------|-----|
|
|
95
|
-
| URI | `/v1/users` | Mais comum, facil |
|
|
96
|
-
| Header | `Accept: application/vnd.api.v1+json` | Mais limpo |
|
|
97
|
-
| Query | `/users?version=1` | Nao recomendado |
|
|
98
|
-
|
|
99
|
-
## Autenticacao
|
|
100
|
-
|
|
101
|
-
| Metodo | Quando Usar |
|
|
102
|
-
|--------|-------------|
|
|
103
|
-
| JWT | SPAs, mobile apps |
|
|
104
|
-
| API Keys | Servicos, integracao |
|
|
105
|
-
| OAuth 2.0 | Login social, terceiros |
|
|
106
|
-
| Session | Apps tradicionais |
|
|
107
|
-
|
|
108
|
-
## Rate Limiting
|
|
109
|
-
|
|
110
|
-
### Headers de Resposta
|
|
111
|
-
```
|
|
112
|
-
X-RateLimit-Limit: 100
|
|
113
|
-
X-RateLimit-Remaining: 95
|
|
114
|
-
X-RateLimit-Reset: 1640995200
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Anti-Patterns
|
|
118
|
-
|
|
119
|
-
| NAO Fazer | Fazer |
|
|
120
|
-
|-----------|-------|
|
|
121
|
-
| `/getUsers` | `GET /users` |
|
|
122
|
-
| `/createUser` | `POST /users` |
|
|
123
|
-
| Retornar 200 para erros | Usar status codes corretos |
|
|
124
|
-
| Expor erros internos | Mensagens genericas |
|
|
125
|
-
| Pular rate limiting | Sempre limitar |
|
|
126
|
-
|
|
127
|
-
## Checklist
|
|
128
|
-
|
|
129
|
-
- [ ] Escolhi estilo de API para o contexto?
|
|
130
|
-
- [ ] Formato de resposta consistente?
|
|
131
|
-
- [ ] Estrategia de versionamento?
|
|
132
|
-
- [ ] Autenticacao definida?
|
|
133
|
-
- [ ] Rate limiting planejado?
|
|
134
|
-
- [ ] Documentacao (OpenAPI)?
|
|
1
|
+
# Contexto: API Patterns
|
|
2
|
+
|
|
3
|
+
> Principios de design de API e tomada de decisao.
|
|
4
|
+
|
|
5
|
+
## Mapa de Conteudo
|
|
6
|
+
|
|
7
|
+
| Topico | Quando Usar |
|
|
8
|
+
|--------|-------------|
|
|
9
|
+
| REST vs GraphQL vs tRPC | Escolher tipo de API |
|
|
10
|
+
| Resource naming, HTTP methods | Design REST |
|
|
11
|
+
| Envelope pattern, error format | Estrutura de resposta |
|
|
12
|
+
| Schema design | GraphQL |
|
|
13
|
+
| Type safety | TS fullstack |
|
|
14
|
+
|
|
15
|
+
## Arvore de Decisao: Escolher Tipo de API
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Projeto → TypeScript monorepo?
|
|
19
|
+
├── Sim → tRPC (type safety end-to-end)
|
|
20
|
+
│
|
|
21
|
+
└── Nao → Clientes diversos?
|
|
22
|
+
├── Sim → REST (universal, cacheable)
|
|
23
|
+
│
|
|
24
|
+
└── Nao → Queries complexas?
|
|
25
|
+
├── Sim → GraphQL (flexivel, self-documenting)
|
|
26
|
+
└── Nao → REST (simples, padrao da industria)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## REST Design
|
|
30
|
+
|
|
31
|
+
### Naming de Recursos
|
|
32
|
+
```
|
|
33
|
+
GET /users # Lista
|
|
34
|
+
GET /users/{id} # Detalhe
|
|
35
|
+
POST /users # Criar
|
|
36
|
+
PUT /users/{id} # Atualizar (completo)
|
|
37
|
+
PATCH /users/{id} # Atualizar (parcial)
|
|
38
|
+
DELETE /users/{id} # Remover
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Status Codes
|
|
42
|
+
| Code | Uso |
|
|
43
|
+
|------|-----|
|
|
44
|
+
| 200 | OK - Sucesso |
|
|
45
|
+
| 201 | Created - Recurso criado |
|
|
46
|
+
| 204 | No Content - Deletado |
|
|
47
|
+
| 400 | Bad Request - Input invalido |
|
|
48
|
+
| 401 | Unauthorized - Nao autenticado |
|
|
49
|
+
| 403 | Forbidden - Sem permissao |
|
|
50
|
+
| 404 | Not Found - Recurso nao existe |
|
|
51
|
+
| 422 | Unprocessable - Validacao falhou |
|
|
52
|
+
| 500 | Internal Error - Erro do servidor |
|
|
53
|
+
|
|
54
|
+
## Formato de Resposta
|
|
55
|
+
|
|
56
|
+
### Sucesso
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"data": { ... },
|
|
60
|
+
"meta": {
|
|
61
|
+
"pagination": { "page": 1, "total": 100 }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Erro
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"error": {
|
|
70
|
+
"code": "VALIDATION_ERROR",
|
|
71
|
+
"message": "Email invalido",
|
|
72
|
+
"details": [
|
|
73
|
+
{ "field": "email", "message": "Formato invalido" }
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Paginacao
|
|
80
|
+
|
|
81
|
+
### Offset-based
|
|
82
|
+
```
|
|
83
|
+
GET /users?page=2&limit=20
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Cursor-based (recomendado para grandes volumes)
|
|
87
|
+
```
|
|
88
|
+
GET /users?cursor=abc123&limit=20
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Versionamento
|
|
92
|
+
|
|
93
|
+
| Metodo | Exemplo | Uso |
|
|
94
|
+
|--------|---------|-----|
|
|
95
|
+
| URI | `/v1/users` | Mais comum, facil |
|
|
96
|
+
| Header | `Accept: application/vnd.api.v1+json` | Mais limpo |
|
|
97
|
+
| Query | `/users?version=1` | Nao recomendado |
|
|
98
|
+
|
|
99
|
+
## Autenticacao
|
|
100
|
+
|
|
101
|
+
| Metodo | Quando Usar |
|
|
102
|
+
|--------|-------------|
|
|
103
|
+
| JWT | SPAs, mobile apps |
|
|
104
|
+
| API Keys | Servicos, integracao |
|
|
105
|
+
| OAuth 2.0 | Login social, terceiros |
|
|
106
|
+
| Session | Apps tradicionais |
|
|
107
|
+
|
|
108
|
+
## Rate Limiting
|
|
109
|
+
|
|
110
|
+
### Headers de Resposta
|
|
111
|
+
```
|
|
112
|
+
X-RateLimit-Limit: 100
|
|
113
|
+
X-RateLimit-Remaining: 95
|
|
114
|
+
X-RateLimit-Reset: 1640995200
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Anti-Patterns
|
|
118
|
+
|
|
119
|
+
| NAO Fazer | Fazer |
|
|
120
|
+
|-----------|-------|
|
|
121
|
+
| `/getUsers` | `GET /users` |
|
|
122
|
+
| `/createUser` | `POST /users` |
|
|
123
|
+
| Retornar 200 para erros | Usar status codes corretos |
|
|
124
|
+
| Expor erros internos | Mensagens genericas |
|
|
125
|
+
| Pular rate limiting | Sempre limitar |
|
|
126
|
+
|
|
127
|
+
## Checklist
|
|
128
|
+
|
|
129
|
+
- [ ] Escolhi estilo de API para o contexto?
|
|
130
|
+
- [ ] Formato de resposta consistente?
|
|
131
|
+
- [ ] Estrategia de versionamento?
|
|
132
|
+
- [ ] Autenticacao definida?
|
|
133
|
+
- [ ] Rate limiting planejado?
|
|
134
|
+
- [ ] Documentacao (OpenAPI)?
|
|
@@ -1,210 +1,210 @@
|
|
|
1
|
-
# Contexto: Next.js & React
|
|
2
|
-
|
|
3
|
-
> Patterns de performance e boas praticas para Next.js e React.
|
|
4
|
-
|
|
5
|
-
## Eliminando Waterfalls
|
|
6
|
-
|
|
7
|
-
### Problema: Requests Sequenciais
|
|
8
|
-
```typescript
|
|
9
|
-
// ERRADO - waterfall
|
|
10
|
-
const user = await getUser(id);
|
|
11
|
-
const posts = await getPosts(user.id);
|
|
12
|
-
const comments = await getComments(posts);
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### Solucao: Parallelizar
|
|
16
|
-
```typescript
|
|
17
|
-
// CORRETO - paralelo
|
|
18
|
-
const [user, posts] = await Promise.all([
|
|
19
|
-
getUser(id),
|
|
20
|
-
getPosts(id)
|
|
21
|
-
]);
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Bundle Size Optimization
|
|
25
|
-
|
|
26
|
-
### Code Splitting
|
|
27
|
-
```typescript
|
|
28
|
-
// Dynamic imports
|
|
29
|
-
const HeavyComponent = dynamic(() => import('./Heavy'), {
|
|
30
|
-
loading: () => <Skeleton />
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### Tree Shaking
|
|
35
|
-
```typescript
|
|
36
|
-
// ERRADO - importa tudo
|
|
37
|
-
import _ from 'lodash';
|
|
38
|
-
|
|
39
|
-
// CORRETO - importa so o necessario
|
|
40
|
-
import debounce from 'lodash/debounce';
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Server-Side Performance
|
|
44
|
-
|
|
45
|
-
### Streaming
|
|
46
|
-
```typescript
|
|
47
|
-
// app/page.tsx
|
|
48
|
-
export default function Page() {
|
|
49
|
-
return (
|
|
50
|
-
<main>
|
|
51
|
-
<Header />
|
|
52
|
-
<Suspense fallback={<Loading />}>
|
|
53
|
-
<SlowComponent />
|
|
54
|
-
</Suspense>
|
|
55
|
-
</main>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### Caching
|
|
61
|
-
```typescript
|
|
62
|
-
// Revalidate a cada hora
|
|
63
|
-
export const revalidate = 3600;
|
|
64
|
-
|
|
65
|
-
// Ou fetch com cache
|
|
66
|
-
const data = await fetch(url, {
|
|
67
|
-
next: { revalidate: 3600 }
|
|
68
|
-
});
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Client-Side Data Fetching
|
|
72
|
-
|
|
73
|
-
### SWR ou React Query
|
|
74
|
-
```typescript
|
|
75
|
-
import useSWR from 'swr';
|
|
76
|
-
|
|
77
|
-
function Profile() {
|
|
78
|
-
const { data, error, isLoading } = useSWR('/api/user', fetcher);
|
|
79
|
-
|
|
80
|
-
if (isLoading) return <Loading />;
|
|
81
|
-
if (error) return <Error />;
|
|
82
|
-
return <User data={data} />;
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Re-render Optimization
|
|
87
|
-
|
|
88
|
-
### useMemo para calculos pesados
|
|
89
|
-
```typescript
|
|
90
|
-
const expensiveValue = useMemo(() => {
|
|
91
|
-
return heavyCalculation(data);
|
|
92
|
-
}, [data]);
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### useCallback para funcoes
|
|
96
|
-
```typescript
|
|
97
|
-
const handleClick = useCallback(() => {
|
|
98
|
-
doSomething(id);
|
|
99
|
-
}, [id]);
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### React.memo para componentes
|
|
103
|
-
```typescript
|
|
104
|
-
const Card = React.memo(function Card({ user }) {
|
|
105
|
-
return <div>{user.name}</div>;
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Rendering Performance
|
|
110
|
-
|
|
111
|
-
### Keys corretas
|
|
112
|
-
```typescript
|
|
113
|
-
// ERRADO - index como key
|
|
114
|
-
{items.map((item, i) => <Item key={i} />)}
|
|
115
|
-
|
|
116
|
-
// CORRETO - id unico
|
|
117
|
-
{items.map(item => <Item key={item.id} />)}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### Virtualizacao para listas longas
|
|
121
|
-
```typescript
|
|
122
|
-
import { FixedSizeList } from 'react-window';
|
|
123
|
-
|
|
124
|
-
<FixedSizeList
|
|
125
|
-
height={400}
|
|
126
|
-
itemCount={1000}
|
|
127
|
-
itemSize={35}
|
|
128
|
-
>
|
|
129
|
-
{Row}
|
|
130
|
-
</FixedSizeList>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## JavaScript Performance
|
|
134
|
-
|
|
135
|
-
### Debounce inputs
|
|
136
|
-
```typescript
|
|
137
|
-
const debouncedSearch = useDebouncedCallback(
|
|
138
|
-
(value) => search(value),
|
|
139
|
-
300
|
|
140
|
-
);
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Web Workers para calculos pesados
|
|
144
|
-
```typescript
|
|
145
|
-
const worker = new Worker('/worker.js');
|
|
146
|
-
worker.postMessage(heavyData);
|
|
147
|
-
worker.onmessage = (e) => setResult(e.data);
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## Advanced Patterns
|
|
151
|
-
|
|
152
|
-
### Server Components
|
|
153
|
-
```typescript
|
|
154
|
-
// Componente servidor (default no App Router)
|
|
155
|
-
async function Posts() {
|
|
156
|
-
const posts = await db.posts.findMany(); // Direto no banco!
|
|
157
|
-
return <PostList posts={posts} />;
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Server Actions
|
|
162
|
-
```typescript
|
|
163
|
-
async function submitForm(formData: FormData) {
|
|
164
|
-
'use server';
|
|
165
|
-
await db.users.create({ data: formData });
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Parallel Routes
|
|
170
|
-
```typescript
|
|
171
|
-
// app/@dashboard/page.tsx
|
|
172
|
-
// app/@sidebar/page.tsx
|
|
173
|
-
// Carregam em paralelo
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
## Image Optimization
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
import Image from 'next/image';
|
|
180
|
-
|
|
181
|
-
<Image
|
|
182
|
-
src="/hero.jpg"
|
|
183
|
-
width={1200}
|
|
184
|
-
height={600}
|
|
185
|
-
placeholder="blur"
|
|
186
|
-
priority // Para imagens above-the-fold
|
|
187
|
-
/>
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## Font Optimization
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
import { Inter } from 'next/font/google';
|
|
194
|
-
|
|
195
|
-
const inter = Inter({
|
|
196
|
-
subsets: ['latin'],
|
|
197
|
-
display: 'swap',
|
|
198
|
-
});
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## Checklist de Performance
|
|
202
|
-
|
|
203
|
-
- [ ] Requests em paralelo (Promise.all)?
|
|
204
|
-
- [ ] Code splitting implementado?
|
|
205
|
-
- [ ] Imagens otimizadas (next/image)?
|
|
206
|
-
- [ ] Fontes otimizadas (next/font)?
|
|
207
|
-
- [ ] Caching configurado?
|
|
208
|
-
- [ ] Listas virtualizadas?
|
|
209
|
-
- [ ] Memos apropriados?
|
|
210
|
-
- [ ] Bundle analisado?
|
|
1
|
+
# Contexto: Next.js & React
|
|
2
|
+
|
|
3
|
+
> Patterns de performance e boas praticas para Next.js e React.
|
|
4
|
+
|
|
5
|
+
## Eliminando Waterfalls
|
|
6
|
+
|
|
7
|
+
### Problema: Requests Sequenciais
|
|
8
|
+
```typescript
|
|
9
|
+
// ERRADO - waterfall
|
|
10
|
+
const user = await getUser(id);
|
|
11
|
+
const posts = await getPosts(user.id);
|
|
12
|
+
const comments = await getComments(posts);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Solucao: Parallelizar
|
|
16
|
+
```typescript
|
|
17
|
+
// CORRETO - paralelo
|
|
18
|
+
const [user, posts] = await Promise.all([
|
|
19
|
+
getUser(id),
|
|
20
|
+
getPosts(id)
|
|
21
|
+
]);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Bundle Size Optimization
|
|
25
|
+
|
|
26
|
+
### Code Splitting
|
|
27
|
+
```typescript
|
|
28
|
+
// Dynamic imports
|
|
29
|
+
const HeavyComponent = dynamic(() => import('./Heavy'), {
|
|
30
|
+
loading: () => <Skeleton />
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Tree Shaking
|
|
35
|
+
```typescript
|
|
36
|
+
// ERRADO - importa tudo
|
|
37
|
+
import _ from 'lodash';
|
|
38
|
+
|
|
39
|
+
// CORRETO - importa so o necessario
|
|
40
|
+
import debounce from 'lodash/debounce';
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Server-Side Performance
|
|
44
|
+
|
|
45
|
+
### Streaming
|
|
46
|
+
```typescript
|
|
47
|
+
// app/page.tsx
|
|
48
|
+
export default function Page() {
|
|
49
|
+
return (
|
|
50
|
+
<main>
|
|
51
|
+
<Header />
|
|
52
|
+
<Suspense fallback={<Loading />}>
|
|
53
|
+
<SlowComponent />
|
|
54
|
+
</Suspense>
|
|
55
|
+
</main>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Caching
|
|
61
|
+
```typescript
|
|
62
|
+
// Revalidate a cada hora
|
|
63
|
+
export const revalidate = 3600;
|
|
64
|
+
|
|
65
|
+
// Ou fetch com cache
|
|
66
|
+
const data = await fetch(url, {
|
|
67
|
+
next: { revalidate: 3600 }
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Client-Side Data Fetching
|
|
72
|
+
|
|
73
|
+
### SWR ou React Query
|
|
74
|
+
```typescript
|
|
75
|
+
import useSWR from 'swr';
|
|
76
|
+
|
|
77
|
+
function Profile() {
|
|
78
|
+
const { data, error, isLoading } = useSWR('/api/user', fetcher);
|
|
79
|
+
|
|
80
|
+
if (isLoading) return <Loading />;
|
|
81
|
+
if (error) return <Error />;
|
|
82
|
+
return <User data={data} />;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Re-render Optimization
|
|
87
|
+
|
|
88
|
+
### useMemo para calculos pesados
|
|
89
|
+
```typescript
|
|
90
|
+
const expensiveValue = useMemo(() => {
|
|
91
|
+
return heavyCalculation(data);
|
|
92
|
+
}, [data]);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### useCallback para funcoes
|
|
96
|
+
```typescript
|
|
97
|
+
const handleClick = useCallback(() => {
|
|
98
|
+
doSomething(id);
|
|
99
|
+
}, [id]);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### React.memo para componentes
|
|
103
|
+
```typescript
|
|
104
|
+
const Card = React.memo(function Card({ user }) {
|
|
105
|
+
return <div>{user.name}</div>;
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Rendering Performance
|
|
110
|
+
|
|
111
|
+
### Keys corretas
|
|
112
|
+
```typescript
|
|
113
|
+
// ERRADO - index como key
|
|
114
|
+
{items.map((item, i) => <Item key={i} />)}
|
|
115
|
+
|
|
116
|
+
// CORRETO - id unico
|
|
117
|
+
{items.map(item => <Item key={item.id} />)}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Virtualizacao para listas longas
|
|
121
|
+
```typescript
|
|
122
|
+
import { FixedSizeList } from 'react-window';
|
|
123
|
+
|
|
124
|
+
<FixedSizeList
|
|
125
|
+
height={400}
|
|
126
|
+
itemCount={1000}
|
|
127
|
+
itemSize={35}
|
|
128
|
+
>
|
|
129
|
+
{Row}
|
|
130
|
+
</FixedSizeList>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## JavaScript Performance
|
|
134
|
+
|
|
135
|
+
### Debounce inputs
|
|
136
|
+
```typescript
|
|
137
|
+
const debouncedSearch = useDebouncedCallback(
|
|
138
|
+
(value) => search(value),
|
|
139
|
+
300
|
|
140
|
+
);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Web Workers para calculos pesados
|
|
144
|
+
```typescript
|
|
145
|
+
const worker = new Worker('/worker.js');
|
|
146
|
+
worker.postMessage(heavyData);
|
|
147
|
+
worker.onmessage = (e) => setResult(e.data);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Advanced Patterns
|
|
151
|
+
|
|
152
|
+
### Server Components
|
|
153
|
+
```typescript
|
|
154
|
+
// Componente servidor (default no App Router)
|
|
155
|
+
async function Posts() {
|
|
156
|
+
const posts = await db.posts.findMany(); // Direto no banco!
|
|
157
|
+
return <PostList posts={posts} />;
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Server Actions
|
|
162
|
+
```typescript
|
|
163
|
+
async function submitForm(formData: FormData) {
|
|
164
|
+
'use server';
|
|
165
|
+
await db.users.create({ data: formData });
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Parallel Routes
|
|
170
|
+
```typescript
|
|
171
|
+
// app/@dashboard/page.tsx
|
|
172
|
+
// app/@sidebar/page.tsx
|
|
173
|
+
// Carregam em paralelo
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Image Optimization
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import Image from 'next/image';
|
|
180
|
+
|
|
181
|
+
<Image
|
|
182
|
+
src="/hero.jpg"
|
|
183
|
+
width={1200}
|
|
184
|
+
height={600}
|
|
185
|
+
placeholder="blur"
|
|
186
|
+
priority // Para imagens above-the-fold
|
|
187
|
+
/>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Font Optimization
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { Inter } from 'next/font/google';
|
|
194
|
+
|
|
195
|
+
const inter = Inter({
|
|
196
|
+
subsets: ['latin'],
|
|
197
|
+
display: 'swap',
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Checklist de Performance
|
|
202
|
+
|
|
203
|
+
- [ ] Requests em paralelo (Promise.all)?
|
|
204
|
+
- [ ] Code splitting implementado?
|
|
205
|
+
- [ ] Imagens otimizadas (next/image)?
|
|
206
|
+
- [ ] Fontes otimizadas (next/font)?
|
|
207
|
+
- [ ] Caching configurado?
|
|
208
|
+
- [ ] Listas virtualizadas?
|
|
209
|
+
- [ ] Memos apropriados?
|
|
210
|
+
- [ ] Bundle analisado?
|