@girardelli/architect 2.2.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -116
- package/__test_agent_output__/INDEX.md +1 -0
- package/__test_agent_output__/agents/AGENT-ORCHESTRATOR.md +1 -0
- package/__test_agent_output__/agents/DATABASE-ENGINEER.md +174 -0
- package/__test_agent_output__/agents/QA-TEST-ENGINEER.md +138 -0
- package/__test_agent_output__/agents/SECURITY-AUDITOR.md +106 -0
- package/__test_agent_output__/agents/TECH-DEBT-CONTROLLER.md +104 -0
- package/__test_agent_output__/agents/TYPESCRIPT-BACKEND-DEVELOPER.md +135 -0
- package/__test_agent_output__/guards/CODE-REVIEW-CHECKLIST.md +95 -0
- package/__test_agent_output__/guards/PREFLIGHT.md +200 -0
- package/__test_agent_output__/guards/QUALITY-GATES.md +1 -0
- package/__test_agent_output__/rules/00-general.md +229 -0
- package/__test_agent_output__/rules/01-architecture.md +191 -0
- package/__test_agent_output__/rules/02-security.md +402 -0
- package/__test_agent_output__/rules/03-nestjs.md +124 -0
- package/__test_agent_output__/templates/ADR.md +95 -0
- package/__test_agent_output__/templates/BDD.md +58 -0
- package/__test_agent_output__/templates/C4.md +68 -0
- package/__test_agent_output__/templates/TDD.md +86 -0
- package/__test_agent_output__/templates/THREAT-MODEL.md +82 -0
- package/__test_agent_output__/workflows/fix-bug.md +228 -0
- package/__test_agent_output__/workflows/new-feature.md +311 -0
- package/__test_agent_output__/workflows/review.md +95 -0
- package/__test_context_7RvUrO/src/modules/empty/empty.ts +0 -0
- package/__test_context_Rf5fNJ/src/modules/mixed/mixed.ts +5 -0
- package/__test_context_WRCnYH/src/modules/test/test.ts +10 -0
- package/__test_context_YsnVS3/src/modules/test/test.ts +10 -0
- package/__test_context_w7XZeH/src/modules/mixed/mixed.ts +5 -0
- package/__test_context_y5noh6/src/modules/empty/empty.ts +0 -0
- package/__test_framework__24OjAu/package.json +1 -0
- package/__test_framework__3ZDZsx/pyproject.toml +8 -0
- package/__test_framework__4T54Jn/package.json +1 -0
- package/__test_framework__4tlXu9/pyproject.toml +8 -0
- package/__test_framework__6boWqQ/Pipfile +6 -0
- package/__test_framework__6gygMU/pom.xml +10 -0
- package/__test_framework__6kxj0N/go.mod +8 -0
- package/__test_framework__7CEoXw/pom.xml +10 -0
- package/__test_framework__85DDz0/Pipfile +6 -0
- package/__test_framework__9WrRIr/pom.xml +7 -0
- package/__test_framework__ANqGKl/Gemfile +5 -0
- package/__test_framework__BCXTEM/go.mod +3 -0
- package/__test_framework__BHiPNq/setup.py +2 -0
- package/__test_framework__BqkiKv/package.json +1 -0
- package/__test_framework__C5yd8X/Pipfile.lock +1 -0
- package/__test_framework__C5yd8X/requirements.txt +1 -0
- package/__test_framework__C87d3a/manage.py +1 -0
- package/__test_framework__C87d3a/requirements.txt +2 -0
- package/__test_framework__DXNwc5/build.gradle +7 -0
- package/__test_framework__GhHSt3/build.gradle.kts +4 -0
- package/__test_framework__GzklJP/Cargo.toml +7 -0
- package/__test_framework__H4hd13/go.mod +8 -0
- package/__test_framework__HKjOXO/composer.json +1 -0
- package/__test_framework__HaDN45/Gemfile +3 -0
- package/__test_framework__IBO7YG/pyproject.toml +9 -0
- package/__test_framework__JwSOyF/pyproject.toml +6 -0
- package/__test_framework__K6HrCr/build.gradle +2 -0
- package/__test_framework__KzRPlh/pubspec.yaml +9 -0
- package/__test_framework__L6uIym/pyproject.toml +6 -0
- package/__test_framework__LOdoGK/requirements.txt +4 -0
- package/__test_framework__LgHzss/package.json +1 -0
- package/__test_framework__M76M6q/Gemfile +5 -0
- package/__test_framework__Mr9vWW/composer.json +1 -0
- package/__test_framework__N03Gnv/package.json +1 -0
- package/__test_framework__Num4UE/requirements +1 -0
- package/__test_framework__OAGw3Y/build.gradle +7 -0
- package/__test_framework__OQc8yG/pubspec.yaml +9 -0
- package/__test_framework__OwKZcd/requirements.txt +3 -0
- package/__test_framework__P0gFv7/requirements +1 -0
- package/__test_framework__PN55Rq/package.json +1 -0
- package/__test_framework__PQiqX8/pubspec.yaml +3 -0
- package/__test_framework__RBHsg7/composer.json +1 -0
- package/__test_framework__RHxif4/Cargo.toml +7 -0
- package/__test_framework__T0v0p1/Cargo.toml +4 -0
- package/__test_framework__Tu0clt/Pipfile.lock +1 -0
- package/__test_framework__Tu0clt/requirements.txt +1 -0
- package/__test_framework__TwDj9P/Cargo.toml +4 -0
- package/__test_framework__VQJNC4/pom.xml +7 -0
- package/__test_framework__W6sm05/package.json +1 -0
- package/__test_framework__W7vBLy/pyproject.toml +4 -0
- package/__test_framework__WNJOWT/setup.py +2 -0
- package/__test_framework__WSJs7U/package.json +1 -0
- package/__test_framework__YQ5VpA/build.gradle.kts +4 -0
- package/__test_framework__ZNEUEs/package.json +1 -0
- package/__test_framework__Znt922/pom.xml +7 -0
- package/__test_framework__azyg0h/pom.xml +7 -0
- package/__test_framework__c6otLr/package.json +1 -0
- package/__test_framework__cl9S9G/build.gradle +2 -0
- package/__test_framework__eilvV4/composer.json +1 -0
- package/__test_framework__gQZxXO/manage.py +1 -0
- package/__test_framework__gQZxXO/requirements.txt +2 -0
- package/__test_framework__ghvl26/poetry.lock +1 -0
- package/__test_framework__ghvl26/pyproject.toml +2 -0
- package/__test_framework__hR7b9U/Makefile +11 -0
- package/__test_framework__iESVsi/composer.json +1 -0
- package/__test_framework__jm6TJy/package.json +1 -0
- package/__test_framework__kBUpjs/pyproject.toml +9 -0
- package/__test_framework__kqoZrw/requirements.txt +4 -0
- package/__test_framework__lWkoyO/pyproject.toml +4 -0
- package/__test_framework__mTKnUO/package.json +1 -0
- package/__test_framework__nCeZwe/Makefile +11 -0
- package/__test_framework__oljsU0/package.json +1 -0
- package/__test_framework__osRG4q/go.mod +3 -0
- package/__test_framework__pCHH4F/package.json +1 -0
- package/__test_framework__pExx6E/Gemfile +3 -0
- package/__test_framework__pyBoGd/pyproject.toml +5 -0
- package/__test_framework__qw16VQ/package.json +1 -0
- package/__test_framework__rRayrG/package.json +1 -0
- package/__test_framework__s82zO5/package.json +1 -0
- package/__test_framework__tp8MFK/pyproject.toml +5 -0
- package/__test_framework__w44k4w/composer.json +1 -0
- package/__test_framework__yefPZY/poetry.lock +1 -0
- package/__test_framework__yefPZY/pyproject.toml +2 -0
- package/__test_framework__zCiyDT/requirements.txt +3 -0
- package/__test_framework__zGZN3j/pubspec.yaml +3 -0
- package/__test_framework__zXpnxL/package.json +1 -0
- package/architect-run.sh +431 -0
- package/assets/banner-v3.html +561 -0
- package/dist/agent-generator/context-enricher.d.ts +58 -0
- package/dist/agent-generator/context-enricher.d.ts.map +1 -0
- package/dist/agent-generator/context-enricher.js +581 -0
- package/dist/agent-generator/context-enricher.js.map +1 -0
- package/dist/agent-generator/domain-inferrer.d.ts +52 -0
- package/dist/agent-generator/domain-inferrer.d.ts.map +1 -0
- package/dist/agent-generator/domain-inferrer.js +575 -0
- package/dist/agent-generator/domain-inferrer.js.map +1 -0
- package/dist/agent-generator/framework-detector.d.ts +40 -0
- package/dist/agent-generator/framework-detector.d.ts.map +1 -0
- package/dist/agent-generator/framework-detector.js +611 -0
- package/dist/agent-generator/framework-detector.js.map +1 -0
- package/dist/agent-generator/index.d.ts +33 -0
- package/dist/agent-generator/index.d.ts.map +1 -0
- package/dist/agent-generator/index.js +477 -0
- package/dist/agent-generator/index.js.map +1 -0
- package/dist/agent-generator/stack-detector.d.ts +12 -0
- package/dist/agent-generator/stack-detector.d.ts.map +1 -0
- package/dist/agent-generator/stack-detector.js +128 -0
- package/dist/agent-generator/stack-detector.js.map +1 -0
- package/dist/agent-generator/templates/core/agents.d.ts +17 -0
- package/dist/agent-generator/templates/core/agents.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/agents.js +1252 -0
- package/dist/agent-generator/templates/core/agents.js.map +1 -0
- package/dist/agent-generator/templates/core/architecture-rules.d.ts +7 -0
- package/dist/agent-generator/templates/core/architecture-rules.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/architecture-rules.js +274 -0
- package/dist/agent-generator/templates/core/architecture-rules.js.map +1 -0
- package/dist/agent-generator/templates/core/general-rules.d.ts +8 -0
- package/dist/agent-generator/templates/core/general-rules.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/general-rules.js +301 -0
- package/dist/agent-generator/templates/core/general-rules.js.map +1 -0
- package/dist/agent-generator/templates/core/index-md.d.ts +7 -0
- package/dist/agent-generator/templates/core/index-md.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/index-md.js +246 -0
- package/dist/agent-generator/templates/core/index-md.js.map +1 -0
- package/dist/agent-generator/templates/core/orchestrator.d.ts +8 -0
- package/dist/agent-generator/templates/core/orchestrator.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/orchestrator.js +422 -0
- package/dist/agent-generator/templates/core/orchestrator.js.map +1 -0
- package/dist/agent-generator/templates/core/preflight.d.ts +8 -0
- package/dist/agent-generator/templates/core/preflight.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/preflight.js +213 -0
- package/dist/agent-generator/templates/core/preflight.js.map +1 -0
- package/dist/agent-generator/templates/core/quality-gates.d.ts +11 -0
- package/dist/agent-generator/templates/core/quality-gates.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/quality-gates.js +254 -0
- package/dist/agent-generator/templates/core/quality-gates.js.map +1 -0
- package/dist/agent-generator/templates/core/security-rules.d.ts +7 -0
- package/dist/agent-generator/templates/core/security-rules.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/security-rules.js +528 -0
- package/dist/agent-generator/templates/core/security-rules.js.map +1 -0
- package/dist/agent-generator/templates/core/skills-generator.d.ts +6 -0
- package/dist/agent-generator/templates/core/skills-generator.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/skills-generator.js +207 -0
- package/dist/agent-generator/templates/core/skills-generator.js.map +1 -0
- package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts +7 -0
- package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/workflow-fix-bug.js +237 -0
- package/dist/agent-generator/templates/core/workflow-fix-bug.js.map +1 -0
- package/dist/agent-generator/templates/core/workflow-new-feature.d.ts +8 -0
- package/dist/agent-generator/templates/core/workflow-new-feature.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/workflow-new-feature.js +321 -0
- package/dist/agent-generator/templates/core/workflow-new-feature.js.map +1 -0
- package/dist/agent-generator/templates/core/workflow-review.d.ts +7 -0
- package/dist/agent-generator/templates/core/workflow-review.d.ts.map +1 -0
- package/dist/agent-generator/templates/core/workflow-review.js +104 -0
- package/dist/agent-generator/templates/core/workflow-review.js.map +1 -0
- package/dist/agent-generator/templates/domain/index.d.ts +22 -0
- package/dist/agent-generator/templates/domain/index.d.ts.map +1 -0
- package/dist/agent-generator/templates/domain/index.js +1176 -0
- package/dist/agent-generator/templates/domain/index.js.map +1 -0
- package/dist/agent-generator/templates/stack/index.d.ts +8 -0
- package/dist/agent-generator/templates/stack/index.d.ts.map +1 -0
- package/dist/agent-generator/templates/stack/index.js +695 -0
- package/dist/agent-generator/templates/stack/index.js.map +1 -0
- package/dist/agent-generator/templates/template-helpers.d.ts +75 -0
- package/dist/agent-generator/templates/template-helpers.d.ts.map +1 -0
- package/dist/agent-generator/templates/template-helpers.js +726 -0
- package/dist/agent-generator/templates/template-helpers.js.map +1 -0
- package/dist/agent-generator/types.d.ts +196 -0
- package/dist/agent-generator/types.d.ts.map +1 -0
- package/dist/agent-generator/types.js +27 -0
- package/dist/agent-generator/types.js.map +1 -0
- package/dist/analyzer.d.ts +5 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +35 -4
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzers/forecast.d.ts +85 -0
- package/dist/analyzers/forecast.d.ts.map +1 -0
- package/dist/analyzers/forecast.js +337 -0
- package/dist/analyzers/forecast.js.map +1 -0
- package/dist/analyzers/git-cache.d.ts +7 -0
- package/dist/analyzers/git-cache.d.ts.map +1 -0
- package/dist/analyzers/git-cache.js +41 -0
- package/dist/analyzers/git-cache.js.map +1 -0
- package/dist/analyzers/git-history.d.ts +113 -0
- package/dist/analyzers/git-history.d.ts.map +1 -0
- package/dist/analyzers/git-history.js +333 -0
- package/dist/analyzers/git-history.js.map +1 -0
- package/dist/analyzers/index.d.ts +10 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +7 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/temporal-scorer.d.ts +72 -0
- package/dist/analyzers/temporal-scorer.d.ts.map +1 -0
- package/dist/analyzers/temporal-scorer.js +140 -0
- package/dist/analyzers/temporal-scorer.js.map +1 -0
- package/dist/cli.d.ts +2 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +275 -113
- package/dist/cli.js.map +1 -1
- package/dist/html-reporter.d.ts +3 -1
- package/dist/html-reporter.d.ts.map +1 -1
- package/dist/html-reporter.js +248 -12
- package/dist/html-reporter.js.map +1 -1
- package/dist/index.d.ts +16 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +63 -4
- package/dist/index.js.map +1 -1
- package/dist/project-summarizer.d.ts +18 -0
- package/dist/project-summarizer.d.ts.map +1 -0
- package/dist/project-summarizer.js +306 -0
- package/dist/project-summarizer.js.map +1 -0
- package/dist/refactor-reporter.js +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -3
- package/src/agent-generator/context-enricher.ts +643 -0
- package/src/agent-generator/domain-inferrer.ts +625 -0
- package/src/agent-generator/framework-detector.ts +669 -0
- package/src/agent-generator/index.ts +555 -0
- package/src/agent-generator/stack-detector.ts +103 -0
- package/src/agent-generator/templates/core/agents.ts +1293 -0
- package/src/agent-generator/templates/core/architecture-rules.ts +287 -0
- package/src/agent-generator/templates/core/general-rules.ts +306 -0
- package/src/agent-generator/templates/core/index-md.ts +260 -0
- package/src/agent-generator/templates/core/orchestrator.ts +459 -0
- package/src/agent-generator/templates/core/preflight.ts +215 -0
- package/src/agent-generator/templates/core/quality-gates.ts +256 -0
- package/src/agent-generator/templates/core/security-rules.ts +543 -0
- package/src/agent-generator/templates/core/skills-generator.ts +236 -0
- package/src/agent-generator/templates/core/workflow-fix-bug.ts +239 -0
- package/src/agent-generator/templates/core/workflow-new-feature.ts +323 -0
- package/src/agent-generator/templates/core/workflow-review.ts +106 -0
- package/src/agent-generator/templates/domain/index.ts +1201 -0
- package/src/agent-generator/templates/stack/index.ts +705 -0
- package/src/agent-generator/templates/template-helpers.ts +776 -0
- package/src/agent-generator/types.ts +232 -0
- package/src/analyzer.ts +38 -4
- package/src/analyzers/forecast.ts +496 -0
- package/src/analyzers/git-cache.ts +52 -0
- package/src/analyzers/git-history.ts +488 -0
- package/src/analyzers/index.ts +33 -0
- package/src/analyzers/temporal-scorer.ts +227 -0
- package/src/cli.ts +316 -117
- package/src/html-reporter.ts +263 -13
- package/src/index.ts +92 -9
- package/src/project-summarizer.ts +347 -0
- package/src/refactor-reporter.ts +1 -1
- package/src/types.ts +10 -0
- package/tests/agent-generator.test.ts +411 -0
- package/tests/analyzers-integration.test.ts +174 -0
- package/tests/architect-adapter-enrichment.test.ts +9 -0
- package/tests/context-enricher.test.ts +971 -0
- package/tests/forecast.test.ts +509 -0
- package/tests/framework-detector.test.ts +1172 -0
- package/tests/git-history.test.ts +254 -0
- package/tests/scanner.test.ts +7 -8
- package/tests/scorer.test.ts +588 -0
- package/tests/stack-detector.test.ts +241 -0
- package/tests/template-generation.test.ts +706 -0
- package/tests/template-helpers.test.ts +1152 -0
- package/tests/temporal-scorer.test.ts +307 -0
- package/dist/agent-generator.d.ts +0 -106
- package/dist/agent-generator.d.ts.map +0 -1
- package/dist/agent-generator.js +0 -1398
- package/dist/agent-generator.js.map +0 -1
- package/src/agent-generator.ts +0 -1526
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
---
|
|
2
|
+
antigravity:
|
|
3
|
+
trigger: 'always_on'
|
|
4
|
+
globs: ['**/*']
|
|
5
|
+
description: 'Regras de segurança para test-project'
|
|
6
|
+
priority: CRITICAL
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# 🛡️ Regras de Segurança — test-project
|
|
10
|
+
|
|
11
|
+
> **Segurança NÃO é feature — é requisito. Toda linha de código é superfície de ataque.**
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## ⚠️ REGRA ZERO DE SEGURANÇA
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
19
|
+
║ NUNCA confiar em input do usuário. ║
|
|
20
|
+
║ NUNCA expor detalhes internos em respostas de erro. ║
|
|
21
|
+
║ NUNCA armazenar secrets em código. ║
|
|
22
|
+
║ NUNCA desabilitar validação "temporariamente". ║
|
|
23
|
+
║ NUNCA commitar com security warnings ignorados. ║
|
|
24
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🔐 OWASP Top 10 — Checklist Obrigatório
|
|
30
|
+
|
|
31
|
+
### A01: Broken Access Control
|
|
32
|
+
```
|
|
33
|
+
❌ PROIBIDO: Endpoint sem verificação de autorização
|
|
34
|
+
❌ PROIBIDO: IDOR (Insecure Direct Object Reference) — acessar recurso de outro usuário via ID
|
|
35
|
+
✅ CORRETO: RBAC (Role-Based Access Control) em TODOS os endpoints
|
|
36
|
+
✅ CORRETO: Verificar ownership do recurso antes de retornar
|
|
37
|
+
|
|
38
|
+
Padrão:
|
|
39
|
+
1. Autenticar (quem é?)
|
|
40
|
+
2. Autorizar (pode fazer isso?)
|
|
41
|
+
3. Verificar ownership (esse recurso é dele?)
|
|
42
|
+
4. Executar ação
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### A02: Cryptographic Failures
|
|
46
|
+
```
|
|
47
|
+
❌ PROIBIDO: Senhas em plain text
|
|
48
|
+
❌ PROIBIDO: HTTP para dados sensíveis
|
|
49
|
+
❌ PROIBIDO: Algoritmos fracos (MD5, SHA1 para passwords)
|
|
50
|
+
✅ CORRETO: bcrypt/argon2 para passwords (cost ≥ 12)
|
|
51
|
+
✅ CORRETO: HTTPS everywhere (HSTS)
|
|
52
|
+
✅ CORRETO: AES-256-GCM para dados em repouso
|
|
53
|
+
✅ CORRETO: TLS 1.2+ para dados em trânsito
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### A03: Injection
|
|
57
|
+
```
|
|
58
|
+
❌ PROIBIDO: Concatenação de strings em queries SQL
|
|
59
|
+
❌ PROIBIDO: Template strings com input de usuário
|
|
60
|
+
❌ PROIBIDO: eval(), exec(), Function() com input externo
|
|
61
|
+
✅ CORRETO: Queries parametrizadas SEMPRE
|
|
62
|
+
✅ CORRETO: ORM com bindings
|
|
63
|
+
✅ CORRETO: Input sanitization na borda (controller/pipe)
|
|
64
|
+
|
|
65
|
+
Exemplos:
|
|
66
|
+
❌ `SELECT * FROM users WHERE id = '${userId}'`
|
|
67
|
+
✅ `SELECT * FROM users WHERE id = $1` + [userId]
|
|
68
|
+
❌ `db.query(`...WHERE name = '${name}'`)`
|
|
69
|
+
✅ `db.query('...WHERE name = ?', [name])`
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### A04: Insecure Design
|
|
73
|
+
```
|
|
74
|
+
❌ PROIBIDO: Endpoints sem rate limiting
|
|
75
|
+
❌ PROIBIDO: Reset de senha via link sem expiração
|
|
76
|
+
❌ PROIBIDO: Lógica de negócio sem threat model
|
|
77
|
+
✅ CORRETO: STRIDE analysis antes de implementar features sensíveis
|
|
78
|
+
✅ CORRETO: Rate limiting em auth endpoints (≤ 5 tentativas/minuto)
|
|
79
|
+
✅ CORRETO: Tokens com expiração curta (15min access, 7d refresh)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### A05: Security Misconfiguration
|
|
83
|
+
```
|
|
84
|
+
❌ PROIBIDO: CORS com origin: '*' em produção
|
|
85
|
+
❌ PROIBIDO: Debug mode em produção
|
|
86
|
+
❌ PROIBIDO: Default credentials
|
|
87
|
+
❌ PROIBIDO: Stack traces em respostas de erro
|
|
88
|
+
✅ CORRETO: CORS restritivo (origins explícitos)
|
|
89
|
+
✅ CORRETO: Headers de segurança (X-Frame-Options, CSP, X-Content-Type-Options)
|
|
90
|
+
✅ CORRETO: Error handling que retorna apenas mensagem genérica ao usuário
|
|
91
|
+
|
|
92
|
+
Headers obrigatórios:
|
|
93
|
+
X-Content-Type-Options: nosniff
|
|
94
|
+
X-Frame-Options: DENY
|
|
95
|
+
X-XSS-Protection: 0 (CSP substitui)
|
|
96
|
+
Content-Security-Policy: default-src 'self'
|
|
97
|
+
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
|
98
|
+
Referrer-Policy: strict-origin-when-cross-origin
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### A06: Vulnerable and Outdated Components
|
|
102
|
+
```
|
|
103
|
+
❌ PROIBIDO: Dependências com vulnerabilidades conhecidas
|
|
104
|
+
❌ PROIBIDO: Ignorar security advisories
|
|
105
|
+
✅ CORRETO: Audit regular (npm audit / pip audit / safety check)
|
|
106
|
+
✅ CORRETO: Renovate/Dependabot configurado
|
|
107
|
+
✅ CORRETO: Lock files commitados (package-lock.json, poetry.lock)
|
|
108
|
+
|
|
109
|
+
Comandos de verificação:
|
|
110
|
+
$ npm audit
|
|
111
|
+
$ npx audit-ci --critical
|
|
112
|
+
$ npx snyk test
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### A07: Identification and Authentication Failures
|
|
116
|
+
```
|
|
117
|
+
❌ PROIBIDO: Sessions sem expiração
|
|
118
|
+
❌ PROIBIDO: Tokens previsíveis
|
|
119
|
+
❌ PROIBIDO: Brute force sem proteção
|
|
120
|
+
✅ CORRETO: JWT com algoritmo explícito (RS256 ou ES256)
|
|
121
|
+
✅ CORRETO: Refresh token rotation
|
|
122
|
+
✅ CORRETO: Account lockout após N tentativas
|
|
123
|
+
✅ CORRETO: MFA para operações sensíveis
|
|
124
|
+
|
|
125
|
+
JWT Checklist:
|
|
126
|
+
□ Algoritmo explícito (nunca 'none')
|
|
127
|
+
□ Audience (aud) verificado
|
|
128
|
+
□ Issuer (iss) verificado
|
|
129
|
+
□ Expiração (exp) curta
|
|
130
|
+
□ Secret key ≥ 256 bits
|
|
131
|
+
□ Stored em httpOnly cookie (não localStorage)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### A08: Software and Data Integrity Failures
|
|
135
|
+
```
|
|
136
|
+
❌ PROIBIDO: CI/CD sem verificação de integridade
|
|
137
|
+
❌ PROIBIDO: Deserialização de dados não confiáveis
|
|
138
|
+
✅ CORRETO: Subresource Integrity (SRI) para CDN scripts
|
|
139
|
+
✅ CORRETO: Signed commits
|
|
140
|
+
✅ CORRETO: Pipeline protegido (branch protection rules)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### A09: Security Logging and Monitoring Failures
|
|
144
|
+
```
|
|
145
|
+
❌ PROIBIDO: Ações sensíveis sem log
|
|
146
|
+
❌ PROIBIDO: Logs com dados sensíveis (passwords, tokens, PII)
|
|
147
|
+
✅ CORRETO: Audit log para: login, logout, password change, permission change
|
|
148
|
+
✅ CORRETO: Log level adequado (WARN/ERROR para falhas de auth)
|
|
149
|
+
✅ CORRETO: Alertas para atividades anômalas
|
|
150
|
+
|
|
151
|
+
O que logar:
|
|
152
|
+
✅ Quem (user ID)
|
|
153
|
+
✅ O quê (ação)
|
|
154
|
+
✅ Quando (timestamp UTC)
|
|
155
|
+
✅ Onde (IP, user-agent)
|
|
156
|
+
✅ Resultado (sucesso/falha)
|
|
157
|
+
|
|
158
|
+
O que NUNCA logar:
|
|
159
|
+
❌ Passwords (nem em debug)
|
|
160
|
+
❌ Tokens de autenticação
|
|
161
|
+
❌ Dados de cartão de crédito
|
|
162
|
+
❌ PII sem necessidade
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### A10: Server-Side Request Forgery (SSRF)
|
|
166
|
+
```
|
|
167
|
+
❌ PROIBIDO: Fetch de URL fornecida pelo usuário sem validação
|
|
168
|
+
❌ PROIBIDO: Acesso a metadata endpoints (169.254.169.254)
|
|
169
|
+
✅ CORRETO: Allowlist de domínios para requests externos
|
|
170
|
+
✅ CORRETO: Validação de schema (https only)
|
|
171
|
+
✅ CORRETO: Block de IPs internos/privados
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 🔑 Validação de Input
|
|
177
|
+
|
|
178
|
+
### NestJS — class-validator + class-transformer
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// ✅ CORRETO: DTO com validação
|
|
182
|
+
import { IsString, IsEmail, MinLength, MaxLength, IsOptional } from 'class-validator';
|
|
183
|
+
|
|
184
|
+
export class CreateUserDto {
|
|
185
|
+
@IsString()
|
|
186
|
+
@MinLength(2)
|
|
187
|
+
@MaxLength(100)
|
|
188
|
+
name: string;
|
|
189
|
+
|
|
190
|
+
@IsEmail()
|
|
191
|
+
email: string;
|
|
192
|
+
|
|
193
|
+
@IsString()
|
|
194
|
+
@MinLength(8)
|
|
195
|
+
@MaxLength(128)
|
|
196
|
+
password: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Controller com ValidationPipe
|
|
200
|
+
@Post()
|
|
201
|
+
@UsePipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
|
|
202
|
+
async create(@Body() dto: CreateUserDto) { ... }
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Regras:**
|
|
206
|
+
- `whitelist: true` — remove campos não declarados no DTO
|
|
207
|
+
- `forbidNonWhitelisted: true` — retorna 400 se campo extra enviado
|
|
208
|
+
- `transform: true` — converte tipos automaticamente
|
|
209
|
+
- NUNCA usar `@Body()` sem DTO validado
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 🔒 Autenticação & Autorização
|
|
214
|
+
|
|
215
|
+
### NestJS Auth Pattern
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
Implementação padrão:
|
|
219
|
+
1. AuthGuard global para rotas protegidas
|
|
220
|
+
2. @Public() decorator para rotas abertas
|
|
221
|
+
3. RolesGuard para autorização
|
|
222
|
+
4. CurrentUser decorator para extrair user do token
|
|
223
|
+
|
|
224
|
+
Hierarquia:
|
|
225
|
+
@Public() → Sem autenticação
|
|
226
|
+
@UseGuards(AuthGuard) → Autenticado
|
|
227
|
+
@Roles('admin') → Autenticado + Role específica
|
|
228
|
+
@OwnerGuard() → Autenticado + Dono do recurso
|
|
229
|
+
|
|
230
|
+
Fluxo de token:
|
|
231
|
+
Login → Access Token (15min) + Refresh Token (7d, httpOnly cookie)
|
|
232
|
+
Request → AuthGuard verifica Access Token
|
|
233
|
+
Expired → Refresh endpoint gera novo par
|
|
234
|
+
Logout → Invalidar Refresh Token no banco
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 🗝️ Gestão de Secrets
|
|
240
|
+
|
|
241
|
+
### Regras de Secrets
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
245
|
+
║ SECRETS NUNCA NO CÓDIGO. NUNCA. SEM EXCEÇÃO. ║
|
|
246
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
247
|
+
|
|
248
|
+
❌ PROIBIDO:
|
|
249
|
+
- API keys hardcoded
|
|
250
|
+
- Passwords em arquivos de config
|
|
251
|
+
- Tokens em constantes
|
|
252
|
+
- Connection strings com credenciais no código
|
|
253
|
+
- .env commitado no repositório
|
|
254
|
+
|
|
255
|
+
✅ CORRETO:
|
|
256
|
+
- Environment variables
|
|
257
|
+
- Secret manager (AWS SSM, Vault, GCP Secret Manager)
|
|
258
|
+
- .env.example com placeholders (sem valores reais)
|
|
259
|
+
- .gitignore com: .env, .env.local, .env.*.local
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### .gitignore obrigatório
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
# Secrets — NUNCA commitar
|
|
266
|
+
.env
|
|
267
|
+
.env.local
|
|
268
|
+
.env.*.local
|
|
269
|
+
*.pem
|
|
270
|
+
*.key
|
|
271
|
+
*.p12
|
|
272
|
+
credentials.json
|
|
273
|
+
service-account.json
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Detecção de secrets no CI
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Pre-commit hook (recomendado)
|
|
280
|
+
# .pre-commit-config.yaml
|
|
281
|
+
repos:
|
|
282
|
+
- repo: https://github.com/gitleaks/gitleaks
|
|
283
|
+
rev: v8.18.0
|
|
284
|
+
hooks:
|
|
285
|
+
- id: gitleaks
|
|
286
|
+
|
|
287
|
+
# Ou manualmente:
|
|
288
|
+
gitleaks detect --source . --verbose
|
|
289
|
+
git secrets --scan
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Padrão de configuração
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
// ✅ CORRETO
|
|
296
|
+
const config = {
|
|
297
|
+
database: {
|
|
298
|
+
url: process.env.DATABASE_URL, // De environment variable
|
|
299
|
+
ssl: process.env.DB_SSL === 'true',
|
|
300
|
+
},
|
|
301
|
+
jwt: {
|
|
302
|
+
secret: process.env.JWT_SECRET, // NUNCA hardcoded
|
|
303
|
+
expiresIn: '15m',
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
// Validação no startup — falha rápido se falta secret
|
|
308
|
+
const required = ['DATABASE_URL', 'JWT_SECRET'];
|
|
309
|
+
for (const key of required) {
|
|
310
|
+
if (!process.env[key]) throw new Error(\`Missing env: \${key}\`);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 🚨 Security Anti-Patterns Detectados
|
|
317
|
+
|
|
318
|
+
✅ Nenhum anti-pattern de segurança detectado no scan automático.\n> ⚠️ Isso NÃO significa que o projeto está seguro. Análise manual é necessária.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## ✅ Checklist de Segurança por Camada
|
|
323
|
+
|
|
324
|
+
### Controller / API Layer
|
|
325
|
+
```
|
|
326
|
+
□ Input validado com DTO/Schema
|
|
327
|
+
□ Rate limiting configurado
|
|
328
|
+
□ Auth guard aplicado
|
|
329
|
+
□ CORS configurado corretamente
|
|
330
|
+
□ Response não expõe dados internos
|
|
331
|
+
□ Error handling sem stack trace
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Service / Business Layer
|
|
335
|
+
```
|
|
336
|
+
□ Autorização verificada (ownership)
|
|
337
|
+
□ Dados sensíveis criptografados
|
|
338
|
+
□ Lógica de negócio com audit log
|
|
339
|
+
□ Sem eval/exec com input externo
|
|
340
|
+
□ Timeout em operações externas
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Data / Repository Layer
|
|
344
|
+
```
|
|
345
|
+
□ Queries parametrizadas (NUNCA concatenação)
|
|
346
|
+
□ Connection pooling com limits
|
|
347
|
+
□ Migrations reversíveis
|
|
348
|
+
□ Dados sensíveis com encryption at rest
|
|
349
|
+
□ Backup policy definida
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Frontend / Mobile Layer
|
|
353
|
+
```
|
|
354
|
+
□ XSS prevenido (sanitization)
|
|
355
|
+
□ CSRF token em formulários
|
|
356
|
+
□ Tokens em httpOnly cookies (não localStorage)
|
|
357
|
+
□ Content Security Policy
|
|
358
|
+
□ Sem secrets no bundle (NUNCA)
|
|
359
|
+
□ Validação client-side + server-side
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 🛡️ Threat Model (STRIDE)
|
|
365
|
+
|
|
366
|
+
Antes de implementar features sensíveis, usar template STRIDE:
|
|
367
|
+
|
|
368
|
+
```
|
|
369
|
+
| Ameaça | Descrição | Mitigação |
|
|
370
|
+
|---------------------|------------------------------------|-----------|
|
|
371
|
+
| Spoofing | Alguém se passando por outro | Auth forte, MFA |
|
|
372
|
+
| Tampering | Dados alterados em trânsito | TLS, HMAC, checksums |
|
|
373
|
+
| Repudiation | Negar ação realizada | Audit logs |
|
|
374
|
+
| Info Disclosure | Vazamento de dados | Encryption, access control |
|
|
375
|
+
| Denial of Service | Indisponibilidade | Rate limiting, CDN, autoscaling |
|
|
376
|
+
| Elevation of Priv. | Escalar permissões | Least privilege, RBAC |
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
> Template completo disponível em: `templates/THREAT-MODEL.md`
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## 📊 Verificação Automatizada
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
# Scan de vulnerabilidades em dependências
|
|
387
|
+
npm audit
|
|
388
|
+
npx audit-ci --critical
|
|
389
|
+
|
|
390
|
+
# Scan de secrets no código
|
|
391
|
+
# (configure pre-commit hook)
|
|
392
|
+
git secrets --scan
|
|
393
|
+
gitleaks detect
|
|
394
|
+
|
|
395
|
+
# Score de arquitetura (inclui métricas de segurança)
|
|
396
|
+
architect score ./src
|
|
397
|
+
architect anti-patterns ./src
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
**Gerado por Architect v3.1 · Score: 72/100**
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
antigravity:
|
|
3
|
+
trigger: 'always_on'
|
|
4
|
+
globs: ['**/*.ts']
|
|
5
|
+
description: 'Regras NestJS para test-project'
|
|
6
|
+
priority: HIGH
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ⚙️ Regras NestJS — test-project
|
|
10
|
+
|
|
11
|
+
> **Padrões obrigatórios para desenvolvimento NestJS.**
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 📦 Estrutura de Módulo
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Cada feature = 1 módulo NestJS
|
|
19
|
+
|
|
20
|
+
src/modules/[feature]/
|
|
21
|
+
├── [feature].module.ts → @Module({ imports, providers, exports })
|
|
22
|
+
├── [feature].controller.ts → @Controller() — HTTP endpoints
|
|
23
|
+
├── [feature].controller.spec.ts → Testes do controller
|
|
24
|
+
├── [feature].service.ts → @Injectable() — Lógica de negócio
|
|
25
|
+
├── [feature].service.spec.ts → Testes do service
|
|
26
|
+
├── dto/
|
|
27
|
+
│ ├── create-[feature].dto.ts → class-validator + class-transformer
|
|
28
|
+
│ ├── update-[feature].dto.ts → Partial<CreateDto>
|
|
29
|
+
│ └── [feature]-response.dto.ts → Response shape (NUNCA entity direta)
|
|
30
|
+
├── entities/
|
|
31
|
+
│ └── [feature].entity.ts → @Entity() TypeORM / Prisma model
|
|
32
|
+
├── guards/ → Guards específicos
|
|
33
|
+
├── pipes/ → Pipes customizados
|
|
34
|
+
└── interfaces/ → Interfaces do módulo
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 🎯 Decorators — Uso Correto
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
@Controller() → Routing APENAS. Sem lógica de negócio.
|
|
43
|
+
@Injectable() → Services, Repositories. Injetáveis.
|
|
44
|
+
@Module() → Agrupa components. Declara imports/exports.
|
|
45
|
+
@Entity() → Modelo de banco. NUNCA expor na API.
|
|
46
|
+
|
|
47
|
+
Guards:
|
|
48
|
+
@UseGuards(AuthGuard) → Autenticação
|
|
49
|
+
@UseGuards(RolesGuard) → Autorização
|
|
50
|
+
@Roles('admin', 'user') → Roles necessárias
|
|
51
|
+
|
|
52
|
+
Pipes:
|
|
53
|
+
@UsePipes(ValidationPipe) → Validação de DTO
|
|
54
|
+
{ whitelist: true, forbidNonWhitelisted: true, transform: true }
|
|
55
|
+
|
|
56
|
+
Interceptors:
|
|
57
|
+
@UseInterceptors(LoggingInterceptor) → Logging
|
|
58
|
+
@UseInterceptors(TransformInterceptor) → Response shape
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 🚫 Anti-Patterns NestJS
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
❌ PROIBIDO: Lógica de negócio no controller
|
|
67
|
+
→ Mover para service
|
|
68
|
+
|
|
69
|
+
❌ PROIBIDO: Entity como response de API
|
|
70
|
+
→ Criar DTO de response
|
|
71
|
+
|
|
72
|
+
❌ PROIBIDO: @Body() sem DTO validado
|
|
73
|
+
→ Criar DTO com class-validator
|
|
74
|
+
|
|
75
|
+
❌ PROIBIDO: Service importando Request/Response
|
|
76
|
+
→ Service recebe dados puros, controller adapta
|
|
77
|
+
|
|
78
|
+
❌ PROIBIDO: Circular module imports
|
|
79
|
+
→ Usar forwardRef() ou extrair shared module
|
|
80
|
+
|
|
81
|
+
❌ PROIBIDO: Repository no controller
|
|
82
|
+
→ Controller → Service → Repository
|
|
83
|
+
|
|
84
|
+
❌ PROIBIDO: try/catch genérico no controller
|
|
85
|
+
→ Usar exception filters
|
|
86
|
+
|
|
87
|
+
❌ PROIBIDO: console.log
|
|
88
|
+
→ Usar @nestjs/common Logger ou winston
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## ✅ Patterns NestJS Obrigatórios
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
✅ Global validation pipe no bootstrap
|
|
97
|
+
✅ Global exception filter (HttpExceptionFilter)
|
|
98
|
+
✅ DTOs com class-validator para TODOS os endpoints
|
|
99
|
+
✅ Config via @nestjs/config + .env
|
|
100
|
+
✅ Database via TypeORM/Prisma com migrations
|
|
101
|
+
✅ Auth via Passport + JWT strategy
|
|
102
|
+
✅ Swagger via @nestjs/swagger + ApiProperty()
|
|
103
|
+
✅ Health check endpoint (/health)
|
|
104
|
+
✅ Cobertura ≥ 80%
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 📋 Checklist por Endpoint
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
□ DTO de request com validação
|
|
113
|
+
□ DTO de response (não entity)
|
|
114
|
+
□ Guard de auth aplicado
|
|
115
|
+
□ Swagger decorators (@ApiTags, @ApiOperation, @ApiResponse)
|
|
116
|
+
□ Error handling (HttpException com status correto)
|
|
117
|
+
□ Teste unitário do service method
|
|
118
|
+
□ Teste de integração do endpoint
|
|
119
|
+
□ Logging estruturado
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
**Gerado por Architect v3.1**
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# 📋 Template: ADR — Architecture Decision Record
|
|
2
|
+
|
|
3
|
+
> Use quando uma decisão técnica é significativa ou controversa.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ADR-001: Uso de NestJS para Backend
|
|
8
|
+
|
|
9
|
+
**Status:** proposed | accepted | deprecated | superseded by ADR-YYY
|
|
10
|
+
**Data:** YYYY-MM-DD
|
|
11
|
+
**Autores:** [quem participou da decisão]
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
### Contexto
|
|
16
|
+
|
|
17
|
+
> Qual é o problema ou necessidade que levou a esta decisão?
|
|
18
|
+
|
|
19
|
+
O projeto requer uma API REST escalável com TypeScript. Precisamos escolher um framework que:
|
|
20
|
+
- Suporte TypeScript nativo
|
|
21
|
+
- Tenha decorators e dependency injection
|
|
22
|
+
- Tenha comunidade ativa e documentação excelente
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
### Decisão
|
|
27
|
+
|
|
28
|
+
> O que foi decidido?
|
|
29
|
+
|
|
30
|
+
Decidimos usar NestJS como framework backend principal. NestJS oferece:
|
|
31
|
+
- Arquitetura modular built-in
|
|
32
|
+
- Decorators para roteamento e middleware
|
|
33
|
+
- Injeção de dependência nativa
|
|
34
|
+
- Suporte a bancos de dados (TypeORM, Prisma, etc.)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### Alternativas Consideradas
|
|
39
|
+
|
|
40
|
+
| # | Alternativa | Prós | Contras | Por que descartada |
|
|
41
|
+
|---|-----------|------|---------|-------------------|
|
|
42
|
+
| 1 | Express.js + middleware customizado | [prós] | [contras] | [motivo] |
|
|
43
|
+
| 2 | Fastify | [prós] | [contras] | [motivo] |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### Consequências
|
|
48
|
+
|
|
49
|
+
**Positivas:**
|
|
50
|
+
- Arquitetura clara e escalável
|
|
51
|
+
- Código mais organizado e testável
|
|
52
|
+
- Comunidade ativa para suporte
|
|
53
|
+
|
|
54
|
+
**Negativas:**
|
|
55
|
+
- Curva de aprendizado para novos desenvolvedores
|
|
56
|
+
- Overhead de dependências
|
|
57
|
+
|
|
58
|
+
**Riscos:**
|
|
59
|
+
- Atualização de versões major — probabilidade: média
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### Notas
|
|
64
|
+
|
|
65
|
+
- Revisar em 6 meses se a decisão continua válida
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## ADR-002: Banco de Dados PostgreSQL
|
|
71
|
+
|
|
72
|
+
**Status:** accepted
|
|
73
|
+
**Data:** 2024-01-15
|
|
74
|
+
**Autores:** [equipe técnica]
|
|
75
|
+
|
|
76
|
+
### Contexto
|
|
77
|
+
|
|
78
|
+
Precisamos escolher um banco de dados relacional que:
|
|
79
|
+
- Suporte transações ACID
|
|
80
|
+
- Tenha integração com NestJS
|
|
81
|
+
- Permita escalabilidade horizontal
|
|
82
|
+
|
|
83
|
+
### Decisão
|
|
84
|
+
|
|
85
|
+
Escolhemos PostgreSQL como banco de dados principal por:
|
|
86
|
+
- Suporte a JSON nativo
|
|
87
|
+
- Excelente performance em leitura/escrita
|
|
88
|
+
- Integração com TypeORM/Prisma é padrão
|
|
89
|
+
|
|
90
|
+
### Alternativas Consideradas
|
|
91
|
+
|
|
92
|
+
| # | Alternativa | Prós | Contras |
|
|
93
|
+
|---|-----------|------|---------|
|
|
94
|
+
| 1 | MySQL | Popular, estável | Menos recursos avançados |
|
|
95
|
+
| 2 | MongoDB | Escalável | Sem ACID nativo, schema dinâmico |
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# 🧪 Template: BDD — Behavior-Driven Development
|
|
2
|
+
|
|
3
|
+
> Um cenário para cada critério de aceite + cenários de erro + edge cases.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Feature: Criar e Validar User.Entity
|
|
8
|
+
|
|
9
|
+
```gherkin
|
|
10
|
+
Feature: Criar e Validar User.Entity
|
|
11
|
+
Como usuário,
|
|
12
|
+
Quero interagir com User.Entity,
|
|
13
|
+
Para alcançar meu objetivo de negócio.
|
|
14
|
+
|
|
15
|
+
# ── Happy Path ──
|
|
16
|
+
|
|
17
|
+
Scenario: Criar User.Entity com sucesso
|
|
18
|
+
Given o usuário está no formulário de criação de User.Entity
|
|
19
|
+
And todos os campos obrigatórios estão vazios
|
|
20
|
+
When o usuário preenche os campos corretamente
|
|
21
|
+
Then a entidade é persistida no banco de dados
|
|
22
|
+
And uma mensagem de sucesso é exibida ao usuário
|
|
23
|
+
|
|
24
|
+
# ── Validações ──
|
|
25
|
+
|
|
26
|
+
Scenario: Validação de dados obrigatórios
|
|
27
|
+
Given um formulário de criação
|
|
28
|
+
When o usuário tenta enviar sem preencher campos obrigatórios
|
|
29
|
+
Then mensagens de erro são exibidas para cada campo
|
|
30
|
+
|
|
31
|
+
# ── Edge Cases ──
|
|
32
|
+
|
|
33
|
+
Scenario: Lidar com valores boundary
|
|
34
|
+
Given o sistema aceita valores de 0 a 999999.99
|
|
35
|
+
When o usuário tenta inserir um valor fora do range
|
|
36
|
+
Then um erro de validação é retornado
|
|
37
|
+
|
|
38
|
+
# ── Permissões ──
|
|
39
|
+
|
|
40
|
+
Scenario: Acesso a dados sensíveis de paciente
|
|
41
|
+
Given um profissional de saúde autenticado
|
|
42
|
+
When o profissional acessa registros de paciente
|
|
43
|
+
Then o acesso é registrado com timestamp e usuário
|
|
44
|
+
And a ação é auditada para compliance
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Checklist
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
□ Cada critério de aceite tem ≥ 1 cenário
|
|
53
|
+
□ Happy path coberto
|
|
54
|
+
□ Error paths cobertos
|
|
55
|
+
□ Edge cases cobertos
|
|
56
|
+
□ Permissões/autenticação cobertos
|
|
57
|
+
□ Cenários são independentes entre si
|
|
58
|
+
```
|