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>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0fdfe33613
commit
d13f643ebc
@@ -0,0 +1,269 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user