spec-first-copilot 0.6.0-beta.9 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +252 -167
  2. package/bin/cli.js +70 -70
  3. package/lib/init.js +92 -92
  4. package/lib/update.js +132 -132
  5. package/package.json +1 -1
  6. package/templates/.ai/memory/napkin.md +68 -68
  7. package/templates/.github/CHANGELOG.md +121 -0
  8. package/templates/.github/adapters/SETUP.md +314 -314
  9. package/templates/.github/adapters/confluence.md +295 -295
  10. package/templates/.github/adapters/errors.md +234 -234
  11. package/templates/.github/adapters/filesystem.md +353 -353
  12. package/templates/.github/adapters/interface.md +301 -301
  13. package/templates/.github/adapters/naming.md +241 -241
  14. package/templates/.github/adapters/registry.md +244 -244
  15. package/templates/.github/agents/backend-coder.md +14 -14
  16. package/templates/.github/agents/db-coder.md +165 -165
  17. package/templates/.github/agents/doc-writer.md +66 -53
  18. package/templates/.github/agents/frontend-coder.md +5 -5
  19. package/templates/.github/agents/infra-coder.md +341 -341
  20. package/templates/.github/agents/reviewer.md +6 -6
  21. package/templates/.github/agents/security-reviewer.md +153 -153
  22. package/templates/.github/copilot-instructions.md +272 -262
  23. package/templates/.github/instructions/docs.instructions.md +147 -145
  24. package/templates/.github/instructions/sensitive-files.instructions.md +32 -32
  25. package/templates/.github/rules.md +229 -229
  26. package/templates/.github/scripts/bootstrap-confluence.js +289 -223
  27. package/templates/.github/skills/sf-design/SKILL.md +161 -216
  28. package/templates/.github/skills/sf-dev/SKILL.md +204 -351
  29. package/templates/.github/skills/sf-discovery/SKILL.md +415 -414
  30. package/templates/.github/skills/sf-extract/SKILL.md +225 -249
  31. package/templates/.github/skills/sf-load/SKILL.md +296 -295
  32. package/templates/.github/skills/sf-mcp/SKILL.md +386 -385
  33. package/templates/.github/skills/sf-merge-docs/SKILL.md +152 -100
  34. package/templates/.github/skills/sf-plan/SKILL.md +152 -128
  35. package/templates/.github/skills/sf-publish/SKILL.md +144 -143
  36. package/templates/.github/skills/sf-session-finish/SKILL.md +93 -120
  37. package/templates/.github/skills/sf-start/SKILL.md +192 -145
  38. package/templates/.github/templates/estrutura/apiContracts.template.md +160 -159
  39. package/templates/.github/templates/estrutura/architecture.template.md +169 -168
  40. package/templates/.github/templates/estrutura/conventions.template.md +214 -212
  41. package/templates/.github/templates/estrutura/decisions.template.md +107 -107
  42. package/templates/.github/templates/estrutura/domain.template.md +161 -160
  43. package/templates/.github/templates/feature/PRD.template.md +279 -286
  44. package/templates/.github/templates/feature/Progresso.template.md +141 -141
  45. package/templates/.github/templates/feature/TRD.template.md +358 -0
  46. package/templates/.github/templates/feature/context.template.md +89 -48
  47. package/templates/.github/templates/feature/extract-log.template.md +49 -39
  48. package/templates/.github/templates/feature/projetos.template.yaml +79 -79
  49. package/templates/.github/templates/global/progresso_global.template.md +59 -57
  50. package/templates/.github/templates/specs/brief.template.md +66 -59
  51. package/templates/.github/templates/specs/contracts.template.md +147 -141
  52. package/templates/.github/templates/specs/scenarios.template.md +125 -117
  53. package/templates/.github/templates/specs/tasks.template.md +65 -63
  54. package/templates/_gitignore +35 -35
  55. package/templates/sfw.config.yml.example +147 -147
  56. package/templates/.github/templates/feature/backlog-extraido.template.md +0 -156
  57. package/templates/.github/templates/feature/sdd.template.md +0 -559
@@ -1,244 +1,244 @@
1
- # Adapter Registry
2
-
3
- > Como o SFW resolve `adapter: "confluence"` no `sfw.config.yml` pra uma
4
- > instância concreta de `SourceAdapter`.
5
- >
6
- > Este arquivo é a **especificação** do registry. A implementação real vive
7
- > no bootstrap do kit (quando for codada — §9.9.P0.2+).
8
-
9
- ---
10
-
11
- ## Conceito
12
-
13
- O usuário declara no manifest:
14
-
15
- ```yaml
16
- input:
17
- adapter: confluence
18
- config:
19
- space_key: ST
20
- parent_page_id: "360668"
21
- ```
22
-
23
- As skills **nunca** veem a string `"confluence"`. Elas recebem uma instância
24
- que implementa `SourceAdapter` — já configurada, já validada. O registry é
25
- a ponte entre os dois.
26
-
27
- ---
28
-
29
- ## Responsabilidades do registry
30
-
31
- 1. **Descobrir adapters disponíveis** (builtin + futuros plugins)
32
- 2. **Resolver** a string `adapter: X` na classe correta
33
- 3. **Instanciar** o adapter passando o objeto `config` do manifest
34
- 4. **Validar** chamando `adapter.validateConfig(config)` antes de devolver
35
- 5. **Falhar cedo e rápido** se o adapter não existe ou config está errado
36
-
37
- ---
38
-
39
- ## Adapters built-in no MVP
40
-
41
- | Chave no YAML | Classe | Arquivo de runbook | Status MVP |
42
- |---------------|--------|-------------------|------------|
43
- | `confluence` | `ConfluenceAdapter` | `.github/adapters/confluence.md` | P0.2 — reuso do validado em testes/barbearia |
44
- | `filesystem` | `FilesystemAdapter` | `.github/adapters/filesystem.md` | P0.2 — novo, trivial |
45
-
46
- **Apenas esses 2 no MVP.** Qualquer outro valor em `adapter:` → `ValidationError`
47
- no load do manifest.
48
-
49
- ---
50
-
51
- ## Fluxo de resolução
52
-
53
- ```
54
- 1. Skill começa (ex: /sf-load)
55
- 2. Carrega sfw.config.yml
56
- 3. Para cada seção que precisa de adapter (input, cada output.target):
57
- a. Lê string `adapter: X`
58
- b. Consulta registry: registry.get("X")
59
- - Se X não existe → ValidationError: "unknown adapter 'X' (available: confluence, filesystem)"
60
- c. Instancia: const a = new AdapterClass()
61
- d. Valida config: a.validateConfig(target.config)
62
- - Se inválido → ValidationError (propaga do adapter)
63
- e. Armazena a instância configurada em memória pra reuso durante a skill
64
- 4. Usa as instâncias via interface — nunca chama .name direto no hot path
65
- ```
66
-
67
- **Importante**: o registry é consultado **1 vez** por execução de skill.
68
- Instâncias são cached pela duração da skill. Skills que rodam em sequência
69
- (`/sf-extract` → `/sf-design`) podem re-instanciar — não há estado compartilhado
70
- entre execuções (não deveria haver, por contrato).
71
-
72
- ---
73
-
74
- ## Contrato textual do registry
75
-
76
- ```typescript
77
- interface AdapterRegistry {
78
- /**
79
- * Retorna a classe do adapter (não instancia).
80
- * @throws ValidationError se a chave não existir
81
- */
82
- get(key: string): AdapterClass;
83
-
84
- /**
85
- * Lista as chaves disponíveis. Usado em mensagens de erro.
86
- */
87
- available(): string[];
88
-
89
- /**
90
- * Registra um novo adapter. No MVP só é chamado internamente pros 2 builtin.
91
- * Plugin system (P2) usaria isso pra carregar adapters externos.
92
- */
93
- register(key: string, cls: AdapterClass): void;
94
- }
95
-
96
- interface AdapterClass {
97
- new(): SourceAdapter;
98
- /** Chave que o adapter usa no YAML — deve bater com o que está no registry */
99
- readonly adapterName: string;
100
- }
101
- ```
102
-
103
- ### Inicialização builtin (pseudo-código)
104
-
105
- ```typescript
106
- const registry = new AdapterRegistry();
107
- registry.register("confluence", ConfluenceAdapter);
108
- registry.register("filesystem", FilesystemAdapter);
109
-
110
- // quando o manifest é carregado:
111
- function resolveAdapter(section: { adapter: string; config: object }): SourceAdapter {
112
- const cls = registry.get(section.adapter); // throws se não existe
113
- const instance = new cls();
114
- instance.validateConfig(section.config); // throws se config errada
115
- return instance;
116
- }
117
- ```
118
-
119
- ---
120
-
121
- ## Declaração de config requerida (contrato por adapter)
122
-
123
- Cada adapter **documenta** (em `.github/adapters/{name}.md`) quais campos
124
- são obrigatórios e quais são opcionais na seção `config`. O registry não
125
- valida isso — delega pro `validateConfig` do adapter. Isso evita duplicação
126
- e mantém a responsabilidade localizada.
127
-
128
- **Exemplo — ConfluenceAdapter**:
129
- | Campo | Obrigatório | Tipo | Descrição |
130
- |-------|:---:|------|-----------|
131
- | `space_key` | ✅ | string | ex: `"ST"` |
132
- | `parent_page_id` | ✅ | string | ID numérico da page pai |
133
- | `recursive` | — | boolean | default `true` |
134
- | `include_attachments` | — | boolean | default `true` |
135
-
136
- **Exemplo — FilesystemAdapter**:
137
- | Campo | Obrigatório | Tipo | Descrição |
138
- |-------|:---:|------|-----------|
139
- | `root_path` | ✅ | string | path absoluto ou relativo ao projeto |
140
- | `glob` | — | string | default `**/*.md` |
141
- | `watch` | — | boolean | default `false` (watch mode é P2) |
142
-
143
- ---
144
-
145
- ## Ordem de validação no load do manifest
146
-
147
- Quando skill chama `loadConfig("sfw.config.yml")`:
148
-
149
- 1. **Parse YAML.** Erro de sintaxe → `ValidationError` (nem chama registry).
150
- 2. **Valida shape top-level.** Presença de `project`, `naming`, `input`, `output.targets[]`.
151
- 3. **Resolve `input.adapter`** via registry + `validateConfig` do adapter.
152
- 4. **Resolve cada `output.targets[i].adapter`** via registry + `validateConfig`.
153
- 5. **Valida `naming.*`** — templates precisam ser strings não-vazias; placeholders
154
- desconhecidos detectados agora (antecipa erro de runtime).
155
- 6. **Valida coerência inter-seções**: ex., `output.targets[i].mode: auto` exige
156
- `approval_mechanism` presente quando `publishes` contém PRD/SDD (artefatos
157
- com gate de aprovação).
158
-
159
- Tudo no load. Se qualquer passo falha, skill para antes de tocar backend.
160
-
161
- ---
162
-
163
- ## Config de exemplo resolvida
164
-
165
- Input YAML:
166
- ```yaml
167
- project:
168
- name: "Barbearia"
169
- input:
170
- adapter: confluence
171
- config:
172
- space_key: ST
173
- parent_page_id: "360668"
174
- output:
175
- targets:
176
- - name: confluence-mirror
177
- adapter: confluence
178
- config:
179
- space_key: ST
180
- parent_page_id: "294931"
181
- publishes: [PRD, SDD, Progresso]
182
- mode: auto
183
- - name: local-mirror
184
- adapter: filesystem
185
- config:
186
- root_path: "./mirror"
187
- publishes: [PRD, SDD, Progresso, backlog]
188
- mode: auto
189
- ```
190
-
191
- Após load:
192
- ```typescript
193
- const manifest = {
194
- project: { name: "Barbearia" },
195
- input: <ConfluenceAdapter instance, configured>,
196
- outputs: [
197
- { name: "confluence-mirror", adapter: <ConfluenceAdapter>, publishes: [...], mode: "auto" },
198
- { name: "local-mirror", adapter: <FilesystemAdapter>, publishes: [...], mode: "auto" },
199
- ],
200
- };
201
- ```
202
-
203
- Skill chama `manifest.input.listChildren(...)` e `manifest.outputs[0].adapter.update(...)`.
204
- A string `"confluence"` nunca aparece fora do registry.
205
-
206
- ---
207
-
208
- ## O que NÃO é responsabilidade do registry
209
-
210
- - **Credenciais.** Adapter lê `.mcp.json` / env var direto. Registry nem vê.
211
- - **Retry/backoff.** Cada adapter implementa. Registry devolve instância "crua".
212
- - **Logging.** Skills logam. Adapter/registry silenciam (exceto em erro).
213
- - **Connection pooling.** MVP é single-process single-skill. Se virar batch,
214
- registry pode cachear. Não agora.
215
-
216
- ---
217
-
218
- ## Futuro (P2) — Plugin system
219
-
220
- Quando aparecer o 3º caso real de backend não-builtin:
221
-
222
- 1. `sfw.config.yml` ganha seção `plugins:`:
223
- ```yaml
224
- plugins:
225
- - npm:@sfw/notion-adapter@1.2.0
226
- - file:./local-adapters/sharepoint.js
227
- ```
228
- 2. Bootstrap do kit carrega plugins antes do manifest.
229
- 3. Cada plugin exporta `{ key, class }` e chama `registry.register(...)`.
230
- 4. Interface do adapter fica estável (breaking change vira major version).
231
-
232
- **Decisão (2026-04-11)**: não implementar agora. Builtin resolve 95% dos casos
233
- e prova que a interface está certa. Plugin system vira prioridade quando um
234
- usuário real pedir.
235
-
236
- ---
237
-
238
- ## Referências
239
-
240
- - Interface: `.github/adapters/interface.md`
241
- - Erros: `.github/adapters/errors.md`
242
- - Naming: `.github/adapters/naming.md`
243
- - Manifest: `sfw.config.yml.example`
244
- - Roadmap: `planodetarefas.md §9.9.P0.2` (implementação dos builtins)
1
+ # Adapter Registry
2
+
3
+ > Como o SFW resolve `adapter: "confluence"` no `sfw.config.yml` pra uma
4
+ > instância concreta de `SourceAdapter`.
5
+ >
6
+ > Este arquivo é a **especificação** do registry. A implementação real vive
7
+ > no bootstrap do kit (quando for codada — §9.9.P0.2+).
8
+
9
+ ---
10
+
11
+ ## Conceito
12
+
13
+ O usuário declara no manifest:
14
+
15
+ ```yaml
16
+ input:
17
+ adapter: confluence
18
+ config:
19
+ space_key: ST
20
+ parent_page_id: "360668"
21
+ ```
22
+
23
+ As skills **nunca** veem a string `"confluence"`. Elas recebem uma instância
24
+ que implementa `SourceAdapter` — já configurada, já validada. O registry é
25
+ a ponte entre os dois.
26
+
27
+ ---
28
+
29
+ ## Responsabilidades do registry
30
+
31
+ 1. **Descobrir adapters disponíveis** (builtin + futuros plugins)
32
+ 2. **Resolver** a string `adapter: X` na classe correta
33
+ 3. **Instanciar** o adapter passando o objeto `config` do manifest
34
+ 4. **Validar** chamando `adapter.validateConfig(config)` antes de devolver
35
+ 5. **Falhar cedo e rápido** se o adapter não existe ou config está errado
36
+
37
+ ---
38
+
39
+ ## Adapters built-in no MVP
40
+
41
+ | Chave no YAML | Classe | Arquivo de runbook | Status MVP |
42
+ |---------------|--------|-------------------|------------|
43
+ | `confluence` | `ConfluenceAdapter` | `.github/adapters/confluence.md` | P0.2 — reuso do validado em testes/barbearia |
44
+ | `filesystem` | `FilesystemAdapter` | `.github/adapters/filesystem.md` | P0.2 — novo, trivial |
45
+
46
+ **Apenas esses 2 no MVP.** Qualquer outro valor em `adapter:` → `ValidationError`
47
+ no load do manifest.
48
+
49
+ ---
50
+
51
+ ## Fluxo de resolução
52
+
53
+ ```
54
+ 1. Skill começa (ex: /sf-load)
55
+ 2. Carrega sfw.config.yml
56
+ 3. Para cada seção que precisa de adapter (input, cada output.target):
57
+ a. Lê string `adapter: X`
58
+ b. Consulta registry: registry.get("X")
59
+ - Se X não existe → ValidationError: "unknown adapter 'X' (available: confluence, filesystem)"
60
+ c. Instancia: const a = new AdapterClass()
61
+ d. Valida config: a.validateConfig(target.config)
62
+ - Se inválido → ValidationError (propaga do adapter)
63
+ e. Armazena a instância configurada em memória pra reuso durante a skill
64
+ 4. Usa as instâncias via interface — nunca chama .name direto no hot path
65
+ ```
66
+
67
+ **Importante**: o registry é consultado **1 vez** por execução de skill.
68
+ Instâncias são cached pela duração da skill. Skills que rodam em sequência
69
+ (`/sf-extract` → `/sf-design`) podem re-instanciar — não há estado compartilhado
70
+ entre execuções (não deveria haver, por contrato).
71
+
72
+ ---
73
+
74
+ ## Contrato textual do registry
75
+
76
+ ```typescript
77
+ interface AdapterRegistry {
78
+ /**
79
+ * Retorna a classe do adapter (não instancia).
80
+ * @throws ValidationError se a chave não existir
81
+ */
82
+ get(key: string): AdapterClass;
83
+
84
+ /**
85
+ * Lista as chaves disponíveis. Usado em mensagens de erro.
86
+ */
87
+ available(): string[];
88
+
89
+ /**
90
+ * Registra um novo adapter. No MVP só é chamado internamente pros 2 builtin.
91
+ * Plugin system (P2) usaria isso pra carregar adapters externos.
92
+ */
93
+ register(key: string, cls: AdapterClass): void;
94
+ }
95
+
96
+ interface AdapterClass {
97
+ new(): SourceAdapter;
98
+ /** Chave que o adapter usa no YAML — deve bater com o que está no registry */
99
+ readonly adapterName: string;
100
+ }
101
+ ```
102
+
103
+ ### Inicialização builtin (pseudo-código)
104
+
105
+ ```typescript
106
+ const registry = new AdapterRegistry();
107
+ registry.register("confluence", ConfluenceAdapter);
108
+ registry.register("filesystem", FilesystemAdapter);
109
+
110
+ // quando o manifest é carregado:
111
+ function resolveAdapter(section: { adapter: string; config: object }): SourceAdapter {
112
+ const cls = registry.get(section.adapter); // throws se não existe
113
+ const instance = new cls();
114
+ instance.validateConfig(section.config); // throws se config errada
115
+ return instance;
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Declaração de config requerida (contrato por adapter)
122
+
123
+ Cada adapter **documenta** (em `.github/adapters/{name}.md`) quais campos
124
+ são obrigatórios e quais são opcionais na seção `config`. O registry não
125
+ valida isso — delega pro `validateConfig` do adapter. Isso evita duplicação
126
+ e mantém a responsabilidade localizada.
127
+
128
+ **Exemplo — ConfluenceAdapter**:
129
+ | Campo | Obrigatório | Tipo | Descrição |
130
+ |-------|:---:|------|-----------|
131
+ | `space_key` | ✅ | string | ex: `"ST"` |
132
+ | `parent_page_id` | ✅ | string | ID numérico da page pai |
133
+ | `recursive` | — | boolean | default `true` |
134
+ | `include_attachments` | — | boolean | default `true` |
135
+
136
+ **Exemplo — FilesystemAdapter**:
137
+ | Campo | Obrigatório | Tipo | Descrição |
138
+ |-------|:---:|------|-----------|
139
+ | `root_path` | ✅ | string | path absoluto ou relativo ao projeto |
140
+ | `glob` | — | string | default `**/*.md` |
141
+ | `watch` | — | boolean | default `false` (watch mode é P2) |
142
+
143
+ ---
144
+
145
+ ## Ordem de validação no load do manifest
146
+
147
+ Quando skill chama `loadConfig("sfw.config.yml")`:
148
+
149
+ 1. **Parse YAML.** Erro de sintaxe → `ValidationError` (nem chama registry).
150
+ 2. **Valida shape top-level.** Presença de `project`, `naming`, `input`, `output.targets[]`.
151
+ 3. **Resolve `input.adapter`** via registry + `validateConfig` do adapter.
152
+ 4. **Resolve cada `output.targets[i].adapter`** via registry + `validateConfig`.
153
+ 5. **Valida `naming.*`** — templates precisam ser strings não-vazias; placeholders
154
+ desconhecidos detectados agora (antecipa erro de runtime).
155
+ 6. **Valida coerência inter-seções**: ex., `output.targets[i].mode: auto` exige
156
+ `approval_mechanism` presente quando `publishes` contém PRD/TRD (artefatos
157
+ com gate de aprovação).
158
+
159
+ Tudo no load. Se qualquer passo falha, skill para antes de tocar backend.
160
+
161
+ ---
162
+
163
+ ## Config de exemplo resolvida
164
+
165
+ Input YAML:
166
+ ```yaml
167
+ project:
168
+ name: "Barbearia"
169
+ input:
170
+ adapter: confluence
171
+ config:
172
+ space_key: ST
173
+ parent_page_id: "360668"
174
+ output:
175
+ targets:
176
+ - name: confluence-mirror
177
+ adapter: confluence
178
+ config:
179
+ space_key: ST
180
+ parent_page_id: "294931"
181
+ publishes: [PRD, TRD, Progresso]
182
+ mode: auto
183
+ - name: local-mirror
184
+ adapter: filesystem
185
+ config:
186
+ root_path: "./mirror"
187
+ publishes: [PRD, TRD, Progresso]
188
+ mode: auto
189
+ ```
190
+
191
+ Após load:
192
+ ```typescript
193
+ const manifest = {
194
+ project: { name: "Barbearia" },
195
+ input: <ConfluenceAdapter instance, configured>,
196
+ outputs: [
197
+ { name: "confluence-mirror", adapter: <ConfluenceAdapter>, publishes: [...], mode: "auto" },
198
+ { name: "local-mirror", adapter: <FilesystemAdapter>, publishes: [...], mode: "auto" },
199
+ ],
200
+ };
201
+ ```
202
+
203
+ Skill chama `manifest.input.listChildren(...)` e `manifest.outputs[0].adapter.update(...)`.
204
+ A string `"confluence"` nunca aparece fora do registry.
205
+
206
+ ---
207
+
208
+ ## O que NÃO é responsabilidade do registry
209
+
210
+ - **Credenciais.** Adapter lê `.mcp.json` / env var direto. Registry nem vê.
211
+ - **Retry/backoff.** Cada adapter implementa. Registry devolve instância "crua".
212
+ - **Logging.** Skills logam. Adapter/registry silenciam (exceto em erro).
213
+ - **Connection pooling.** MVP é single-process single-skill. Se virar batch,
214
+ registry pode cachear. Não agora.
215
+
216
+ ---
217
+
218
+ ## Futuro (P2) — Plugin system
219
+
220
+ Quando aparecer o 3º caso real de backend não-builtin:
221
+
222
+ 1. `sfw.config.yml` ganha seção `plugins:`:
223
+ ```yaml
224
+ plugins:
225
+ - npm:@sfw/notion-adapter@1.2.0
226
+ - file:./local-adapters/sharepoint.js
227
+ ```
228
+ 2. Bootstrap do kit carrega plugins antes do manifest.
229
+ 3. Cada plugin exporta `{ key, class }` e chama `registry.register(...)`.
230
+ 4. Interface do adapter fica estável (breaking change vira major version).
231
+
232
+ **Decisão (2026-04-11)**: não implementar agora. Builtin resolve 95% dos casos
233
+ e prova que a interface está certa. Plugin system vira prioridade quando um
234
+ usuário real pedir.
235
+
236
+ ---
237
+
238
+ ## Referências
239
+
240
+ - Interface: `.github/adapters/interface.md`
241
+ - Erros: `.github/adapters/errors.md`
242
+ - Naming: `.github/adapters/naming.md`
243
+ - Manifest: `sfw.config.yml.example`
244
+ - Roadmap: `planodetarefas.md §9.9.P0.2` (implementação dos builtins)
@@ -1,7 +1,7 @@
1
1
  # Agent: Backend Coder (.NET 8)
2
2
 
3
3
  > Especialista em desenvolvimento backend com .NET 8 / C#.
4
- > Implementa tasks da área BACK seguindo SDD + rules.md.
4
+ > Implementa tasks da área BACK seguindo specs/{nome}/ + rules.md.
5
5
 
6
6
  ---
7
7
 
@@ -25,7 +25,7 @@
25
25
  | xUnit | latest | Testes unit + integration |
26
26
  | FluentAssertions | latest | Assertions legíveis |
27
27
  | FluentValidation | latest | Validação de DTOs/requests |
28
- | MediatR | latest | CQRS / mediator (se SDD indicar) |
28
+ | MediatR | latest | CQRS / mediator (se TRD indicar) |
29
29
  | Serilog | latest | Logging estruturado |
30
30
 
31
31
  ## Padrões obrigatórios
@@ -173,15 +173,15 @@ public static class DomainErrors
173
173
  Cada endpoint implementado DEVE ter:
174
174
 
175
175
  ### Autenticação
176
- - Seguir mecanismo definido no SDD §5 (Bearer token, API Key, público)
177
- - Se o SDD diz "Bearer token" → implementar `[Authorize]` ou `.RequireAuthorization()`
178
- - Se o SDD diz "público" → usar `.AllowAnonymous()` explicitamente
179
- - **Nunca criar endpoint sem auth definido** — se SDD omitiu → PARAR e reportar
176
+ - Seguir mecanismo definido no TRD §2.1 (Bearer token, API Key, público)
177
+ - Se o TRD / specs/ diz "Bearer token" → implementar `[Authorize]` ou `.RequireAuthorization()`
178
+ - Se o TRD / specs/ diz "público" → usar `.AllowAnonymous()` explicitamente
179
+ - **Nunca criar endpoint sem auth definido** — se TRD omitiu → PARAR e reportar
180
180
 
181
181
  ### Autorização
182
- - Seguir roles/permissões definidos no SDD §5
182
+ - Seguir roles/permissões definidos no TRD §2.1
183
183
  - Implementar via policies: `.RequireAuthorization("PolicyName")`
184
- - Validar ownership quando SDD indica (ex: "owner" → usuário só acessa seus dados)
184
+ - Validar ownership quando TRD indica (ex: "owner" → usuário só acessa seus dados)
185
185
  - Testar: criar teste unit que valida acesso negado sem role correto
186
186
 
187
187
  ### Validação de Input
@@ -193,11 +193,11 @@ Cada endpoint implementado DEVE ter:
193
193
  ### Erros de Segurança
194
194
  - 401 Unauthorized → sempre retornar corpo genérico (não vazar info do sistema)
195
195
  - 403 Forbidden → retornar "sem permissão", nunca revelar se o recurso existe
196
- - Rate limiting → implementar se SDD especificar
196
+ - Rate limiting → implementar se TRD especificar
197
197
 
198
198
  ### Checklist de Segurança por Task
199
199
  Ao finalizar cada task de endpoint, verificar:
200
- - [ ] Auth configurado conforme SDD
200
+ - [ ] Auth configurado conforme TRD
201
201
  - [ ] Roles/policies implementados
202
202
  - [ ] Validação de input completa
203
203
  - [ ] Teste de acesso negado existe
@@ -205,11 +205,11 @@ Ao finalizar cada task de endpoint, verificar:
205
205
 
206
206
  ## Comportamento
207
207
 
208
- 1. **Lê SDD §N + task** — nunca o SDD inteiro, só as seções referenciadas
208
+ 1. **Lê specs/{nome}/ §N + task** — nunca o specs/ inteiro, só as seções referenciadas
209
209
  2. **Implementa + testa na mesma task** — código e teste unit juntos
210
210
  3. **Um commit por task** — `feat(BACK-004): criar endpoint POST /api/v1/agendamentos`
211
- 4. **Se SDD é ambíguo** → para e reporta. Nunca inventa regra de negócio
212
- 5. **Auth/AuthZ por endpoint** — todo endpoint DEVE ter auth definido. Se SDD omitiu → PARAR
213
- 6. **Segue patterns acima** — se o SDD não contradiz, usar os padrões deste agent
211
+ 4. **Se specs/ está ambíguo** → para e reporta. Nunca inventa regra de negócio
212
+ 5. **Auth/AuthZ por endpoint** — todo endpoint DEVE ter auth definido. Se TRD omitiu → PARAR
213
+ 6. **Segue patterns acima** — se o TRD / specs/ não contradiz, usar os padrões deste agent
214
214
  7. **Erros de negócio via Result<T>** — não usar exceptions para fluxo normal
215
215
  8. **Async em tudo** — nunca bloquear thread