# eCook-Plus LOJA — Regras do Projeto para o Agente Cursor

Documentação de referência completa: `README.md` e `CONVENCOES_DESENVOLVIMENTO.md`.

---

## Visão geral

- **Produto:** eCook-Plus — painel web SaaS multi-tenant (White Label) para restaurantes/filiais.
- **Nome e versão:** `includes/app_config.php` (`ECOOK_APP_NOME`, `ECOOK_APP_VERSAO`).
- **Idioma:** responder sempre em **português (Brasil)**.
- **Escopo das alterações:** mudanças mínimas e focadas; reutilizar funções e padrões existentes; não refatorar código não relacionado à tarefa.

---

## Stack tecnológico

| Camada | Tecnologia |
|--------|------------|
| Backend | PHP 8.x (modular: páginas, includes, APIs) |
| Banco | MariaDB / MySQL (InnoDB, `ON DELETE CASCADE`) |
| Frontend | HTML5, CSS3 (variáveis nativas), JavaScript (Fetch API) |
| UI | Glassmorphism (`backdrop-filter`, painéis translúcidos, bordas suaves) |
| White Label | `--cor-primaria`, `--cor-secundaria`, logo por filial (`config`) |

---

## Estrutura de diretórios

```
index.php              # Motor SPA/PWA, login, roteador AJAX, shell do painel
layout_login.php       # Tela de login
logout.php
paginas/               # Telas carregadas via AJAX ou carga inicial
includes/              # Lógica compartilhada, menus, conexões, regras de negócio
api/                   # Endpoints JSON (CRUD, downloads, integrações)
css/                   # Estilos globais e por módulo
js/                    # Scripts por módulo
sql/                   # Scripts DDL/DML de referência
IMG/                   # Logos e imagens estáticas
```

**Separação de responsabilidades:**
- `paginas/*.php` — markup/HTML da tela (sem lógica pesada de negócio).
- `includes/*.php` — funções de domínio, permissões, consultas, helpers.
- `api/*.php` — camada HTTP JSON; delega para `includes/`.
- `css/` e `js/` — um par por módulo quando necessário (ex.: `cadastro_produtos.css`, `cadastro_produtos.js`).

---

## Arquitetura multi-tenant

### Conexões de banco

| Arquivo | Uso |
|---------|-----|
| `includes/conecta.php` | Banco **operacional da loja logada** (tenant da sessão ou padrão local) |
| `includes/conecta_loja.php` | Banco fixo da instalação LOJA (`simsoftdsv_ecookplus_loja`) — ADM local |
| `includes/conecta_master.php` | Orquestrador SaaS (empresas, login global, usuários master) |
| `includes/conecta_tenant.php` | Conexão dinâmica por credenciais de tenant |

**Regra:** em telas/APIs que operam dados da loja do usuário logado, usar `obterPdoBancoLojaLogada()` de `includes/perfil_acesso.php` (retorna `['pdo' => PDO, 'nome_banco' => string]`).

### Login (3 camadas em `index.php`)

1. **ADM local** — `cad_usuarios` no banco LOJA, perfil `ADM`.
2. **ADM Master / Dono SaaS** — `usuarios_master` ou `empresas` no banco master.
3. **Funcionários** — `login_global` + tenant da empresa no master.

Sessão relevante: `logado`, `usuario_nivel`, `filial_id`, `tenant_db_*`, `adm_empresa_selecionada`, `emp_nome`.

### Entidades principais (master)

- `empresas` (master) — clientes SaaS, `emp_sim_codigo`, subdomínios e tenants.
- `cad_perfil` — RBAC (`ADM`, `Gerente`, `Suporte`, etc.).
- `cad_usuarios` — autenticação (`password_hash`).
- `config` (banco LOJA central) — identidade visual por `cfg_emp_sim_codigo`.

### Banco legado da loja (tenant)

Tabelas como `cad_produto` (singular), `cad_grupo_produtos`, `fat_geral`, `cad_ficha_producao_*`, etc. — espelham o eCook Desktop Delphi.

---

## Perfis e permissões (Controle de Acesso)

> **Estado atual (auditoria):** não existe módulo de "Controle de Permissão". O RBAC é **simples e hardcoded** — `cad_perfil` guarda só o **nome** do perfil; o acesso real é decidido por comparações de string em PHP (`$_SESSION['usuario_nivel']`). Evolução planejada: recriar `cad_perfil` e implementar matriz perfil ↔ telas/ações.

### Helpers existentes (`includes/perfil_acesso.php`)

| Termo | Função | Quem |
|-------|--------|------|
| Admin / ADM | `isUsuarioAdmin()` | `usuario_nivel === 'ADM'` |
| Usuário da Loja | `isUsuarioLoja()` | DONO, GERENTE, equipe (qualquer um que não seja ADM) |
| Só Admin | `isSomenteAdmin()` | cadastro usuário global, config visual |
| Admin + Loja | `isAdminOuLoja()` | relatórios, espelho, cadastros operacionais |

**Não confundir:** ADM técnico/SaaS ≠ usuário operacional da loja.

### Tabela `cad_perfil` (banco LOJA — `simsoftdsv_ecookplus_loja`)

- **Estrutura atual no código:** apenas `per_id` (PK) e `per_nome` (string, ex.: `ADM`, `GERENTE`).
- **Sem DDL** em `sql/` — script de recriação ainda não existe no repositório.
- **Vínculo:** `cad_usuarios.usu_nivel_id` → `cad_perfil.per_id`.
- **Criação automática:** em `paginas/cadastro_usuario.php` e `paginas/cadastro_equipe.php`, se o perfil informado não existir, faz `INSERT INTO cad_perfil (per_nome)` — qualquer texto vira perfil, sem tela de gestão.

**Arquivos que usam `cad_perfil`:**

| Arquivo | Uso |
|---------|-----|
| `index.php` | Login ADM local — JOIN `cad_usuarios` + `cad_perfil` |
| `api/autenticar.php` | Autenticação JSON |
| `paginas/cadastro_usuario.php` | CRUD usuários + listagem/criação de perfis |
| `paginas/cadastro_equipe.php` | CRUD equipe da loja + perfis |
| `api/criar_empresa.php` | Busca perfil `ADM` ao provisionar empresa |

### Duas fontes de “perfil” na sessão (inconsistência atual)

| Origem do login | Campo de origem | Valor em `$_SESSION['usuario_nivel']` |
|-----------------|-----------------|----------------------------------------|
| ADM local | `cad_perfil.per_nome` via `cad_usuarios` | `ADM` |
| ADM Master / Dono SaaS | Fixo no código | `ADM` ou `DONO` |
| Funcionário (tenant) | `login_global.log_nivel` (master) | string em maiúsculas (sem FK em `cad_perfil`) |

A sessão guarda **sempre uma string** (`usuario_nivel`); não há consulta centralizada ao banco para autorizar telas.

### Perfis conhecidos hoje (hardcoded)

| Perfil | Origem típica | Observação |
|--------|---------------|------------|
| `ADM` | Admin local ou master SaaS | Menu completo; escolha de empresa |
| `DONO` | Dono da empresa (master) | Gráficos, relatórios, cadastros |
| `GERENTE` | Equipe / cadastro | Similar ao DONO; gerencia equipe |
| Outros | Criados dinamicamente no cadastro de usuário | Sem regras padronizadas no código |

**Regra especial:** `usu_nivel_id == 1` protege o usuário/perfil Master — não pode ser excluído nem inativado (`cadastro_usuario.php`, `cadastro_equipe.php`).

### Controle de acesso hoje (espalhado no código)

| Camada | Arquivo | Padrão |
|--------|---------|--------|
| Menu lateral | `includes/sidebar.php` | `if ($nivel_usuario === 'ADM')` / `DONO`/`GERENTE` / `else` |
| Rotas | `includes/menu_navegacao.php` | Dashboard alterna por `['ADM', 'DONO', 'GERENTE']` |
| Telas | `paginas/*.php` | Checks manuais: `isAdminOuLoja()`, `isSomenteAdmin()`, `in_array(..., ['ADM','DONO'])`, etc. |
| APIs | `api/*.php` | Mesmo padrão + verificação de sessão |
| Bloqueio visual | `paginas/403.php` | Existe, mas pouco usada — telas bloqueiam inline |

**Exemplos de restrição por tela:**

- `config.php`, `salvar_config_visual.php` → `isSomenteAdmin()` (só ADM)
- `cadastro_usuario.php` → `['ADM', 'DONO']`
- `cadastro_equipe.php` → `['DONO', 'GERENTE']`
- Relatórios (`espelho_comandas`, `documentos_fiscais`, `curva_abc`, `caixa`, `comandas_abertas`, `mapa_calor_delivery`) → `isAdminOuLoja()`
- `cadastro_produtos.php` → `cadProdPodeGerenciar()` (Admin ou DONO/GERENTE)

### O que **não** existe ainda (Controle de Permissão)

- Tela `cadastro_perfil` / `controle_permissao`
- API de perfis ou permissões
- Rota ou item de menu dedicado
- Tabelas auxiliares (`cad_permissao`, `cad_perfil_permissao`, `cad_modulo`, etc.)
- Verificação centralizada “este perfil pode acessar esta página/ação?”
- Script SQL de referência para recriar `cad_perfil`

### Diretrizes para evoluir o módulo

1. Recriar `cad_perfil` com DDL em `sql/` (metadados: nome, descrição, ativo, flag sistema).
2. Definir matriz perfil ↔ recurso (página/menu e/ou ação CRUD).
3. Centralizar checagem em `includes/perfil_acesso.php` (ex.: `perfilPodeAcessar('espelho_comandas')`).
4. Manter compatibilidade com `login_global.log_nivel` no master até migração completa.
5. Seguir padrão CRUD existente: `paginas/`, `includes/`, `api/`, rota em `menu_navegacao.php`, item em `sidebar.php`.

---

## Roteamento e SPA

### URLs do painel

- Página: `index.php?p=<chave>` (ex.: `index.php?p=cadastro_produtos`)
- Menu ativo: `index.php?p=<chave>&m=menu-<chave>`
- AJAX: `index.php?ajax=true&p=<chave>`

### Registrar nova tela

1. Criar `paginas/nome_tela.php`.
2. Adicionar rota em `menuRotasPorNivel()` em `includes/menu_navegacao.php`.
3. Se for relatório: incluir em `menuPaginasRelatorios()`.
4. Se for cadastro: incluir em `menuPaginasCadastros()`.
5. Se for configuração: incluir em `menuPaginasConfiguracoes()`.
6. Adicionar item no menu em `includes/sidebar.php` (ou submenu correspondente).
7. Se relatório pesado: considerar carga assíncrona em `$paginasCargaInicialAssincrona` no `index.php`.

### Conteúdo dinâmico

- O conteúdo rola em `#conteudo-dinamico` — listeners de scroll devem usar esse elemento, não só `window`.
- Botão voltar ao topo: `includes/btn_voltar_topo.php`.

---

## Padrões de código PHP

### SQL e segurança

1. **Sempre PDO parametrizado** — `prepare()` + `execute([])`. Nunca concatenar variáveis em SQL.
2. **Validação de tipos** — cores hex: `preg_match('/^#[a-fA-F0-9]{6}$/i', $cor)`.
3. **Try/catch** em operações de banco (`PDOException`); não expor erros crus ao usuário.
4. **Uploads** — validar MIME com `finfo`; restringir tipos seguros.

### APIs (`api/*.php`)

```php
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
// Verificar sessão/permissão
// obterPdoBancoLojaLogada() quando operar banco da loja
echo json_encode([...], JSON_UNESCAPED_UNICODE);
```

**Estrutura JSON padrão:**
```json
{ "sucesso": true|false, "mensagem": "...", "dados_extras": ... }
```

- APIs internas: parâmetro `acao` via GET/POST (ex.: `listar`, `obter`, `salvar`).
- APIs externas (ex.: `criar_empresa.php`): proteger com `HTTP_X_API_KEY`.

### Lógica de negócio

- Colocar regras reutilizáveis em `includes/<modulo>.php`.
- A página (`paginas/`) e a API (`api/`) incluem o mesmo include de domínio.
- Prefixos de funções por módulo (ex.: `cadProd*`, `espelhoComanda*`).

### Versão de assets

- CSS/JS por módulo: query string `?v=N` ao incluir (ex.: `css/cadastro_produtos.css?v=10`).

---

## UI / UX

### Glassmorphism e White Label

- Usar classes existentes: `.glass-card`, variáveis CSS `--cor-primaria`, `--cor-secundaria`, `--cor-texto`.
- Tema carregado via `includes/tema_visual.php` (tabela `config`: `cfg_cor_primaria`, `cfg_cor_secundaria`, `cfg_logo_caminho`).
- Config visual: `paginas/config.php` + `api/salvar_config_visual.php` (upsert em `config`).

### Layout de cadastros (padrão PROVIDA → Web)

Referência: seção "Modelo de Layout para Cadastros" no `README.md`.

**Estrutura:**
- `filterbar` — filtros + ações + toggle cards/lista
- `list-summary` — contador
- Grid de cards OU tabela (`products-grid`)
- Modal overlay (`produto-overlay` / `produto-card`) com abas quando necessário
- Toast de feedback (`produto-toast`)

**Classes BEM principais:** `.filterbar`, `.filterbar__view-toggle`, `.product-card`, `.products-grid`, `.produto-overlay`, `.pform-group`, `.pform-row`, `.pform-input`.

**Referências implementadas:** `paginas/cadastro_produtos.php`, `paginas/cadastro_grupos.php`, `paginas/cadastro_usuario.php`.

### Relatórios

Páginas carregadas via AJAX devem emitir o wrap compartilhado:

```php
require_once __DIR__ . '/../includes/estilos_relatorio_wrap.php';
renderEstilosRelatorioWrap();
```

Usar classes `espelho-comandas-wrap` / `graficos-container`. Relatórios existentes: Espelho de Comandas, Documentos Fiscais, Curva ABC, Caixa, Mapa de Calor Delivery.

### Formatação de datas na interface

- **Exibição ao usuário:** `dd/mm/aaaa hh:mm` (ex.: `16/06/2026 14:30`).
- **PHP:** `date('d/m/Y H:i', $timestamp)`.
- **JavaScript:** converter de `YYYY-MM-DD HH:MM:SS` antes de exibir (ver `formatDataHora()` em `js/config_log.js`).
- **Filtros `<input type="date">`:** manter `YYYY-MM-DD` (padrão HTML).
- APIs JSON podem retornar formato MySQL/ISO; formatação visual fica no PHP/JS da tela.

---

## Responsividade

| Breakpoint | Uso |
|------------|-----|
| ≤ 480px | Celulares estreitos |
| ≤ 768px | Mobile — drawer sidebar, formulários empilhados |
| ≤ 900px | Tablet — grids e cabeçalhos empilham |
| ≥ 769px | Desktop — sidebar fixa |

**Arquivos centrais:**
- `css/style.css` — shell (sidebar drawer, topbar)
- `css/responsive.css` — regras compartilhadas mobile (incluído em `index.php`)
- `includes/estilos_relatorio_wrap.php` — relatórios

**Diretrizes para novas telas:**
1. Evitar larguras fixas; usar `flex-wrap`, `minmax()`, `width: 100%` em `@768px`.
2. Tabelas largas: `.resumo-canais-scroll` com scroll horizontal.
3. Botões de filtro: `width: 100%` abaixo de 768px.
4. Modais: `width: 96vw`, `max-height: 92dvh` no mobile.
5. Testar em DevTools (iPhone SE / Pixel).

---

## Regras de negócio — delivery (`fat_geral`)

Vendas delivery: `FAT_TIP_LOC = 2`. Identificação do app:

| App | Condição |
|-----|----------|
| Neemo | `FAT_IDORDER` preenchido |
| iFood | `FAT_IDORDER_IFOOD` preenchido |
| Demais apps | `FAT_APP_IDORDER` + `FAT_APP_NOME` correspondente |

Funções em `includes/espelho_comanda.php`: `espelhoComandaMontarSqlFiltroAppsDelivery()`, `espelhoComandaResolverCodAppDelivery()`.

---

## Cadastro de produtos (Delphi → Web)

- Fonte legado: `FRM_CADASTRO_PRODUTOS.pas` (repositório Delphi compartilhado).
- Tabela principal: `cad_produto` (singular).
- Implementação web: `paginas/cadastro_produtos.php`, `includes/cadastro_produtos.php`, `api/cadastro_produtos.php`.
- 12 abas no Delphi; web evolui por fases (MVP → fiscal completo).
- Grupo (`cad_grupo_produtos`) define sabores, meia/inteira e opcionais.

---

## Checklist — novo módulo

- [ ] `paginas/<tela>.php` com verificação de permissão
- [ ] `includes/<modulo>.php` com lógica de domínio
- [ ] `api/<modulo>.php` se houver CRUD AJAX
- [ ] `css/` e `js/` se necessário
- [ ] Rota em `includes/menu_navegacao.php`
- [ ] Item de menu em `includes/sidebar.php` ou submenu
- [ ] Responsivo (`@768px` mínimo)
- [ ] Datas formatadas em `dd/mm/aaaa hh:mm` na UI
- [ ] PDO parametrizado em todas as queries
- [ ] JSON com `sucesso` / `mensagem` nas APIs

---

## Arquivos modificados (obrigatório)

Ao concluir qualquer tarefa que altere o repositório, **terminar a resposta** com:

### Arquivos modificados

**Criados** (se houver)
- caminhos relativos à raiz do projeto

**Alterados** (se houver)
- caminhos relativos à raiz do projeto

Se nada foi alterado: *Nenhum arquivo modificado.*

Incluir **todos** os arquivos tocados: PHP, CSS, JS, APIs, menu, rotas (`index.php`), includes compartilhados e documentação criada na mesma tarefa. Não omitir arquivos pequenos.

Regra equivalente em `.cursor/rules/arquivos-modificados.mdc` (`alwaysApply: true`).

---

## Princípios de implementação

1. **Escopo mínimo** — diff simples e correto; não alterar código não relacionado.
2. **Sem over-engineering** — evitar abstrações desnecessárias.
3. **Convenções existentes** — ler o código ao redor antes de escrever; combinar com o estilo do autor.
4. **Comentários** — só para lógica de negócio não óbvia.
5. **Testes** — adicionar apenas se solicitado ou com valor real.
6. **Commits** — só quando o usuário pedir explicitamente.

---

## Arquivos de referência rápida

| Assunto | Arquivo |
|---------|---------|
| Convenções | `CONVENCOES_DESENVOLVIMENTO.md` |
| Documentação técnica | `README.md` |
| Versão do app | `includes/app_config.php` |
| Rotas e menu | `includes/menu_navegacao.php`, `includes/sidebar.php` |
| Permissões | `includes/perfil_acesso.php` |
| Tema visual | `includes/tema_visual.php` |
| Wrap de relatórios | `includes/estilos_relatorio_wrap.php` |
| Modelo CRUD | `paginas/cadastro_usuario.php`, `paginas/cadastro_produtos.php` |
| Modelo API | `api/cadastro_produtos.php` |
| Log de acesso | `includes/mov_log_acesso.php`, `api/mov_log.php` |
