SLA — visão geral
O módulo de SLA (Service Level Agreement) é a tela onde um administrador configura o prazo de laudo que os exames de um grupo ou de uma unidade precisam cumprir. Ele não lista nem mostra o prazo de um exame específico — isso aparece na worklist (coluna/botão Alterar SLA, fora do escopo deste levantamento). Esta tela só guarda a política: quanto tempo cada prioridade (e, opcionalmente, cada modalidade) tem para ser laudada, em qual grade semanal, e quanto esse prazo é apertado quando o exame é AVC ou Trauma.
Este levantamento cobre a interface (Angular) do repositório mm-pacs-portal-main-interface,
branch integration/with-fixlaudo, pasta src/app/pages/sla-policy, testada no ambiente
https://task4.srv1812538.hstgr.cloud/. O contrato de API correspondente já está documentado em
Módulo SLA — visão geral (back); esta página documenta a
experiência de tela, sem repetir o contrato HTTP.
Onde a tela vive
A política de SLA não tem uma rota própria fora da área administrativa — ela é uma aba a mais no
detalhe de Grupo e no detalhe de Unidade. Confirmado em
src/app/app/routes/admin.routes.ts (branch integration/with-fixlaudo):
| Escopo | Rota | Guard | Componente | Onde no código |
|---|---|---|---|---|
| Grupo (tenant) | /admin/tenant/:id/sla | permissionGuard('sla:read', 'route') | TenantSlaPolicyRouteComponent | admin.routes.ts:454-465 |
| Unidade (company) | /admin/company/:id/sla | permissionGuard('sla:read', 'route') + unitReadGuard (permissionGuard('unit:read', 'route')) | UnitSlaPolicyRouteComponent | admin.routes.ts:628-639 |
O item de menu que leva a cada uma (SLA_POLICY.NAV, rótulo "SLA" na sidebar) está declarado em
groupDetailSidebar (admin.routes.ts:118-123) e unitDetailSidebar (admin.routes.ts:202-207),
ambos com requiredTenantPermission: 'sla:read'.
:::caution Achado de código + ambiente: o item de menu e a rota são checados de formas diferentes
O requiredTenantPermission da sidebar não usa o mesmo cálculo do guard da rota. Confirmado em
src/app/app/layouts/main-layout/layout.component.ts:279-286: a visibilidade do item de menu chama
iamSession.hasPermissionInAnyTenantScope('sla:read') — ou seja, só aparece para quem tem
sla:read concedido em algum escopo do tipo tenant, mesmo quando o item está na sidebar da
unidade. Já o guard da própria rota (permissionGuard('sla:read', 'route'),
src/app/app/guards/permission.guard.ts:35-38) resolve o :id da URL e chama
iamSession.hasPermission(scopeId, 'sla:read') — checa exatamente o escopo (tenant OU unidade) da
página que está sendo aberta.
No ambiente de teste (task4, tenant "Clínica Docs Portal 2" / unidade "Unidade Central Docs"),
isso teve um efeito observável: o usuário docs.administrator@mobilemed.test tem sla:read/
sla:write/sla:delete concedidos só no escopo da unidade (confirmado lendo
localStorage['mobilemed:iam-permissions:v2:' + userId] no navegador — a chave tenants está vazia,
só units tem uma entrada). Resultado:
- O item SLA nunca aparece na sidebar — nem na do grupo, nem na da unidade — porque não
existe nenhuma concessão no escopo tenant para nenhum dos 9 perfis de teste (o mesmo vale para
os outros itens com
requiredTenantPermission: Permissões, PACS, Módulos, Auditoria). - A tela de unidade (
/admin/company/:id/sla) abre normalmente por URL direta paraadministrator, porque o guard da rota olha o escopo certo (a unidade). - A tela de grupo (
/admin/tenant/:id/sla) é inacessível por qualquer um dos 9 perfis de teste — inclusiveadministrator— porque nenhum deles temsla:readno escopo tenant. Ao navegar direto para a URL, o guard redireciona silenciosamente para/admin/tenant(lista de grupos), sem toast de erro.
A confirmar — responsável: time de frontend/IAM; data: 24/09/2026.: não foi possível confirmar se
a ausência de concessões em escopo tenant é uma limitação do wizard de criação do tenant de teste
(docs-usuarios.md) ou o comportamento esperado para o papel administrator neste produto. Por
causa disso, as capturas deste levantamento cobrem apenas o escopo de unidade — a tela de grupo
não pôde ser fotografada com nenhum dos perfis disponíveis.
:::
As duas abas da tela
Tanto a rota de grupo quanto a de unidade renderizam o mesmo par de abas, através de um
SlaPolicyStore compartilhado (src/app/pages/sla-policy/model/sla-policy.store.ts) que carrega e
salva as duas independentemente:
| Aba | Cobre | Página deste levantamento |
|---|---|---|
Prazos (SLA_POLICY.PAGE.TAB.DEADLINES) | Grade de prazo por prioridade × modalidade, com agenda semanal | Prazos por prioridade e modalidade |
Protocolos (SLA_POLICY.PAGE.TAB.PROTOCOLS) | Cap de prazo para os protocolos clínicos AVC e Trauma | Cap de protocolo clínico (AVC/Trauma) |
Cada aba carrega, edita e salva de forma independente — trocar de aba não descarta as edições
pendentes da outra, porque cada uma tem seu próprio rascunho (matrixDraft/protocolDraft) dentro
do mesmo store.
Permissões
A tela usa as mesmas três permissões documentadas no back (ver Permissões (back)), mas aplicadas de formas diferentes no front:
| Permissão | Efeito no front |
|---|---|
sla:read | Libera a entrada na rota (permissionGuard('sla:read', 'route')). Sem ela, a navegação é redirecionada. |
sla:write | Habilita os campos do formulário e o botão Salvar em cada aba (canWrite(), sla-policy-editor.component.ts:231-236 e sla-protocol-policy-editor.component.ts:152-157). Com sla:read mas sem sla:write, a tela abre, mas todos os campos ficam somente leitura ([readOnly]/[disabled] amarrados a !canWrite()). |
sla:delete | Habilita o botão Restaurar herança, e só na unidade — nunca no grupo, e só quando a combinação selecionada (regra ou protocolo) tem override próprio da unidade (canRestore() em ambos os editores). |
Segundo o catálogo de papéis do backend
(mm-pacs-portal-main-api/package/identity/authorization/core/models/identity-system-role.ts:48-173),
das 9 personas de teste (docs-usuarios.md), só duas têm as três permissões deste módulo:
| Perfil | sla:read | sla:write | sla:delete |
|---|---|---|---|
administrator | Sim | Sim | Sim |
manager | Sim | Sim | Sim |
doctor, technician, resident, read_only, typist, requestor, financial | Não | Não | Não |
Não existe, no catálogo padrão, um perfil com só sla:read (visualização sem edição) — quem
enxerga a tela sempre pode editar e restaurar. Isso foi confirmado navegando com dois perfis neste
ambiente:
administrator(escopo unidade): abre/admin/company/:id/sla, os campos vêm editáveis (readOnly: falseconfirmado via inspeção do DOM) e os botões Salvar/Restaurar herança aparecem habilitados conforme o estado de "sujo".doctor: ao navegar direto para/admin/company/:id/sla, o guard da rota redireciona para/admin/tenant— a tela nunca chega a renderizar.

Contexto de negócio (legado) — Bitrix
Os cards abaixo (funil de features do sistema legado, entityTypeId 1320) descrevem a intenção de produto original deste módulo. Eles não são fonte de comportamento atual — o próprio card F-003 registrava um teto de 59 minutos para o prazo de protocolo habilitado (BR-SLA-057) que não existe mais no código atual, como já detalhado em Reescrita do legado (back). Listamos aqui só id e título, como contexto histórico:
| Card | Título |
|---|---|
| 696 | F-001 — Configurar SLA por prioridade e modalidade - Front |
| 700 | F-002 — Calcular o prazo de SLA (expiração) do exame - Front |
| 704 | F-003 — Cap de SLA por protocolo clínico (AVC / Trauma) - Front |
| 1314 | F-001 — Configurar SLA por prioridade e modalidade - Front (card duplicado do 696 no funil) |
O card F-002 (cálculo do prazo no exame) não tem tela própria no legado nem no código atual — é o motor de cálculo interno já documentado em Motor de cálculo (back).
Páginas deste módulo
| Página | Cobre |
|---|---|
| Prazos por prioridade e modalidade | Aba "Prazos": SlaPolicyEditorComponent |
| Cap de protocolo clínico (AVC/Trauma) | Aba "Protocolos": SlaProtocolPolicyEditorComponent |