diff --git a/.github/workflows/publish-wiki.yml b/.github/workflows/publish-wiki.yml new file mode 100644 index 00000000..892ecf14 --- /dev/null +++ b/.github/workflows/publish-wiki.yml @@ -0,0 +1,30 @@ +name: Publish wiki + +on: + push: + branches: [main, develop] + paths: + - wiki/** + - .github/workflows/publish-wiki.yml + +concurrency: + group: publish-wiki + cancel-in-progress: true + +permissions: + contents: write + +jobs: + publish-wiki: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: Andrew-Chen-Wang/github-wiki-action@v4 + with: + # Espelha a pasta wiki/ para a aba Wiki do repositório + path: wiki/ + # Converte links .md para o formato wiki e move README.md para Home.md + preprocess: true + # Mensagem de commit opcional + commit-message: "docs(wiki): sync wiki from ${{ github.ref_name }}" diff --git a/.gitignore b/.gitignore index 804fb89e..95dd4134 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,3 @@ themes/dcp/mix-manifest.json .DS_Store .idea .env -AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..15d9eaef --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,367 @@ +# AGENTS.md — Defesa Climática Popular (DCP) + +> Arquivo de referência para agentes de código. Leia este documento antes de modificar qualquer arquivo. O projeto é mantido em **português (Brasil)**; comentários, nomes de variáveis e documentação seguem este idioma sempre que possível. + +--- + +## Visão geral do projeto + +O **Defesa Climática Popular (DCP)** é uma iniciativa de mapeamento participativo de riscos climáticos e fortalecimento de respostas comunitárias em territórios populares. Este repositório mantém a base tecnológica completa do projeto, construída sobre **WordPress** e containerizada com **Docker**. + +A solução é composta por: +- Um **tema customizado** (`themes/dcp/`) que implementa o site público, um painel interno para agentes comunitários (`/dashboard/*`) e blocos customizados para o Gutenberg. +- Um **plugin proprietário** (`plugins/dcp-plugin/`) que expõe endpoints da API REST (`/wp-json/dcp/v1/*`), webhooks e integrações com o framework Pods. +- **Infraestrutura Docker** para desenvolvimento local e deploy em produção (compatível com Traefik e Kubernetes). +- Workflows de CI/CD via **GitHub Actions** (build de assets e releases) e **GitLab CI** (deploy legacy em Kubernetes). + +--- + +## Tecnologias e arquitetura + +| Camada | Tecnologia | +|--------|-----------| +| Backend | WordPress 6.5.3, PHP 8.3 | +| Banco de dados | MariaDB 10.4 | +| Cache (produção) | Redis 7 (AlmLRU, RDB snapshots) | +| Containerização | Docker, Docker Compose 2.x | +| Imagem base local | `hacklab/wp:6.5.3-php8.3` | +| Build de assets | Node.js 20, Laravel Mix 6, Webpack | +| Estilos | Sass/SCSS, ITCSS + BEM | +| Scripts front-end | Vanilla JS, Alpine.js 3, React (para blocos Gutenberg) | +| Campos customizados | Pods Framework | +| Mapas | OpenStreetMap / Leaflet (via plugin Jeo) | +| Automação externa | n8n (workflow de clima/situação atual) | + +### Arquitetura de rede (Docker) +- **Local**: duas redes bridge (`interna` e `wordpress-bot`). +- **Produção**: rede externa nomeada `web` (padrão Traefik). + +### Variáveis de ambiente importantes +- `WORDPRESS_DB_HOST`, `WORDPRESS_DB_USER`, `WORDPRESS_DB_PASSWORD` +- `WORDPRESS_DEBUG` (local: `0`; produção: `1` por padrão) +- `GOOGLE_MAPS_API_KEY` (opcional; se ausente, geocoding usa Nominatim/OpenStreetMap) +- `MYSQL_ROOT_PASSWORD`, `MYSQL_DATABASE`, `MYSQL_USER`, `MYSQL_PASSWORD` + +--- + +## Estrutura de diretórios + +``` +. +├── wp-root/ # Núcleo WordPress versionado +├── themes/dcp/ # Tema principal +│ ├── assets/ +│ │ ├── scss/ # Fontes SCSS (ITCSS) +│ │ ├── javascript/ # Scripts fonte (functionalities/ e shared/) +│ │ ├── images/ # Imagens e ícones do tema +│ │ └── fonts/ # Fontes tipográficas +│ ├── dist/ # Build compilado (CSS, JS, blocos, mix-manifest.json) +│ ├── library/ # Lógica PHP modular +│ │ ├── blocks/ # Blocos Gutenberg customizados +│ │ ├── dashboard*.php # Painel do agente (rotas, widgets, AJAX) +│ │ ├── api/ # Endpoints internos do tema +│ │ ├── template-tags/ # Funções auxiliares de templates +│ │ ├── sanitizers/ # Sanitizadores de entrada +│ │ ├── assets.php # Classe singleton de enfileiramento de assets +│ │ └── ... +│ ├── template-parts/ # Componentes PHP reutilizáveis +│ ├── languages/ # Arquivos de tradução (.po/.mo) +│ ├── package.json # Dependências Node do tema +│ ├── webpack.mix.js # Configuração do Laravel Mix +│ └── theme.json # Paleta de cores, tipografia e espaçamento do tema +├── plugins/dcp-plugin/ +│ └── dcp-plugin.php # Plugin de API REST, webhooks e colunas admin +├── plugins/hacklab-dev-utils/ # Submódulo Git de utilidades de dev (WP-CLI, PsySH) +├── mu-plugins/ # Must-use plugins (vazio por padrão) +├── compose/ +│ ├── local/ +│ │ ├── wordpress/Dockerfile +│ │ ├── watcher/Dockerfile # Container Node para watch de assets +│ │ └── mariadb/data/ # Dumps SQL para inicialização do banco +│ └── entrypoint-extra/ +│ └── sync-dependencies.sh +├── dev-scripts/ # Atalhos de shell para rotina local +├── Pods/ # Exportações JSON das configurações do Pods +├── n8n/ # Workflows exportados do n8n +├── docker-compose.yml # Stack local +├── docker-compose.deploy.yml # Stack de produção +├── .gitlab-ci.yml # CI/CD legacy (GitLab → Kubernetes) +└── .github/workflows/ # CI/CD atual (GitHub Actions) +``` + +### Sobre o `style.css` na raiz +O arquivo `style.css` na raiz do projeto é um **link simbólico** para `themes/dcp/style.css`. Ele existe para compatibilidade com o plugin **git-updater**, que atualiza o tema diretamente via release do GitHub. + +--- + +## Comandos de build e desenvolvimento + +### Setup inicial +```bash +git clone dcp +cd dcp +git submodule update --init --recursive +docker-compose up --build +``` + +### Scripts utilitários (`dev-scripts/`) + +| Script | Descrição | +|--------|-----------| +| `./dev-scripts/wp ` | Executa WP-CLI dentro do container `wordpress` | +| `./dev-scripts/mysql` | Acessa o MariaDB como usuário `wordpress` | +| `./dev-scripts/mysql-root` | Acessa o MariaDB como `root` | +| `./dev-scripts/dump` | Gera dump do banco de dados | +| `./dev-scripts/dev.sh` | Roda o PHP built-in server localmente (sem Docker) | +| `./dev-scripts/compilar.sh` | Build de produção do tema via container Node efêmero | +| `./dev-scripts/zip.sh` | Gera `zips/dcp.zip` do tema (exclui `node_modules`) | + +### Build de assets do tema +```bash +cd themes/dcp + +# Desenvolvimento (com watch) +npm install +npm run watch + +# Produção (minificado) +npm run production +``` + +O serviço `watcher` do `docker-compose.yml` executa `npm install && npm run watch` automaticamente ao subir os containers. + +### Estrutura do build (`webpack.mix.js`) +- **SCSS**: `app.scss`, `dashboard.scss`, `editor.scss` +- **JS**: cada arquivo em `assets/javascript/functionalities/*.js` vira um chunk separado em `dist/js/functionalities/` +- **Blocos Gutenberg**: cada pasta em `library/blocks/*/` com `.js` e `.scss` gera assets em `dist/blocks//` +- **Source maps**: `eval-source-map` em dev; `source-map` em produção +- **Extração de dependências**: `@wordpress/dependency-extraction-webpack-plugin` com `combineAssets: true` + +--- + +## Convenções de código + +### PHP +- **Namespace base**: `hacklabr` para o tema; funções do plugin usam prefixo `dcp_`. +- O tema ainda usa `require` em arquivos procedurais (veja `library/README.md`: *"The idea is migrate later to classes"*). +- A classe `Assets` (`library/assets.php`) é um **singleton** que gerencia enfileiramento de scripts e estilos. +- **Indentação**: 4 espaços (`.editorconfig`). +- **Charset**: UTF-8, fim de linha LF. + +### SCSS: ITCSS + BEM +A organização de estilos segue rigorosamente **ITCSS** (Inverted Triangle CSS) com nomenclatura **BEM**: + +``` +assets/scss/ +├── 1-settings/ # Variáveis globais (cores, breakpoints) +├── 2-tools/ # Mixins e funções Sass +├── 3-generic/ # Reset, fontes, estilos html/body +├── 4-elements/ # Estilos de elementos HTML puros +├── 5-objects/ # Objetos reutilizáveis (botões, containers, forms) +├── 6-components/ # Componentes específicos do projeto +├── 7-trumps/ # Utilitários e helpers (!important) +├── 9-overrides/ # Sobrescritas de plugins/componentes de terceiros +└── app.scss # Ponto de entrada principal +``` + +**Regras importantes:** +- SEMPRE usar variáveis Sass para cores, tamanhos e espaçamentos. +- EVITE estilizar elementos HTML diretamente; prefira classes. Se necessário, seja específico (`.myblock>.content>p`, nunca `.myblock p`). +- Objetos e componentes **NÃO devem** conter estilização externa (margin, position, width, max-width). Quem define é o elemento pai ou modificador. +- Overrides de terceiros ficam em `9-overrides/`, mas **sempre** usando variáveis do projeto. + +### JavaScript +- Cada funcionalidade isolada vive em seu próprio arquivo dentro de `assets/javascript/functionalities/`. +- Arquivos em `assets/javascript/shared/` são módulos reutilizáveis (ex: `wait.js`, `pins.js`, `legends.js`). +- Blocos Gutenberg usam React e se beneficiam da extração automática de dependências do WordPress. + +### WordPress +- **Text domain do tema**: `hacklabr` +- **Role customizada**: `agente-dcp` (`DASHBOARD_AGENT_ROLE`), criada em `library/dashboard.php`. +- **Rewrite rules**: `^dashboard/([^/]+)/?` mapeia para `pagename=dashboard&ver=$matches[1]`. +- **Custom post types gerenciados via Pods**: `risco`, `acao`, `relato`, `apoio`, `recomendacao`, `situacao_atual`, entre outros. + +--- + +## Dashboard (`/dashboard/*`) + +O dashboard é uma área administrativa frontend customizada do tema, acessível em `/dashboard/{rota}`. Ele não utiliza o wp-admin padrão; toda a interface é renderizada via template `page-dashboard.php` com rotas amigáveis definidas pelo rewrite rule `^dashboard/([^/]+)/?`. + +### Autenticação e permissões +- **Role `agente-dcp`** (label "Community agent") é criada automaticamente em `library/dashboard.php` com capacidades de CRUD sobre o CPT `risco` e `upload_files`. +- O acesso ao dashboard exige `current_user_can('edit_riscos')`; usuários sem permissão são redirecionados para a tela de login. +- Após login, usuários com role `agente-dcp` são redirecionados automaticamente para o dashboard. +- ⚠️ **Inconsistência detectada:** `library/frontend_auth.php` possui uma restrição paralela que redireciona não-administradores em `is_page('dashboard')`, o que pode conflitar com a lógica de `dashboard.php`. O login AJAX também restringe acesso a administradores, impedindo que agentes comunitários autentiquem-se pelo formulário frontend. + +### Rotas e funcionalidades + +| Rota | Descrição | +|------|-----------| +| `/dashboard/inicio` | Página inicial com saudação, card da Situação Atual, contador de novos relatos e lista de riscos aguardando avaliação. | +| `/dashboard/riscos` | Lista de riscos com tabs: Aguardando Aprovação (`draft`), Publicados (`publish`) e Arquivados (`pending`). Cards com categoria, data, endereço, descrição e galeria de mídias (Swiper.js). | +| `/dashboard/adicionar-risco` | Formulário de cadastro de novo risco. | +| `/dashboard/editar-risco` | Edição de risco existente. | +| `/dashboard/acoes` | Lista de ações com tabs: Sugestões, Agendadas, Realizadas, Arquivadas e Ações Relatadas. Renderiza via `loop-post-card-{tipo_acao}`. | +| `/dashboard/adicionar-acao` / `/dashboard/editar-acao` | CRUD de ações. | +| `/dashboard/adicionar-relato` / `/dashboard/editar-relato` | CRUD de relatos de ações realizadas. | +| `/dashboard/apoio` | Lista de pontos de apoio filtrados por taxonomy `tipo_apoio` (Locais Seguros, Caçambas, Iniciativas Locais, Quem Acionar). Suporta arquivamento via meta `apoio_arquivado`. | +| `/dashboard/adicionar-apoio` / `/dashboard/editar-apoio-novo` | CRUD de pontos de apoio. | +| `/dashboard/situacao_atual` | Exibe o alerta climático ativo (CPT `situacao_atual`) e recomendações ativas (CPT `recomendacao` com `is_active = true`). | +| `/dashboard/alterar_risco` | Alterar situação de risco atual. | +| `/dashboard/editar_recomendacao` | Editar recomendações de segurança. | +| `/dashboard/editar_cacambas` | Editar caçambas. | +| `/dashboard/editar_quem_acionar` | Editar "quem acionar". | +| `/dashboard/indicadores` | Painel de estatísticas com filtros por data, cards de contadores e gráficos Chart.js (riscos por categoria, ações agendadas vs sugestões, realizadas vs arquivadas). | + +### AJAX e operações CRUD (`dashboard-ajax.php`) +Todas as operações de criação, edição e exclusão são feitas via AJAX: +- `form_single_risco_new` / `edit` — CRUD de riscos (pode ser anônimo) +- `form_single_acao_new` / `edit` — CRUD de ações (pode ser anônimo) +- `form_single_relato_new` / `edit` — CRUD de relatos +- `form_single_apoio_new` / `edit` — CRUD de apoios +- `form_participar_acao` — Inscrição em ação +- `download_participantes_acao` — Exporta CSV de inscritos +- `form_single_delete_attachment` — Remove mídia anexada + +### Indicadores (`dashboard-indicadores.php`) +Funções para contagem de posts com filtros por intervalo de datas: +- `dashboard_get_post_type_by_status_between_date()` — Conta posts por status e data +- `dashboard_get_riscos_count_by_taxonomy()` / `by_term()` — Conta riscos por taxonomia/termo + +### Utilitários (`dashboard-utils.php`) +- `formatarTelefoneBR()` / `limparTelefone()` — Formatação de telefones +- `risco_badge_category()` — Badges com ícones Iconify por categoria de risco +- `upload_file_to_attachment_by_ID()` — Upload de múdias (jpg, jpeg, png, mp4) +- `dashboard_excerpt()` — Texto truncado com "Ver mais" +- `wpcf7_form_sugestao_acao()` — Hook Contact Form 7 que cria post `acao` a partir de formulário público + +### Estrutura visual +- Layout: sidebar fixa à esquerda + conteúdo principal +- Ícones: Iconify + Bootstrap Icons +- Sliders: Swiper.js (galerias de mídia) +- Gráficos: Chart.js + plugin datalabels +- Responsivo: tratamento diferenciado para mobile (`wp_is_mobile()`) + +--- + +## Testes + +**Não há suíte de testes automatizados configurada neste projeto** (não há PHPUnit, Jest, Pest, Cypress, etc.). + +A validação é feita manualmente e pelos pipelines de CI/CD: +1. O workflow do GitHub Actions compila os assets (`npm run production`) e falha se o build quebrar. +2. O artefato do tema é inspecionado (`ls -lhtra`) antes do upload. +3. Em produção, o deploy via git-updater aciona um curl de teste no endpoint de atualização. + +Para testar localmente: +- Use `./dev-scripts/wp` para rodar comandos WP-CLI e verificar estado do WordPress. +- Para depuração interativa, insira `eval(\psy\sh());` no código PHP e execute `./dev-scripts/dev.sh`. + +--- + +## Segurança + +- O plugin `dcp-plugin` expõe endpoints REST **públicos** (`permission_callback => '__return_true'`). Isso é intencional para consumo por apps parceiras, mas qualquer modificação nesses endpoints deve avaliar impacto de exposição de dados. +- O webhook `/wp-json/dcp/v1/webhook/situacao-atual` aceita POST sem autenticação (ou com autenticação básica via WordPress API, conforme configuração do n8n). Verifique se a URL está protegida por firewall ou chave secreta em produção. +- **Nunca commite** dumps de produção com dados reais para o repositório. +- `WORDPRESS_DEBUG` deve permanecer `0` em produção. +- O arquivo `.htaccess` local está em `compose/local/wordpress/htaccess`; em produção a configuração é gerenciada pela imagem Docker ou pelo reverse proxy (Traefik). + +--- + +## Deploy e CI/CD + +### GitHub Actions (fluxo atual) +Localizado em `.github/workflows/`: + +1. **Build and Publish on DockerHub** + - Gatilho: push para branches `release/**`, `hotfix/**`, `feature/**` ou tags. + - Build e push da imagem Docker `nossas/dcp-wp` para o Docker Hub. + +2. **CI (build de tema e release)** + - Gatilho: push para `main` ou tags. + - Remove `dist/`, `node_modules` e `package-lock.json`. + - Executa `npm install && npm run production`. + - Faz upload do artefato `dcp`. + - Em tags: cria release no GitHub, gera `.zip` e dispara atualização via git-updater no site de produção. + +### GitLab CI (legacy) +O arquivo `.gitlab-ci.yml` contém pipelines para deploy em Kubernetes em namespaces `base-theme-site-dev` e `base-theme-site-prod`. O fluxo: +1. `build_assets`: compila o tema com Node 20. +2. `create_pack_*`: gera zip do tema e publica como package genérico do GitLab. +3. `deploy_to_*`: usa `kubectl` para copiar o zip para o pod WordPress e instalar via `wp theme install --force`. + +### Deploy em produção (Docker Compose) +O arquivo `docker-compose.deploy.yml`: +- Usa a imagem `nossas/dcp-wp` (tag configurável via `WORDPRESS_DOCKER_IMAGE`). +- Inclui Redis para cache de objetos. +- Espera a rede externa `web` (padrão Traefik). +- Variáveis sensíveis são injetadas via environment. + +--- + +## Dados e integrações externas + +### Pods (Custom Post Types e Campos) +As definições de Pods estão exportadas em `Pods/`. O arquivo `autores.json` é um exemplo de exportação de taxonomy com campos customizados (avatar). Alterações estruturais no Pods devem ser acompanhadas de exportação atualizada para versionamento. + +### n8n +O workflow `n8n/NOSSAS_DCP___SITUACAO_ATUAL.json` é executado automaticamente a cada hora (minuto 1) e realiza a coleta de dados meteorológicos e de estágio de risco, enviando-os ao WordPress via webhook. + +**Fluxo de execução:** +1. **Schedule Trigger** (`scheduleTrigger`) — dispara a cada hora, no minuto 1. +2. **HG_GET_RJ_LAT_LON** (`httpRequest`) — consulta a API HG Brasil (`https://api.hgbrasil.com/weather`) para obter a condição climática do Rio de Janeiro (coordenadas `-22.8873378, -43.2559982`). Parâmetros da consulta: + - `key`: `` + - `fields`: `only_results,temp,date,time,condition_code,description,currently,rain,condition_slug` +3. **HTTP GET ESTAGIO** (`httpRequest`) — consulta a API de estágio da COCR (`https://aplicativo.cocr.com.br/estagio_api`) com um timestamp no query-string para evitar cache. +4. **Merge** (`merge`) — combina os dois resultados (clima + estágio) em um único objeto. +5. **SAVE DCP SITUACAO ATUAL ESTAGIO** (`httpRequest`) — envia os dados combinados via `POST` para o endpoint WordPress `/wp-json/dcp/v1/webhook/situacao-atual/`. + +**Payload enviado ao webhook (`multipart/form-data`):** +| Campo | Origem | +|-------|--------| +| `temp` | `$json.clima.temp` | +| `condition_code` | `$json.clima.condition_code` | +| `description` | `$json.clima.description` | +| `is_rain` | `$json.clima.rain` | +| `estagio` | `$json.estagio.estagio` | +| `date` | `$json.clima.date` | +| `time` | `$json.clima.time` | +| `currently` | `$json.clima.currently` | +| `condition_slug` | `$json.clima.condition_slug` | + +**Destinos configurados:** +- `https:///wp-json/dcp/v1/webhook/situacao-atual/` (ambiente staging) +- `https://defesaclimaticapopular.org/wp-json/dcp/v1/webhook/situacao-atual/` (produção) +- `https:///wp-json/dcp/v1/webhook/situacao-atual/` (desabilitado; ambiente local via ngrok) + +A autenticação nos dois primeiros nós usa credenciais do tipo `wordpressApi` (WP DCP PROD); o nó local usa `WP_DCP_LOCAL`. Para reimportar o workflow no n8n, utilize a interface web do n8n. + +### API REST do plugin (`dcp-plugin`) +Endpoints documentados (não é uma lista exaustiva; consulte o código fonte): +- `GET /wp-json/dcp/v1/riscos` — lista riscos com paginação. +- `GET /wp-json/dcp/v1/riscos-resumo` — resumo das ocorrências nas últimas 24h. +- `GET /wp-json/dcp/v1/abrigos` — lista locais seguros (tipo `locais-seguros`). +- `GET /wp-json/dcp/v1/dicas` — recomendações ativas (filtro por `tipo` e `active`). +- `GET /wp-json/dcp/v1/contatos` — contatos de emergência (Bombeiros, Defesa Civil, SAMU). +- `GET /wp-json/dcp/v1/risco-regiao` — situação atual ativa (alerta, estágio, temperatura). +- `GET /wp-json/dcp/v1/situacao-atual-home` — conteúdo dinâmico da home. +- `POST /wp-json/dcp/v1/webhook/situacao-atual` — webhook para atualização de clima/estágio. + +--- + +## Atualizações do tema base (boilerplate Hacklab) + +Este projeto nasceu do boilerplate `base-wordpress-project` da Hacklab. Para herdar melhorias: +```bash +git remote add temaBase git@git.hacklab.com.br:open-source/base-wordpress-project.git +git pull temaBase develop +``` +Revise os commits antes de aplicar para evitar reverter personalizações do DCP. + +--- + +## Contatos e suporte + +- Infraestrutura/integrações: equipe Hacklab — `contato@hacklab.com.br` +- Issues e pull requests: abra no repositório com descrição do fluxo esperado, dependências externas e anexos relevantes. diff --git a/README.md b/README.md index 36185d5c..c06d5396 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,25 @@ Importe um dump para `compose/local/mariadb/data/` e reinicie os containers (`do - `template-parts/`: componentes PHP utilizados nas páginas públicas e no dashboard. - `assets/js`, `assets/scss`: código fonte compilado pelo Laravel Mix definido em `webpack.mix.js`. +### Dashboard +O dashboard é uma área administrativa frontend customizada (`/dashboard/*`), renderizada pelo template `page-dashboard.php`. Ela não utiliza o wp-admin padrão e é voltada para agentes comunitários gerenciarem conteúdo do projeto. + +**Autenticação:** +- Role customizada `agente-dcp` (criada em `library/dashboard.php`) com permissões de CRUD sobre riscos. +- Acesso restrito a usuários com `edit_riscos`; não-autenticados são redirecionados para login. +- ⚠️ **Conflito conhecido:** `library/frontend_auth.php` restringe o dashboard a administradores, o que pode impedir que agentes comunitários acessem via formulário frontend. + +**Principais rotas:** +- `/dashboard/inicio` — Visão geral com situação atual, novos relatos e riscos pendentes. +- `/dashboard/riscos` — Gestão de riscos (aprovação, publicação, arquivamento) com galeria de mídias. +- `/dashboard/acoes` — Gestão de ações comunitárias (sugestões, agendadas, realizadas). +- `/dashboard/apoio` — Pontos de apoio (locais seguros, caçambas, iniciativas, quem acionar). +- `/dashboard/situacao_atual` — Alerta climático ativo e recomendações de segurança. +- `/dashboard/indicadores` — Estatísticas e gráficos (Chart.js) sobre riscos e ações. + +**Operações CRUD:** +Todas as operações de criação, edição e exclusão são feitas via AJAX centralizado em `library/dashboard-ajax.php`. Riscos e ações podem ser criados por usuários anônimos no frontend do site. + ### API e integrações O plugin `dcp-plugin` entrega endpoints públicos para uso em apps e integrações: - `GET /wp-json/dcp/v1/riscos`: lista riscos com paginação, anexos e metadados. @@ -48,6 +67,33 @@ O plugin `dcp-plugin` entrega endpoints públicos para uso em apps e integraçõ - `GET /wp-json/dcp/v1/situacao-atual-home`: conteúdo dinâmico da home. Outros endpoints tratam de tarefas de ETL, dashboards e sincronização com Pods. Consulte o arquivo `plugins/dcp-plugin/dcp-plugin.php` para detalhes de parâmetros e cargas. +#### Webhook `situacao-atual` (n8n) +O workflow n8n (`n8n/NOSSAS_DCP___SITUACAO_ATUAL.json`) é executado a cada hora para coletar dados meteorológicos e de estágio de risco e enviá-los ao WordPress. + +**Fontes de dados:** +- **Clima:** API HG Brasil (`https://api.hgbrasil.com/weather`), consultando as coordenadas do Rio de Janeiro (`-22.8873378, -43.2559982`). Retorna `temp`, `date`, `time`, `condition_code`, `description`, `currently`, `rain`, `condition_slug`. +- **Estágio:** API da COCR (`https://aplicativo.cocr.com.br/estagio_api`), que retorna o estágio operacional de risco. + +**Payload enviado ao WordPress (`multipart/form-data`):** +| Campo | Descrição | +|-------|-----------| +| `temp` | Temperatura atual (°C) | +| `condition_code` | Código numérico da condição climática | +| `description` | Descrição textual do clima | +| `is_rain` | Indicador booleano de chuva | +| `estagio` | Estágio operacional de risco da COCR | +| `date` | Data da leitura | +| `time` | Hora da leitura | +| `currently` | Período do dia (`dia` / `noite`) | +| `condition_slug` | Slug da condição climática | + +**Destinos configurados no workflow:** +1. `https:///wp-json/dcp/v1/webhook/situacao-atual/` — ambiente staging +2. `https://defesaclimaticapopular.org/wp-json/dcp/v1/webhook/situacao-atual/` — ambiente de produção +3. `https:///wp-json/dcp/v1/webhook/situacao-atual/` — ambiente local (desabilitado) + +A autenticação nos ambientes staging e produção utiliza credenciais do tipo `wordpressApi` (WP DCP PROD); o nó local usa `WP_DCP_LOCAL`. + ## Deploy O arquivo `docker-compose.deploy.yml` referencia a imagem `nossas/dcp-wp` e espera os serviços na rede externa `web` (compatível com Traefik). Ajuste as variáveis `WORDPRESS_DB_*`, `GOOGLE_MAPS_API_KEY` e a tag da imagem conforme o ambiente. diff --git a/n8n/NOSSAS_DCP___SITUACAO_ATUAL.json b/n8n/NOSSAS_DCP___SITUACAO_ATUAL.json new file mode 100644 index 00000000..c4d8bd90 --- /dev/null +++ b/n8n/NOSSAS_DCP___SITUACAO_ATUAL.json @@ -0,0 +1,459 @@ +{ + "name": "NOSSAS DCP - SITUACAO ATUAL", + "nodes": [ + { + "parameters": { + "url": "=https://aplicativo.cocr.com.br/estagio_api?_={{ $now.format( 'x' ) }}", + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + -2080, + 1260 + ], + "id": "3305b906-f256-43d0-b51d-7a706bd9f022", + "name": "HTTP GET ESTAGIO" + }, + { + "parameters": { + "method": "POST", + "url": "https://nossasdcp.hacklab.com.br/wp-json/dcp/v1/webhook/situacao-atual/", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "wordpressApi", + "sendBody": true, + "contentType": "multipart-form-data", + "bodyParameters": { + "parameters": [ + { + "name": "temp", + "value": "={{ $json.clima.temp }}" + }, + { + "name": "condition_code", + "value": "={{ $json.clima.condition_code }}" + }, + { + "name": "description", + "value": "={{ $json.clima.description }}" + }, + { + "name": "=is_rain", + "value": "={{ $json.clima.rain }}" + }, + { + "name": "estagio", + "value": "={{ $json.estagio.estagio }}" + }, + { + "name": "date", + "value": "={{ $json.clima.date }}" + }, + { + "name": "time", + "value": "={{ $json.clima.time }}" + }, + { + "name": "currently", + "value": "={{ $json.clima.currently }}" + }, + { + "name": "condition_slug", + "value": "={{ $json.clima.condition_slug }}" + } + ] + }, + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + -1080, + 1160 + ], + "id": "782b280a-8930-4ac6-8908-604dd81cac41", + "name": "SAVE DCP SITUACAO ATUAL ESTAGIO STAGING1", + "executeOnce": true, + "credentials": { + "wordpressApi": { + "id": "dzKs6w6ceaJ8jL9u", + "name": "WP DCP PROD" + } + }, + "onError": "continueRegularOutput" + }, + { + "parameters": {}, + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [ + -2560, + 1040 + ], + "id": "56a07ed7-65fc-4301-8cb6-5ca29d86e258", + "name": "When clicking ‘Execute workflow’" + }, + { + "parameters": { + "url": "https://api.hgbrasil.com/weather", + "sendQuery": true, + "queryParameters": { + "parameters": [ + { + "name": "key", + "value": "" + }, + { + "name": "lat", + "value": "-22.8873378" + }, + { + "name": "lon", + "value": "-43.2559982" + }, + { + "name": "fields", + "value": "only_results,temp,date,time,condition_code,description,currently,rain,condition_slug" + } + ] + }, + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + -2080, + 1040 + ], + "id": "67d0f38b-db40-4360-8b53-fb5dc7c76116", + "name": "HG_GET_RJ_LAT_LON" + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "f91a9672-686a-4ddb-bcc6-e20c6cede44e", + "name": "clima", + "value": "={{ $json }}", + "type": "object" + } + ] + }, + "options": {} + }, + "type": "n8n-nodes-base.set", + "typeVersion": 3.4, + "position": [ + -1860, + 1040 + ], + "id": "f98acd5d-a35f-41bc-900e-808f6dff7e61", + "name": "Edit Fields4" + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "eecfe3ba-66ef-414d-9eb7-4a079134018b", + "name": "estagio", + "value": "={{ $json }}", + "type": "object" + } + ] + }, + "options": {} + }, + "type": "n8n-nodes-base.set", + "typeVersion": 3.4, + "position": [ + -1860, + 1260 + ], + "id": "316bec2f-2a18-4dac-a7eb-b4b7e25833a1", + "name": "Edit Fields5" + }, + { + "parameters": { + "mode": "combine", + "combineBy": "combineByPosition", + "options": {} + }, + "type": "n8n-nodes-base.merge", + "typeVersion": 3.2, + "position": [ + -1440, + 1160 + ], + "id": "926a1c15-46a9-473b-9bbd-2aff148463cb", + "name": "Merge", + "executeOnce": true, + "alwaysOutputData": true + }, + { + "parameters": { + "method": "POST", + "url": "https://defesaclimaticapopular.org/wp-json/dcp/v1/webhook/situacao-atual/", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "wordpressApi", + "sendBody": true, + "contentType": "multipart-form-data", + "bodyParameters": { + "parameters": [ + { + "name": "temp", + "value": "={{ $json.clima.temp }}" + }, + { + "name": "condition_code", + "value": "={{ $json.clima.condition_code }}" + }, + { + "name": "description", + "value": "={{ $json.clima.description }}" + }, + { + "name": "=is_rain", + "value": "={{ $json.clima.rain }}" + }, + { + "name": "estagio", + "value": "={{ $json.estagio.estagio }}" + }, + { + "name": "date", + "value": "={{ $json.clima.date }}" + }, + { + "name": "time", + "value": "={{ $json.clima.time }}" + }, + { + "name": "currently", + "value": "={{ $json.clima.currently }}" + }, + { + "name": "condition_slug", + "value": "={{ $json.clima.condition_slug }}" + } + ] + }, + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + -1080, + 1380 + ], + "id": "46686bef-d4b3-48c3-b192-b718c499ea84", + "name": "SAVE DCP SITUACAO ATUAL ESTAGIO STAGING2", + "executeOnce": true, + "credentials": { + "wordpressApi": { + "id": "dzKs6w6ceaJ8jL9u", + "name": "WP DCP PROD" + } + } + }, + { + "parameters": { + "method": "POST", + "url": "https://fabad1cbf7fe.ngrok-free.app/wp-json/dcp/v1/webhook/situacao-atual/", + "authentication": "predefinedCredentialType", + "nodeCredentialType": "wordpressApi", + "sendBody": true, + "contentType": "multipart-form-data", + "bodyParameters": { + "parameters": [ + { + "name": "temp", + "value": "={{ $json.clima.temp }}" + }, + { + "name": "condition_code", + "value": "={{ $json.clima.condition_code }}" + }, + { + "name": "description", + "value": "={{ $json.clima.description }}" + }, + { + "name": "=is_rain", + "value": "={{ $json.clima.rain }}" + }, + { + "name": "estagio", + "value": "={{ $json.estagio.estagio }}" + }, + { + "name": "date", + "value": "={{ $json.clima.date }}" + }, + { + "name": "time", + "value": "={{ $json.clima.time }}" + }, + { + "name": "currently", + "value": "={{ $json.clima.currently }}" + }, + { + "name": "condition_slug", + "value": "={{ $json.clima.condition_slug }}" + } + ] + }, + "options": {} + }, + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [ + -1080, + 1600 + ], + "id": "a976d280-a607-48c3-9b16-cbdcd5b4a614", + "name": "SAVE DCP SITUACAO ATUAL ESTAGIO STAGING3", + "executeOnce": true, + "credentials": { + "wordpressApi": { + "id": "DQ9t4Rsmo6gRcPxB", + "name": "WP_DCP_LOCAL" + } + }, + "disabled": true, + "onError": "continueRegularOutput" + }, + { + "parameters": { + "rule": { + "interval": [ + { + "field": "hours", + "triggerAtMinute": 1 + } + ] + } + }, + "type": "n8n-nodes-base.scheduleTrigger", + "typeVersion": 1.2, + "position": [ + -2560, + 880 + ], + "id": "57dd7248-dba4-4662-8b87-11d2816bc879", + "name": "Schedule Trigger" + } + ], + "pinData": {}, + "connections": { + "HTTP GET ESTAGIO": { + "main": [ + [ + { + "node": "Edit Fields5", + "type": "main", + "index": 0 + } + ] + ] + }, + "When clicking ‘Execute workflow’": { + "main": [ + [ + { + "node": "HG_GET_RJ_LAT_LON", + "type": "main", + "index": 0 + }, + { + "node": "HTTP GET ESTAGIO", + "type": "main", + "index": 0 + } + ] + ] + }, + "HG_GET_RJ_LAT_LON": { + "main": [ + [ + { + "node": "Edit Fields4", + "type": "main", + "index": 0 + } + ] + ] + }, + "Edit Fields4": { + "main": [ + [ + { + "node": "Merge", + "type": "main", + "index": 0 + } + ] + ] + }, + "Edit Fields5": { + "main": [ + [ + { + "node": "Merge", + "type": "main", + "index": 1 + } + ] + ] + }, + "Merge": { + "main": [ + [ + { + "node": "SAVE DCP SITUACAO ATUAL ESTAGIO STAGING1", + "type": "main", + "index": 0 + }, + { + "node": "SAVE DCP SITUACAO ATUAL ESTAGIO STAGING2", + "type": "main", + "index": 0 + }, + { + "node": "SAVE DCP SITUACAO ATUAL ESTAGIO STAGING3", + "type": "main", + "index": 0 + } + ] + ] + }, + "Schedule Trigger": { + "main": [ + [ + { + "node": "HG_GET_RJ_LAT_LON", + "type": "main", + "index": 0 + }, + { + "node": "HTTP GET ESTAGIO", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": true, + "settings": { + "executionOrder": "v1" + }, + "versionId": "d2b15436-3850-4ccd-85a9-636e9016aa27", + "meta": { + "instanceId": "db42eb628adb8a96f89b5102d4f195dea8ea8b7d9a243e7e722577df23266ff3" + }, + "id": "RzwJs5UDS3Mppkin", + "tags": [] +} \ No newline at end of file diff --git "a/wiki/API-e-Integra\303\247\303\265es.md" "b/wiki/API-e-Integra\303\247\303\265es.md" new file mode 100644 index 00000000..ee15c525 --- /dev/null +++ "b/wiki/API-e-Integra\303\247\303\265es.md" @@ -0,0 +1,59 @@ +# API e Integrações + +## API REST do plugin (`dcp-plugin`) + +Endpoints documentados (não é uma lista exaustiva; consulte o código fonte): +- `GET /wp-json/dcp/v1/riscos` — lista riscos com paginação. +- `GET /wp-json/dcp/v1/riscos-resumo` — resumo das ocorrências nas últimas 24h. +- `GET /wp-json/dcp/v1/abrigos` — lista locais seguros (tipo `locais-seguros`). +- `GET /wp-json/dcp/v1/dicas` — recomendações ativas (filtro por `tipo` e `active`). +- `GET /wp-json/dcp/v1/contatos` — contatos de emergência (Bombeiros, Defesa Civil, SAMU). +- `GET /wp-json/dcp/v1/risco-regiao` — situação atual ativa (alerta, estágio, temperatura). +- `GET /wp-json/dcp/v1/situacao-atual-home` — conteúdo dinâmico da home. +- `POST /wp-json/dcp/v1/webhook/situacao-atual` — webhook para atualização de clima/estágio. + +## Webhook `situacao-atual` (n8n) + +O workflow n8n (`n8n/NOSSAS_DCP___SITUACAO_ATUAL.json`) é executado a cada hora para coletar dados meteorológicos e de estágio de risco e enviá-los ao WordPress. + +### Fontes de dados +- **Clima:** API HG Brasil (`https://api.hgbrasil.com/weather`), consultando as coordenadas do Rio de Janeiro (`-22.8873378, -43.2559982`). Retorna `temp`, `date`, `time`, `condition_code`, `description`, `currently`, `rain`, `condition_slug`. +- **Estágio:** API da COCR (`https://aplicativo.cocr.com.br/estagio_api`), que retorna o estágio operacional de risco. + +### Payload enviado ao WordPress (`multipart/form-data`) + +| Campo | Descrição | +|-------|-----------| +| `temp` | Temperatura atual (°C) | +| `condition_code` | Código numérico da condição climática | +| `description` | Descrição textual do clima | +| `is_rain` | Indicador booleano de chuva | +| `estagio` | Estágio operacional de risco da COCR | +| `date` | Data da leitura | +| `time` | Hora da leitura | +| `currently` | Período do dia (`dia` / `noite`) | +| `condition_slug` | Slug da condição climática | + +### Destinos configurados no workflow +1. `https:///wp-json/dcp/v1/webhook/situacao-atual/` — ambiente staging +2. `https://defesaclimaticapopular.org/wp-json/dcp/v1/webhook/situacao-atual/` — ambiente de produção +3. `https:///wp-json/dcp/v1/webhook/situacao-atual/` — ambiente local (desabilitado) + +A autenticação nos ambientes staging e produção utiliza credenciais do tipo `wordpressApi` (WP DCP PROD); o nó local usa `WP_DCP_LOCAL`. + +## Pods (Custom Post Types e Campos) + +As definições de Pods estão exportadas em `Pods/`. O arquivo `autores.json` é um exemplo de exportação de taxonomy com campos customizados (avatar). Alterações estruturais no Pods devem ser acompanhadas de exportação atualizada para versionamento. + +CPTs gerenciados via Pods: +- `risco` — Riscos mapeados pela comunidade +- `acao` — Ações comunitárias +- `relato` — Relatos de ações realizadas +- `apoio` — Pontos de apoio +- `recomendacao` — Recomendações de segurança +- `situacao_atual` — Situação climática atual + +Taxonomias: +- `situacao_de_risco` — Categorias de risco +- `tipo_acao` — Tipos de ação +- `tipo_apoio` — Tipos de apoio diff --git a/wiki/Arquitetura.md b/wiki/Arquitetura.md new file mode 100644 index 00000000..d5561490 --- /dev/null +++ b/wiki/Arquitetura.md @@ -0,0 +1,66 @@ +# Arquitetura + +## Tecnologias e stack + +| Camada | Tecnologia | +|--------|-----------| +| Backend | WordPress 6.5.3, PHP 8.3 | +| Banco de dados | MariaDB 10.4 | +| Cache (produção) | Redis 7 (AlmLRU, RDB snapshots) | +| Containerização | Docker, Docker Compose 2.x | +| Imagem base local | `hacklab/wp:6.5.3-php8.3` | +| Build de assets | Node.js 20, Laravel Mix 6, Webpack | +| Estilos | Sass/SCSS, ITCSS + BEM | +| Scripts front-end | Vanilla JS, Alpine.js 3, React (para blocos Gutenberg) | +| Campos customizados | Pods Framework | +| Mapas | OpenStreetMap / Leaflet (via plugin Jeo) | +| Automação externa | n8n (workflow de clima/situação atual) | + +## Arquitetura de rede (Docker) +- **Local**: duas redes bridge (`interna` e `wordpress-bot`). +- **Produção**: rede externa nomeada `web` (padrão Traefik). + +## Variáveis de ambiente importantes +- `WORDPRESS_DB_HOST`, `WORDPRESS_DB_USER`, `WORDPRESS_DB_PASSWORD` +- `WORDPRESS_DEBUG` (local: `0`; produção: `1` por padrão) +- `GOOGLE_MAPS_API_KEY` (opcional; se ausente, geocoding usa Nominatim/OpenStreetMap) +- `MYSQL_ROOT_PASSWORD`, `MYSQL_DATABASE`, `MYSQL_USER`, `MYSQL_PASSWORD` + +## Estrutura de diretórios + +``` +. +├── wp-root/ # Núcleo WordPress versionado +├── themes/dcp/ # Tema principal +│ ├── assets/ +│ │ ├── scss/ # Fontes SCSS (ITCSS) +│ │ ├── javascript/ # Scripts fonte +│ │ ├── images/ # Imagens e ícones +│ │ └── fonts/ # Fontes tipográficas +│ ├── dist/ # Build compilado +│ ├── library/ # Lógica PHP modular +│ │ ├── blocks/ # Blocos Gutenberg +│ │ ├── dashboard*.php # Painel do agente +│ │ ├── api/ # Endpoints internos +│ │ ├── template-tags/ # Funções auxiliares +│ │ ├── sanitizers/ # Sanitizadores +│ │ └── assets.php # Classe singleton de assets +│ ├── template-parts/ # Componentes PHP reutilizáveis +│ ├── languages/ # Traduções +│ ├── package.json +│ ├── webpack.mix.js +│ └── theme.json # Cores, tipografia, espaçamento +├── plugins/dcp-plugin/ # Plugin de API REST e webhooks +├── plugins/hacklab-dev-utils/ # Submódulo de utilidades +├── mu-plugins/ # Must-use plugins +├── compose/ # Docker local e deploy +├── dev-scripts/ # Atalhos de shell +├── Pods/ # Exportações Pods +├── n8n/ # Workflows n8n +├── docker-compose.yml +├── docker-compose.deploy.yml +└── .github/workflows/ # CI/CD +``` + +### Sobre o `style.css` na raiz +O arquivo `style.css` na raiz é um **link simbólico** para `themes/dcp/style.css`. Ele existe para compatibilidade com o plugin **git-updater**. diff --git "a/wiki/Conven\303\247\303\265es-de-C\303\263digo.md" "b/wiki/Conven\303\247\303\265es-de-C\303\263digo.md" new file mode 100644 index 00000000..513b0055 --- /dev/null +++ "b/wiki/Conven\303\247\303\265es-de-C\303\263digo.md" @@ -0,0 +1,41 @@ +# Convenções de Código + +## PHP +- **Namespace base**: `hacklabr` para o tema; funções do plugin usam prefixo `dcp_`. +- O tema ainda usa `require` em arquivos procedurais (veja `library/README.md`: *"The idea is migrate later to classes"*). +- A classe `Assets` (`library/assets.php`) é um **singleton** que gerencia enfileiramento de scripts e estilos. +- **Indentação**: 4 espaços (`.editorconfig`). +- **Charset**: UTF-8, fim de linha LF. + +## SCSS: ITCSS + BEM +A organização de estilos segue rigorosamente **ITCSS** (Inverted Triangle CSS) com nomenclatura **BEM**: + +``` +assets/scss/ +├── 1-settings/ # Variáveis globais (cores, breakpoints) +├── 2-tools/ # Mixins e funções Sass +├── 3-generic/ # Reset, fontes, estilos html/body +├── 4-elements/ # Estilos de elementos HTML puros +├── 5-objects/ # Objetos reutilizáveis (botões, containers, forms) +├── 6-components/ # Componentes específicos do projeto +├── 7-trumps/ # Utilitários e helpers (!important) +├── 9-overrides/ # Sobrescritas de plugins/componentes de terceiros +└── app.scss # Ponto de entrada principal +``` + +**Regras importantes:** +- SEMPRE usar variáveis Sass para cores, tamanhos e espaçamentos. +- EVITE estilizar elementos HTML diretamente; prefira classes. Se necessário, seja específico (`.myblock>.content>p`, nunca `.myblock p`). +- Objetos e componentes **NÃO devem** conter estilização externa (margin, position, width, max-width). Quem define é o elemento pai ou modificador. +- Overrides de terceiros ficam em `9-overrides/`, mas **sempre** usando variáveis do projeto. + +## JavaScript +- Cada funcionalidade isolada vive em seu próprio arquivo dentro de `assets/javascript/functionalities/`. +- Arquivos em `assets/javascript/shared/` são módulos reutilizáveis (ex: `wait.js`, `pins.js`, `legends.js`). +- Blocos Gutenberg usam React e se beneficiam da extração automática de dependências do WordPress. + +## WordPress +- **Text domain do tema**: `hacklabr` +- **Role customizada**: `agente-dcp` (`DASHBOARD_AGENT_ROLE`), criada em `library/dashboard.php`. +- **Rewrite rules**: `^dashboard/([^/]+)/?` mapeia para `pagename=dashboard&ver=$matches[1]`. +- **Custom post types gerenciados via Pods**: `risco`, `acao`, `relato`, `apoio`, `recomendacao`, `situacao_atual`, entre outros. diff --git a/wiki/Dashboard.md b/wiki/Dashboard.md new file mode 100644 index 00000000..c25ede49 --- /dev/null +++ b/wiki/Dashboard.md @@ -0,0 +1,58 @@ +# Dashboard + +O dashboard é uma área administrativa frontend customizada do tema, acessível em `/dashboard/{rota}`. Ele não utiliza o wp-admin padrão; toda a interface é renderizada via template `page-dashboard.php` com rotas amigáveis definidas pelo rewrite rule `^dashboard/([^/]+)/?`. + +## Autenticação e permissões +- **Role `agente-dcp`** (label "Community agent") é criada automaticamente em `library/dashboard.php` com capacidades de CRUD sobre o CPT `risco` e `upload_files`. +- O acesso ao dashboard exige `current_user_can('edit_riscos')`; usuários sem permissão são redirecionados para a tela de login. +- Após login, usuários com role `agente-dcp` são redirecionados automaticamente para o dashboard. +- ⚠️ **Inconsistência detectada:** `library/frontend_auth.php` possui uma restrição paralela que redireciona não-administradores em `is_page('dashboard')`, o que pode conflitar com a lógica de `dashboard.php`. O login AJAX também restringe acesso a administradores, impedindo que agentes comunitários autentiquem-se pelo formulário frontend. + +## Rotas e funcionalidades + +| Rota | Descrição | +|------|-----------| +| `/dashboard/inicio` | Página inicial com saudação, card da Situação Atual, contador de novos relatos e lista de riscos aguardando avaliação. | +| `/dashboard/riscos` | Lista de riscos com tabs: Aguardando Aprovação (`draft`), Publicados (`publish`) e Arquivados (`pending`). Cards com categoria, data, endereço, descrição e galeria de mídias (Swiper.js). | +| `/dashboard/adicionar-risco` | Formulário de cadastro de novo risco. | +| `/dashboard/editar-risco` | Edição de risco existente. | +| `/dashboard/acoes` | Lista de ações com tabs: Sugestões, Agendadas, Realizadas, Arquivadas e Ações Relatadas. Renderiza via `loop-post-card-{tipo_acao}`. | +| `/dashboard/adicionar-acao` / `/dashboard/editar-acao` | CRUD de ações. | +| `/dashboard/adicionar-relato` / `/dashboard/editar-relato` | CRUD de relatos de ações realizadas. | +| `/dashboard/apoio` | Lista de pontos de apoio filtrados por taxonomy `tipo_apoio` (Locais Seguros, Caçambas, Iniciativas Locais, Quem Acionar). Suporta arquivamento via meta `apoio_arquivado`. | +| `/dashboard/adicionar-apoio` / `/dashboard/editar-apoio-novo` | CRUD de pontos de apoio. | +| `/dashboard/situacao_atual` | Exibe o alerta climático ativo (CPT `situacao_atual`) e recomendações ativas (CPT `recomendacao` com `is_active = true`). | +| `/dashboard/alterar_risco` | Alterar situação de risco atual. | +| `/dashboard/editar_recomendacao` | Editar recomendações de segurança. | +| `/dashboard/editar_cacambas` | Editar caçambas. | +| `/dashboard/editar_quem_acionar` | Editar "quem acionar". | +| `/dashboard/indicadores` | Painel de estatísticas com filtros por data, cards de contadores e gráficos Chart.js (riscos por categoria, ações agendadas vs sugestões, realizadas vs arquivadas). | + +## AJAX e operações CRUD (`dashboard-ajax.php`) +Todas as operações de criação, edição e exclusão são feitas via AJAX: +- `form_single_risco_new` / `edit` — CRUD de riscos (pode ser anônimo) +- `form_single_acao_new` / `edit` — CRUD de ações (pode ser anônimo) +- `form_single_relato_new` / `edit` — CRUD de relatos +- `form_single_apoio_new` / `edit` — CRUD de apoios +- `form_participar_acao` — Inscrição em ação +- `download_participantes_acao` — Exporta CSV de inscritos +- `form_single_delete_attachment` — Remove mídia anexada + +## Indicadores (`dashboard-indicadores.php`) +Funções para contagem de posts com filtros por intervalo de datas: +- `dashboard_get_post_type_by_status_between_date()` — Conta posts por status e data +- `dashboard_get_riscos_count_by_taxonomy()` / `by_term()` — Conta riscos por taxonomia/termo + +## Utilitários (`dashboard-utils.php`) +- `formatarTelefoneBR()` / `limparTelefone()` — Formatação de telefones +- `risco_badge_category()` — Badges com ícones Iconify por categoria de risco +- `upload_file_to_attachment_by_ID()` — Upload de mídias (jpg, jpeg, png, mp4) +- `dashboard_excerpt()` — Texto truncado com "Ver mais" +- `wpcf7_form_sugestao_acao()` — Hook Contact Form 7 que cria post `acao` a partir de formulário público + +## Estrutura visual +- Layout: sidebar fixa à esquerda + conteúdo principal +- Ícones: Iconify + Bootstrap Icons +- Sliders: Swiper.js (galerias de mídia) +- Gráficos: Chart.js + plugin datalabels +- Responsivo: tratamento diferenciado para mobile (`wp_is_mobile()`) diff --git a/wiki/Deploy-e-CI-CD.md b/wiki/Deploy-e-CI-CD.md new file mode 100644 index 00000000..063dec82 --- /dev/null +++ b/wiki/Deploy-e-CI-CD.md @@ -0,0 +1,28 @@ +# Deploy e CI-CD + +## GitHub Actions (fluxo atual) +Localizado em `.github/workflows/`: + +### 1. Build and Publish on DockerHub +- Gatilho: push para branches `release/**`, `hotfix/**`, `feature/**` ou tags. +- Build e push da imagem Docker `nossas/dcp-wp` para o Docker Hub. + +### 2. CI (build de tema e release) +- Gatilho: push para `main` ou tags. +- Remove `dist/`, `node_modules` e `package-lock.json`. +- Executa `npm install && npm run production`. +- Faz upload do artefato `dcp`. +- Em tags: cria release no GitHub, gera `.zip` e dispara atualização via git-updater no site de produção. + +## GitLab CI (legacy) +O arquivo `.gitlab-ci.yml` contém pipelines para deploy em Kubernetes em namespaces `base-theme-site-dev` e `base-theme-site-prod`. O fluxo: +1. `build_assets`: compila o tema com Node 20. +2. `create_pack_*`: gera zip do tema e publica como package genérico do GitLab. +3. `deploy_to_*`: usa `kubectl` para copiar o zip para o pod WordPress e instalar via `wp theme install --force`. + +## Deploy em produção (Docker Compose) +O arquivo `docker-compose.deploy.yml`: +- Usa a imagem `nossas/dcp-wp` (tag configurável via `WORDPRESS_DOCKER_IMAGE`). +- Inclui Redis para cache de objetos. +- Espera a rede externa `web` (padrão Traefik). +- Variáveis sensíveis são injetadas via environment. diff --git a/wiki/Home.md b/wiki/Home.md new file mode 100644 index 00000000..e510a272 --- /dev/null +++ b/wiki/Home.md @@ -0,0 +1,39 @@ +# Defesa Climática Popular (DCP) + +Repositório que mantém o stack WordPress do projeto **Defesa Climática Popular**. Aqui vivem o tema `dcp`, o plugin de integração com serviços externos e a infraestrutura Docker usada por designers, desenvolvedores e equipe de dados. O objetivo desta base é sustentar o mapa colaborativo de riscos, o painel interno para agentes comunitários e as APIs consumidas por aplicações parceiras. + +## Arquitetura em alto nível +- `wp-root/`: núcleo WordPress versionado para garantir reprodutibilidade do ambiente. +- `themes/dcp/`: tema principal, com assets em `assets/`, builds em `dist/` e lógica modular em `library/` (dashboard, auth, integrações e importações). +- `plugins/dcp-plugin/`: plugin proprietário que expõe a API REST (`/wp-json/dcp/v1/*`), webhooks e rotinas de sincronização com Pods. +- `plugins/hacklab-dev-utils`: submódulo com utilidades de desenvolvimento (WP-CLI, PsySH etc.). +- `compose/`: imagens, entrypoints e configs extras de PHP, MariaDB e watcher de assets. +- `dev-scripts/`: atalhos para rotina local (`./wp`, `./mysql`, `./dev.sh`, `./dump`, entre outros). +- `style.css`: link simbólico que aponta para `themes/dcp/style.css`, exigência do fluxo com o plugin git-updater. + +## Navegação da Wiki +- [[Arquitetura]] — Stack tecnológico, Docker, redes e variáveis de ambiente. +- [[Setup e Desenvolvimento]] — Como clonar, buildar e rodar o projeto localmente. +- [[Dashboard]] — Painel interno para agentes comunitários (`/dashboard/*`). +- [[API e Integrações]] — Endpoints REST, webhook n8n e integrações externas. +- [[Deploy e CI-CD]] — Pipelines de deploy e release. +- [[Convenções de Código]] — PHP, SCSS (ITCSS + BEM), JS e WordPress. +- [[Segurança]] — Endpoints públicos, autenticação e cuidados com dados. + +--- + +## Contexto do Projeto + +A **Defesa Climática Popular** é uma iniciativa voltada ao fortalecimento das respostas comunitárias frente aos impactos da crise climática em territórios populares. O projeto parte do reconhecimento de que eventos como alagamentos, deslizamentos, ondas de calor e outros desastres climáticos afetam de forma desproporcional populações historicamente vulnerabilizadas, demandando soluções que integrem tecnologia, organização comunitária e produção de conhecimento local. + +O projeto piloto foi realizado no **Jacarezinho (RJ)** e envolveu a formação de lideranças climáticas, ações de aprendizado coletivo e mobilização comunitária, além do desenvolvimento de tecnologias comunitárias e mapeamentos participativos de risco. + +Este repositório mantém a base tecnológica do projeto, construída sobre WordPress, e sustenta mapas colaborativos, conteúdos informativos e ferramentas digitais que apoiam a tomada de decisão comunitária e a redução de danos em contextos de risco climático. + +### Componentes da Solução + +- **Recomendações** — orienta a população sobre **o que fazer** em situações de risco climático. +- **Quem Chamar** — auxilia na **identificação e no contato** com pessoas, serviços e órgãos públicos. +- **Rede de Apoio** — apresenta **locais, serviços e iniciativas** onde é possível buscar abrigo ou assistência. +- **Mapa de Riscos e Apoios** — mapa interativo com legendas e camadas temáticas (plugin **Jeo**). +- **Conteúdos sobre Riscos Climáticos** — conteúdos educativos sobre lixo, alagamentos e outros riscos ambientais. diff --git "a/wiki/Seguran\303\247a.md" "b/wiki/Seguran\303\247a.md" new file mode 100644 index 00000000..86309a4c --- /dev/null +++ "b/wiki/Seguran\303\247a.md" @@ -0,0 +1,7 @@ +# Segurança + +- O plugin `dcp-plugin` expõe endpoints REST **públicos** (`permission_callback => '__return_true'`). Isso é intencional para consumo por apps parceiras, mas qualquer modificação nesses endpoints deve avaliar impacto de exposição de dados. +- O webhook `/wp-json/dcp/v1/webhook/situacao-atual` aceita POST sem autenticação (ou com autenticação básica via WordPress API, conforme configuração do n8n). Verifique se a URL está protegida por firewall ou chave secreta em produção. +- **Nunca commite** dumps de produção com dados reais para o repositório. +- `WORDPRESS_DEBUG` deve permanecer `0` em produção. +- O arquivo `.htaccess` local está em `compose/local/wordpress/htaccess`; em produção a configuração é gerenciada pela imagem Docker ou pelo reverse proxy (Traefik). diff --git a/wiki/Setup-e-Desenvolvimento.md b/wiki/Setup-e-Desenvolvimento.md new file mode 100644 index 00000000..5030927a --- /dev/null +++ b/wiki/Setup-e-Desenvolvimento.md @@ -0,0 +1,58 @@ +# Setup e Desenvolvimento + +## Pré-requisitos +- Git e acesso ao repositório. +- Docker e Docker Compose 2.x. +- Node 18+ e npm para builds locais do tema. +- Acesso ao repositório do submódulo `hacklab-dev-utils`. +- (Opcional) Chave `GOOGLE_MAPS_API_KEY` para geocoding via Google. + +## Setup rápido +```bash +git clone dcp +cd dcp +git submodule update --init --recursive +docker-compose up --build +``` +O serviço `watcher` instala dependências do tema e roda `npm run watch` automaticamente. Caso prefira rodar localmente, entre em `themes/dcp/` e execute `npm install && npm run watch`. + +Importe um dump para `compose/local/mariadb/data/` e reinicie os containers (`docker-compose down -v && docker-compose up`) quando precisar carregar dados reais. + +## Fluxo de desenvolvimento +1. Trabalhe em branches a partir de `develop`; `main` acompanha o ambiente de produção. +2. Use `./dev-scripts/wp` para comandos WP-CLI no container e `./dev-scripts/mysql` para acessar o banco. +3. Para depuração com PsySH, execute `./dev-scripts/dev.sh` e injete `eval(\psy\sh());` no ponto desejado. +4. Gere builds de produção com `npm run production` antes de publicar mudanças que afetem front-end ou APIs. + +## Scripts utilitários (`dev-scripts/`) + +| Script | Descrição | +|--------|-----------| +| `./dev-scripts/wp ` | Executa WP-CLI dentro do container `wordpress` | +| `./dev-scripts/mysql` | Acessa o MariaDB como usuário `wordpress` | +| `./dev-scripts/mysql-root` | Acessa o MariaDB como `root` | +| `./dev-scripts/dump` | Gera dump do banco de dados | +| `./dev-scripts/dev.sh` | Roda o PHP built-in server localmente (sem Docker) | +| `./dev-scripts/compilar.sh` | Build de produção do tema via container Node efêmero | +| `./dev-scripts/zip.sh` | Gera `zips/dcp.zip` do tema (exclui `node_modules`) | + +## Build de assets do tema +```bash +cd themes/dcp + +# Desenvolvimento (com watch) +npm install +npm run watch + +# Produção (minificado) +npm run production +``` + +O serviço `watcher` do `docker-compose.yml` executa `npm install && npm run watch` automaticamente ao subir os containers. + +## Estrutura do build (`webpack.mix.js`) +- **SCSS**: `app.scss`, `dashboard.scss`, `editor.scss` +- **JS**: cada arquivo em `assets/javascript/functionalities/*.js` vira um chunk separado em `dist/js/functionalities/` +- **Blocos Gutenberg**: cada pasta em `library/blocks/*/` com `.js` e `.scss` gera assets em `dist/blocks//` +- **Source maps**: `eval-source-map` em dev; `source-map` em produção +- **Extração de dependências**: `@wordpress/dependency-extraction-webpack-plugin` com `combineAssets: true`