# ldpost-squad — Instruções Gerais --- ## Princípio Central: Testabilidade Independente **Cada CLI deve rodar de forma isolada, sem depender que outro CLI tenha rodado antes.** Regras: - Toda CLI aceita `--post ` como entrada principal - Toda CLI aceita `--dry-run` para operar sem side effects (sem salvar arquivo, sem chamar API externa) - Toda CLI pode ser testada com um fixture manual (arquivo criado à mão no workspace) - Nenhuma CLI assume estado global — lê e escreve apenas no workspace do post --- ## Workspace Layout ``` $LDPOST_WORKSPACE/ / post.json ← metadados: tema, formato, imagens desc, status draft.md ← rascunho cru (gerado pelo redator) final.md ← versão formatada LinkedIn (gerado pelo editor) img/ cover.png ← imagem principal slide-*.png ← slides do carrossel (se aplicável) status.json ← pipeline state: pending|approved|published + URL ``` **Como testar qualquer CLI isoladamente:** ```bash # Crie o fixture mínimo manualmente mkdir -p "$LDPOST_WORKSPACE/meu-slug" echo '{"slug":"meu-slug","topic":"IA no RH","format":"lista"}' \ > "$LDPOST_WORKSPACE/meu-slug/post.json" # Agora rode qualquer CLI contra esse slug ldpost-redator --post meu-slug --dry-run ldpost-editor --post meu-slug --no-interactive ldpost-art --post meu-slug --dry-run ldpost-director --post meu-slug --skip-telegram ldpost-publisher --post meu-slug --dry-run ``` --- ## Variáveis de Ambiente Arquivo `.env` na raiz do workspace **ou** exportadas no shell. ```env # Obrigatórias GROQ_API_KEY= # modelo rápido (redator, evaluator) GEMINI_API_KEY= # imagens e análise (art, editor) LDPOST_WORKSPACE=C:\Textos-LinkedIn # Telegram (director) TELEGRAM_BOT_TOKEN= TELEGRAM_CHAT_ID= # LinkedIn (publisher) — opcional, fallback manual LINKEDIN_ACCESS_TOKEN= LINKEDIN_CLIENT_ID= LINKEDIN_CLIENT_SECRET= ``` Cada CLI deve chamar `godotenv.Load()` no init para carregar `.env` automaticamente se presente. --- ## Estrutura de Módulo Go Cada CLI é um módulo Go **independente** dentro de `C:\gocode\jobmaker-ldpost\`: ``` jobmaker-ldpost/ shared/ ← módulo compartilhado (go.mod: ldpost/shared) evaluator/ ← go.mod: ldpost/evaluator redator/ ← go.mod: ldpost/redator editor/ ← go.mod: ldpost/editor art/ ← go.mod: ldpost/art director/ ← go.mod: ldpost/director publisher/ ← go.mod: ldpost/publisher ``` CLIs dependem de `ldpost/shared` via `replace` no `go.mod`: ``` require ldpost/shared v0.0.0 replace ldpost/shared => ../shared ``` --- ## Convenções de Código ### Flags padrão (toda CLI implementa) | Flag | Tipo | Descrição | |------|------|-----------| | `--post` | string | Slug do post (obrigatória na maioria) | | `--dry-run` | bool | Opera sem salvar/publicar | | `--model` | string | Override do modelo LLM | | `--workspace` | string | Override de `LDPOST_WORKSPACE` | | `--verbose` | bool | Log detalhado | ### Saída padrão - Sucesso: imprime caminho do arquivo gerado ou URL publicada - Erro: `fmt.Fprintf(os.Stderr, "erro: %v\n", err)` + `os.Exit(1)` - Dry-run: imprime conteúdo que seria gerado/enviado ### Arquivo `post.json` (schema mínimo) ```json { "slug": "ia-no-rh-2026", "topic": "IA no recrutamento em 2026", "format": "lista", "images": [ {"index": 1, "prompt": "robô entrevistando humano, estilo flat design"}, {"index": 2, "prompt": "dashboard de triagem de currículos com IA"} ], "created_at": "2026-05-02T11:00:00Z" } ``` ### Arquivo `status.json` ```json { "slug": "ia-no-rh-2026", "pipeline_status": "pending", "steps_completed": ["evaluated", "drafted", "edited"], "approved_at": null, "published_url": null } ``` --- ## Padrões do jobmaker-squad (reutilizar) Referência: `C:\gocode\jobmaker-squad\` | Padrão | Onde está | O que reusar | |--------|-----------|-------------| | Gemini API calls | `jobmaker-redator/main.go` | Stream + retry pattern | | Imagen (geração de imagem) | `jobmaker-art/main.go` | Gemini Imagen 3.0 call | | Telegram bot | `jobmaker-editor/internal/telegram/` | Keyboard inline, await response | | Config loader | `jobmaker-editor/internal/config/` | `.env` + flags merge | | Vector store local | `jobmaker-editor/internal/vectorstore/` | chromem-go pattern | --- ## Como Rodar Testes ```bash # Cada CLI cd evaluator && go test ./... -v # Shared cd shared && go test ./... -v # Smoke test completo (requer .env configurado) ./scripts/smoke-test.sh meu-slug ``` --- ## Ordem de Implementação Seguir essa ordem — cada passo desbloqueia o próximo: 1. `shared/` — structs + workspace utils 2. `evaluator/` — sem este, nenhum slug existe 3. `redator/` — depende de `post.json` do evaluator 4. `editor/` — depende de `draft.md` do redator 5. `art/` — depende de `post.json` (descriptions de imagem) 6. `director/` — depende de `final.md` + imagens 7. `publisher/` — depende de `status.json` aprovado Mas cada um pode ser desenvolvido/testado **isoladamente** com fixtures manuais.