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

270 lines
10 KiB
Markdown

# 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
```text
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:
```text
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:
```text
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:
```text
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.