specifica-br 1.2.2 → 1.5.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 +114 -44
- package/dist/boilerplate/commands/executar-task.md +133 -0
- package/dist/boilerplate/commands/gerar-contexto.md +1462 -0
- package/dist/boilerplate/commands/gerar-prd.md +289 -0
- package/dist/boilerplate/commands/gerar-tasks.md +168 -0
- package/dist/boilerplate/commands/gerar-techspec.md +1467 -0
- package/dist/boilerplate/commands/gerar-visao.md +731 -0
- package/dist/boilerplate/commands/realizar-codereview.md +288 -0
- package/dist/boilerplate/opencode-commands/executar-task.md +55 -48
- package/dist/boilerplate/opencode-commands/gerar-contexto.md +1462 -0
- package/dist/boilerplate/opencode-commands/gerar-prd.md +232 -40
- package/dist/boilerplate/opencode-commands/gerar-tasks.md +112 -31
- package/dist/boilerplate/opencode-commands/gerar-techspec.md +1464 -80
- package/dist/boilerplate/opencode-commands/gerar-visao.md +731 -0
- package/dist/boilerplate/opencode-commands/realizar-codereview.md +288 -0
- package/dist/boilerplate/skills/product-manager/SKILL.md +32 -0
- package/dist/boilerplate/skills/techspec-generator/SKILL.md +489 -0
- package/dist/boilerplate/skills/techspec-generator/references/api-contracts.md +421 -0
- package/dist/boilerplate/skills/techspec-generator/references/architecture-patterns.md +316 -0
- package/dist/boilerplate/skills/techspec-generator/references/database-modeling.md +436 -0
- package/dist/boilerplate/skills/techspec-generator/references/observability-testing.md +436 -0
- package/dist/boilerplate/skills/techspec-generator/references/security-hardening.md +238 -0
- package/dist/boilerplate/skills/techspec-generator/references/ux-ui-accessibility.md +511 -0
- package/dist/boilerplate/specs-templates/architecture-template.md +736 -0
- package/dist/boilerplate/specs-templates/codereview-template.md +95 -0
- package/dist/boilerplate/specs-templates/prd-template.md +101 -19
- package/dist/boilerplate/specs-templates/product_vision-template.md +284 -0
- package/dist/boilerplate/specs-templates/task-template.md +64 -18
- package/dist/boilerplate/specs-templates/tasks-template.md +12 -4
- package/dist/boilerplate/specs-templates/techspec-template.md +1227 -89
- package/dist/boilerplate/templates/architecture-template.md +736 -0
- package/dist/boilerplate/templates/codereview-template.md +95 -0
- package/dist/boilerplate/templates/prd-template.md +167 -0
- package/dist/boilerplate/templates/product_vision-template.md +284 -0
- package/dist/boilerplate/templates/task-template.md +169 -0
- package/dist/boilerplate/templates/tasks-template.md +15 -0
- package/dist/boilerplate/templates/techspec-template.md +1306 -0
- package/dist/commands/help.js +33 -11
- package/dist/commands/init.js +39 -43
- package/dist/tools-mapping.json +32 -0
- package/dist/types/init.d.ts +14 -17
- package/dist/utils/file-service.d.ts +5 -3
- package/dist/utils/file-service.js +168 -56
- package/dist/utils/message-formatter.d.ts +2 -1
- package/dist/utils/message-formatter.js +39 -22
- package/package.json +1 -1
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
# Modelagem de Banco de Dados
|
|
2
|
+
|
|
3
|
+
Referência técnica para modelagem de dados ao gerar Tech Specs.
|
|
4
|
+
|
|
5
|
+
## Sumário
|
|
6
|
+
|
|
7
|
+
1. [Princípios de Modelagem](#1-principios-de-modelagem)
|
|
8
|
+
2. [Tipos de Dados Específicos](#2-tipos-de-dados-especificos)
|
|
9
|
+
3. [Chaves Primárias e Estratégias](#3-chaves-primarias-e-estrategias)
|
|
10
|
+
4. [Chaves Estrangeiras e Relacionamentos](#4-chaves-estrangeiras-e-relacionamentos)
|
|
11
|
+
5. [Índices](#5-indices)
|
|
12
|
+
6. [Constraints e Integridade](#6-constraints-e-integridade)
|
|
13
|
+
7. [Migrations](#7-migrations)
|
|
14
|
+
8. [Padrões Avançados](#8-padroes-avancados)
|
|
15
|
+
9. [ORM Mapping](#9-orm-mapping)
|
|
16
|
+
10. [Checklist de Modelagem](#9-checklist-de-modelagem)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. Princípios de Modelagem
|
|
21
|
+
|
|
22
|
+
### 1.1. Normalização
|
|
23
|
+
|
|
24
|
+
Aplicar conforme complexidade do domínio:
|
|
25
|
+
|
|
26
|
+
| Forma Normal | Regra | Exemplo de Violação |
|
|
27
|
+
|:---|:---|:---|
|
|
28
|
+
| **1NF** | Valores atômicos, sem arrays | Coluna "tags": "java,spring,api" |
|
|
29
|
+
| **2NF** | Sem dependências parciais | PK composta (order_id, item_id) mas nome_do_produto depende só de item_id |
|
|
30
|
+
| **3NF** | Sem dependências transitivas | customer_name em Order (depende de customer_id) |
|
|
31
|
+
| **BCNF** | Cada determinante é chave candidata | Manager → Department, mas Department → Manager também |
|
|
32
|
+
|
|
33
|
+
### 1.2. Denormalização Estratégica
|
|
34
|
+
|
|
35
|
+
**Quando denormalizar (e documentar justificativa):**
|
|
36
|
+
- Performance de leitura crítica (ex: total calculado em vez de sum())
|
|
37
|
+
- Dados históricos que não mudam (ex: preço no momento da compra)
|
|
38
|
+
- Reduzir JOINs em queries frequentes (ex: customer_name em Order para listagem)
|
|
39
|
+
|
|
40
|
+
**Sempre documentar:**
|
|
41
|
+
```
|
|
42
|
+
Denormalização: customer_name em orders
|
|
43
|
+
Justificativa: Listagem de pedidos evita JOIN com users table (query mais frequente)
|
|
44
|
+
Atualização: Trigger ou Application Event quando customer muda nome
|
|
45
|
+
Consistência: Eventual (aceitável para display)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 1.3. Nomenclatura
|
|
49
|
+
|
|
50
|
+
**Verificar padrão do projeto antes de decidir:**
|
|
51
|
+
|
|
52
|
+
| Elemento | snake_case | PascalCase | camelCase |
|
|
53
|
+
|:---|:---|:---|:---|
|
|
54
|
+
| Tabelas | orders, order_items | Orders, OrderItems | orders, orderItems |
|
|
55
|
+
| Colunas | created_at, user_id | CreatedAt, UserId | createdAt, userId |
|
|
56
|
+
| PK | id | Id | id |
|
|
57
|
+
| FK | user_id | UserId | userId |
|
|
58
|
+
| Índice | idx_orders_user_id | IX_Orders_UserId | idx_orders_userId |
|
|
59
|
+
|
|
60
|
+
**Sempre alinhar com padrão existente no projeto.**
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 2. Tipos de Dados Específicos
|
|
65
|
+
|
|
66
|
+
### 2.1. Strings
|
|
67
|
+
|
|
68
|
+
| Tipo | Quando usar | Tamanho |
|
|
69
|
+
|:---|:---|:---|
|
|
70
|
+
| `VARCHAR(N)` | Texto com tamanho conhecido | email: 255, nome: 100, telefone: 20 |
|
|
71
|
+
| `TEXT` | Texto sem limite definido | descrição, comentário |
|
|
72
|
+
| `CHAR(N)` | Tamanho fixo | CEP: CHAR(8), UF: CHAR(2) |
|
|
73
|
+
| `UUID` | Identificadores únicos | `UUID` ou `VARCHAR(36)` dependendo do banco |
|
|
74
|
+
|
|
75
|
+
**Na TechSpec, sempre especificar tamanho:**
|
|
76
|
+
```
|
|
77
|
+
email (VARCHAR(255), Not Null): Email do usuário
|
|
78
|
+
description (TEXT, Nullable): Descrição opcional do pedido
|
|
79
|
+
zip_code (CHAR(8), Not Null): CEP sem formatação
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 2.2. Numéricos
|
|
83
|
+
|
|
84
|
+
| Tipo | Quando usar | Precisão |
|
|
85
|
+
|:---|:---|:---|
|
|
86
|
+
| `DECIMAL(P,S)` | Valores monetários | DECIMAL(10,2) para até 99.999.999,99 |
|
|
87
|
+
| `INTEGER` | Contadores, quantidades | INT para valores até ~2 bilhões |
|
|
88
|
+
| `BIGINT` | IDs de alta escala, timestamps | Para tabelas com milhões de registros |
|
|
89
|
+
| `SMALLINT` | Enums numéricos | Para status com poucos valores |
|
|
90
|
+
| `SERIAL` / `BIGSERIAL` | Auto-incremento | PK auto-incrementada (PostgreSQL) |
|
|
91
|
+
| `FLOAT` / `DOUBLE` | Científico, NÃO usar para dinheiro | - |
|
|
92
|
+
|
|
93
|
+
**Regra: NUNCA usar FLOAT para valores monetários.**
|
|
94
|
+
|
|
95
|
+
### 2.3. Temporais
|
|
96
|
+
|
|
97
|
+
| Tipo | Quando usar |
|
|
98
|
+
|:---|:---|
|
|
99
|
+
| `TIMESTAMP` / `TIMESTAMPTZ` | created_at, updated_at (com timezone) |
|
|
100
|
+
| `DATE` | birth_date, due_date (sem horário) |
|
|
101
|
+
| `TIME` | horário de funcionamento |
|
|
102
|
+
| `INTERVAL` | duração |
|
|
103
|
+
|
|
104
|
+
**Padrão de auditoria:**
|
|
105
|
+
```
|
|
106
|
+
created_at (TIMESTAMPTZ, Not Null, Default: NOW()): Momento de criação
|
|
107
|
+
updated_at (TIMESTAMPTZ, Nullable): Última atualização
|
|
108
|
+
deleted_at (TIMESTAMPTZ, Nullable): Soft delete (se aplicável)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 2.4. Booleanos
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
is_active (BOOLEAN, Not Null, Default: true): Registro ativo
|
|
115
|
+
is_verified (BOOLEAN, Not Null, Default: false): Verificação pendente
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 2.5. JSON
|
|
119
|
+
|
|
120
|
+
**Quando usar:**
|
|
121
|
+
- Dados semi-estruturados que variam (ex: metadata, configurações)
|
|
122
|
+
- Dados que não precisam de queries por campo interno
|
|
123
|
+
|
|
124
|
+
**Quando NÃO usar:**
|
|
125
|
+
- Dados que são consultados frequentemente por campos internos
|
|
126
|
+
- Dados que têm relacionamentos
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
metadata (JSONB, Nullable): Metadados flexíveis da ordem
|
|
130
|
+
Exemplo: { "source": "mobile", "campaign": "summer2024" }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 3. Chaves Primárias e Estratégias
|
|
136
|
+
|
|
137
|
+
### 3.1. Estratégias de PK
|
|
138
|
+
|
|
139
|
+
| Estratégia | Vantagens | Desvantagens | Quando usar |
|
|
140
|
+
|:---|:---|:---|:---|
|
|
141
|
+
| **UUID v4** | Globalmente único, não sequencial | 36 chars, indexação menos eficiente | Distribuído, APIs públicas |
|
|
142
|
+
| **UUID v7** | Ordenável por tempo, único | Mais novo, menos suporte | Melhor que v4 para indexação |
|
|
143
|
+
| **SERIAL/BIGSERIAL** | Eficiente, sequencial | Sequencial (expõe volume) | Sistemas monolíticos |
|
|
144
|
+
| **ULID** | Ordenável, único | Menos comum | Quando precisa ordenação + unicidade |
|
|
145
|
+
|
|
146
|
+
### 3.2. Especificação na TechSpec
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
PK Strategy: UUID v4 com gen_random_uuid()
|
|
150
|
+
Justificativa: Padrão do projeto (conforme AGENTS.md)
|
|
151
|
+
ORM: Prisma @id @default(uuid())
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 4. Chaves Estrangeiras e Relacionamentos
|
|
157
|
+
|
|
158
|
+
### 4.1. Padrões de FK
|
|
159
|
+
|
|
160
|
+
| Relacionamento | Tabela A | Tabela B | FK Location |
|
|
161
|
+
|:---|:---|:---|:---|
|
|
162
|
+
| 1:1 | User | UserProfile | user_id em UserProfile (Unique) |
|
|
163
|
+
| 1:N | User | Order | user_id em Order |
|
|
164
|
+
| N:N | User | Role | user_id + role_id em user_roles (junction) |
|
|
165
|
+
|
|
166
|
+
### 4.2. Comportamento de Delete
|
|
167
|
+
|
|
168
|
+
| Comportamento | Quando usar | Exemplo |
|
|
169
|
+
|:---|:---|:---|
|
|
170
|
+
| `ON DELETE CASCADE` | Filhos não fazem sentido sem pai | OrderItem quando Order é deletada |
|
|
171
|
+
| `ON DELETE RESTRICT` | Proteger dados referenciados | User com Orders existentes |
|
|
172
|
+
| `ON DELETE SET NULL` | Referência opcional | assigned_to quando User é deletado |
|
|
173
|
+
| `ON DELETE SET DEFAULT` | Valor padrão quando referência some | status → default status |
|
|
174
|
+
|
|
175
|
+
### 4.3. Especificação de Relacionamento
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
Order → User (N:1)
|
|
179
|
+
FK: user_id (UUID, Not Null, Indexed) REFERENCES users(id) ON DELETE RESTRICT
|
|
180
|
+
|
|
181
|
+
Order → OrderItem (1:N)
|
|
182
|
+
FK em OrderItem: order_id (UUID, Not Null) REFERENCES orders(id) ON DELETE CASCADE
|
|
183
|
+
|
|
184
|
+
User ↔ Role (N:N)
|
|
185
|
+
Junction: user_roles (user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
|
186
|
+
role_id UUID REFERENCES roles(id) ON DELETE CASCADE)
|
|
187
|
+
PK Composta: (user_id, role_id)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## 5. Índices
|
|
193
|
+
|
|
194
|
+
### 5.1. Tipos de Índice
|
|
195
|
+
|
|
196
|
+
| Tipo | Quando usar | Banco |
|
|
197
|
+
|:---|:---|:---|
|
|
198
|
+
| **B-tree** (default) | Igualdade, range, ordenação | Todos |
|
|
199
|
+
| **Hash** | Apenas igualdade exata | PostgreSQL |
|
|
200
|
+
| **GIN** | Full-text search, JSONB, arrays | PostgreSQL |
|
|
201
|
+
| **GiST** | Dados geoespaciais, range | PostgreSQL |
|
|
202
|
+
| **Partial** | Subset de dados | PostgreSQL, MySQL 8+ |
|
|
203
|
+
| **Composite** | Múltiplas colunas na mesma query | Todos |
|
|
204
|
+
| **Covering** | Query inteira resolvida pelo índice | PostgreSQL 11+, SQL Server |
|
|
205
|
+
|
|
206
|
+
### 5.2. Quando Criar Índices
|
|
207
|
+
|
|
208
|
+
**SEMPRE criar índice para:**
|
|
209
|
+
- Chaves estrangeiras (FK)
|
|
210
|
+
- Colunas em WHERE frequentes
|
|
211
|
+
- Colunas em ORDER BY
|
|
212
|
+
- Colunas em JOIN
|
|
213
|
+
|
|
214
|
+
**NUNCA criar índice para:**
|
|
215
|
+
- Tabelas pequenas (< 1000 registros)
|
|
216
|
+
- Colunas com baixa seletividade (booleano, status com 2-3 valores)
|
|
217
|
+
- Colunas que mudam frequentemente (write-heavy)
|
|
218
|
+
|
|
219
|
+
### 5.3. Especificação de Índice
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
Indexes:
|
|
223
|
+
- idx_orders_user_id ON orders(user_id) -- FK index, listagem por usuário
|
|
224
|
+
- idx_orders_status ON orders(status) -- Filtro por status
|
|
225
|
+
- idx_orders_created_at ON orders(created_at DESC) -- Ordenação por data
|
|
226
|
+
- idx_orders_user_status ON orders(user_id, status) -- Composite: user + status
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Sempre justificar: "qual query este índice otimiza?"**
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 6. Constraints e Integridade
|
|
234
|
+
|
|
235
|
+
### 6.1. Constraints Comuns
|
|
236
|
+
|
|
237
|
+
```sql
|
|
238
|
+
-- Unique
|
|
239
|
+
CONSTRAINT uq_users_email UNIQUE (email)
|
|
240
|
+
|
|
241
|
+
-- Check
|
|
242
|
+
CONSTRAINT chk_orders_total CHECK (total_amount >= 0)
|
|
243
|
+
CONSTRAINT chk_orders_quantity CHECK (quantity > 0)
|
|
244
|
+
CONSTRAINT chk_users_age CHECK (birth_date <= CURRENT_DATE - INTERVAL '18 years')
|
|
245
|
+
|
|
246
|
+
-- Not Null (explícito)
|
|
247
|
+
total_amount DECIMAL(10,2) NOT NULL
|
|
248
|
+
status VARCHAR(50) NOT NULL DEFAULT 'PENDING'
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 6.2. Enum vs VARCHAR
|
|
252
|
+
|
|
253
|
+
| Abordagem | Vantagens | Desvantagens |
|
|
254
|
+
|:---|:---|:---|
|
|
255
|
+
| **ENUM** | Validação no banco, eficiente | Adicionar valor requer ALTER TYPE |
|
|
256
|
+
| **VARCHAR + CHECK** | Flexível, fácil migração | Sem validação automática |
|
|
257
|
+
| **Lookup table** | Extensível sem migration | JOIN necessário |
|
|
258
|
+
|
|
259
|
+
**Recomendação:** Seguir padrão do projeto. Se não definido, VARCHAR com CHECK para enums estáveis, lookup table para enums dinâmicos.
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## 7. Migrations
|
|
264
|
+
|
|
265
|
+
### 7.1. Padrões de Nomenclatura
|
|
266
|
+
|
|
267
|
+
| Ferramenta | Padrão | Exemplo |
|
|
268
|
+
|:---|:---|:---|
|
|
269
|
+
| Prisma | Timestamp automático | `20240301120000_create_orders` |
|
|
270
|
+
| Knex | Timestamp + nome | `20240301120000_create_orders_table.js` |
|
|
271
|
+
| EF Core | Timestamp + nome | `20240301120000_CreateOrdersTable.cs` |
|
|
272
|
+
| Flyway | V{version}__nome | `V1_0_0__create_orders_table.sql` |
|
|
273
|
+
|
|
274
|
+
### 7.2. Conteúdo da Migration na TechSpec
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
Migration: 20240301_create_orders_table.sql
|
|
278
|
+
|
|
279
|
+
UP:
|
|
280
|
+
CREATE TABLE orders (
|
|
281
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
282
|
+
user_id UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
|
|
283
|
+
total_amount DECIMAL(10,2) NOT NULL,
|
|
284
|
+
status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
|
|
285
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
286
|
+
updated_at TIMESTAMPTZ
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
CREATE INDEX idx_orders_user_id ON orders(user_id);
|
|
290
|
+
CREATE INDEX idx_orders_status ON orders(status);
|
|
291
|
+
|
|
292
|
+
DOWN:
|
|
293
|
+
DROP TABLE IF EXISTS orders;
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### 7.3. Seeding
|
|
297
|
+
|
|
298
|
+
**Quando especificar seed:**
|
|
299
|
+
- Dados iniciais necessários (roles, categorias, configurações)
|
|
300
|
+
- Dados de teste/desenvolvimento
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
Seed: prisma/seed.ts
|
|
304
|
+
Dados:
|
|
305
|
+
- 3 roles: ADMIN, MANAGER, CUSTOMER
|
|
306
|
+
- 5 categorias de produto
|
|
307
|
+
- 1 usuário admin (admin@example.com)
|
|
308
|
+
Ferramenta: Faker.js para dados de teste
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## 8. Padrões Avançados
|
|
314
|
+
|
|
315
|
+
### 8.1. Soft Delete
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
deleted_at TIMESTAMPTZ NULLABLE -- NULL = ativo, data = deletado
|
|
319
|
+
|
|
320
|
+
Queries: WHERE deleted_at IS NULL (sempre filtrar)
|
|
321
|
+
ORM: Global filter (Prisma middleware, EF Core query filter)
|
|
322
|
+
Limpeza: Job periódico para hard delete após N dias
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Quando usar:** Dados que podem precisar ser recuperados ou auditoria
|
|
326
|
+
**Quando NÃO usar:** Dados temporários, alta volumetria de delete, LGPD compliance
|
|
327
|
+
|
|
328
|
+
### 8.2. Optimistic Locking
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
version INTEGER NOT NULL DEFAULT 1
|
|
332
|
+
|
|
333
|
+
UPDATE orders SET status = 'PAID', version = version + 1
|
|
334
|
+
WHERE id = ? AND version = ?
|
|
335
|
+
|
|
336
|
+
Se 0 rows affected: concurrency conflict → retry ou erro
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### 8.3. Partitioning
|
|
340
|
+
|
|
341
|
+
```
|
|
342
|
+
-- Partitioning por mês (para tabelas de alta volumetria)
|
|
343
|
+
CREATE TABLE order_events (
|
|
344
|
+
id UUID,
|
|
345
|
+
order_id UUID,
|
|
346
|
+
event_type VARCHAR(50),
|
|
347
|
+
payload JSONB,
|
|
348
|
+
created_at TIMESTAMPTZ
|
|
349
|
+
) PARTITION BY RANGE (created_at);
|
|
350
|
+
|
|
351
|
+
CREATE TABLE order_events_2024_01 PARTITION OF order_events
|
|
352
|
+
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### 8.4. Polimorfismo
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
-- Single Table Inheritance
|
|
359
|
+
payments (
|
|
360
|
+
id UUID,
|
|
361
|
+
type VARCHAR(50), -- 'credit_card', 'pix', 'boleto'
|
|
362
|
+
amount DECIMAL(10,2),
|
|
363
|
+
-- Credit card fields (nullable)
|
|
364
|
+
card_last4 VARCHAR(4),
|
|
365
|
+
-- PIX fields (nullable)
|
|
366
|
+
pix_key VARCHAR(100),
|
|
367
|
+
-- Boleto fields (nullable)
|
|
368
|
+
boleto_barcode VARCHAR(44)
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
-- OU Class Table Inheritance
|
|
372
|
+
payments (id, type, amount)
|
|
373
|
+
credit_card_payments (payment_id FK, card_last4)
|
|
374
|
+
pix_payments (payment_id FK, pix_key)
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## 9. ORM Mapping
|
|
380
|
+
|
|
381
|
+
### 9.1. Prisma
|
|
382
|
+
|
|
383
|
+
```prisma
|
|
384
|
+
model Order {
|
|
385
|
+
id String @id @default(uuid())
|
|
386
|
+
userId String @map("user_id")
|
|
387
|
+
user User @relation(fields: [userId], references: [id], onDelete: Restrict)
|
|
388
|
+
items OrderItem[]
|
|
389
|
+
totalAmount Decimal @map("total_amount") @db.Decimal(10, 2)
|
|
390
|
+
status String @default("PENDING")
|
|
391
|
+
createdAt DateTime @map("created_at") @default(now()) @db.Timestamptz()
|
|
392
|
+
updatedAt DateTime? @map("updated_at") @db.Timestamptz()
|
|
393
|
+
|
|
394
|
+
@@map("orders")
|
|
395
|
+
@@index([userId])
|
|
396
|
+
@@index([status])
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### 9.2. Entity Framework Core
|
|
401
|
+
|
|
402
|
+
```csharp
|
|
403
|
+
public class OrderConfiguration : IEntityTypeConfiguration<Order>
|
|
404
|
+
{
|
|
405
|
+
public void Configure(EntityTypeBuilder<Order> builder)
|
|
406
|
+
{
|
|
407
|
+
builder.ToTable("orders");
|
|
408
|
+
builder.HasKey(o => o.Id);
|
|
409
|
+
builder.Property(o => o.Id).ValueGeneratedOnAdd();
|
|
410
|
+
builder.Property(o => o.TotalAmount).HasColumnType("DECIMAL(10,2)").IsRequired();
|
|
411
|
+
builder.Property(o => o.Status).HasColumnType("VARCHAR(50)").IsRequired().HasDefaultValue("PENDING");
|
|
412
|
+
builder.HasOne(o => o.User).WithMany(u => u.Orders).HasForeignKey(o => o.UserId).OnDelete(DeleteBehavior.Restrict);
|
|
413
|
+
builder.HasIndex(o => o.UserId).HasDatabaseName("idx_orders_user_id");
|
|
414
|
+
builder.HasIndex(o => o.Status).HasDatabaseName("idx_orders_status");
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## 10. Checklist de Modelagem
|
|
422
|
+
|
|
423
|
+
Antes de finalizar a seção de dados na TechSpec, verificar:
|
|
424
|
+
|
|
425
|
+
- [ ] Todas as entidades/tabelas listadas com colunas
|
|
426
|
+
- [ ] Tipos de dados específicos com tamanhos (VARCHAR(255), DECIMAL(10,2))
|
|
427
|
+
- [ ] PK definida com estratégia (UUID, SERIAL, etc.)
|
|
428
|
+
- [ ] Todas as FKs com onDelete behavior
|
|
429
|
+
- [ ] Índices justificados (qual query otimizam)
|
|
430
|
+
- [ ] Constraints de integridade (CHECK, UNIQUE, NOT NULL)
|
|
431
|
+
- [ ] Campos de auditoria (created_at, updated_at)
|
|
432
|
+
- [ ] Soft delete justificado (se aplicável)
|
|
433
|
+
- [ ] Nomenclatura consistente com padrão do projeto
|
|
434
|
+
- [ ] Migration necessária identificada
|
|
435
|
+
- [ ] Seeding necessário documentado
|
|
436
|
+
- [ ] Relacionamentos documentados (1:1, 1:N, N:N)
|