# Drive — Gaps, Dívidas e Comparativo v5 -> v6

## 1. Bugs e erros conhecidos

| # | Achado | Evidência | Severidade |
|---|---|---|---|
| B1 | O campo de busca chama `searchImage()`, função que **não existe** no JavaScript do módulo (que define `setupSearch`/`filterImages`) | `v6/resources/views/prefecture/contents/midias/form.blade.php:10` vs `v6/public/assets/js/custom/contents/midias/index.js` | Média (erro de JS a cada digitação) |
| B2 | A listagem do Drive não tem escopo: devolve **todos** os arquivos do sistema | `v6/app/Http/Controllers/Prefecture/ArchiveController.php:161-162` | Alta |
| B3 | A exclusão remove o registro mas **não** o arquivo físico | `ArchiveController@deleteArchives` (linhas 168-180) | Média |
| B4 | Não há validação de tipo nem de tamanho no upload | `ArchiveController@saveArchivesFromGalleryOrDriver` | Alta (upload de conteúdo arbitrário servido pelo `storage`) |
| B5 | A rota `GET /cms/galeria/{column?}/{id?}` injeta o nome da coluna vindo da URL na query | `->where($colunm, $id)` | Média |
| B6 | `ArchiveController` não aplica `check.route.permission` nem `has_access()`: qualquer usuário logado no CMS gerencia arquivos | construtor do controller (linhas 37-40) | Alta |
| B7 | O nome original do arquivo é perdido (nome aleatório gerado) | `v6/app/Http/Traits/FileTrait.php:78-82` | Média (usabilidade e rastreabilidade) |
| B8 | `GET /cms/conteudos/midias` redireciona para o dashboard | `genericIndex` sem caso `midias` (`v6/app/Http/Controllers/Prefecture/ContentController.php:118`) | Baixa |
| B9 | A API de listagem devolve a coleção inteira; o “lote de 50” é só front-end | `chargeGallery` em `v6/public/assets/js/custom/contents/midias/index.js` | Média em volume alto |
| B10 | Uma requisição `HEAD` por arquivo para verificar existência | `verifyAndLoadImages` | Média (N+1 de rede) |
| B11 | `where('extension', '!=', null)` depende do SGBD (no PostgreSQL a comparação com NULL é NULL) | `ArchiveController@getArchivesFromGalleryOrDriver` | Baixa |
| B12 | `updateArchivesOrder` monta `where($relatedType, $relatedId)` com valor vindo do cliente | `ArchiveController@updateArchivesOrder` | Baixa |
| B13 | O mesmo JS é usado por 10 telas: regressão em um módulo afeta os outros | `assets/js/custom/contents/midias/index.js` | Média |

## 2. Funcionalidades incompletas ou mortas

| Item | Situação |
|---|---|
| Categoria `midias` (id 31) | existe e aparece no CMS, mas **nenhum `contents` é criado** para ela: serve apenas de rótulo (“Mídias”) |
| `types_sizes` | não é usado pelo Drive (colunas `type_size_id`, `width`, `height` ficam nulas) |
| `updateArchiveTitle` e `updateArchivesOrder` | existem no backend, mas o JavaScript do Drive **não os chama** (só as ações Copiar/Baixar/Visualizar/Excluir) |
| `defaultOrder` e `putOrder` do `ArchiveController` | não são usados pelo módulo nem registrados em rota |
| Rutas `galeria.*` | não têm `->name()`: não há route name para o JavaScript usar |
| Link do menu | aponta para `/cms/conteudos/cadastrar/midias` (rota de “cadastrar”), mesmo não havendo tela de cadastro |

## 3. Riscos de dados

| Risco | Detalhe |
|---|---|
| Arquivos órfãos | 87 dos 91 registros de `archives` estão com `contents_id` nulo; a listagem do Drive mistura arquivos de vários módulos |
| Binários órfãos | a exclusão lógica deixa os arquivos em `public/storage`, ocupando espaço para sempre |
| Ausência de proprietário | sem `contents_id` não há como saber quem enviou o arquivo nem a quem ele serve |
| Sem registro do mime/tamanho confiável | `type` e `hash` são preenchidos, mas `size` não existe na tabela `archives` |
| Caminhos divergentes | o `path` pode vir com ou sem o prefixo `storage/` (há helper `archiveWebPath` em `v6/app/Helpers/functions.php` para normalizar) |
| Sem soft-delete-aware na listagem | `Archive` usa `SoftDeletes`, então os arquivos excluídos somem da listagem, mas continuam no disco |

## 4. Estado atual no banco (`prefeituras_v5`)

| Consulta | Resultado |
|---|---|
| `select count(*) from archives` | 91 |
| `select count(*) from archives where contents_id is null` | 87 |
| `select count(*) from archives where path like 'storage/content/midias%'` | 0 |
| `select count(*) from types_sizes` | 4 |

A biblioteca do Drive está **vazia** no ambiente de desenvolvimento; os 91 arquivos são de outros
módulos (por exemplo `storage/manual-usuario/`), e seriam todos exibidos na tela do Drive.

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

1. O Drive deve ser uma biblioteca com **dono** (arquivo vinculado a um conteúdo) ou continuar sem vínculo?
2. Deve haver limite de tamanho e de tipos aceitos?
3. A exclusão deve apagar o arquivo físico?
4. Deve existir busca por nome do arquivo original (e metadados)?
5. O Drive deve ter categorias/pastas para organizar a biblioteca?
6. É aceitável que os arquivos sejam servidos publicamente sem autenticação?
7. Deve haver auditoria de quem enviou/excluiu cada arquivo?

## 6. Mapa v5 -> v6

| Aspecto | v5 | v6 | Impacto |
|---|---|---|---|
| Telas do Drive | `v5/resources/views/prefecture/contents/midias/` | `v6/resources/views/prefecture/contents/midias/` | idênticas (`form` + `edit`) |
| JavaScript da galeria | `v5/public/assets/js/custom/contents/midias/index.js` | idem | idêntico |
| Controller de arquivos | `v5/app/Http/Controllers/Prefecture/ArchiveController.php` | `v6/app/Http/Controllers/Prefecture/ArchiveController.php` | a v6 acrescenta `updateArchiveTitle` e `updateArchivesOrder` |
| Rotas `galeria.*` | `v5/routes/basepro.php:381` | `v6/routes/basepro.php:384` | mesmas 5 rotas |
| Componente de galeria | `v5/resources/views/prefecture/contents/components/galerias/index.blade.php` | idem | idêntico |
| Rótulo do menu | `case 'midias':` com outro texto | `case 'midias':` -> texto **“Drive”**, url `/cms/conteudos/cadastrar/midias` | renomeado |
| Recurso/permissão | `resources.slug = midias` | `resources.slug = drive` (`v6/database/seeds/AjustesMigracao.php:81-90`), permissões `midias.*` | **divergência**: recurso `drive` com permissões `midias.*` |
| Módulo do CMS | inexistente | `modulos` id 30 `drive`, `status = true` | **novo na v6** |
| Pasta física | `storage/content/midias` | idem | sem mudança |

### Itens da v5 que não existem na v6

Nenhum. As funcionalidades do Drive (upload, listagem, busca, ações, exclusão) são idênticas.

### Itens novos na v6

- Tabela `modulos` com o módulo `drive` habilitado.
- Resource `drive` (id de módulo 30), com o resource antigo `midias` renomeado.
- Métodos `updateArchiveTitle` e `updateArchivesOrder` no `ArchiveController` (disponíveis, mas não
  usados pelo JavaScript do Drive).

## 7. Checklist de migração v6 -> v7

| Passo | Ação | Verificação |
|---|---|---|
| 1 | Exportar `archives` com `path`, `name`, `extension`, `type`, `hash`, `contents_id`, `static_pages_id`, `calendar_events_id`, `highlight`, `order` | 91 linhas no ambiente de desenvolvimento |
| 2 | Classificar cada arquivo em coleção (`drive`, `galeria`, `destaque`) | relatório por `path` |
| 3 | Verificar no disco se cada `path` existe | relatório de arquivos órfãos |
| 4 | Importar para `media` | contagem idêntica |
| 5 | Migrar o nome original (o legado perdeu essa informação; recuperar do disco, quando possível) | amostragem |
| 6 | Recriar as permissões com prefixo `drive.*` | `php artisan tinker` verificando `can()` |
| 7 | Criar o componente `<x-media-grid>` e substituir as 10 inclusões manuais | conferência em cada tela |
| 8 | Decidir o destino dos 87 arquivos órfãos | decisão do negócio registrada |
