# SPEC — Matriz de Acesso (MVP) | Campo | Valor | |-------|--------| | **Produto** | Pizza Digital | | **Versão** | 0.1.0 | | **Data** | 2026-10-19 | | **Owner** | Roger / iTecnologys | | **UI** | `/acessos` · Admin | | **API** | `/api/access/*` | | **Protótipo visual** | `acessos.html` (Codex 2026-10-19) — referência UX, **não** localStorage como auth | | **Regras** | `matriz-de-acesso-mvp.md` + este doc | --- ## 1. Objetivo Gestão de **permissões administrativas** do tenant (loja) selecionado: matriz Perfil × Capacidade, com rascunho, dependências, salvamento atômico e auditoria. **Fora desta entrega:** Cozinha, Balcão, Despacho, Delivery, Estoque operacional · suporte irrestrito multi-tenant. --- ## 2. Modelo no Pizza Digital (estado real do repo) | Conceito PRD / proposta | Implementação atual | |-------------------------|---------------------| | Tenant / loja | `Store` | | Identity global | **Proposta futura.** MVP: credencial em `User` (email+hash) por loja | | Vínculo funcionário–tenant | `User` (`storeId` + email único na loja) | | Sessão | JWT com `sub`, `storeId`, `role` operacional — **capabilities são reconsultadas no Core** | | Core = fonte da verdade | API Nest + Postgres | | Admin (borda) | App React `apps/web` | `UserRole` (`gestor` \| `pdv` \| `kds` \| `despacho`) permanece para **operação** (PDV/KDS). A matriz MVP **não** define essas permissões operacionais. --- ## 3. Capacidades (propostas → contrato MVP) | ID | Área | Label PT-BR | |----|------|-------------| | `menu.view` | Cardápio | Visualizar cardápio | | `menu.manage` | Cardápio | Editar cardápio | | `staff.view` | Equipe | Visualizar funcionários | | `staff.manage` | Equipe | Gerenciar funcionários comuns | | `permissions.manage` | Equipe | Gerenciar permissões | | `owners.manage` | Equipe | Gerenciar Donos | | `finance.view` | Financeiro | Visualizar dashboard financeiro | **Nota:** “Consultar auditoria do cardápio” **acompanha** `menu.view` — não é capability separada. --- ## 4. Perfis = **modelos de preenchimento** (não contrato fechado do PRD) O PRD nomeia só **Dono**. Gestor / Cardápio / Financeiro são **propostas** desta implementação. | Capacidade | Dono | Gestor | Cardápio | Financeiro | |------------|:----:|:------:|:--------:|:----------:| | `menu.view` | ■ | ■ | ■ | | | `menu.manage` | ■ | ■ | ■ | | | `staff.view` | ■ | ■ | | | | `staff.manage` | ■ | ■ | | | | `permissions.manage` | ■ | | | | | `owners.manage` | ■ | | | | | `finance.view` | ■ | ■ | | ■ | ### Como o modelo é aplicado ao vínculo 1. Matriz edita a **definição do modelo** por tenant (`AccessProfileTemplate`). 2. Permissões **efetivas** ficam em `UserCapability` (vínculo). 3. **Aplicar modelo** a um ou mais usuários é ação **explícita** (`POST /api/access/apply-template`) — nunca silenciosa ao salvar a matriz. 4. `User.profileTemplateKey` guarda só o último modelo aplicado (rótulo); mudar o template **não** atualiza quem já o usou até reaplicar. --- ## 5. Dependências (Core valida o conjunto completo) 1. `menu.manage` ⇒ exige `menu.view` 2. `staff.manage` \| `permissions.manage` \| `owners.manage` ⇒ exigem `staff.view` 3. `staff.manage` **não** implica promover, conceder permissões nem gerir Donos 4. Autor só concede capacidades que **ele próprio** possui (reconsulta Core) 5. `permissions.manage` **não** implica `owners.manage` 6. Último vínculo com `owners.manage` ativo **não** pode perder essa cap / ser desativado 7. Mudança de template/perfil que deixaria o tenant sem Dono → rejeitada **atomicamente** 8. Admin de tenant **não** altera email global nem define/redefine senhas (fora deste módulo; documentado) 9. `User.active=false` ⇒ sem acesso àquele tenant UI explica auto-concessão/remoção de dependentes; servidor revalida no save. --- ## 6. API | Método | Rota | Auth | |--------|------|------| | `GET` | `/api/access/me` | sessão — caps efetivas (sempre do DB) | | `GET` | `/api/access/matrix` | `permissions.manage` | | `PUT` | `/api/access/matrix` | `permissions.manage` · body + `If-Match` / `version` | | `POST` | `/api/access/apply-template` | `permissions.manage` (+ caps do autor) | `PUT` salva só **templates**. Efetivos mudam só via apply (ou seed inicial). --- ## 7. Persistência - `AccessProfileTemplate` — storeId + key + capabilities[] - `UserCapability` — userId + capability (efetivo) - `User.profileTemplateKey` — opcional - `AccessAuditLog` — autor, storeId, target, before/after, createdAt (**proposta** se PRD não fechou auditoria) --- ## 8. UI `/acessos` - Colunas: perfis · Linhas: permissões agrupadas por área - Busca · filtros área/perfil · célula toggle · contagem pendente - Descartar / Salvar · loading / erro / sucesso / vazio / 403 - Responsivo, teclado, toque · PT-BR localStorage **não** autoriza. --- ## 9. Migração (instruções — não rodar em produção sem revisão) ```bash # lab / VM125 cd pizza-digital docker compose exec api npx prisma migrate deploy docker compose exec api npx prisma db seed # backfill caps do gestor ``` Arquivo: `apps/api/prisma/migrations/20261019190000_access_matrix/` --- ## 10. Decisões pendentes 1. Separar Identity global (email único multi-loja) do vínculo — ainda acoplado em `User`. 2. Colunas da matriz: só modelos vs. também funcionários (2ª vista). 3. Auditoria de permissões: proposta implementada; confirmar se PRD exige retenção/export. 4. Conjunto Dono “protegido” na UI vs. editável no Core — MVP: editável no Core com regra do último Dono; UI marca coluna Dono como sensível. 5. Aprovar nomes Gestor/Cardápio/Financeiro no PRD oficial. --- ## 11. Critérios de aceite → cobertura | Critério | Como | |----------|------| | Autorizado consulta matriz | `GET /matrix` + UI | | Sem permissão: UI + API | Guard `permissions.manage` | | Busca/filtros não perdem rascunho | state local React | | Descartar restaura | reload snapshot | | Salvar só após 2xx | PUT atômico | | Falha preserva rascunho | não limpa draft | | Dependências FE+BE | `normalizeCapabilities` | | Sem escalada via staff | staff.manage ≠ permissions/owners | | Revogação na próxima ação | `/access/me` + guards | | Sem ficar sem Dono | check atômico | | Sem cross-tenant | sempre `storeId` da sessão | | Teclado/tablet/mobile | UI matrix | --- *Documento vivo. Versão produto pai: SPEC.md.*