product-runner 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +165 -0
  2. package/common/agents/README.md +68 -0
  3. package/common/agents/agente-conceituacao.md +141 -0
  4. package/common/agents/agente-documentacao-funcional.md +107 -0
  5. package/common/agents/agente-gerador-spec.md +106 -0
  6. package/common/agents/agente-kickoff.md +121 -0
  7. package/common/agents/agente-prod-runner.md +107 -0
  8. package/common/agents/agente-review-code.md +97 -0
  9. package/common/agents/agente-review-llm.md +94 -0
  10. package/common/agents/agente-review-product.md +98 -0
  11. package/common/agents/agente-user-review.md +99 -0
  12. package/common/agents/protocolo-de-gates.md +51 -0
  13. package/common/claude-md.template.md +210 -0
  14. package/common/design-principles.md +229 -0
  15. package/common/lessons-learned.md +440 -0
  16. package/common/pipeline.md +143 -0
  17. package/common/spec-guide.md +327 -0
  18. package/common/specs/_open-issues.md +46 -0
  19. package/common/specs/_overview.md +75 -0
  20. package/dist/cli.js +187 -0
  21. package/dist/migrations.js +147 -0
  22. package/dist/scaffold.js +276 -0
  23. package/dist/update.js +400 -0
  24. package/migrations/0.3.0.md +54 -0
  25. package/migrations/0.4.0.md +76 -0
  26. package/migrations/0.5.0.md +55 -0
  27. package/migrations/README.md +68 -0
  28. package/package.json +41 -0
  29. package/profile-cli/README.md +54 -0
  30. package/profile-cli/claude-md.extension.md +102 -0
  31. package/profile-cli/code-patterns.md +363 -0
  32. package/profile-ssr/DESIGN-SYSTEM.md +795 -0
  33. package/profile-ssr/README.md +51 -0
  34. package/profile-ssr/api-patterns.md +70 -0
  35. package/profile-ssr/claude-md.extension.md +113 -0
  36. package/profile-ssr/code-patterns.md +175 -0
  37. package/profile-ssr/ui-patterns.md +97 -0
@@ -0,0 +1,51 @@
1
+ # Perfil: Web SSR (Next.js Pages Router)
2
+
3
+ Use este perfil em projetos que:
4
+
5
+ - Rodam como **servidor web** com SSR/SSG (Next.js, Remix, etc.).
6
+ - Têm **API routes** + **UI React**.
7
+ - Precisam de **autenticação**, **formulários**, **componentes interativos**.
8
+ - Persistem em DB via ORM (Prisma + Postgres como default), ou em
9
+ arquivos como acoplamento com outros sistemas.
10
+
11
+ ## Conteúdo
12
+
13
+ | Arquivo | Pra quê |
14
+ |---|---|
15
+ | [code-patterns](./code-patterns.md) | Estrutura de pastas, schemas Zod, services, repository, mapper toOutput |
16
+ | [api-patterns](./api-patterns.md) | API routes Next.js, validação, respostas, erros |
17
+ | [ui-patterns](./ui-patterns.md) | Componentes React, formulários, Tailwind, **responsividade mobile** |
18
+ | [claude-md.extension](../CLAUDE.md) | Seções específicas pra SSR (Next.js, deploy, comandos) |
19
+
20
+ ## Como combinar com `common/`
21
+
22
+ Use o CLI — ele copia `common/` + este perfil pra `docs/` e gera o
23
+ `CLAUDE.md` raiz (mescla template + extension, substitui `{...}`):
24
+
25
+ ```bash
26
+ npx product-runner --name meu-projeto --profile ssr --port 3000 --dir .
27
+ ```
28
+
29
+ Equivalente manual, se preferir sem npm:
30
+
31
+ ```bash
32
+ cp common/*.md meu-projeto/docs/
33
+ cp profile-ssr/*.md meu-projeto/docs/
34
+ cat common/claude-md.template.md profile-ssr/claude-md.extension.md \
35
+ > meu-projeto/CLAUDE.md
36
+ ```
37
+
38
+ ## Origem
39
+
40
+ Conteúdo extraído de:
41
+ - **DocManager** (`retro-20260419`) — base SSR Next.js + Prisma + shadcn/ui
42
+ - **tradeBot** (`tradebot-202605`) — atualizações importadas:
43
+ - Princípios LLM-first (em [design-principles](./design-principles.md))
44
+ - Critérios meta M1/M2/M3 (em [spec-guide](./spec-guide.md))
45
+ - [_open-issues](../specs/_open-issues.md) (seed em `common/specs/`)
46
+ - Adições de responsividade mobile e integração com skill
47
+ `ui-design-system` (em [ui-patterns](./ui-patterns.md) deste perfil)
48
+
49
+ ## Anti-pattern: usar este perfil pra projeto CLI
50
+
51
+ Stack assume request/response + UI. CLI sem isso. Use `profile-cli/`.
@@ -0,0 +1,70 @@
1
+ # API route patterns
2
+
3
+ API routes são cascas finas — sem lógica de negócio.
4
+
5
+ ## Estrutura padrão
6
+
7
+ ```typescript
8
+ export default async function handler(req, res) {
9
+ try {
10
+ switch (req.method) {
11
+ case "GET": return handleGet(req, res);
12
+ case "POST": return handlePost(req, res);
13
+ default:
14
+ res.setHeader("Allow", ["GET", "POST"]);
15
+ return res.status(405).json({ error: "Método não permitido" });
16
+ }
17
+ } catch (err) {
18
+ return handleError(err, res);
19
+ }
20
+ }
21
+
22
+ async function handlePost(req, res) {
23
+ const parsed = Schema.safeParse(req.body);
24
+ if (!parsed.success) {
25
+ return res.status(400).json({
26
+ error: "Dados inválidos",
27
+ details: parsed.error.flatten().fieldErrors,
28
+ });
29
+ }
30
+ const result = await serviceFunction(parsed.data);
31
+ return res.status(201).json(result);
32
+ }
33
+ ```
34
+
35
+ ## Tratamento de erros centralizado
36
+
37
+ ```typescript
38
+ export function handleError(err: unknown, res) {
39
+ if (err instanceof DomainError) {
40
+ return res.status(err.statusCode).json({
41
+ error: err.message, code: err.code,
42
+ });
43
+ }
44
+ console.error("Erro inesperado:", err);
45
+ return res.status(500).json({ error: "Erro interno" });
46
+ }
47
+ ```
48
+
49
+ ## Validação
50
+
51
+ Sempre `safeParse`, nunca `parse` em API routes.
52
+ Query params com `z.coerce` pra converter strings.
53
+
54
+ ## Respostas padronizadas
55
+
56
+ | Situação | Status | Body |
57
+ |----------------------|--------|-------------------------|
58
+ | Sucesso (read) | 200 | `{ ...data }` |
59
+ | Sucesso (create) | 201 | `{ ...data }` |
60
+ | Sucesso (no content) | 204 | vazio |
61
+ | Aceito (async) | 202 | `{ ...queue info }` |
62
+ | Validação falhou | 400 | `{ error, details }` |
63
+ | Não encontrado | 404 | `{ error, code }` |
64
+ | Conflito | 409 | `{ error, code }` |
65
+ | Método não permitido | 405 | `{ error }` + Allow |
66
+ | Erro interno | 500 | `{ error }` genérico |
67
+
68
+ ## Upload de arquivos
69
+
70
+ Desabilitar bodyParser, usar lib de parsing multipart.
@@ -0,0 +1,113 @@
1
+ <!--
2
+ Extensão do CLAUDE.md — Perfil SSR.
3
+ Este arquivo NÃO é concatenado: cada bloco abaixo declara, via diretiva
4
+ `prod-runner-merge`, como dobra numa seção do template-base (common/claude-md.template.md).
5
+ Modos: replace (troca a seção), append (acrescenta ao fim da seção),
6
+ after (insere logo após a seção). Edite o conteúdo, não as diretivas.
7
+ -->
8
+
9
+ <!-- prod-runner-merge: append section="Stack" -->
10
+
11
+ - **Framework:** Next.js (Pages Router)
12
+ - **ORM:** Prisma + PostgreSQL (ou outro adapter quando configurado)
13
+ - **UI:** Tailwind CSS + shadcn/ui
14
+ - **Forms:** React Hook Form + Zod resolver
15
+ - **Charts (se aplicável):** Recharts (default) ou TradingView lightweight
16
+ charts (séries financeiras)
17
+ - **Background jobs (se aplicável):** BullMQ + Redis
18
+ - **Deploy:** Docker + VPS (Vercel não cobre storage persistente +
19
+ background jobs)
20
+
21
+ <!-- prod-runner-merge: replace section="Princípio central" -->
22
+
23
+ ### Princípio central
24
+
25
+ Lógica de domínio desacoplada do framework. Services são TypeScript
26
+ puro. API routes são cascas finas que validam e delegam pros services.
27
+ Componentes UI consomem outputs tipados dos services.
28
+
29
+ <!-- prod-runner-merge: replace section="Estrutura de pastas" -->
30
+
31
+ ### Estrutura de pastas
32
+
33
+ ```
34
+ {project}/
35
+ ├── CLAUDE.md
36
+ ├── prisma/ ← schema.prisma + migrations
37
+ ├── src/
38
+ │ ├── pages/
39
+ │ │ ├── api/ ← API routes (cascas finas)
40
+ │ │ └── {páginas SSR}
41
+ │ ├── services/
42
+ │ │ ├── {dominio}/
43
+ │ │ │ ├── schema.ts ← Zod entity + derivações
44
+ │ │ │ └── repository.ts ← Prisma queries + toOutput
45
+ │ │ └── integrations/ ← clients de APIs externas
46
+ │ ├── components/
47
+ │ │ └── ui/ ← shadcn/ui (gerados)
48
+ │ └── lib/
49
+ │ ├── prisma.ts
50
+ │ ├── errors.ts
51
+ │ └── {outros utilitários}
52
+ ├── scripts/
53
+ ├── specs/
54
+ ├── docs/
55
+ └── docker-compose.yml ← infra (Postgres, Redis se aplicável)
56
+ ```
57
+
58
+ <!-- prod-runner-merge: append section="Convenções de código" -->
59
+
60
+ ### API Routes (SSR)
61
+
62
+ - Validar com `Schema.safeParse()`.
63
+ - Chamar o service e retornar o resultado.
64
+ - Sem lógica de negócio.
65
+ - Detalhe em [api-patterns](./docs/api-patterns.md).
66
+
67
+ ### UI (SSR)
68
+
69
+ - Componentes shadcn/ui como base (gerados via CLI).
70
+ - Tailwind utility classes — sem CSS modules.
71
+ - Formulários com React Hook Form + Zod resolver.
72
+ - **Responsividade mobile validada em todo componente novo** (M4 — ver
73
+ [ui-patterns](./docs/ui-patterns.md)).
74
+ - Considerar skill `ui-design-system` em revisões de componente.
75
+
76
+ ### Validação visual no browser (SSR)
77
+
78
+ Insubstituível — `tsc --noEmit` pega erros de tipo mas não de
79
+ comportamento. Smoke check humano em mobile (375x667) e desktop
80
+ (1280x720) faz parte do M4.
81
+
82
+ <!-- prod-runner-merge: replace section="Comandos úteis" -->
83
+
84
+ ## Comandos úteis
85
+
86
+ ```bash
87
+ docker compose up -d # infra (Postgres, Redis)
88
+ npm install # deps
89
+ npx prisma migrate dev # migrations
90
+ npx prisma generate # client
91
+ npm run dev # dev server (port {PORT})
92
+ npm test # testes
93
+ npx tsc --noEmit # typecheck
94
+ npx shadcn@latest add <comp> # adicionar componente
95
+ npm run format # formatar tudo
96
+ ```
97
+
98
+ Configurar port fixo no `package.json` (`"dev": "next dev -p {PORT}"`) pra
99
+ evitar mudança entre sessões. Code deve reportar o port real no output ao
100
+ iniciar o dev server.
101
+
102
+ <!-- prod-runner-merge: replace section="Configuração" -->
103
+
104
+ ## Configuração
105
+
106
+ | Arquivo | Conteúdo | Comitado? |
107
+ | ---------------------- | --------------------- | --------- |
108
+ | `.env` | DATABASE_URL, secrets | ❌ NUNCA |
109
+ | `.env.example` | Mesmas chaves sem valor | ✅ |
110
+ | `prisma/schema.prisma` | Schema do DB | ✅ |
111
+ | `next.config.js` | Config Next | ✅ |
112
+ | `tailwind.config.ts` | Config Tailwind | ✅ |
113
+ | `components.json` | Config shadcn/ui | ✅ |
@@ -0,0 +1,175 @@
1
+ # Data patterns
2
+
3
+ Padrões para definição de schemas, derivação de tipos,
4
+ e transformação de dados entre camadas.
5
+
6
+ ## Princípio
7
+
8
+ Cada domínio tem UM arquivo `schema.ts` com:
9
+ 1. Entity base (espelha o ORM model)
10
+ 2. Refs de relações (formas simplificadas de entities relacionadas)
11
+ 3. Inputs (derivados da entity por pick/extend)
12
+ 4. Outputs (derivados da entity por omit/extend)
13
+
14
+ Nunca escrever interfaces ou types manualmente.
15
+ Sempre derivar do schema de validação e inferir tipos.
16
+
17
+ ## Entity base
18
+
19
+ ```typescript
20
+ // services/{domínio}/schema.ts
21
+
22
+ export const {Entity}Entity = z.object({
23
+ id: z.string().uuid(),
24
+ // ... espelha todos os campos do ORM model
25
+ createdAt: z.string().datetime(),
26
+ updatedAt: z.string().datetime(),
27
+ });
28
+
29
+ export type {Entity}Entity = z.infer<typeof {Entity}Entity>;
30
+ ```
31
+
32
+ Regras:
33
+ - Nomes de campos idênticos ao ORM model.
34
+ - DateTime → `z.string().datetime()`.
35
+ - Nullable → `.nullable()`.
36
+ - Enums como `z.enum([...])`.
37
+
38
+ ## Refs de relações
39
+
40
+ Formas simplificadas pra usar como campos em outputs:
41
+
42
+ ```typescript
43
+ export const {Related}Ref = z.object({
44
+ id: z.string().uuid(),
45
+ name: z.string(),
46
+ });
47
+ ```
48
+
49
+ ## Derivação de inputs
50
+
51
+ ```typescript
52
+ export const Create{Entity}Input = {Entity}Entity
53
+ .pick({ /* campos editáveis */ })
54
+ .partial()
55
+ .extend({ /* campos adicionais */ });
56
+
57
+ export type Create{Entity}Input = z.infer<typeof Create{Entity}Input>;
58
+ ```
59
+
60
+ Regras:
61
+ - Usar `.shape.fieldName` pra referenciar tipos da entity.
62
+ - Usar `.unwrap()` pra remover nullable quando obrigatório no input.
63
+
64
+ ## Derivação de outputs
65
+
66
+ ```typescript
67
+ export const {Entity}Output = {Entity}Entity
68
+ .omit({ /* campos internos */ })
69
+ .extend({
70
+ // relações resolvidas
71
+ {related}: {Related}Ref.nullable(),
72
+ });
73
+ ```
74
+
75
+ Regras:
76
+ - Omitir campos internos (paths, IDs de FK).
77
+ - Substituir FK IDs por refs resolvidas.
78
+
79
+ ## Mapper toOutput
80
+
81
+ ```typescript
82
+ function toOutput(doc: any): {Entity}OutputType {
83
+ return {
84
+ // mapear campos, resolver relações
85
+ createdAt: doc.createdAt.toISOString(),
86
+ };
87
+ }
88
+ ```
89
+
90
+ ## Validação de output em dev
91
+
92
+ ```typescript
93
+ if (process.env.NODE_ENV === "development") {
94
+ return {Entity}Output.parse(data);
95
+ }
96
+ ```
97
+
98
+ ---
99
+
100
+ # Service patterns
101
+
102
+ Padrões para services, repositories, erros e integrações.
103
+
104
+ ## Estrutura de um domínio
105
+
106
+ ```
107
+ services/{domínio}/
108
+ ├── schema.ts ← entity + inputs + outputs
109
+ ├── repository.ts ← CRUD via ORM, mapper
110
+ ├── {lógica}.ts ← lógica de negócio específica
111
+ ```
112
+
113
+ Regras:
114
+ - `repository.ts` faz queries e retorna outputs tipados.
115
+ - Outros arquivos contêm lógica de negócio.
116
+ - Services podem importar outros services.
117
+ - Services NUNCA importam tipos do framework.
118
+
119
+ ## Repository
120
+
121
+ ```typescript
122
+ const defaultInclude = { /* relações padrão */ } as const;
123
+
124
+ export async function create{Entity}(
125
+ input: Create{Entity}Input
126
+ ): Promise<{Entity}Output> {
127
+ const record = await orm.{entity}.create({
128
+ data: { /* ... */ },
129
+ include: defaultInclude,
130
+ });
131
+ return toOutput(record);
132
+ }
133
+ ```
134
+
135
+ ## Erros de domínio
136
+
137
+ ```typescript
138
+ export class DomainError extends Error {
139
+ constructor(message: string, public code: string, public statusCode: number = 400) {
140
+ super(message);
141
+ }
142
+ }
143
+
144
+ export class NotFoundError extends DomainError { /* 404 */ }
145
+ export class ConflictError extends DomainError { /* 409 */ }
146
+ export class ValidationError extends DomainError { /* 400 */ }
147
+ ```
148
+
149
+ ## Regras de integridade
150
+
151
+ Validações que o ORM não cobre ficam no service:
152
+ - XOR constraints (campo A OU B, nunca ambos)
153
+ - Prevenção de ciclos (auto-referência hierárquica)
154
+ - Recálculo de campos derivados
155
+
156
+ ## Integrações externas
157
+
158
+ ```
159
+ services/integrations/
160
+ ├── {provider}.ts ← client isolado, tipos simples
161
+ ```
162
+
163
+ - Retornam tipos simples, não outputs de domínio.
164
+ - O service de domínio orquestra e converte resultados.
165
+ - Credenciais via env vars, nunca hardcoded.
166
+
167
+ ## Transações
168
+
169
+ ```typescript
170
+ await orm.$transaction(async (tx) => {
171
+ // operações atômicas
172
+ });
173
+ ```
174
+
175
+ Usar sempre que uma operação envolve múltiplas writes.
@@ -0,0 +1,97 @@
1
+ # UI patterns
2
+
3
+ Padrões para componentes, páginas, formulários e estilização.
4
+
5
+ ## Estrutura
6
+
7
+ ```
8
+ src/components/
9
+ ├── ui/ ← componentes da lib (shadcn, etc) — gerados
10
+ ├── {componente}.tsx ← componentes do projeto
11
+ ```
12
+
13
+ ## Estilização
14
+
15
+ Tailwind utility classes para tudo. Sem CSS modules,
16
+ sem styled-components, sem arquivos CSS customizados.
17
+
18
+ ## Formulários
19
+
20
+ Usar React Hook Form + Zod resolver, reutilizando
21
+ os schemas do service:
22
+
23
+ ```typescript
24
+ const form = useForm<InputType>({
25
+ resolver: zodResolver(InputSchema),
26
+ defaultValues: { /* ... */ },
27
+ });
28
+ ```
29
+
30
+ Regras:
31
+ - NUNCA duplicar validação — reutilizar o schema do service.
32
+ - Erros inline via FormMessage do componente lib.
33
+ - Erros de API via toast.
34
+
35
+ ## Páginas
36
+
37
+ - Tipar dados com os types de output do service.
38
+ - Loading states com skeleton.
39
+ - Empty states com mensagem + ação sugerida.
40
+ - Layout consistente.
41
+
42
+ ## Componentes da lib (ex: shadcn/ui)
43
+
44
+ - Sempre usar CLI pra instalar: `npx shadcn@latest add <comp>`.
45
+ - Nunca criar componentes da lib manualmente.
46
+ - Editar depois de gerado é permitido.
47
+
48
+ ## Responsividade mobile
49
+
50
+ Toda página/componente novo é validado em **dois viewports** antes
51
+ de declarar pronto:
52
+
53
+ | Viewport | Resolução | Comportamento esperado |
54
+ |---|---|---|
55
+ | Mobile | 375 × 667 (iPhone SE) | Sem scroll horizontal; touch targets ≥ 44px; menus colapsam |
56
+ | Desktop | 1280 × 720 | Layout completo; hover states funcionam |
57
+
58
+ ### Regras de Tailwind
59
+
60
+ - Mobile-first: classes sem prefix são pra mobile; `md:`, `lg:`
61
+ são extensões pra telas maiores.
62
+ - Evitar `w-screen` puro (causa scroll horizontal); usar `w-full`.
63
+ - Espaçamentos generosos em mobile (`p-4`, `gap-4`) que diminuem
64
+ em desktop (`md:p-6`, `lg:p-8`).
65
+ - Tipografia: `text-base` mobile, `md:text-lg` desktop quando
66
+ precisar de hierarquia visual.
67
+
68
+ ### Anti-patterns
69
+
70
+ - ❌ `min-w-[800px]` — causa scroll horizontal em mobile.
71
+ - ❌ `fixed` sem prever que mobile pode cobrir conteúdo.
72
+ - ❌ Testar só em desktop e descobrir o mobile depois.
73
+
74
+ ## Skill de UI/UX (suporte externo)
75
+
76
+ Considerar invocar a skill `ui-design-system` (Cowork) ao revisar
77
+ componentes novos pra obter:
78
+ - Análise de hierarquia visual.
79
+ - Identificação de inconsistências com design system existente.
80
+ - Indicação de pontos de responsividade frágeis.
81
+ - Sugestões de spec-anchored (componentes para o Code aplicar
82
+ consistentemente).
83
+
84
+ ## Critério meta M4 — UI responsiva
85
+
86
+ Toda spec que cria/altera componente UI inclui no checklist:
87
+
88
+ - [ ] Componente funciona em viewport `375x667` (mobile) sem scroll
89
+ horizontal.
90
+ - [ ] Touch targets ≥ 44px em mobile (botões, links clicáveis).
91
+ - [ ] Componente funciona em viewport `1280x720` (desktop) com
92
+ hover states ativos.
93
+ - [ ] Code rodou screenshot ou descreveu o layout nos dois viewports
94
+ no report final.
95
+
96
+ M4 é critério meta da própria spec — referenciar como "aplicam-se
97
+ M1, M2, M3, M4" em specs de UI.