--- name: plano-de-ataque description: Gera ou atualiza o PPTX "Plano de Ataque" (progresso por quinzena de Geotecnia/Estaqueamento, Infraestrutura/Bloco e Superestrutura/Pilar) deste repositório. Use quando o usuário pedir para regenerar o plano de ataque, atualizar quinzenas com uma planilha nova, mudar as cores/legenda do PPTX, ajustar o mapeamento de pixels de uma planta nova, ou reempacotar os pacotes standalone (dist-linux/dist-windows). Escopo: repositório bethania_porto_santos (raiz do projeto). --- # Plano de Ataque — PPTX de progresso por quinzena Este skill resume o que foi aprendido construindo `gerar_plano.py`: um gerador que pega um PPTX-modelo (1 slide de "uma quinzena") e uma planilha de planejamento, e produz um PPTX com 1 slide por quinzena, pintando cada quadrante da planta conforme o status de cada estrutura naquela data. ## Onde as coisas estão - `gerar_plano.py` (raiz) — script-fonte, único arquivo, sem módulos próprios além de `openpyxl`, `python-pptx`, `lxml`. - `cores.json` (raiz) — cores/opacidades/parâmetros de quinzena, editável sem tocar no código (ver seção "Cores" abaixo). - `dist-linux/` — pacote pronto (executável standalone via PyInstaller) + modelo `.pptx` + planilha `.xlsx` de exemplo + `LEIA-ME.txt`. - `dist-windows/` — pacote pronto (Python "embeddable" do python.org com as libs já instaladas em `python/Lib/site-packages`, sem precisar instalar nada) + `PlanoDeAtaque.bat` + mesmos exemplos + `LEIA-ME.txt` + um `.zip` com tudo empacotado. ## Fluxo normal de uso (regenerar o PPTX) 1. Reunir em uma pasta: 1 `.json` de cores, 1 `.pptx` modelo (slide 2 = layout de uma quinzena), 1 `.xlsx` de planejamento. 2. `python3 gerar_plano.py` dentro dessa pasta (ou rodar o executável/`.bat` em `dist-linux`/`dist-windows`). 3. O script AUTO-DETECTA os 3 arquivos pela extensão na própria pasta (não usa nomes fixos) e gera `_ATUALIZADO.pptx`. 4. Se o usuário mandar uma planilha/modelo NOVO por upload, é só copiar para `.uploads/` (ou onde estiver rodando), gerar, e comparar visualmente (ver "Como validar" abaixo) antes de entregar. ## Modelo de dados da planilha Aba **"Planejamento"**, dados a partir da linha 4: - Coluna B: nome do quadrante, formato `"-/-"`, ex. `"10-11/A1-B"` (colunas são números 1-48; linhas são rótulos entre `D, C, B1, B, A1, A`). Regex usado: `^(\d+)-(\d+)/([A-Z0-9]+)-([A-Z0-9]+)$`. - Colunas C/D: Geotecnia (Início/Término) - Colunas E/F: Infraestrutura (Início/Término) - Colunas G/H: Superestrutura (Início/Término) Status por quadrante/estrutura numa data de corte `p_end`: - `None` (não pintar) se Início vazio ou Início > p_end - `"concluido"` se Término preenchido e Término <= p_end - `"andamento"` caso contrário ## Quinzenas Períodos de **14 dias** começando em `2026-12-14 = Quinzena 02` (a planilha não tem atividade antes dessa data — por isso a numeração já começa em 02, não em 01). Esses três parâmetros ficam em `cores.json → quinzena` e dão para editar sem mexer no código: `duracao_dias`, `data_inicio`, `numero_inicial`. ## Cores (`cores.json`) Uma seção por estrutura (`geotecnia`, `superestrutura`, `infraestrutura`), cada uma com `andamento` e `concluido`, cada um com `preenchimento` (hex sem `#`), `borda` (hex sem `#`) e `alpha_preenchimento` (0-100). A legenda do slide sempre usa 100% de opacidade (fiel à cor pedida); o desenho usa o `alpha_preenchimento` configurado — mais baixo na geotecnia (cobre o quadrante inteiro, não pode esconder a planta) e mais alto nos marcadores de pilar/bloco (são pequenos, não atrapalham). **Regra de ouro ao pedir "mude a cor X pra Y"**: sempre pedir/usar um print em ALTA resolução da legenda e fazer amostragem de pixel (não confiar em screenshot comprimido/pequeno — já erramos assim uma vez nesta conversa). Amostrar tanto o preenchimento quanto a BORDA (são cores diferentes, e a legenda de referência sempre tem as duas). ## Como as camadas são desenhadas (importante para não perder fidelidade) - **Geotecnia/Estaqueamento**: retângulo arredondado cobrindo o quadrante INTEIRO (não um recorte menor). - **Superestrutura/Pilar e Infraestrutura/Bloco**: NÃO são um retângulo proporcional ao quadrante — são marcadores pequenos (quadrado arredondado, `marcador_fracao` do espaçamento entre colunas) plantados nos 4 VÉRTICES (colunaxlinha) de cada quadrante ativo. Como vértices são compartilhados entre quadrantes vizinhos, dedupe por ponto usando o status mais avançado (`concluido` > `andamento`) para não desenhar marcadores duplicados/ sobrepostos no mesmo lugar. ## Mapeamento pixel → EMU (a parte mais delicada) As posições de colunas/linhas da planta (`IM1_COLPX`, `IM2_COLPX`, `IM1_ROWPX`, `IM2_ROWPX` no script) são constantes medidas a dedo nas imagens do modelo, usando detecção de blobs por soma de pixels escuros por coluna/linha (círculos dos eixos, ver histórico da conversa para o script de medição). Se a planta do modelo mudar, essas constantes têm que ser remedidas — **sempre medir direto na imagem que está DE FATO embutida no `.pptx`** (`ppt/media/imageN.png` dentro do zip), não em uma cópia enviada separadamente por upload: já tivemos um bug de desalinhamento porque as duas não eram pixel-idênticas. **Gotcha crítico**: se a imagem no slide tiver um corte aplicado no PowerPoint (`` para baixar as wheels certas (mesmo rodando de um Linux — `pip download` só baixa o arquivo, não executa nada) e extrair (unzip) cada wheel dentro de `python/Lib/site-packages`. Lançador é um `.bat` simples chamando `python\python.exe gerar_plano.py`. Depois de montar, gerar de novo o `PlanoDeAtaque_windows.zip` (cuidado: gerar o zip DENTRO da própria pasta que está sendo zipada faz o zip se autoincluir — gerar em `/tmp` e mover para dentro depois). ## Como validar antes de entregar Como não há LibreOffice/PowerPoint disponível neste ambiente para renderizar o `.pptx`, a validação usada foi: 1. Integridade: `zipfile.testzip()` + `lxml.etree.fromstring` em cada `.xml`/`.rels` do pacote. 2. Reconstrução visual manual: ler `off/ext` (EMU) de cada `` e forma colorida do slide via `python-pptx`, converter para pixels e compor com Pillow (`Image.alpha_composite`) para gerar um PNG de conferência — é assim que os desalinhamentos e cores erradas foram detectados nesta conversa. ## Git neste repositório Não existe identidade de git configurada globalmente por padrão aqui. Em vez de rodar `git config --global` (proibido pelas regras de segurança do ambiente), usar override só para o comando do commit: `git -c user.name="..." -c user.email="..." commit -m "..."`. `.uploads/` está no `.gitignore` (são anexos de conversa, não arquivos do projeto) — os artefatos finais que importam ficam em `dist-linux/` e `dist-windows/`.