create-sdd-ai-stack 0.1.17

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 (72) hide show
  1. package/AGENTS.md +164 -0
  2. package/APP-STACK.md +31 -0
  3. package/APP.md +46 -0
  4. package/ARCHITECTURE.md +115 -0
  5. package/DESIGN.md +219 -0
  6. package/LICENSE +21 -0
  7. package/NEXT.md +345 -0
  8. package/NODE.md +107 -0
  9. package/REACT.md +92 -0
  10. package/README.md +260 -0
  11. package/SKILLS/check-docs/SKILL.md +24 -0
  12. package/SKILLS/check-docs/check-docs.mjs +56 -0
  13. package/SKILLS/create-feature/SKILL.md +40 -0
  14. package/SKILLS/create-feature/create-feature.mjs +128 -0
  15. package/SKILLS/create-feature.sh +112 -0
  16. package/SKILLS/install-submodule/SKILL.md +42 -0
  17. package/SKILLS/install-submodule/install-submodule.mjs +119 -0
  18. package/bin/create-sdd-ai-stack.mjs +93 -0
  19. package/docs/CHANGELOG.md +209 -0
  20. package/docs/PLANNING.md +68 -0
  21. package/docs/PRODUCT.md +76 -0
  22. package/docs/RELEASE.md +332 -0
  23. package/lib/check-links.mjs +42 -0
  24. package/lib/constants.mjs +60 -0
  25. package/lib/scaffold.mjs +253 -0
  26. package/package.json +80 -0
  27. package/specs/BACKLOG.md +24 -0
  28. package/specs/PLAN.md +57 -0
  29. package/specs/ROADMAP.md +35 -0
  30. package/specs/history/phases/phase-0-bootstrap.md +67 -0
  31. package/specs/tasks/TASK_TEMPLATE.md +46 -0
  32. package/src/cli.mjs +119 -0
  33. package/stacks/README.md +33 -0
  34. package/stacks/ai.md +52 -0
  35. package/stacks/ci.md +59 -0
  36. package/stacks/database.md +56 -0
  37. package/stacks/git.md +51 -0
  38. package/stacks/shadcn.md +52 -0
  39. package/stacks/tailwind.md +65 -0
  40. package/stacks/testing.md +74 -0
  41. package/stacks/typescript.md +58 -0
  42. package/template/next/.env.example +4 -0
  43. package/template/next/README.md +47 -0
  44. package/template/next/biome.json +36 -0
  45. package/template/next/gitignore +32 -0
  46. package/template/next/next.config.ts +12 -0
  47. package/template/next/package.json +47 -0
  48. package/template/next/playwright.config.ts +21 -0
  49. package/template/next/postcss.config.mjs +7 -0
  50. package/template/next/src/app/(app)/app/page.tsx +18 -0
  51. package/template/next/src/app/(app)/error.tsx +30 -0
  52. package/template/next/src/app/(app)/layout.tsx +25 -0
  53. package/template/next/src/app/(marketing)/page.tsx +73 -0
  54. package/template/next/src/app/globals.css +437 -0
  55. package/template/next/src/app/layout.tsx +41 -0
  56. package/template/next/src/app/not-found.tsx +11 -0
  57. package/template/next/src/features/example/actions.ts +43 -0
  58. package/template/next/src/features/example/application/create-example.usecase.ts +26 -0
  59. package/template/next/src/features/example/container.ts +16 -0
  60. package/template/next/src/features/example/domain/IExampleRepository.ts +11 -0
  61. package/template/next/src/features/example/domain/example.schema.ts +18 -0
  62. package/template/next/src/features/example/infrastructure/example.repository.ts +26 -0
  63. package/template/next/src/features/example/ui/create-example-form.tsx +56 -0
  64. package/template/next/src/proxy.ts +23 -0
  65. package/template/next/src/shared/lib/cn.ts +6 -0
  66. package/template/next/src/shared/server/auth.ts +32 -0
  67. package/template/next/src/shared/server/env.ts +14 -0
  68. package/template/next/src/shared/ui/index.ts +3 -0
  69. package/template/next/tests/e2e/routes.spec.ts +34 -0
  70. package/template/next/tests/unit/create-example.test.ts +55 -0
  71. package/template/next/tsconfig.json +37 -0
  72. package/template/next/vitest.config.ts +19 -0
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "create-sdd-ai-stack",
3
+ "version": "0.1.17",
4
+ "description": "Cria um projeto pronto para agentes de IA com Spec-Driven Development: regras SDD + template Next.js 16 + design system.",
5
+ "keywords": [
6
+ "sdd",
7
+ "spec-driven-development",
8
+ "ai",
9
+ "agent",
10
+ "agents",
11
+ "claude",
12
+ "cursor",
13
+ "nextjs",
14
+ "template",
15
+ "boilerplate",
16
+ "scaffold"
17
+ ],
18
+ "homepage": "https://github.com/marcelinosandroni/sdd-ai-stack#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/marcelinosandroni/sdd-ai-stack/issues"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/marcelinosandroni/sdd-ai-stack.git"
25
+ },
26
+ "license": "MIT",
27
+ "author": "Marcelino Sandroni <marcelino.sandroni@gmail.com>",
28
+ "type": "module",
29
+ "bin": {
30
+ "create-sdd-ai-stack": "bin/create-sdd-ai-stack.mjs"
31
+ },
32
+ "main": "lib/scaffold.mjs",
33
+ "exports": {
34
+ ".": "./lib/scaffold.mjs",
35
+ "./scaffold": "./lib/scaffold.mjs",
36
+ "./constants": "./lib/constants.mjs",
37
+ "./check-links": "./lib/check-links.mjs",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "engines": {
41
+ "node": ">=20.9.0"
42
+ },
43
+ "files": [
44
+ "bin",
45
+ "src",
46
+ "lib",
47
+ "template",
48
+ "AGENTS.md",
49
+ "APP.md",
50
+ "APP-STACK.md",
51
+ "ARCHITECTURE.md",
52
+ "DESIGN.md",
53
+ "NEXT.md",
54
+ "NODE.md",
55
+ "REACT.md",
56
+ "stacks",
57
+ "specs",
58
+ "docs",
59
+ "SKILLS",
60
+ "README.md",
61
+ "LICENSE"
62
+ ],
63
+ "scripts": {
64
+ "test": "node --test tests/*.test.mjs",
65
+ "check:docs": "node SKILLS/check-docs/check-docs.mjs",
66
+ "check:pack": "npm pack --dry-run",
67
+ "version:patch": "npm version patch --git-tag-version",
68
+ "version:minor": "npm version minor --git-tag-version",
69
+ "version:major": "npm version major --git-tag-version",
70
+ "prepublishOnly": "npm run test && npm run check:pack"
71
+ },
72
+ "publishConfig": {
73
+ "access": "public"
74
+ },
75
+ "directories": {
76
+ "doc": "docs",
77
+ "lib": "lib",
78
+ "test": "tests"
79
+ }
80
+ }
@@ -0,0 +1,24 @@
1
+ # 📥 BACKLOG
2
+
3
+ > Ideias soltas, débito técnico e explorações. **Nada aqui é promessa.**
4
+ > Quando virar trabalho de verdade, promova para `specs/PLAN.md` como task.
5
+
6
+ ## 💡 Ideias
7
+
8
+ - [ ] Definir regras de refinamento/produto em `docs/PLANNING.md` (artefatos visuais de planejamento)
9
+ - [ ] Gerar PR template que force o preenchimento da evidência de teste
10
+ - [ ] Script de release que abre PR automático do changelog
11
+ - [ ] Storybook para os componentes de `src/shared/ui`
12
+ - [ ] Integração com GitHub Actions para o Next.js DevTools MCP
13
+
14
+ ## 🧾 Débito técnico
15
+
16
+ _(adicionado quando algo fica pra depois — com o motivo)_
17
+
18
+ - [ ] Nenhum registrado ainda
19
+
20
+ ## 🗑️ Descartado
21
+
22
+ _(ideias que testamos e não valem o custo — registre o porquê pra não repetir)_
23
+
24
+ - _(vazio)_
package/specs/PLAN.md ADDED
@@ -0,0 +1,57 @@
1
+ # 🎯 PLAN (O Cérebro do Projeto)
2
+
3
+ > 🛑 **REGRA FIXA (Agente IA, LEIA ISSO ANTES DE CODAR):**
4
+ > O desenvolvedor (Marcelino) tem TDAH. As tarefas AQUI devem ser **microscópicas**.
5
+ > Se uma tarefa levar mais de 1 hora pra fazer, QUEBRE ELA EM DUAS.
6
+ > Nunca pule um passo. Nunca comece o Passo 2 sem testar e commitar o Passo 1.
7
+ > Atualize os status rigorosamente no final de cada prompt: `[ ]` (To Do), `[-]` (In Progress), `[x]` (Done).
8
+
9
+ > **Existe exatamente UMA task `[-]` em todo momento.** Se houver duas, o agente parou errado.
10
+
11
+ ---
12
+
13
+ ## Fase atual: 0 — Bootstrap
14
+
15
+ > Status: ✅ concluída (template + regras + CLI)
16
+ > Histórico: [`history/phases/phase-0-bootstrap.md`](./history/phases/phase-0-bootstrap.md)
17
+
18
+ ### Como usar este arquivo
19
+
20
+ 1. Substitua o bloco abaixo pela fase atual do seu projeto.
21
+ 2. Nomeie a task `TASK-<FASE>-<NÚMERO>` e crie o arquivo em `specs/tasks/TASK-<FASE>-<NÚMERO>.md`
22
+ (use o [template](./tasks/TASK_TEMPLATE.md)).
23
+ 3. Marque `[-]` **antes** de começar a codar. Marque `[x]` **depois** de colar a evidência verde do terminal.
24
+ 4. Ao fechar a fase, arquive em `history/phases/` e gere a tag SemVer.
25
+
26
+ ---
27
+
28
+ ```markdown
29
+ ## Fase atual: [N] — [NOME DA FASE]
30
+
31
+ [ ] - [TASK-1.1](./tasks/TASK-1.1.md) - [fazer]
32
+ [-] - [TASK-1.2](./tasks/TASK-1.2.md) - [fazendo] ← única task em progresso
33
+ [ ] - [TASK-1.3](./tasks/TASK-1.3.md) - [fazer]
34
+
35
+ ### Critério de saída da fase
36
+ - [ ] Todas as tasks `[x]` com evidência de teste colada
37
+ - [ ] `npm run typecheck && npm run lint && npm run test && npm run build` verdes
38
+ - [ ] `docs/CHANGELOG.md` atualizado
39
+ - [ ] `specs/history/phases/phase-N-finished.md` escrito
40
+ - [ ] Tag SemVer gerada
41
+ ```
42
+
43
+ ---
44
+
45
+ ## 📋 Checklist de entrega (cole no fim de cada task)
46
+
47
+ ```markdown
48
+ **Evidência:**
49
+ - `npm run typecheck` → exit 0
50
+ - `npm run lint` → 0 erros
51
+ - `npm run test` → N passed
52
+ - `npm run test:e2e` → N passed
53
+ - `npm run build` → ✓ Compiled successfully
54
+
55
+ **Arquivos tocados:** (liste — máximo 5 por passo)
56
+ **Commit:** `tipo(escopo): descrição. (Agent: <Ferramenta> - <Modelo>)`
57
+ ```
@@ -0,0 +1,35 @@
1
+ # 🗺️ ROADMAP
2
+
3
+ > Visão macro. **Não use isto para trabalhar** — use [`PLAN.md`](./PLAN.md) para a task de agora.
4
+
5
+ ## Fase 0 — Bootstrap ✅
6
+
7
+ Template Next.js 16, regras SDD, design system, CLI `npx create-sdd-ai-stack`, instalação por submodule.
8
+
9
+ ## Fase 1 — Fundação do produto
10
+
11
+ Entregar o primeiro slice de ponta a ponta (vertical): domínio → use case → repository → rota → UI → teste.
12
+
13
+ ## Fase 2 — Escala
14
+
15
+ Multi-tenant, autorização por papel, auditoria, filas, observabilidade.
16
+
17
+ ## Fase 3 — Produto
18
+
19
+ Billing, onboarding, growth loop, o que o negócio pedir.
20
+
21
+ ---
22
+
23
+ ## 🧭 Como este roadmap conversa com o PLAN
24
+
25
+ ```text
26
+ ROADMAP.md → macro, anos (visão)
27
+ ↓
28
+ PLAN.md → esta semana (1 task por vez)
29
+ ↓
30
+ tasks/ → esta task, em detalhe (micro-passos)
31
+ ↓
32
+ commit → esta task, um passo (evidência)
33
+ ```
34
+
35
+ > Regra: **nenhuma task entra no PLAN sem existir no ROADMAP** (nem que seja uma linha só).
@@ -0,0 +1,67 @@
1
+ # ✅ Fase 0 — Bootstrap (CONCLUÍDA)
2
+
3
+ > **Período:** reestruturação do core SDD
4
+ > **Resultado:** template Next.js 16 funcional + regras Next-first + CLI `npx create-sdd-ai-stack`
5
+
6
+ ---
7
+
8
+ ## 🧭 O que era
9
+
10
+ - Stack focada em **React (Vite) + Node.js** (monorepo `client/` + `server/`)
11
+ - Sem template de projeto
12
+ - Sem regras de Next.js
13
+ - Sem CLI / pacote npm
14
+ - Regras espalhadas na raiz
15
+ - Design system genérico (Vercel/Linear padrão)
16
+
17
+ ## 🧭 O que virou
18
+
19
+ | Antes | Depois |
20
+ | --- | --- |
21
+ | React + Vite como padrão | **Next.js 16 (App Router)** como padrão |
22
+ | `NODE.md` genérico | `NODE.md` como **complemento** (worker/cron/fila) |
23
+ | `REACT.md` como doc de frontend | `REACT.md` como **complemento** (Server-First) |
24
+ | — | **`NEXT.md`** com 11 seções de regra |
25
+ | regras soltas na raiz | **`stacks/`** (typescript, tailwind, shadcn, testing, database, ai, git, ci) |
26
+ | `DESIGN.md` genérico | **`DESIGN.md`** Executive Engineering com tokens completos |
27
+ | — | **`APP-STACK.md`** (ponteiro de stack) |
28
+ | — | **`template/next/`** — Next.js 16 completo e testado |
29
+ | — | **CLI npm `create-sdd-ai-stack`** |
30
+ | — | **SKILL `install-submodule`** para projeto existente |
31
+ | — | **SKILL `check-docs`** (valida links entre documentos) |
32
+ | — | **`.github/workflows/ci.yml`** que revalida o template a cada push |
33
+
34
+ ## 🧪 Evidência
35
+
36
+ ```text
37
+ # CLI e documentação (21 testes)
38
+ npm test → tests 20 | pass 20 | fail 0
39
+ node SDD/SKILLS/check-docs/check-docs.mjs → ✓ 29 documentos, links OK
40
+
41
+ # Template gerado (evidence real)
42
+ npm run typecheck → exit 0
43
+ npm run lint → Checked 28 files, 0 erros, 0 warnings
44
+ npm run test → Test Files 1 passed, Tests 3 passed
45
+ npm run test:e2e → 4 passed
46
+ npm run build → ✓ Compiled successfully (Turbopack, Cache Components)
47
+ ┌ ○ / ├ ○ /_not-found └ ○ /app ƒ Proxy
48
+ ```
49
+
50
+ ## 🐛 Bugs encontrados e corrigidos durante a validação
51
+
52
+ 1. `import type { CreateExampleInput }` de arquivo errado (typecheck pegou)
53
+ 2. Import de path errado no `container.ts` do slice (typecheck pegou)
54
+ 3. `error.tsx` sem `"use client"` (build pegou)
55
+ 4. `reactCompiler: true` sem `babel-plugin-react-compiler` instalado (build pegou)
56
+ 5. `biome.json` no schema antigo (`recommended` → `preset`) (lint pegou)
57
+ 6. `prepare: "husky || true"` quebrava `npm install` no Windows (install pegou)
58
+ 7. `proxy.ts` redirecionava `/` e escondia a landing marketing (E2E pegou)
59
+ 8. Dupla rota em `/` (`app/page.tsx` + `(marketing)/page.tsx`) (E2E pegou)
60
+
61
+ > **Isso é a razão de existir a regra "prova de vida anti-alucinação" do AGENTS.md.**
62
+
63
+ ## 🏷️ Release
64
+
65
+ ```bash
66
+ git tag v0.1.17
67
+ ```
@@ -0,0 +1,46 @@
1
+ # ✅ TASK [NOME DA TASK]
2
+
3
+ > 🛑 **REGRA FIXA (Agente IA, LEIA ISSO):**
4
+ > 1. O dev (Marcelino) tem TDAH, cegueira temporal e zero paciência pra lixo.
5
+ > 2. Se a task inteira levar mais de 1 hora, QUEBRE EM DUAS TASKS AGORA.
6
+ > 3. Entregue o código de um passo, espere ele testar, e SÓ DEPOIS vá para o próximo.
7
+ > 4. O nome do arquivo da TASK deve ser sempre `TASK-PHASE-TASK` (ex: `TASK-1.1.md`).
8
+ > 5. Manter sempre na pasta `tasks/` e subpasta da fase (`tasks/phase-1/`).
9
+ > 6. **PROIBIDO EDITAR ACIMA DO TRAÇO.** Você SÓ tem permissão para preencher os dados ABAIXO da linha `---`.
10
+
11
+ ---
12
+
13
+ ## 🎯 Objetivo da Task
14
+
15
+ [1 linha. O que você quer fazer. Ex: "Criar o botão de gerar vídeo IA na feature video".]
16
+
17
+ ## 📂 Onde mexer
18
+
19
+ - [ ] `src/features/[x]/application/` — regra de negócio
20
+ - [ ] `src/features/[x]/infrastructure/` — repo/adaptador
21
+ - [ ] `src/features/[x]/actions.ts` — entrada de escrita
22
+ - [ ] `src/features/[x]/ui/` — componente
23
+ - [ ] `src/app/...` — rota (só roteia)
24
+ - [ ] `tests/` — testes
25
+
26
+ ## 🛠️ Micro-Passos (Checklist Dopamina)
27
+
28
+ *(Passos RIDICULAMENTE pequenos. Máximo 5 por task.)*
29
+
30
+ - [ ] Passo 1: [Ex: Criar a interface `IVideo.ts` em `domain/`]
31
+ - [ ] Passo 2: [Ex: Criar o layout burro do botão]
32
+ - [ ] Passo 3: [Ex: Ligar o botão no hook de DI]
33
+ - [ ] Passo 4: [Ex: Teste unit do use case]
34
+ - [ ] Passo 5: [Ex: E2E do fluxo]
35
+
36
+ ## 🏁 Definition of Done (Critério de Sucesso)
37
+
38
+ - [ ] `npm run typecheck` → exit 0
39
+ - [ ] `npm run lint` → 0 erros, 0 warnings
40
+ - [ ] `npm run test` → todo verde
41
+ - [ ] `npm run test:e2e` → todo verde
42
+ - [ ] `npm run build` → ✓ Compiled successfully
43
+ - [ ] Zero `any` no código novo
44
+ - [ ] Cores/estilos usando tokens do `DESIGN.md` (se tocou em UI)
45
+ - [ ] Evidência verde colada na resposta
46
+ - [ ] `specs/PLAN.md` atualizado para `[x]`
package/src/cli.mjs ADDED
@@ -0,0 +1,119 @@
1
+ import { DEFAULT_SUBMODULE_URL, DEFAULT_TEMPLATE, TEMPLATES } from "../lib/constants.mjs";
2
+
3
+ export const HELP = `
4
+ create-sdd-ai-stack — projeto pronto para agentes de IA (Spec-Driven Development)
5
+
6
+ USO
7
+ npx create-sdd-ai-stack <nome-do-app> [opções]
8
+
9
+ EXEMPLO
10
+ npx create-sdd-ai-stack meu-dashboard
11
+ npx create-sdd-ai-stack meu-dashboard --no-install
12
+ npx create-sdd-ai-stack meu-dashboard --submodule
13
+ npx create-sdd-ai-stack meu-dashboard --rules-only
14
+
15
+ OPÇÕES
16
+ --template <${TEMPLATES.join("|")}|none> Template de projeto (padrão: ${DEFAULT_TEMPLATE})
17
+ --rules-only Instala só as regras (sem app), em ./SDD
18
+ --submodule [url] Instala ./SDD como git submodule (padrão: repo oficial)
19
+ --no-install Não roda npm install
20
+ --install Roda npm install (padrão: não roda)
21
+ --git / --no-git git init + primeiro commit (padrão: não roda)
22
+ --shortcuts <auto|stub|symlink>
23
+ Como criar os atalhos da raiz (padrão: auto)
24
+ -y, --yes Não pede confirmação
25
+ -h, --help Esta ajuda
26
+ -v, --version Versão
27
+
28
+ O QUE É CRIADO
29
+ <app>/
30
+ ├── src/ … template Next.js 16 (App Router, Tailwind v4, Biome, Vitest)
31
+ ├── SDD/ as regras: AGENTS.md, NEXT.md, DESIGN.md, stacks/, specs/…
32
+ ├── AGENTS.md atalho → ./SDD/AGENTS.md
33
+ ├── CLAUDE.md, GEMINI.md, .cursorrules, .github/copilot-instructions.md …
34
+ └── package.json
35
+
36
+ DOCS
37
+ https://github.com/marcelinosandroni/sdd-ai-stack
38
+ `;
39
+
40
+ export function parseArgs(argv) {
41
+ const opts = {
42
+ name: null,
43
+ template: DEFAULT_TEMPLATE,
44
+ install: false,
45
+ git: false,
46
+ submodule: null,
47
+ rulesOnly: false,
48
+ shortcutMode: "auto",
49
+ help: false,
50
+ version: false,
51
+ };
52
+
53
+ for (let i = 0; i < argv.length; i++) {
54
+ const arg = argv[i];
55
+ const next = () => argv[++i];
56
+
57
+ switch (arg) {
58
+ case "-h":
59
+ case "--help":
60
+ opts.help = true;
61
+ break;
62
+ case "-v":
63
+ case "--version":
64
+ opts.version = true;
65
+ break;
66
+ case "-y":
67
+ case "--yes":
68
+ break;
69
+ case "--rules-only":
70
+ opts.rulesOnly = true;
71
+ opts.template = "none";
72
+ break;
73
+ case "--install":
74
+ opts.install = true;
75
+ break;
76
+ case "--no-install":
77
+ opts.install = false;
78
+ break;
79
+ case "--git":
80
+ opts.git = true;
81
+ break;
82
+ case "--no-git":
83
+ opts.git = false;
84
+ break;
85
+ case "--submodule": {
86
+ const value = argv[i + 1];
87
+ if (value && !value.startsWith("-")) {
88
+ opts.submodule = value;
89
+ i++;
90
+ } else {
91
+ opts.submodule = DEFAULT_SUBMODULE_URL;
92
+ }
93
+ break;
94
+ }
95
+ case "--template": {
96
+ const value = next();
97
+ if (!value) throw new Error("--template exige um valor");
98
+ if (value !== "none" && !TEMPLATES.includes(value)) {
99
+ throw new Error(`Template inválido: "${value}". Use: ${TEMPLATES.join(", ")} ou none.`);
100
+ }
101
+ opts.template = value;
102
+ break;
103
+ }
104
+ case "--shortcuts": {
105
+ const value = next();
106
+ if (!["auto", "stub", "symlink"].includes(value)) {
107
+ throw new Error(`--shortcuts inválido: "${value}". Use: auto, stub, symlink.`);
108
+ }
109
+ opts.shortcutMode = value;
110
+ break;
111
+ }
112
+ default:
113
+ if (arg.startsWith("-")) throw new Error(`Opção desconhecida: ${arg}`);
114
+ if (!opts.name) opts.name = arg;
115
+ }
116
+ }
117
+
118
+ return opts;
119
+ }
@@ -0,0 +1,33 @@
1
+ # 🧱 STACKS — REGRAS POR LINGUAGEM E FERRAMENTA
2
+
3
+ > **Leia o índice, depois abra só o arquivo do que você está tocando.**
4
+ > Stack padrão do projeto: **[Next.js](../NEXT.md)**. React e Node são complementos.
5
+
6
+ ## 📇 Índice
7
+
8
+ | Arquivo | Quando abrir |
9
+ | --- | --- |
10
+ | [typescript.md](./typescript.md) | Tipos, interfaces, genéricos, strict mode |
11
+ | [tailwind.md](./tailwind.md) | Estilo, tokens, classes utilitárias |
12
+ | [shadcn.md](./shadcn.md) | Componentes de UI, primitives, variações |
13
+ | [testing.md](./testing.md) | Unit, integração, E2E, cobertura |
14
+ | [database.md](./database.md) | Prisma, migrations, queries, transações |
15
+ | [ai.md](./ai.md) | Integrações com LLM/IA, streaming, tokens |
16
+ | [git.md](./git.md) | Commits, branches, PRs, releases |
17
+ | [ci.md](./ci.md) | GitHub Actions, lint, typecheck, deploy |
18
+
19
+ ## 🎯 Módulos de regra fora desta pasta
20
+
21
+ | Arquivo | Escopo |
22
+ | --- | --- |
23
+ | [../NEXT.md](../NEXT.md) | Next.js 16 (App Router, RSC, Cache Components) — **PADRÃO** |
24
+ | [../NODE.md](../NODE.md) | Node.js puro (workers, cron, filas, scripts) |
25
+ | [../REACT.md](../REACT.md) | React (hooks, estado, composição) |
26
+ | [../DESIGN.md](../DESIGN.md) | Design system completo (tokens, tipografia, componentes) |
27
+ | [../ARCHITECTURE.md](../ARCHITECTURE.md) | Arquitetura global e vertical slices |
28
+
29
+ ## 🚫 Regra de ouro
30
+
31
+ > **Antes de instalar qualquer lib, prove que o nativo resolve.**
32
+ > `fetch` > axios. `<dialog>` > lib de modal. CSS > tailwind plugin.
33
+ > Se a lib entrar, ela entra com uma nota em `docs/CHANGELOG.md` explicando o porquê.
package/stacks/ai.md ADDED
@@ -0,0 +1,52 @@
1
+ # 🤖 AI / LLM
2
+
3
+ > Regras para integrar modelos de linguagem. Custo, latência e segurança importam tanto quanto a resposta.
4
+
5
+ ## 🚨 Regras não-negociáveis
6
+
7
+ 1. **Chamada de LLM NUNCA acontece dentro de um Server Component.** Vai para uma Server Action ou um use case em `application/`.
8
+ 2. **NUNCA exponha a `OPENAI/ANTHROPIC_API_KEY` no client.** Sempre `import "server-only"` no módulo.
9
+ 3. **Toda chamada a LLM tem `timeout` e tratamento de erro.** O usuário nunca fica em loading eterno.
10
+ 4. **Streaming para UX longa.** Resposta de LLM > 1s é streaming (ver AI SDK / `ReadableStream`).
11
+ 5. **Limite de tokens SEMPRE explícito** (`max_tokens`/`maxOutputTokens`). Nunca deixe o modelo "falar à vontade".
12
+ 6. **Custo é requisito, não detalhe.** Modelos caros (Opus/GPT-4o) só com justificativa em `docs/CHANGELOG.md`.
13
+ 7. **Nada de dado sensível no prompt** sem necessidade (LGPD).Anonimize antes.
14
+
15
+ ## 🧩 Padrão de chamada
16
+
17
+ ```ts
18
+ // features/chat/application/generate-reply.ts
19
+ import "server-only";
20
+ import { generateText } from "ai";
21
+
22
+ export async function generateReply(prompt: string) {
23
+ const { text } = await generateText({
24
+ model: "openai/gpt-4o-mini",
25
+ prompt,
26
+ maxTokens: 1024, // SEMPRE limite
27
+ abortSignal: AbortSignal.timeout(15_000), // SEMPRE timeout
28
+ });
29
+ return text;
30
+ }
31
+ ```
32
+
33
+ ## 🎯 Escolha de modelo (custo vs qualidade)
34
+
35
+ | Caso | Modelo típico |
36
+ | --- | --- |
37
+ | Classificar/extrair/formatar | mini / small |
38
+ | Copy de marketing, resumo | mini / small |
39
+ | Raciocínio complexo, código | big / Opus |
40
+ | Embedding | `*-embed` dedicado |
41
+
42
+ ## 🛡️ Segurança
43
+
44
+ - **Valide a saída do LLM antes de usar.** Saída é input não-confiável. Zod no retorno, sempre.
45
+ - **Never inlined secrets em prompt de cliente.**
46
+ - **Rate limit por usuário/rota** em qualquer endpoint que chame LLM (evite key draining).
47
+ - **Log de chamada** com modelo + tokens (custo visível em produção).
48
+
49
+ ## 📊 O que observar
50
+
51
+ - **Streaming vs não:** UX (streaming) vs complexidade.
52
+ - **Caching:** mesmo prompt → cache sem custo. Use `'use cache'` quando a entrada for estável.
package/stacks/ci.md ADDED
@@ -0,0 +1,59 @@
1
+ # ⚙️ CI / CD
2
+
3
+ ## 🚨 Regras não-negociáveis
4
+
5
+ 1. **Pipeline mínimo obrigatório em todo repo:** `lint` → `typecheck` → `test` → `build`. Nessa ordem.
6
+ 2. **CI é o portão.** Se passou local mas falha no CI, o CI está certo.
7
+ 3. **Node e pnpm/npm fixados por versão** (Node 20.9+ para Next 16). Sem `latest` em CI.
8
+ 4. **Deploy só da `main`.** Feature branch nunca faz deploy de produção.
9
+ 5. **Segredo só via secrets do repositório.** Nunca no código do workflow.
10
+ 6. **Ambiente de preview por PR** é obrigatório (qualidade de review).
11
+
12
+ ## 🔧 Pipeline padrão (GitHub Actions)
13
+
14
+ ```yaml
15
+ # .github/workflows/ci.yml
16
+ name: CI
17
+ on:
18
+ pull_request: { branches: [main] }
19
+ push: { branches: [main] }
20
+
21
+ jobs:
22
+ quality:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: actions/setup-node@v4
27
+ with: { node-version: 22, cache: npm }
28
+ - run: npm ci
29
+ - run: npm run lint
30
+ - run: npm run typecheck
31
+ - run: npm run test:unit -- --run
32
+ - run: npm run build
33
+ ```
34
+
35
+ ## 📦 Deploy (Vercel / Node)
36
+
37
+ - **Vercel:** conecte o repo. Preview por PR é automático. `SDD/` é ignorado no build.
38
+ - **Node (workers/CLI):** build no CI, artefato, deploy no `main` com approval manual.
39
+
40
+ ## 🔒 Segurança no pipeline
41
+
42
+ - `npm audit --production` como gate de aviso (não bloqueia minor).
43
+ - Dependabot ativo.
44
+ - Nunca logar `.env`/tokens no output do job.
45
+
46
+ ## 🏷️ Release
47
+
48
+ 1. Fechou fase → tag SemVer (`vX.Y.Z`).
49
+ 2. CI roda em tag → build de release.
50
+ 3. Changelog atualizado ([../docs/CHANGELOG.md](../docs/CHANGELOG.md)).
51
+
52
+ ## 🚫 Anti-padrões
53
+
54
+ | ❌ | ✅ |
55
+ | --- | --- |
56
+ | `continue-on-error: true` em tudo | Deixar o gate barrar de verdade |
57
+ | `npm install` (sem lock) em CI | `npm ci` |
58
+ | Deploy manual sem aprovação | Preview + approval em main |
59
+ | Rodar build sem typecheck | build sempre depois de typecheck |
@@ -0,0 +1,56 @@
1
+ # 🗄️ DATABASE
2
+
3
+ > Padrão: **Prisma ORM + PostgreSQL**. Acesso **sempre** dentro de `features/*/infrastructure/` ou `shared/server/db.ts`.
4
+
5
+ ## 🚨 Regras não-negociáveis
6
+
7
+ 1. **Query fora de `infrastructure/` é PROIBIDA.** O domínio só conhece a interface `I*Repository`.
8
+ 2. **`select` explícito em toda query.** Nunca `findMany()` sem filtro de colunas. Vaza dado e pesa payload.
9
+ 3. **Toda query que filtra por usuário filtra por `userId`/`tenantId`.** Autorização no dado, não na UI.
10
+ 4. **N+1 é proibido.** Use `include` aninhado ou `Promise.all` com mapa explícito.
11
+ 5. **Escrita que precisa de 2+ tabelas = `prisma.$transaction`.** Sem exceções.
12
+ 6. **Migration é feita via `npx prisma migrate dev --name <descricao>`** e vai pro repo. **Proibido `db push` em produção.**
13
+ 7. **Índice todo campo usado em `where` ou `orderBy` quente.** Antes de reclamar de performance no banco, indexa.
14
+
15
+ ## 🧱 Onde fica o quê
16
+
17
+ ```text
18
+ features/billing/
19
+ ├── domain/IBillingRepository.ts # contrato puro (interface)
20
+ └── infrastructure/
21
+ ├── billing-repository.ts # implementa a interface com Prisma
22
+ └── billing.mapper.ts # <row do Prisma> <-> <entidade de domínio>
23
+ ```
24
+
25
+ ## 🧩 Exemplo
26
+
27
+ ```ts
28
+ // infrastructure/billing-repository.ts
29
+ import "server-only";
30
+ import { db } from "@/shared/server/db";
31
+ import type { IBillingRepository } from "../domain/IBillingRepository";
32
+
33
+ export class PrismaBillingRepository implements IBillingRepository {
34
+ async findActiveByUser(userId: string) {
35
+ return db.subscription.findFirst({
36
+ where: { userId, status: "ACTIVE" }, // SEMPRE filtra por userId
37
+ select: { id: true, planId: true, status: true, renewsAt: true },
38
+ });
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## 🚫 Proibido
44
+
45
+ | Padrão | Por quê | Faça |
46
+ | --- | --- | --- |
47
+ | `db.x.findMany()` sem `select` | Vaza dado, pesa payload | Sempre `select` |
48
+ | Query sem filtro de dono | Vazamento entre tenants | `where: { userId }` |
49
+ | `db` importado em Server Component direto | Quebra o slice | via `queries.ts` do feature |
50
+ | `db push` / `db seed` em prod | perde dado | `migrate deploy` |
51
+ | `$transaction` aninhado profundo | lock demais | achatar /Batch |
52
+
53
+ ## 🧪 Testes
54
+
55
+ - **Integração:** use **banco de verdade separado** (ou SQLite/Mongo in-memory via adapter). Mock do client Prisma só em unit.
56
+ - **Migrations:** rode `migrate deploy` no setup do CI antes dos testes de integração.