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>
270 lines
10 KiB
Markdown
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.
|