# PLATAFORMA — Riscos de Dados, Perguntas em Aberto e Mapa v5→v6

> Continuação de `08-GAPS-E-DIVIDAS.md`. Ver também `08-GAPS-E-DIVIDAS.md`.

## 4. Riscos de dados (migração de schema)

| # | Risco | Severidade | Mitigação |
|---|---|---|---|
| D1 | **IDs `serial`** mudam se o schema for recriado → URLs com id, nomes de arquivo com id (`diario-oficial/content/{id}/images`), FKs | **Alta** | Migrar com PK explícita, ou usar UUID + mapa |
| D2 | **75 views SQL** não existem no schema novo → 40+ telas do CMS quebram | **Alta** | Recriar as views ou convertê-las em Query Objects (ADR-016/017) |
| D3 | **Colunas de apresentação dentro das views** (`status_name`, `data_publicacao`) — nome é contrato do CMS | **Alta** | Mapear explicitamente nos Resources |
| D4 | **`row_number()`** como `value` — a ordem manual de widgets depende | Média | Ordem explícita em `order` |
| D5 | **`timestamp(0) without time zone`** → `timestamptz` muda semântica de data | **Alta** | Revisar os 75 `to_char(... 'DD/MM/YYYY')` e as comparações de período |
| D6 | **Caminhos de arquivo** em string livre (`archives.path`, `service_letter_pdfs.path`) | **Alta** | Serviço de migração de arquivos + normalização do storage |
| D7 | **PII em texto claro** (`ombudsman_requests.cpf/cnpj`, `mask_description` só incluído em 2026) | **Alta** | Crypto-shredding + blind index (spec 4 do `cms/`), ADR-019 |
| D8 | **Sem fila** — PDF gerado dentro da request; reinício do worker perde o trabalho | Média | Fila + `generation_status` (coluna já existe) |
| D9 | **`resources` × `modulos` × `menu_orders`** — 3 tabelas de configuração manual com slugs divergentes | Média | Recriar a partir do manifesto de módulos (ADR-014) |
| D10 | **PostGIS** — nenhuma coluna geometry, mas a extensão pode faltar no PG de destino | Baixa | Garantir `CREATE EXTENSION postgis` |
| D11 | **Sequências** com `nextval` — se o dump for restaurado em outro schema, os valores mudam | Média | `setval` explícito no pós-migração |
| D12 | **Slugs** são chaves de URL em 4 níveis (categoria → conteúdo → seção) | Média | Preservar os slugs no cadastro manual |
| D13 | **`clicks`** — contador desnormalizado, sem trigger | Baixa | Recalcular ou zerar |
| D14 | **`configurations`** — chave/valor com 30+ chaves, sem tipagem | Média | Config tipada por módulo |
| D15 | **Roles e permissões** do Sentinel (`roles.permissions` é JSON) | Média | Recriar perfis no `cms_users` (ADR-033) |

---

## 5. Riscos técnicos da reconstrução

| # | Risco | Probabilidade | Impacto | Mitigação |
|---|---|---|---|---|
| R1 | **Escopo**: 928 rotas, 158 controllers, 131 models, 1.659 Blades, 138 tabelas, 75 views | Alta | Alto | Recortar por módulo (Onda 2 do plano de migração) |
| R2 | **Duplicação de 6 temas**: 889 Blades só nos `modeloN` | Alta | Alto | 1 design system + engine de slots (ADR-016) |
| R3 | **SQL crudo** (35 `whereRaw`, 9 `DB::raw`, 17 `DB::select`) | Alta | Médio | Reescrever como Query Objects/Eloquent |
| R4 | **N+1** (23 queries em `foreach`) | Alta | Médio | Eager loading obrigatório |
| R5 | **Dependências abandonadas** (17 pacotes em risco) | Alta | Médio | ADR-002: mínimo de dependências, nativo primeiro |
| R6 | **Autorização por nome de rota** | Média | Alto | Policies nativas (ADR-033) |
| R7 | **Conteúdo não migra automaticamente** (ADR-042) | **Certa** | Alto | Curadoria editorial manual — é a decisão do dono, mas implica **custo de projeto** |
| R8 | **Sem knowledge transfer**: nenhuma documentação do legado além do `v6/wiki/modules/DiarioOficial/` (18 arquivos) | Alta | Alto | Estes dossiês — 56 módulos |
| R9 | **Cobertura ~2%** — nenhuma rede de segurança para a reescrita | Alta | Alto | E2E por módulo + testes de não-regressão (ADR-038) |
| R10 | **Fila nova** — 0 jobs no legado; o modelo mental da equipe é "síncrono" | Média | Médio | Filas só onde o volume justificar (PDF do diário) |
| R11 | **Dependência do `sniffCSS`** (binário externo no `PATH`) na E2E | Média | Baixo | Substituir por Playwright visual comparison ou axe |
| R12 | **`active.landing`** órfão e outros ramos mortos | Média | Baixo | Inventário de código morto (ADR-023 + `dead-code-detector`) |
| R13 | **PostgreSQL 10 → 18** (ADR-007): 10 anos de acúmulo de SQL | Média | Médio | Revisar os 75 `CREATE VIEW` e o `orderByRaw` com regex |
| R14 | **Duas aplicações v7** (`public-v7/` e `cms/`) com visões de arquitetura **diferentes** (`src/modules` vs `Modules/` + Filament) | **Certa** | **Alto** | **Alinhamento formal necessário** — ver §6 |
| R15 | **Escopo do CMS v7**: `cms/` usa **Filament 4**, mas a ADR-009 do `public-v7` decide **CMS próprio sem framework pesado** | **Certa** | **Alto** | **Contradição entre os dois repositórios** — ver §6 |

---

## 6. Contradições entre os dois repositórios v7

O repositório contém **duas** implementações v7 com decisões conflitantes:

| Aspecto | `public-v7/` (Concordia Portal) | `cms/` (Concordia CMS) |
|---|---|---|
| Autoload | `App\`, `Core\`, `Services\`, `Layout\`, `Modules\`, `Demonstration\`, `Database\Factories\`, `Database\Seeders\` | `Core\`, `Services\`, `Modules\`, `Core\`, `Tests\` |
| Raiz do domínio | `src/` | `core/`, `services/`, `modules/` (raiz) |
| UI do CMS | **CMS próprio** (Blade + Tailwind + daisyUI), ADR-009 | **Filament 4** (`filament/filament ^4.0`) |
| Descoberta de módulos | `src/modules/{Grupo}/{Modulo}/ModuleProvider.php`, ADR-014 | `Core\Internal\ModuleDiscovery\ModuleDiscoveryService` + `ModuleDiscoverySetting` |
| Áreas | `src/core/Access`, `src/core/Area` | `core/Area/{Api,Cms,Parceiros,Portal,Super}` |
| Modelo de área | `src/layout` (portal e CMS no mesmo repo) | `core/Area/*` (áreas no Core) |
| Persistência | services headless com contrato próprio (ADR-015) | Filament + `spatie/laravel-medialibrary` |
| Banco | PostgreSQL 18 (ADR-007) | PostgreSQL 18 (container próprio) |
| Storage | S3-like desde o dia zero (ADR-030) | S3 via `league/flysystem-aws-s3-v3` + MinIO |

**Conclusão:** os dois repositórios **não são compatíveis**. O `cms/` é
**multi-tenant** ("CMS multi-tenant, hardened e observável", `cms/README.md`);
o `public-v7/` é **single-tenant** ("o V7 é single-tenant", ADR-033). São
**dois produtos distintos**.

**Ação necessária (bloqueante):** o dono do projeto precisa decidir qual
arquitetura é a da v7 do portal municipal, ou se o `cms/` vira um produto
paralelo. Este dossiê **não decide** — registra o conflito.

---

## 7. Perguntas em aberto para o negócio

| # | Pergunta | Por que importa | Quem decide |
|---|---|---|---|
| Q1 | Os módulos **exclusivos da v5** (Obras, Concursos PSS, Estagiários, Fila SUS, Licitantes Sancionados, Terceirizados, Gemini, Relatório Ouvidoria) voltam? | 15 tabelas e 19 controllers de conteúdo público | Município / produto |
| Q2 | Os **6 temas** (`modelo1`..`modelo6`) viram os 6 presets da v7, ou o município escolhe **um** tema único? | Define o escopo do design system (L vs XL) | Município / produto |
| Q3 | O `diario-ofifical` (id 16, typo) e o `logs-do-sistema` duplicado (ids 7 e 32) devem ser **removidos** no cadastro? | 2 slugs órfãos | Suporte / produto |
| Q4 | A **Carta de Serviços** (módulo novo da v6) está em produção? A migration `2026_01_20_160719_create_service_letters_table.php` é de 2026 e a v6 está em desenvolvimento ativo | 12 tabelas a migrar | Produto |
| Q5 | **VIAP** está em produção? O módulo só existe por `ViapSeeder.php` (sem migration de módulo) | Módulo instável | Produto |
| Q6 | O **`Drive`** (módulo 30) tem integração implementada? Não há controller nem model correspondente na v6 | Módulo fantasma no catálogo | Produto |
| Q7 | **Suporte** (módulo 9) e **Manual do Sistema** (módulo 8) têm telas no CMS? `v6/resources/views/prefecture/support/` existe, `manual-areas` tem model | Verificar completude | Produto |
| Q8 | A **API de dados abertos** tem contrato público consumido por terceiros? O formato `titulo`/`autor`/… precisa ser preservado? | Versionamento da API | Município / produto |
| Q9 | O **`active_landing`** (landing page) deve existir na v7? O middleware está pronto mas nenhuma rota o usa | Recurso orfão | Produto |
| Q10 | Qual o **horizonte de migração do conteúdo**? ADR-042 define migração manual caso a caso — 928 rotas e 138 tabelas de histórico exigem capacidade editorial | Viabilidade | Dono do projeto |
| Q11 | O **`cms/`** (Filament, multi-tenant) é o CMS da v7, ou o CMS próprio do `public-v7/`? | **Bloqueante** — §6 | Dono do projeto |
| Q12 | A **v5** continua em produção durante a reconstrução? | Define se há janela de coexistência | Município |

---

## 8. Mapa v5 → v6 (resumo operacional)

| Camada | v5 | v6 | Impacto na v7 |
|---|---|---|---|
| Rotas | 578 `Route::` | 620 `Route::` | Reimplementar as 928 (registradas) |
| Controllers | 147 | 158 | 158 no legado; a v7 reescreve por Action |
| Models | 115 | 131 | 131 no legado; a v7 usa UUID |
| Blades | 1.524 | 1.659 | Substituir por componentes |
| Tabelas | 130 | 138 | 138 no legado; novo schema |
| Views SQL | — | 75 | Eliminadas (ADR-016) |
| Migrations | 349 | 358 | Novo schema, 358 → novo conjunto |
| Dependências | 34 | 35 | 35 → ~20 (ADR-002) |
| Testes | 5 | 34 | Cobertura real ~2% |
| Módulos (registry) | inexistente | 58 linhas | Manifesto por autodescoberta (ADR-014) |
| Breadcrumb | quebrado (404 GitHub) | fork `diglactic` | Não replicar |

---

## 9. Referências

| Item | Caminho |
|---|---|
| Handler de exceções | `v6/app/Exceptions/Handler.php` |
| Middleware de permissão | `v6/app/Http/Middleware/CheckRoutePermission.php` |
| Middleware de manutenção | `v6/app/Http/Middleware/CheckSiteManutention.php` |
| Middleware órfão | `v6/app/Http/Middleware/ActiveLanding.php` |
| Repositório base com `dd()` | `v6/app/Repositories/Repository.php` |
| Cache de módulos | `v6/app/Providers/ModulosServiceProvider.php` |
| Controller de layout | `v6/app/Http/Controllers/Prefecture/LayoutController.php` |
| Model de layout (fillable com `kay`) | `v6/app/Http/Model/Prefecture/Layout.php` |
| Providers com placeholder | `v6/app/Providers/AuthServiceProvider.php`, `v6/app/Providers/EventServiceProvider.php` |
| Migration da tabela `modulos` | `v6/database/migrations/2024_11_01_150206_create_modulos_table.php` |
| Correção de `menu_orders` | `v6/database/migrations/2026_09_01_100000_fix_menu_orders_missing_modulo_id.php` |
| Seeder do VIAP | `v6/database/seeds/ViapSeeder.php` |
| SQL cru de contratos | `v6/app/Http/Controllers/Prefecture/ContractController.php` |
| SQL cru de propostas | `v6/app/Http/Controllers/Prefecture/ProposalController.php` |
| ADR de não-retrocompatibilidade | `public-v7/wiki/adr/ADR-042-sem-retrocompatibilidade-conteudo-migrado-a-mao.md` |
| ADR de dependências mínimas | `public-v7/wiki/adr/ADR-002-minimas-dependencias-vendorizacao.md` |
| ADR de UI do CMS | `public-v7/wiki/adr/ADR-009-ui-cms-proprio-tailwind-daisyui.md` |
| README do CMS v7 | `cms/README.md` |
| README do portal v7 | `public-v7/wiki/README.md` |
