"""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": "diretoria", "label": "Diretoria"}, {"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": [ # 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 do resto de SECTORAL_KEYS, que herda automático). { "key": "qualidade", "label": "Qualidade", "tools": [{"key": "nao-conformidades", "label": "Não Conformidades"}], }, # Mesmo padrão de "qualidade" acima — subgrupo com uma única tool # (toggle único). Restrita por padrão: ver o override em # seed_portal.py (só "Integração e Inovação" nasce com acesso), já # que a ferramenta expõe balancete/DRE completos dos clientes. { "key": "contabilidade", "label": "Contabilidade", "tools": [{"key": "dashboard-contabil", "label": "Relatório Contábil"}], }, ], # Ferramentas para as empresas do próprio escritório. Fora de BASE_KEYS e # SECTORAL_KEYS de propósito: nenhum perfil ganha acesso automático, a # liberação é sempre manual pela tela de Perfis de Acesso. O Relatório # Contábil - De Paula tem permissão própria, independente da # `dashboard-contabil` de Relatórios. "diretoria": [ {"key": "dashboard-contabil-de-paula", "label": "Relatório Contábil - De Paula"}, ], "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"}, {"key": "importacao-plano-saude-de-paula", "label": "Importação de Plano de Saúde - De Paula"}, # Restrita ao perfil "Inovação" por decisão do usuário (override em # seed_portal.py), liberada a outros perfis depois pela tela. {"key": "conciliacao-fornecedores", "label": "Conciliação de Fornecedores"}, ], "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 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}