# Spec 040 — Desk Design System v0.13 (UI Operacional) **Criado:** 2026-06-29 **Solicitado por:** Roger **Status:** ✅ UI Access Control Hub **aprovado Roger** 2026-06-25 · `0.13.1-ac-hub-ui-aprovado-roger` **Prioridade:** P0 **Versão Desk:** `0.13.1-ac-hub-ui-aprovado-roger` **Rollback DS v0.13:** `projects/ops-desk/frontend/staging-snapshot/v0.12.2-pre-ds-20260625/` **Rollback UI aprovado:** `projects/ops-desk/frontend/staging-snapshot/v0.13.1-ac-hub-ui-aprovado-20260625/` **Aprovação Obsidian:** [[APROVADO-UI-ROGER-20260625]] **Estende:** Spec **027** (Matriz RBAC), **039** (catálogo autorização), **015** (módulos Desk) **Não inclui:** Central Operacional / Operational Feed — ver **[Spec 041](../041-desk-operational-feed/spec.md)** --- ## 1. Problema O Desk v0.12.2 tinha: - Modal simples para criar utilizador (1 ecrã) - Controle de acesso em split compacto (tabela inline) - Aba «Mensagens» = apenas pedidos de cadastro Roger definiu **Design System enterprise** (UI principles, visual language, navigation, action patterns, user wizard) e mockups para: 1. **UserWizard** — criar utilizador (5 passos, fullscreen) 2. **Access Control Hub** — gestão completa na aba Controle de acesso (Matriz) 3. Vocabulário: *Operational feed*, *Access capabilities*, *Desactivar conta* A Spec **041** cobre isoladamente a aba Central Operacional (ex-Mensagens). --- ## 2. Escopo desta spec (040) | Incluído | Excluído (→ 041) | |----------|------------------| | UserWizard fullscreen | Feed omnicanal | | Access Control Hub | `/api/v1/ops-inbox/*` | | Governance API | Canais WhatsApp, email inbound | | Audit log utilizadores | KPIs inbox | | Design tokens CSS (`ligbox-ds.css`) | | --- ## 3. Arquitetura UI ```text Matriz de Acesso (#view-access-matrix) └── Aba «Controle de acesso» (tab access-control) └── DeskAccessControlHub (DS-FE-004) ├── Sub-aba «Gestão de utilizadores» │ ├── StatsCard row (KPIs) │ ├── Entity cards (lista utilizadores — NÃO tabela primária) │ ├── Right detail panel (Detalhes | Access capabilities | Actividades) │ └── + Criar utilizador → DeskUserWizard (DS-FE-003) └── Sub-aba «Capacidades da função» └── DeskAccessControlPanel.paintCapabilitiesOnly (Spec 027/039) DeskUserWizard (DS-FE-003) — fullscreen modal ├── Step 1 Basic data ├── Step 2 Profile and group ├── Step 3 Access capabilities (module matrix) ├── Step 4 Review └── Step 5 Success (+ audit + invite link) ``` --- ## 4. Registo de ficheiros (referência futura) Código interno: **`DS-{tipo}-{nnn}`** — usar em commits, PRs e tickets. ### 4.1 Frontend — Design System | Código | Ficheiro | Global JS | Função | |--------|----------|-----------|--------| | **DS-FE-001** | `frontend/assets/ligbox-ds.css` | — | Tokens CSS (`--lb-*`), cards, wizard, modals, layout ops | | **DS-FE-002** | `frontend/assets/ligbox-ds.css` | — | Cache bust: `?v=20260629v013` | ### 4.2 Frontend — Módulos | Código | Ficheiro | Global JS | Função | |--------|----------|-----------|--------| | **DS-FE-003** | `frontend/assets/user-wizard.js` | `window.DeskUserWizard` | Wizard fullscreen criar utilizador (≥3 passos) | | **DS-FE-004** | `frontend/assets/access-control-hub.js` | `window.DeskAccessControlHub` | Hub img 4 — cards, KPIs, painel direito | | **DS-FE-005** | `frontend/assets/access-control-panel.js` | `window.DeskAccessControlPanel` | Delega hub; sub-aba capacidades (Spec 039) | | **DS-FE-006** | `frontend/assets/user-management-panel.js` | `window.DeskUserManagement` | Edit modal, clone; `openEdit()` para hub | ### 4.3 Frontend — Integração | Código | Ficheiro | Alteração | |--------|----------|-----------| | **DS-FE-010** | `frontend/index.html` | Scripts DS-FE-003/004/005/006, `ligbox-ds.css`, nav «Central Operacional», footer v0.13.0 | | **DS-FE-011** | `frontend/assets/app.staging.js` | Títulos Spec 040/041; `renderMessages()` delega Spec 041 | | **DS-FE-012** | `frontend/assets/access-matrix.js` | Host `#am-access-control-host` → `DeskAccessControlPanel.paint` | ### 4.4 API — Backend | Código | Ficheiro | Router prefix | Função | |--------|----------|---------------|--------| | **DS-API-001** | `api/app/desk_governance_store.py` | — | Schema SQLite: audit, user_meta, module permissions | | **DS-API-002** | `api/app/governance_routes.py` | `/api/v1/governance` | Wizard, freeze, reset password, audit, stats | | **DS-API-003** | `api/app/main.py` | — | Registo routers; init schema; version `0.13.0-design-system` | ### 4.5 Versionamento e rollback | Código | Ficheiro | Função | |--------|----------|--------| | **DS-META-001** | `projects/ops-desk/VERSION` | `0.13.0-design-system` | | **DS-META-002** | `frontend/staging-snapshot/v0.12.2-pre-ds-20260625/` | Snapshot pré-build + `ROLLBACK.md` | ### 4.6 Skills (Cursor — design system) | Código | Ficheiro | Função | |--------|----------|--------| | **DS-SK-001** | `~/.cursor/skills/ligbox/product.skill.md` | Identidade produto | | **DS-SK-002** | `~/.cursor/skills/ligbox/ux.skill.md` | UX + visual + navigation | | **DS-SK-003** | `~/.cursor/skills/ligbox/permissions.skill.md` | Hierarquia RBAC UI | | **DS-SK-004** | `~/.cursor/skills/ligbox/onboarding.skill.md` | User creation flow | | **DS-SK-005** | `~/.cursor/skills/ligbox/messaging.skill.md` | → aponta Spec 041 | | **DS-SK-006** | `~/.cursor/skills/ligbox/audit.skill.md` | Audit log pattern | --- ## 5. API Governance (resumo) Contrato completo: [contracts/governance-api.md](contracts/governance-api.md) | Método | Endpoint | Código acção | Descrição | |--------|----------|--------------|-----------| | GET | `/api/v1/governance/modules` | `desk.governance.modules.list` | Módulos + níveis + grupos | | GET | `/api/v1/governance/users/stats` | `desk.governance.users.stats` | KPIs gestão utilizadores | | GET | `/api/v1/governance/users/{username}/meta` | `desk.governance.user.meta` | Meta + internal_id + permissions | | POST | `/api/v1/governance/users/wizard` | `desk.auth.user.create` | Criar via wizard (audit + invite) | | POST | `/api/v1/governance/users/{username}/freeze` | `desk.auth.user.freeze` | Congelar/activar + audit | | POST | `/api/v1/governance/users/{username}/reset-password` | `desk.auth.user.password.reset` | Reset admin + audit | | GET | `/api/v1/governance/audit` | `desk.governance.audit.list` | Audit por target | **Auth:** Bearer JWT · `can_manage_users` (super_admin). --- ## 6. Modelo de dados (SQLite) ### `desk_governance_audit` | Coluna | Tipo | Notas | |--------|------|-------| | actor_username | TEXT | Quem executou | | action | TEXT | ex. `user.created`, `user.frozen` | | target_type | TEXT | ex. `user` | | target_id | TEXT | username | | summary | TEXT | «Created by Super Admin» | ### `desk_user_meta` | Coluna | Tipo | Notas | |--------|------|-------| | internal_id | TEXT | `LB-XXXXXXXX` | | main_group | TEXT | Ops, Comercial, … | | secondary_groups_json | TEXT | JSON array | | module_permissions_json | TEXT | Desk/OpenPanel/… × none/read/partial/full | | invite_token | TEXT | Link convite | --- ## 7. User Wizard — fluxo Ver skill **DS-SK-004** e mockups Roger (imgs 1–2). Passos UI: Basic data → Profile/group → Access capabilities → Review → Success. Submit `POST /api/v1/governance/users/wizard` executa: 1. INSERT `desk_users` 2. INSERT `desk_user_meta` 3. INSERT `desk_governance_audit` (`user.created`) 4. E-mail convite (opcional) 5. Resposta: `user`, `meta`, `internal_id`, `invite_link` --- ## 8. Regras UX (obrigatórias) - **Create:** sempre wizard, mínimo 3 passos, fullscreen - **Edit:** side panel / modal médio (`DeskUserManagement.openEdit`) - **Desactivar conta:** small modal + audit (nunca «Delete» na UI) - **Cards > tables** para lista primária de utilizadores - Paleta: `#F6F3EE` / `#5B1632` / cards `#FFFFFF` --- ## 9. Relação com outras specs | Spec | Relação | |------|---------| | 027 | Matriz RBAC; aba Controle de acesso dentro da Matriz | | 039 | Catálogo acções; toggles capacidades da função | | 041 | Central Operacional (aba ex-Mensagens) — **spec separada** | | 004 | Pedidos cadastro — `renderRegistrationRequestsLegacy()` preservado | --- ## 10. Deploy ```bash # VM122 produção docker cp → ligbox-ops-platform_frontend_1:/usr/share/nginx/html/ docker cp → ligbox-ops-platform_api_1:/app/app/ docker restart ligbox-ops-platform_api_1 ``` Validação: - `GET https://desk.ligbox.com.br/api/health` → `"version":"0.13.0-design-system"` - Matriz → Controle de acesso → + Criar utilizador (wizard)