portal_publico/portal_api/catalogo.py

214 lines
9.3 KiB
Python

"""Catálogo de módulos/aplicações do menu do Portal De Paula.
Fonte única da verdade para o que existe no sidebar — o frontend consome isso
via GET /api/catalogo/ em vez de manter uma cópia própria (evita as duas
pontas saírem de sincronia). Mesma estrutura que já existia em
assets/js/profiles.js (PID_MODULES/PID_MODULE_APPS) antes da migração.
"""
from typing import Any
MODULES = [
{"key": "principal", "label": "Principal"},
{"key": "ramais", "label": "Ramais"},
{"key": "calendario", "label": "Calendário De Paula"},
{"key": "calendario-individual", "label": "Calendário Individual"},
{"key": "portais", "label": "Portais"},
{"key": "geradoc", "label": "Geradoc"},
{"key": "relatorios", "label": "Relatórios"},
{"key": "relatorios-gerenciais", "label": "Relatórios Gerenciais"},
{"key": "utilitarios", "label": "Utilitários"},
{"key": "integracoes", "label": "Integrações"},
{"key": "auditorias", "label": "Auditorias"},
{"key": "links-ferramentas", "label": "Links & Ferramentas"},
{"key": "solicitacoes", "label": "Solicitações"},
{"key": "administracao", "label": "Administração"},
]
# Cada entrada é uma aplicação direta ({"key", "label"}) ou um subgrupo com
# ferramentas ({"key", "label", "tools": [...]}) — mesmo formato de dois
# níveis usado hoje em PID_MODULE_APPS (ver Auditorias abaixo).
MODULE_APPS = {
"portais": [
{"key": "portal-do-cliente", "label": "Portal do Cliente"},
{"key": "portal-fiscal", "label": "Portal Fiscal"},
],
# "Gerar Contrato"/"Gerar Procuração" existiam como placeholders (href="#")
# e foram removidos por não serem usados — decisão explícita do usuário,
# não recriar sem confirmar de novo (mesmo espírito da remoção de
# "Conversor de Arquivos"/"Calculadora Fiscal" de Utilitários).
"geradoc": [
{"key": "simulacao-custo-contratacao", "label": "Simulação de Custo de Contratação"},
{"key": "indicador-desempenho", "label": "Indicador de Desempenho"},
],
"relatorios": [
{"key": "relatorio-setorial", "label": "Relatório Setorial"},
# Subgrupo com uma única tool (toggle único, sem par visualizar/editar
# — mesmo formato já usado em Auditorias, ex. "Consultoria Tributária"
# → "Controle Simples Nacional") pra a ferramenta "Não Conformidades"
# ficar em Relatórios > Qualidade no menu. Restrita por padrão: ver o
# override em seed_portal.py (só "Integração e Inovação" nasce com
# acesso, diferente de "relatorio-setorial" que herda automático de
# SECTORAL_KEYS).
{
"key": "qualidade",
"label": "Qualidade",
"tools": [{"key": "nao-conformidades", "label": "Não Conformidades"}],
},
],
"relatorios-gerenciais": [
{"key": "visao-diretoria", "label": "Visão Diretoria"},
{"key": "visao-gerencial", "label": "Visão Gerencial"},
],
"utilitarios": [
{"key": "importacao-plano-saude", "label": "Importação de Plano de Saúde"},
],
"integracoes": [
{"key": "questor", "label": "Questor"},
],
"auditorias": [
{
"key": "consultoria-tributaria",
"label": "Consultoria Tributária",
"tools": [{"key": "controle-simples-nacional", "label": "Controle Simples Nacional"}],
},
{
"key": "fisco-contabil",
"label": "Fisco/Contábil",
"tools": [{"key": "auditoria-de-balancetes", "label": "Auditoria de Balancetes"}],
},
],
# Cada entrada é um tópico que abre um link externo (Asana, hoje) numa aba nova
# — não são telas próprias, a URL de cada um vive só no <a href> do sidebar
# (não dá pra embutir em iframe: o Asana bloqueia isso via X-Frame-Options/CSP,
# já foi tentado e revertido). "Ordem de Serviço" não tem link ainda (será
# reformulada depois), por isso continua com href="#" no sidebar.
"solicitacoes": [
{"key": "controle-notificacoes", "label": "Controle de Notificações"},
{"key": "ordem-servico", "label": "Ordem de Serviço"},
{"key": "pimi", "label": "P.I.M.I."},
{"key": "programa-indicacoes", "label": "Programa de Indicações"},
{"key": "pos-vendas", "label": "Pós-Vendas"},
{"key": "sugestao-inovacao", "label": "Sugestão de Inovação"},
],
# "Links & Ferramentas" virou uma seção com 2 aplicações reais (cada uma com sua
# própria tela) — a grade de cartões original e "Acessos Gerais" (cadastro de
# logins/acessos compartilhados, organizado em seções e linhas). Cada uma delas
# não é "uma aplicação" no sentido dos módulos com subitens simples (portais,
# geradoc etc.) — tem um par visualizar/editar próprio, modelado como subgrupo
# (mesmo formato de "tools" de Auditorias/Ramais) pra reaproveitar 100% a árvore
# de permissões genérica (profiles.js) sem nenhum código de UI novo.
"links-ferramentas": [
{
"key": "links-ferramentas-cartoes",
"label": "Links & Ferramentas",
"tools": [
{"key": "links-ferramentas-visualizar", "label": "Visualizar"},
{"key": "links-ferramentas-editar", "label": "Editar (reordenar, incluir e remover cartões)"},
],
},
{
"key": "acessos-gerais",
"label": "Acessos Gerais",
"tools": [
{"key": "acessos-gerais-visualizar", "label": "Visualizar"},
{"key": "acessos-gerais-editar", "label": "Editar (criar/editar/excluir seções e acessos)"},
],
},
],
# Ramais virou uma seção com 5 subtelas (abas em ramais.html) — cada uma com seu
# próprio "visualizar", e só as 3 com conteúdo administrável (Ramais, Telefones
# Externos, Funções de Telefonia) também com "editar". Modelado como subgrupo
# (mesmo formato de "tools" usado em Auditorias) pra reaproveitar 100% a árvore
# de permissões genérica (profiles.js) sem nenhum código de UI novo.
# Calendário Individual é "base" (visível a todo perfil) e não tem
# visualizar/editar geral — só a criação/edição de eventos de departamento
# ou para todos (compromissos corporativos, distintos dos pessoais
# "somente eu") e o cadastro de categorias de evento são restritos, daí um
# único "tool" em vez do par visualizar/editar completo.
"calendario-individual": [
{
"key": "calendario-individual-eventos",
"label": "Eventos Corporativos",
"tools": [
{
"key": "calendario-individual-criar-evento",
"label": "Criar e gerenciar eventos de departamento/todos e categorias de evento",
}
],
}
],
"ramais": [
{
"key": "ramais-diretorio",
"label": "Ramais",
"tools": [
{"key": "ramais-visualizar", "label": "Visualizar"},
{"key": "ramais-editar", "label": "Editar (adicionar/alterar ramal e criar ausência)"},
],
},
{
"key": "responsavel-tareffa",
"label": "Responsável no Tareffa",
"tools": [{"key": "responsavel-tareffa-visualizar", "label": "Visualizar"}],
},
{
"key": "telefones-externos",
"label": "Telefones Externos",
"tools": [
{"key": "telefones-externos-visualizar", "label": "Visualizar"},
{"key": "telefones-externos-editar", "label": "Editar"},
],
},
{
"key": "ferias",
"label": "Férias",
"tools": [{"key": "ferias-visualizar", "label": "Visualizar"}],
},
{
"key": "funcoes-telefonia",
"label": "Funções de Telefonia",
"tools": [
{"key": "funcoes-telefonia-visualizar", "label": "Visualizar"},
{"key": "funcoes-telefonia-editar", "label": "Editar"},
],
},
],
}
BASE_KEYS = ["principal", "ramais", "calendario", "calendario-individual", "links-ferramentas", "solicitacoes"]
SECTORAL_KEYS = ["portais", "geradoc", "relatorios", "utilitarios", "integracoes", "auditorias"]
def app_keys_for(module_key: str) -> list[str]:
"""Lista achatada de chaves de aplicação/ferramenta de um módulo (entra em subgrupos)."""
keys = []
for entry in MODULE_APPS.get(module_key, []):
if "tools" in entry:
keys.extend(tool["key"] for tool in entry["tools"])
else:
keys.append(entry["key"])
return keys
def empty_permissions(all_enabled: bool = False) -> dict[str, Any]:
perms = {}
for module in MODULES:
key = module["key"]
perms[key] = {
"enabled": bool(all_enabled),
"apps": {app_key: bool(all_enabled) for app_key in app_keys_for(key)},
}
return perms
def permissions_from_keys(enabled_keys: list[str]) -> dict[str, Any]:
perms = empty_permissions(False)
for key in enabled_keys:
perms[key] = {"enabled": True, "apps": {app_key: True for app_key in app_keys_for(key)}}
return perms
def catalogo_payload() -> dict[str, Any]:
return {"modulos": MODULES, "aplicacoes_por_modulo": MODULE_APPS}