Modernize um registro de pedidos existente com Spec Kit
A modernização altera a estrutura técnica preservando um contrato de negócio declarado. Ao contrário de um projeto novo, sucesso não é “a nova aplicação executa”. Ao contrário de uma funcionalidade em projeto existente, o objetivo aqui não é um novo comportamento de negócio.
Resumo do laboratório

Ilustração conceitual original (SVG)
| Em resumo | Sua rota |
|---|---|
| Nível e tempo | 400; 100 minutos (estimativa de facilitação) |
| Ação inicial | Verifique contagens, inteiros exatos, não sobrescrita e rollback de CSV. |
| Materiais do aluno | Baixe 17-modernization.zip |
| Workspace | Abra a raiz do kit extraído; execute a baseline de . relativa a essa raiz |
| Verificação inicial esperada | Os testes de caracterização de CSV passam. A suíte separada de modernização falha intencionalmente até a implementação. |
| Ajuda de configuração | Baixe, extraia, Git local e GitHub opcional |
[!NOTE] Um banco de dados criado não prova uma migração completa e compatível.
Conceitos · Primeira tarefa · Lista de evidências · Redefinir
Objetivos de aprendizagem
- Congele um contrato público antes de alterar o armazenamento.
- Rastreie requisitos de compatibilidade pelos artefatos e testes do Spec Kit.
- Reconcilie contagens importadas, totais, ordem e versão do esquema.
- Verifique a rejeição de dados inválidos e uma reversão prática.
Antes de começar
Conclua a configuração do Spec Kit.
Prepare 17-modernization usando a configuração da unidade de trabalho.
Use a biblioteca padrão do Python e SQLite: nenhum servidor, dependência pip, contêiner,
recurso de nuvem ou banco de dados de produção é necessário.
Conceitos e casos de uso
| Caso | Pergunta principal | Este exercício |
|---|---|---|
| Projeto novo (greenfield) | O que devemos construir? | Já respondido pelo comportamento legado |
| Funcionalidade em projeto existente (brownfield) | Qual novo comportamento adicionamos? | Nenhum nesta migração |
| Modernização | Qual limite técnico muda sem quebrar consumidores? | O armazenamento CSV passa a ter SQLite como opção explícita |
| Transição | Quando os consumidores usam o novo caminho? | Somente quando --backend sqlite é selecionado |
| Reversão | O caminho antigo ainda funciona? | CSV continua sendo o padrão e seus bytes permanecem inalterados |
Cenário do exercício
Um operador depende de service.py retornar um objeto JSON contendo pedidos
ordenados e totais em centavos inteiros. Substitua o armazenamento sem alterar chaves, ordenação,
filtragem por cliente ou o caminho CSV padrão.
A fixture local contém:
| Arquivo | Responsabilidade |
|---|---|
legacy.py |
Contrato congelado de validação e resumo de CSV |
service.py |
CLI de compatibilidade e seleção explícita de backend |
order_store.py |
Leitor SQLite incompleto |
migrate.py |
Importação validada incompleta |
test_legacy.py |
Comportamento existente |
test_modernization.py |
Novos pontos de controle de armazenamento/dados/reversão |
data/orders.csv |
Três registros sintéticos; nenhuma transação real |
Tarefa 1 - Caracterize antes de alterar qualquer coisa
-
Leia
requirements.mdelegacy.py. -
Execute a partir da raiz da fixture preparada:
python -m unittest test_legacy -v python service.py --source data/orders.csv python service.py --source data/orders.csv --customer C-01 -
Confirme um total de 6249 centavos no geral e 3250 centavos para
C-01. Esses são valores determinísticos da fixture, não uma alegação de desempenho. -
Registre hash da fonte, estrutura da saída, ordem, códigos de saída e comportamento do fluxo de erros.
-
Execute
python -m unittest test_modernization -v; a implementação incompleta deve falhar. Não enfraqueça esses testes para obter uma linha de base aprovada.
Tarefa 2 - Especifique preservação e alteração separadamente
Inicialize somente a cópia descartável. Depois:
/speckit-constitution Preserve the JSON CLI contract in requirements.md.
Do not modify legacy.py or baseline assertions. Keep CSV as default. Use no
network or real data. Require validated migration, non-overwrite, reconciliation,
explicit errors and a tested rollback before selecting SQLite.
/speckit-specify Modernize CSV storage to SQLite without changing business behavior.
Implement migrate.py and order_store.py for MOD-1 through MOD-6. Preserve source
bytes, record order, integer cents, customer filtering and CLI output.
Use /speckit-clarify para definir o tratamento de linhas malformadas, IDs duplicados, reexecuções, bancos
de dados ausentes, destinos existentes e falhas no meio da importação.
Tarefa 3 - Modele o limite de armazenamento
---
config:
theme: base
look: classic
themeVariables:
darkMode: false
background: "#ffffff"
primaryColor: "#f5f5f5"
primaryTextColor: "#111111"
primaryBorderColor: "#555555"
secondaryColor: "#e0e0e0"
secondaryTextColor: "#111111"
secondaryBorderColor: "#666666"
tertiaryColor: "#bdbdbd"
tertiaryTextColor: "#111111"
tertiaryBorderColor: "#444444"
lineColor: "#444444"
textColor: "#111111"
mainBkg: "#f5f5f5"
nodeBorder: "#555555"
clusterBkg: "#ffffff"
clusterBorder: "#999999"
edgeLabelBackground: "#ffffff"
actorBkg: "#e0e0e0"
actorBorder: "#555555"
actorTextColor: "#111111"
actorLineColor: "#777777"
signalColor: "#333333"
signalTextColor: "#111111"
labelBoxBkgColor: "#f5f5f5"
labelBoxBorderColor: "#777777"
labelTextColor: "#111111"
loopTextColor: "#111111"
activationBkgColor: "#bdbdbd"
activationBorderColor: "#555555"
noteBkgColor: "#f5f5f5"
noteTextColor: "#111111"
noteBorderColor: "#777777"
attributeBackgroundColorOdd: "#f5f5f5"
attributeBackgroundColorEven: "#e0e0e0"
---
erDiagram
accTitle: Contrato de armazenamento do registro de pedidos
accDescr: Um cliente conceitual possui muitos pedidos. O SQLite armazena registros de pedidos com ID primário, identificador do cliente, centavos inteiros e um status permitido.
CUSTOMER ||--o{ ORDER : identifica
CUSTOMER {
string id
}
ORDER {
string id PK
string customer
int total_cents
string status
}
Legenda. As caixas de entidades listam campos. A aresta em pé de galinha significa que um identificador
de cliente pode aparecer em muitos pedidos. PK marca o identificador do pedido.
Explicação. CUSTOMER é conceitual, não uma nova tabela ou chave estrangeira obrigatória.
O laboratório real migra somente a tabela orders e define PRAGMA user_version = 1.
Adicionar um serviço de clientes ampliaria o escopo e arriscaria alterar o comportamento.
total_cents é logicamente um inteiro. A referência armazena texto decimal validado
porque o intervalo dos inteiros e de SUM do SQLite é menor que o dos valores aceitos pelo Python;
ela converte de volta para inteiros Python para JSON e reconciliação exata.
Tarefa 4 - Planeje uma migração reversível
/speckit-plan Use Python sqlite3 and standard-library unittest. Validate every
CSV record before import. Refuse any existing target. Create a constrained orders
schema, insert with parameterized statements in a transaction, reconcile count
and integer total without narrowing Python integer precision, and close resources.
Open query databases read-only and never
create one on a missing-file read. Keep source CSV unchanged for rollback.
Revise como a implementação diferencia:
- recusar um destino existente de limpar seu próprio novo destino com falha;
- importação bem-sucedida de banco de dados parcial;
- validação dos dados de origem de restrições do SQLite;
- valores parametrizados de SQL executável;
- representação de armazenamento do contrato público de inteiros JSON, incluindo totais além do intervalo de 64 bits com sinal;
- uma exceção do processo local de durabilidade diante de travamento/queda de energia.
A fixture não é um serviço de migração de produção. Documente as limitações de recuperação após falhas e de gravações concorrentes em vez de alegar que estão cobertas.
Tarefa 5 - Implemente por meio de pontos de controle de evidências
-
Execute
/speckit-taskse/speckit-analyze. -
Mapeie cada requisito MOD para a implementação e seu teste.
-
Implemente um limite por vez; não altere o contrato público congelado.
-
Execute:
python -m unittest test_legacy test_modernization -v python migrate.py --source data/orders.csv --target orders.db python service.py --backend sqlite --source orders.db --customer C-01 -
Compare exatamente o JSON de CSV e SQLite. Inspecione contagem e total, não apenas a existência do arquivo.
-
Execute a mesma migração novamente. Ela deve falhar sem sobrescrever
orders.db. -
Use novamente o comando CSV padrão para comprovar a reversão sem excluir a fonte.
-
Execute
/speckit-convergepara revisão entre artefatos. Limite as tentativas de correção e inspecione a saída real dos testes antes de aceitar a convergência.
Verifique seu trabalho
- MOD-1: a caracterização original continua passando.
- MOD-2: contagem 3, total 6249, ordenação e versão 1 do esquema correspondem.
- MOD-3: entrada malformada/duplicada retorna código diferente de zero e não deixa um destino parcial apresentado como bem-sucedido.
- MOD-4: reexecuções preservam qualquer destino existente byte a byte.
- MOD-5: ler um banco de dados ausente não o cria.
- MOD-6: a alternativa CSV e o hash da fonte permanecem inalterados.
- Nenhuma funcionalidade de negócio, dado real de cliente ou infraestrutura de nuvem foi adicionada.
Adaptações de stack
| Stack | Modernização semelhante | Evidências equivalentes obrigatórias |
|---|---|---|
| Python / SQLite | Caminho principal executável aqui | Linha de base e suíte de migração fornecidas |
| .NET 10 | Adaptador de CSV para Microsoft.Data.Sqlite |
Mesmos testes de consumidores JSON e revisão de provedor/pacote |
| TypeScript / Node | Adaptador de CSV para SQLite com suporte na versão selecionada do Node | Mesmos pontos de controle de ordenação, inteiros, reversão e sobrescrita |
| Java | Adaptador de armazenamento JDBC por trás de um serviço existente | Testes existentes de contrato Java e uma fixture de migração |
As alternativas são projetos guiados, não alegações de execução. Compare diferenças de API, transação, erros e empacotamento antes da implementação. Não selecione um novo framework somente porque um assistente consegue gerá-lo.
Solução de problemas
Se os resultados corresponderem somente depois de ordenar um dos lados de outra forma, você pode ter alterado o contrato. Se uma linha inválida deixar um banco de dados parcial, inspecione validação e limpeza. Se uma leitura ausente criar um arquivo, revise o modo de conexão. Se os testes falharem somente na reexecução, inspecione o ponto de controle contra sobrescrita em vez de excluir o destino existente.
Prática independente
Proponha uma alteração de esquema v2 que adicione uma coluna anulável enquanto um leitor mais antigo permanece ativo. Defina negociação de versão, compatibilidade futura e retroativa, idempotência da migração, reversão e critérios de desativação antes de programar.
Restauração
Pare somente o processo de CLI que você iniciou. Salve hashes e saídas e remova somente o
orders.db gerado na cópia descartável após inspecionar seu caminho. Restaure
migrate.py e order_store.py a partir da linha de base local ou prepare uma cópia nova.
Nunca sobrescreva data/orders.csv como técnica de restauração.