Files
gart/code/Engine/docs/10_MAPA_REESTRUTURACAO.md
T
João HenriqueandClaude Sonnet 5 d13f643ebc chore(fase0): higiene do repositório + corrige gitignore que escondia fcpxml/models/
Fase 0 do roteiro de reestruturação (Engine/docs/10_MAPA_REESTRUTURACAO.md):
move code/WHISPERX (2,6 GB de backups órfãos, sem uso ativo, sem
.gitmodules) para ~/Archives/G-ART-WHISPERX-backup fora do workspace git;
traz admin/ para o gate de lint de run_after_fix.sh; corrige
fcpxml/writer/adjustment.py, que gerava um wrapper <adjustment> inexistente
no DTD 1.13 (filtros agora vão direto no <clip>, na ordem exigida), com
teste de regressão novo.

Achado à parte: .gitignore tinha uma regra solta "models/" (pensada só
para o cache do Whisper em code/models/) que também escondia do git todo o
pacote fcpxml/models/ — nunca commitado, sem proteção nenhuma. Corrigida
para /code/models/, ancorada na raiz.

Docs atualizados no mesmo commit (02_MODULES, 09_MANUTENCAO,
10_MAPA_REESTRUTURACAO, 05_EXPERIENCIAS #34 e #36), conforme a regra do
CLAUDE.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 08:28:44 -04:00

10 KiB

10 - Mapa de Reestruturacao de Funcionalidades

Escopo: roteiro pratico para reorganizar o codigo sem quebrar o produto. Baseado na varredura de 2026-08-24 sobre engine Python, ponte do app, ferramentas MCP e app SwiftUI.

1. Diagnostico rapido

O projeto ja tem uma arquitetura-alvo correta: fcpxml/ como engine puro, server.py + server_tools/ como camada MCP, admin/ como ponte JSON-lines do app e MacApp/ como interface. A melhoria agora nao e "reinventar" a arquitetura, e reduzir os pontos onde as responsabilidades ainda se misturam.

Pontos fortes

  • Engine Python bem testado e com regra clara: logica de timeline fica em fcpxml/.
  • writer/ ja foi quebrado em mixins por assunto, preservando API publica.
  • server.py funciona como composition root e usa dispatch por dicionario.
  • Documentacao interna registra decisoes, armadilhas e padroes do projeto.
  • Fluxos criticos tem testes extensos em code/tests/.

Dores atuais

  • Alguns arquivos voltaram a virar centros de gravidade:
    • server_tools/voice.py (~999 linhas)
    • server_tools/subtitles.py (~760 linhas)
    • MacApp/Sources/WizardView.swift (~979 linhas)
    • MacApp/Sources/TranscriptionView.swift (~843 linhas)
    • fcpxml/model_manager.py (~748 linhas)
  • admin/ e server_tools/ expõem fluxos parecidos por caminhos diferentes, o que aumenta risco de uma funcionalidade existir no MCP e faltar no app.
  • admin/ ainda fica fora do lint principal — resolvido na Fase 0 (2026-09-22): admin/ entrou no gate de run_after_fix.sh.
  • WHISPERX e backups aparecem junto da base ativa — resolvido na Fase 0 (2026-09-22): movido para fora do workspace git.
  • O app SwiftUI quase nao tem rede automatizada; compilar nao garante que uma tela abre.

2. Mapa de dominios desejado

Produto
  MacApp/                    Interface e experiencia do usuario
  admin/                     Ponte JSON-lines do app
  server.py + server_tools/  Entrada MCP

Engine
  fcpxml/models/             Dados e contratos
  fcpxml/parser.py           FCPXML -> objetos
  fcpxml/writer/             Escrita e edicao de XML
  fcpxml/voice_*             Analise e decisoes por voz
  fcpxml/text_layout.py      Layout de legendas
  fcpxml/model_manager.py    Catalogo, configs e modelos

Suporte
  tests/                     Rede automatizada
  Engine/docs/               Decisoes e operacao
  examples/                  Fixtures de uso

Legado / referencia
  WHISPERX/                  Deve sair do caminho ativo ou virar referencia clara

Regra de organizacao: uma funcionalidade nasce no engine, depois ganha duas portas finas se necessario: uma tool MCP em server_tools/ e um comando do app em admin/api/.

3. Reestruturacao por fases

Fase 0 - Higiene antes de mexer — concluída em 2026-09-22

Objetivo: reduzir ruido e proteger a base antes de mover codigo.

  • Decidir o destino de code/WHISPERX — não era submodule (sem .gitmodules), era 2,6 GB de backups órfãos do próprio projeto sem nenhuma referência ativa. Movido para ~/Archives/G-ART-WHISPERX-backup (fora do workspace git), copiado com rsync e conferido com diff -rq antes de remover o original. Detalhe: essa pasta também inflava qualquer ruff check --exclude docs/ manual (a flag sobrescrevia o exclude do pyproject.toml, que já ignorava WHISPERX/) — ver 05_EXPERIENCIAS.md #34.
  • Incluir admin/ em uma checagem de lint separada antes de colocar no gate obrigatório — checado com a config real do projeto (não o default do ruff): só 6 erros, todos E402 por sys.path.insert antes de import local. Resolvido com # noqa: E402 (convenção já usada no projeto) e admin/ entrou direto no gate obrigatório (run_after_fix.sh, passo 2/3), sem precisar de etapa intermediária "separada".
  • Corrigido de quebra: fcpxml/writer/adjustment.py gerava um <adjustment> inválido no DTD — não estava no escopo original da Fase 0, mas surgiu na investigação e era pequeno o bastante para resolver junto (ver 05_EXPERIENCIAS.md #34).
  • Atualizados: 02_MODULES.md (versão, linhas de writer/, módulos novos builders.py/adjustment.py/analise.py/transcription/), 09_MANUTENCAO.md (contagem de testes/lint, itens §2.3/§2.6/§2.8 resolvidos, novo item §2.7 registrando test_refine_voice_timeline_tool).
  • Pendente, não fechado nesta rodada: "documentar oficialmente quais pastas são produto ativo, legado e backup" como um documento à parte — o que existia de fato como "legado" (WHISPERX) já foi resolvido, não sobrou candidato claro para justificar um novo documento agora.

Entrega obtida: lint de admin/ no gate, code/writer/adjustment.py correto e testado, ~2,6 GB fora do caminho ativo, docs sincronizados com o código atual.

Fase 1 - Contratos entre camadas

Objetivo: impedir que MCP, app e engine driftam entre si.

  • Criar um registro unico de capacidades, por exemplo:
    • nome interno da funcionalidade;
    • funcao pura do engine;
    • handler MCP, se existir;
    • comando admin, se existir;
    • tela Swift, se existir;
    • testes associados.
  • Adicionar teste que detecta comandos importantes presentes no MCP mas ausentes na ponte do app, quando fizer sentido.
  • Padronizar o retorno dos comandos admin/api: ok, path, message, error, unchanged, artifacts.

Entrega esperada: mapa vivo de funcionalidades e menos "funciona no Claude, nao aparece no app".

Fase 2 - Dividir server_tools/voice.py

Objetivo: separar o fluxo de voz por etapas reais do produto.

Divisao sugerida:

server_tools/voice/
  __init__.py              Reexporta TOOLS e HANDLERS
  analysis.py              analyze_voice_features, build_voice_timeline
  speakers.py              diarize_media, remove_speakers
  refinement.py            refine_voice_timeline, remove_speech_gaps
  actions.py               apply_voice_actions
  local_ai.py              generate_voice_script
  config.py                get/save_voice_analysis_config

Cuidados:

  • Manter os nomes publicos reexportados para nao quebrar testes/imports.
  • Mover em uma etapa por arquivo, rodando testes de voz a cada passo.
  • Nao mover regra de negocio para server_tools/voice/; se aparecer regra nova, ela deve descer para fcpxml/voice_*.

Testes minimos: test_voice_actions.py, test_voice_actions_tool.py, test_voice_timeline.py, test_voice_timeline_tool.py, test_diarize.py, test_voice_features.py.

Fase 3 - Separar fcpxml/model_manager.py

Objetivo: reduzir mistura entre catalogo, download, configuracao e estado.

Divisao sugerida:

fcpxml/model_manager/
  __init__.py              API publica atual
  catalog.py               models.json, recomendados, metadata
  storage.py               diretorios, instalados, migracao
  download.py              download/cancel/progresso
  transcription_config.py  modelo selecionado, idioma
  voice_config.py          analise de voz, silencio, legendas

Cuidados:

  • Preservar imports atuais via __init__.py.
  • Separar funcoes puras de funcoes com I/O para facilitar teste.
  • Nao acoplar config do app a nomes de tela Swift.

Testes minimos: test_models.py, test_models_api.py se existir, test_voice_analysis_config.py, test_project_config.py.

Fase 4 - Reorganizar o Assistente SwiftUI

Objetivo: tornar o fluxo de 7 etapas legivel e testavel por partes.

Divisao sugerida:

MacApp/Sources/Wizard/
  WizardView.swift         Casca, navegacao e estado global
  WizardState.swift        Estado do fluxo e canAdvance
  ProjectStepView.swift
  TranscribeStepView.swift
  VoiceAnalysisStepView.swift
  AIScriptStepView.swift
  ReviewStepHost.swift
  ProcessStepView.swift
  DoneStepView.swift

Boas praticas para essa fase:

  • Extrair primeiro views pequenas, sem alterar comportamento.
  • Depois extrair calculos puros de canAdvance, nomes de arquivos e selecao de artefatos para tipos testaveis.
  • Usar harness manual documentado em 08_APP_MACOS.md para abrir as telas tocadas.

Entrega esperada: cada etapa do wizard vira um arquivo com responsabilidade unica.

Fase 5 - Unificar validacao e saida da ponte admin/

Objetivo: deixar os comandos do app tao disciplinados quanto os handlers MCP.

  • Criar helpers de path/output equivalentes aos de server_tools/_shared, ou mover helpers comuns para uma camada compartilhada que nao saiba de MCP.
  • Trocar chamadas diretas a server.generate_output_path por helper de dominio que nao puxe server.py quando a ponte so precisa de path.
  • Adicionar lint de admin/ ao fluxo de manutencao depois de corrigir erros existentes.

Entrega esperada: ponte mais fina, menos import acidental de transporte MCP.

Fase 6 - Tests e gates de seguranca

Objetivo: fazer a reorganizacao ser barata de continuar.

  • Criar testes de "arquitetura":
    • fcpxml/ nao importa server, server_tools nem admin;
    • handlers MCP sempre retornam via _text_result;
    • comandos admin retornam JSON no formato padrao.
  • Criar teste de import publico para garantir que reexports antigos continuam.
  • Para SwiftUI, manter harnesses por tela critica ate existir um build mais estruturado.

Entrega esperada: mover arquivos deixa de ser aposta.

4. Prioridade recomendada

  1. Fase 0: limpar mapa ativo vs legado.
  2. Fase 1: criar registro de capacidades.
  3. Fase 2: dividir voz em server_tools.
  4. Fase 5: fortalecer admin/.
  5. Fase 4: quebrar WizardView.
  6. Fase 3: dividir model_manager.py.
  7. Fase 6: ampliar gates conforme as fases estabilizam.

Motivo: primeiro se reduz incerteza, depois se separa o arquivo que mais muda no fluxo novo de voz, e so entao se mexe nas telas maiores.

5. Checklist para cada refatoracao

  • Mover sem mudar comportamento na primeira passada.
  • Preservar API publica com reexports.
  • Rodar testes focados depois de cada movimento.
  • Rodar cd code && ./Engine/run_after_fix.sh antes de concluir.
  • Se mexeu em MacApp/, compilar e abrir a tela afetada.
  • Atualizar docs no mesmo commit.
  • Registrar aprendizado em 05_EXPERIENCIAS.md quando houver bug real.

6. Principios de boas praticas para este projeto

  • Engine puro: sem MCP, sem Swift, sem JSON de tela.
  • Camadas de entrada finas: validam, chamam engine, formatam resposta.
  • Tempo de timeline sempre racional (TimeValue), exceto metricas de audio e UI onde segundos float sao apenas apresentacao/analise.
  • Original nunca e sobrescrito.
  • XML sempre entra por safe_xml.py.
  • Dependencias opcionais continuam lazy.
  • Arquivo grande so e problema quando contem varios assuntos.
  • Toda funcionalidade importante deve ter dono, porta MCP/app documentada e teste correspondente.