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.
- package/AGENTS.md +164 -0
- package/APP-STACK.md +31 -0
- package/APP.md +46 -0
- package/ARCHITECTURE.md +115 -0
- package/DESIGN.md +219 -0
- package/LICENSE +21 -0
- package/NEXT.md +345 -0
- package/NODE.md +107 -0
- package/REACT.md +92 -0
- package/README.md +260 -0
- package/SKILLS/check-docs/SKILL.md +24 -0
- package/SKILLS/check-docs/check-docs.mjs +56 -0
- package/SKILLS/create-feature/SKILL.md +40 -0
- package/SKILLS/create-feature/create-feature.mjs +128 -0
- package/SKILLS/create-feature.sh +112 -0
- package/SKILLS/install-submodule/SKILL.md +42 -0
- package/SKILLS/install-submodule/install-submodule.mjs +119 -0
- package/bin/create-sdd-ai-stack.mjs +93 -0
- package/docs/CHANGELOG.md +209 -0
- package/docs/PLANNING.md +68 -0
- package/docs/PRODUCT.md +76 -0
- package/docs/RELEASE.md +332 -0
- package/lib/check-links.mjs +42 -0
- package/lib/constants.mjs +60 -0
- package/lib/scaffold.mjs +253 -0
- package/package.json +80 -0
- package/specs/BACKLOG.md +24 -0
- package/specs/PLAN.md +57 -0
- package/specs/ROADMAP.md +35 -0
- package/specs/history/phases/phase-0-bootstrap.md +67 -0
- package/specs/tasks/TASK_TEMPLATE.md +46 -0
- package/src/cli.mjs +119 -0
- package/stacks/README.md +33 -0
- package/stacks/ai.md +52 -0
- package/stacks/ci.md +59 -0
- package/stacks/database.md +56 -0
- package/stacks/git.md +51 -0
- package/stacks/shadcn.md +52 -0
- package/stacks/tailwind.md +65 -0
- package/stacks/testing.md +74 -0
- package/stacks/typescript.md +58 -0
- package/template/next/.env.example +4 -0
- package/template/next/README.md +47 -0
- package/template/next/biome.json +36 -0
- package/template/next/gitignore +32 -0
- package/template/next/next.config.ts +12 -0
- package/template/next/package.json +47 -0
- package/template/next/playwright.config.ts +21 -0
- package/template/next/postcss.config.mjs +7 -0
- package/template/next/src/app/(app)/app/page.tsx +18 -0
- package/template/next/src/app/(app)/error.tsx +30 -0
- package/template/next/src/app/(app)/layout.tsx +25 -0
- package/template/next/src/app/(marketing)/page.tsx +73 -0
- package/template/next/src/app/globals.css +437 -0
- package/template/next/src/app/layout.tsx +41 -0
- package/template/next/src/app/not-found.tsx +11 -0
- package/template/next/src/features/example/actions.ts +43 -0
- package/template/next/src/features/example/application/create-example.usecase.ts +26 -0
- package/template/next/src/features/example/container.ts +16 -0
- package/template/next/src/features/example/domain/IExampleRepository.ts +11 -0
- package/template/next/src/features/example/domain/example.schema.ts +18 -0
- package/template/next/src/features/example/infrastructure/example.repository.ts +26 -0
- package/template/next/src/features/example/ui/create-example-form.tsx +56 -0
- package/template/next/src/proxy.ts +23 -0
- package/template/next/src/shared/lib/cn.ts +6 -0
- package/template/next/src/shared/server/auth.ts +32 -0
- package/template/next/src/shared/server/env.ts +14 -0
- package/template/next/src/shared/ui/index.ts +3 -0
- package/template/next/tests/e2e/routes.spec.ts +34 -0
- package/template/next/tests/unit/create-example.test.ts +55 -0
- package/template/next/tsconfig.json +37 -0
- 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
|
+
}
|
package/specs/BACKLOG.md
ADDED
|
@@ -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
|
+
```
|
package/specs/ROADMAP.md
ADDED
|
@@ -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
|
+
}
|
package/stacks/README.md
ADDED
|
@@ -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.
|