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>
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.pyfunciona 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/eserver_tools/expõem fluxos parecidos por caminhos diferentes, o que aumenta risco de uma funcionalidade existir no MCP e faltar no app.— resolvido na Fase 0 (2026-09-22):admin/ainda fica fora do lint principaladmin/entrou no gate derun_after_fix.sh.— resolvido na Fase 0 (2026-09-22): movido para fora do workspace git.WHISPERXe backups aparecem junto da base ativa- 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— não era submodule (semcode/WHISPERX.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 comrsynce conferido comdiff -rqantes de remover o original. Detalhe: essa pasta também inflava qualquerruff check --exclude docs/manual (a flag sobrescrevia oexcludedopyproject.toml, que já ignoravaWHISPERX/) — ver05_EXPERIENCIAS.md#34.Incluir— checado com a config real do projeto (não o default do ruff): só 6 erros, todosadmin/em uma checagem de lint separada antes de colocar no gate obrigatórioE402porsys.path.insertantes de import local. Resolvido com# noqa: E402(convenção já usada no projeto) eadmin/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.pygerava 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 (ver05_EXPERIENCIAS.md#34). - Atualizados:
02_MODULES.md(versão, linhas dewriter/, módulos novosbuilders.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 registrandotest_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 parafcpxml/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.mdpara 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_pathpor helper de dominio que nao puxeserver.pyquando 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 importaserver,server_toolsnemadmin;- handlers MCP sempre retornam via
_text_result; - comandos
adminretornam 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
- Fase 0: limpar mapa ativo vs legado.
- Fase 1: criar registro de capacidades.
- Fase 2: dividir voz em
server_tools. - Fase 5: fortalecer
admin/. - Fase 4: quebrar
WizardView. - Fase 3: dividir
model_manager.py. - 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.shantes de concluir. - Se mexeu em
MacApp/, compilar e abrir a tela afetada. - Atualizar docs no mesmo commit.
- Registrar aprendizado em
05_EXPERIENCIAS.mdquando 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.