# Exemplo de SDD — TODO List em Arquitetura Apartada (React + C#) com Spec-Kit > **Exemplo preenchido:** Este exemplo mostra o GitHub Spec-Kit aplicado em **dois repositórios independentes** — `listaja-api` (back-end C#) e `listaja-web` (front-end React) — que se conectam apenas por uma API REST. Use-o como referência depois da Aula 09. [⬇️ Baixar / Copiar Código Fonte do Exemplo](https://raw.githubusercontent.com/paulossjunior/aula-extensao/main/docs/modelos/sdd-exemplo-todo-react-csharp.md) --- ## 1. Visão Geral | Campo | Descrição | |-------|-----------| | Nome do Produto | ListaJá | | Equipe (fictícia) | Grupo 07 | | Data | 04/05/2026 | | Domínio | Aplicativo pessoal de lista de tarefas com prazo opcional | | Repositório do back | `listaja-api` (ASP.NET Core 8 Web API + EF Core + SQLite) | | Repositório do front | `listaja-web` (React 18 + Vite + TypeScript) | | Integração | REST/JSON sobre HTTP, sem autenticação | | Persistência | SQLite (arquivo `todo.db`) — apenas no back | | Objetivo | Demonstrar, do começo ao fim, como o GitHub Spec-Kit conduz um produto pequeno em **dois repositórios apartados**, da constitution ao código | > Esta é **uma execução plausível**, não a única possível. Outro grupo, com a mesma stack, certamente produziria specs e tasks ligeiramente diferentes. ### Por que apartar em dois repositórios? A versão monorepo deste mesmo exemplo (com `back/` e `front/` lado a lado) também é válida. A escolha por dois repositórios independentes é deliberada e tem motivos didáticos claros: 1. **Independência de release.** Front e back podem evoluir em ritmos diferentes. A API pode receber dois deploys numa tarde sem que o front sequer saiba; o front pode trocar `useState` por Zustand sem mexer no servidor. 2. **Times separados.** Em produtos reais, é comum um time tocar a API e outro tocar a UI. Dois repositórios deixam essa fronteira de propriedade explícita, com revisões de PR, esteiras de CI e cadências de release próprias. 3. **Contrato como fronteira.** O REST API vira o **contrato explícito** entre os dois repos. É exatamente o tipo de fronteira que o SDD ajuda a documentar — uma spec de cada lado descreve o que o outro lado pode esperar. 4. **Replicabilidade do back.** Outros clientes (mobile, CLI, integração interna) poderiam consumir a mesma API sem dependerem do código do front. Trade-off honesto, que será revisitado na Seção 12: dois repositórios significam **dois fluxos de spec-kit**, **duas constitutions**, **duas revisões** a cada mudança que cruza a fronteira, e o **risco de o contrato divergir** entre os repos se ninguém olhar lado a lado. Esse custo é real. --- ## 2. Topologia da Solução A interação entre os dois serviços é toda feita por HTTP. Nenhum deles compartilha memória, processo, build ou mesmo sistema de arquivos. ```mermaid flowchart LR subgraph WEB["listaja-web (React + Vite)"] UI[App / TodoForm / TodoList] CLIENT[api/todos.ts] end subgraph API["listaja-api (.NET 8)"] CTRL[TodosController] DB[(SQLite todo.db)] end UI --> CLIENT CLIENT -- "fetch HTTP/JSON" --> CTRL CTRL --> DB style WEB fill:#eef style API fill:#efe ``` Em desenvolvimento, o front sobe na porta `5173` (padrão do Vite) e o back na porta `5080`. O CORS do back libera explicitamente a origem do front. | Aspecto | listaja-api | listaja-web | |---------|-------------|-------------| | Linguagem / runtime | C# / .NET 8 | TypeScript / Node 20+ | | Framework principal | ASP.NET Core Web API | React 18 + Vite | | Persistência | EF Core + SQLite | localStorage opcional para o nome do usuário | | Porta dev | 5080 | 5173 | | Spec-Kit init | `specify init listaja-api` | `specify init listaja-web` | | Tipo de spec | Contratos REST + regras de negócio do servidor | Experiência do usuário + chamadas à API | | CI | xUnit + dotnet test | Vitest + ESLint | | Quem revisa | Time de backend | Time de frontend | A separação por colunas dessa tabela é uma boa heurística: se uma decisão se encaixa bem em uma das colunas e mal na outra, ela provavelmente é uma decisão **de um lado só** e não precisa cruzar a fronteira. --- ## 3. Setup do Spec-Kit nos Dois Repositórios Cada repositório recebe seu próprio `specify init`. Os comandos `/speckit.*` ficam disponíveis dentro de cada um, **independentemente**. ```bash # Pré-requisitos comuns uv --version uv tool install specify-cli --from git+https://github.com/github/spec-kit.git ``` ```bash # Repositório do back-end mkdir listaja-api && cd listaja-api git init specify init . --integration claude ``` ```bash # Repositório do front-end (em outra pasta, paralelamente) mkdir listaja-web && cd listaja-web git init specify init . --integration claude ``` Depois do `init`, cada repositório passou a apresentar a estrutura mínima abaixo (resumida): ``` listaja-api/ ├── .specify/ │ ├── memory/ │ │ └── constitution.md │ └── ... (templates internos) ├── specs/ └── README.md listaja-web/ ├── .specify/ │ ├── memory/ │ │ └── constitution.md │ └── ... (templates internos) ├── specs/ └── README.md ``` Os slash-commands disponíveis em **ambos os repositórios**, depois do `init`, são os mesmos: | Comando | Função | |---------|--------| | `/speckit.constitution` | Registra os princípios do produto | | `/speckit.specify` | Descreve o quê e o porquê da feature | | `/speckit.clarify` | Reduz ambiguidades por perguntas estruturadas | | `/speckit.plan` | Decisões técnicas: stack, arquitetura, contratos | | `/speckit.tasks` | Quebra o plano em tarefas com dependências | | `/speckit.analyze` | Cruza spec, plan e tasks em busca de inconsistências | | `/speckit.checklist` | Gera checklist de qualidade da spec | | `/speckit.implement` | Executa as tarefas e gera código | A diferença é o que cada repositório vai escrever dentro desses comandos: o back foca em contratos e regras; o front foca em experiência e consumo da API. --- ## 4. Fase 1 — Constitution dos Dois Repositórios A constitution descreve princípios duráveis. Como cada repositório tem seu próprio agente e suas próprias decisões, cada um escreve a sua. ### 4.1 Constitution do `listaja-api` **Arquivo:** `listaja-api/.specify/memory/constitution.md` ```markdown # Constitution — listaja-api ## Princípios de Qualidade - Toda mudança de código passa por revisão de Pull Request. - Analyzers do .NET ativados; warnings tratados como erros em CI. - Mensagens de commit seguem Conventional Commits. ## Política de Testes - xUnit cobrindo Controllers e regras de validação. - Cobertura mínima de 70% em projeto de testes dedicado. - Testes de integração com WebApplicationFactory ficam para v2. ## Contrato e Compatibilidade - A API segue padrão REST: substantivos no plural, verbos HTTP semânticos. - Operações de escrita devem ser idempotentes quando o método HTTP exigir (ex.: PATCH `/complete` aplicado duas vezes não falha). - Quebras de contrato exigem nova versão (`/api/v2/...`) e nota de migração. ## Performance - Resposta da API abaixo de 300 ms para listagem de até 500 tarefas. - Sem N+1 em queries do EF Core; uso explícito de `AsNoTracking` em leituras. ## Restrições do Contexto - Sem autenticação na v1. Identificação apenas por nome (`OwnerName`). - Persistência local em SQLite. Sem dependência de serviços de nuvem. - Datas em UTC no servidor. - Idioma de mensagens de erro: pt-BR. ``` ### 4.2 Constitution do `listaja-web` **Arquivo:** `listaja-web/.specify/memory/constitution.md` ```markdown # Constitution — listaja-web ## Princípios de Qualidade - Toda mudança de código passa por revisão de Pull Request. - ESLint + TypeScript estrito; sem `any` solto no código de produção. - Mensagens de commit seguem Conventional Commits. ## Política de Testes - Vitest + Testing Library para componentes-chave (formulário e lista). - Mock da camada `api/` em testes de componente. - Testes ponta a ponta com Playwright ficam para v2. ## Acessibilidade e UX - Foco visível em todos os elementos interativos. - Inputs com `