Entidades e relacionamentos · Área de Trabalho

Diagrama

Trabalho e seus vínculos

Carregando diagrama…

Ver código Mermaid
erDiagram
  USERS ||--o{ WORK_ITEMS : "dono (ownerUserId)"
  WORK_ITEMS ||--o{ WORK_ITEMS : "parentId (subtarefa)"
  WORK_ITEMS ||--o{ WORK_ITEM_PEOPLE : "ligacoes"
  WORK_ITEMS ||--o{ WORK_ITEM_COMMENTS : "comentarios"
  STATUS_LABELS |o--o{ WORK_ITEMS : "situacao"
  WORK_TEMPLATES |o--o{ WORK_ITEMS : "modelo de origem"
  GUIDELINES |o--o{ WORK_ITEMS : "orientacao"
  GUIDELINES |o--o{ WORK_TEMPLATES : "orientacao"
  PEOPLE |o--o{ WORK_ITEMS : "personId"
  CASES |o--o{ WORK_ITEMS : "caseId"
  CONSULTATIONS |o--o{ WORK_ITEMS : "consultationId"
  ASSOCIATIONS |o--o{ WORK_ITEMS : "associationId"
  WORK_GROUPS ||--o{ WORK_GROUP_MEMBERS : "membros"
  USERS ||--o{ WORK_GROUP_MEMBERS : "userId"
  USERS ||--o{ SAVED_VIEWS : "titular"
  USERS ||--o{ AGENDAS : "titular"
  AGENDAS ||--o{ AGENDA_LISTS : "listas"
  AGENDA_LISTS ||--o{ AGENDA_LIST_ITEMS : "itens (itemRef)"
  USERS ||--o| LABEL_REGISTRIES : "vocabulario de etiquetas"
  USERS ||--o{ USAGE_HABITS : "habitos"
  USERS ||--o{ DEADLINE_CALENDAR_COVERAGE : "curador"
  WORK_ITEMS |o--o{ SERVICE_RECORDS : "appointment_id"
  WORK_ITEMS ||--o{ SERVICE_REQUEST_ACTIVITY_LINKS : "activity_id"

O diagrama mostra as chaves estrangeiras. As ligações de work_item_people com usuário, Pessoa, núcleo, subnúcleo e Grupo de Trabalho, os núcleos em nucleos, os Trabalhos citados em saved_views.itemIds e em agenda_list_items.itemRef são referências lógicas, sem chave estrangeira, descritas nas tabelas abaixo.

Modelo físico

O modelo é físico (TypeORM sobre PostgreSQL). O Trabalho concentra Atividade e Compromisso numa tabela só, separadas pelo campo kind: a Atividade preenche vencimento e regra de contagem, o Compromisso preenche hora marcada, duração, local e formato. Quem tem a ver com o Trabalho fica numa tabela de ligação polimórfica, e a conversa numa tabela de comentários; as duas caem por cascata com o Trabalho. Cada pessoa organiza a própria Área de Trabalho em agendas com listas, guarda visões salvas, um vocabulário de etiquetas e seus hábitos de uso. Os cadastros que definem a forma do Trabalho — Modelo, Situação, Orientação e Grupo de Trabalho — vivem em tabelas próprias, e o calendário de feriados decide quais dias são úteis. O adiamento não tem tabela: ele é registrado na trilha do histórico, que é imutável.

Trabalho (work_items)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
kindenum activity ou appointmentSimNão muda depois de criado.
categoryenum, nove valoresSimPrecisa pertencer ao kind (CHK_work_items_category_kind).
titlevarchar(255)Sim—
bodytextNãoDescrição; no Compromisso, também a pauta. Até 100000 caracteres na entrada.
tagsvarchar(64)[], padrão {}, índice GIN—Até 20 etiquetas na entrada.
priorityenum low, medium, high ou urgentNão—
statusenum, seis valores, padrão pending—Precisa pertencer ao kind (CHK_work_items_status_kind): in_progress só na Atividade; postponed e no_show só no Compromisso.
statusLabelIdUUID, FK → status_labels (SET NULL)NãoSituação do quadro; o avanço a movimenta.
dueAttimestamptz(3)NãoVencimento da Atividade; cai no fim do dia civil.
scheduledAttimestamptz(3)NãoHora marcada do Compromisso.
durationMinintegerNão1 a 1440 na entrada; só Compromisso.
locationvarchar(255)NãoEntra em searchText.
meetingUrlvarchar(300)NãoSó Compromisso.
meetingFormatenum in_person, remote ou hybridNãoSó Compromisso.
preclusionRuleenum calendar_days, business_days ou calendar_days_business_endNãoGravada no cálculo; vem da categoria ou do Modelo, nunca do cliente.
stateCodechar(2)NãoUnidade federativa da competência do prazo.
ibgeCodevarchar(7)NãoMunicípio da competência do prazo.
templateIdUUID, FK → work_templates (SET NULL)NãoModelo de origem; lido apenas na criação.
guidelineIdUUID, FK → guidelines (SET NULL)NãoExclusivo com guidanceText (CHK_work_items_guidance_exclusive).
guidanceTexttextNãoExclusivo com guidelineId.
parentIdUUID, FK → work_items (SET NULL)NãoMesmo kind do pai; profundidade máxima 3; sem ciclo.
originRulevarchar(16)NãoSó o servidor escreve; hoje apenas RN1. O par (parentId, originRule) torna a regra idempotente.
ownerUserIdUUID, FK → users (RESTRICT)SimSempre o ator da criação; não vem do corpo.
nucleosvarchar(40)[], padrão {}, índice GIN—Siglas de núcleo e códigos de subnúcleo responsáveis, em caixa alta, ordenados e sem repetição; recalculados das designações org_unit de responsável e envolvido; nunca informados pelo cliente.
confidentialboolean, padrão false—Restringe o Trabalho a quem tem ligação direta com ele.
cancelReasonvarchar(500)CondicionalObrigatório quando status é cancelled (CHK_work_items_cancel_reason).
cancelledAt, cancelledBytimestamptz(3), UUID—Selados no cancelamento; limpos na reabertura.
completedAt, completedBytimestamptz(3), UUID—Selados na conclusão; limpos na reabertura.
personIdUUID, FK → people (SET NULL)NãoPessoa a quem o Trabalho se refere; conferida no cadastro antes de gravar.
caseIdUUID, FK → cases (SET NULL)NãoProcesso ligado.
consultationIdUUID, FK → consultations (SET NULL)NãoEntrevista ligada.
associationIdUUID, FK → associations (SET NULL)NãoAssociação alcançada.
searchTexttext, coluna GERADA STORED, índice GIN—Mantida pelo banco a partir de título, descrição, local e etiquetas; fora do contrato.
deletedAt, deletedBytimestamptz(3), UUID—Exclusão suave; deletedAt preenchido tira o Trabalho das listas.
createdAt, updatedAttimestamptz(3)——

Vocabulários: category aceita task, judicial_deadline e extrajudicial_deadline na Atividade, e service, meeting, hearing, expert_examination, oral_argument e orientation no Compromisso. status aceita pending, in_progress, completed e cancelled na Atividade, e pending, completed, cancelled, postponed e no_show no Compromisso — overdue não é valor de coluna, é calculado na leitura.

Cinco restrições CHECK sustentam as invariantes no próprio banco: coerência entre categoria e tipo; coerência entre estado e tipo; exclusividade entre orientação reutilizável e própria; cancelamento com motivo; e não comparecimento apenas em Compromisso de atendimento. Os índices atendem a paginação por keyset (createdAt, id), o recorte por tipo e categoria, e as buscas por etiqueta, núcleo e texto.

Campos da Ficha da Pessoa em implementação

Estado: em implementação na API.

AtributoTipoObrigatórioRegra
subtypeenum work_item_subtype, anulávelNãoconciliation ou instruction na audiência (hearing); medical ou social na perícia (expert_examination). Outra combinação com a categoria é recusada.
presidingNamevarchar(255), anulávelNãoNome exibido de quem preside o Compromisso. A operação dedicada deriva o nome de uma Pessoa vinculada ou grava um nome livre aparado, sem criar Pessoa.
caseMovementIdUUID anulável, FK → case_movements (SET NULL), indexadoNãoMovimentação do mesmo processo vinculada ao Trabalho; exige caseId.

Pessoas ligadas ao Trabalho (work_item_people)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
workItemIdUUID, FK → work_items (CASCADE)Sim—
roleenum, sete papéisSimDecide as naturezas de alvo admitidas.
targetTypeenum user, person, org_unit ou work_groupSimPrecisa ser admitida pelo papel. org_unit designa um núcleo (nuclei) ou um subnúcleo (org_subnuclei), não matriz nem filial de org_units.
targetIdUUIDSimAlvo polimórfico, sem chave estrangeira; a existência é conferida no serviço, no cadastro que targetType nomeia.
positionsmallint, padrão 0—Ordem declarada dentro do papel; 0 a 999 na entrada.
senderUserIdUUID, FK → users (RESTRICT)NãoQuem criou a ligação.
senderKindenum user, machine ou systemNãoNatureza de quem criou a ligação; reservado à autoria institucional, nulo nas ligações criadas por identidade pessoal.
senderTokenIdUUID, FK → api_tokens (SET NULL)NãoCredencial de integração que criou a ligação.
createdAttimestamptz(3)——

O índice único (workItemId, role, targetType, targetId) impede ligações repetidas; o POST genérico responde conflito à repetição. Um índice único parcial admite no máximo uma ligação presiding por Trabalho. A substituição dedicada é idempotente e mantém a ligação e presidingName na mesma transação. O alvo é polimórfico por decisão registrada: nenhuma das quatro tabelas alvo é apagada fisicamente por rota desta API, então a chave estrangeira cobriria um risco que o sistema não produz.

Papéis e o que cada um dá: assignee responde pelo Trabalho (lê e altera); involved lê; observer lê e nunca altera; participant lê e mantém o alcance mesmo com sigilo; guest e witness apontam pessoas do cadastro e não concedem acesso nenhum. presiding também não concede acesso: quando quem preside é uma Pessoa resolvida, há uma única ligação presiding/person; na variante de nome livre, não há ligação. assignee e involved com alvo org_unit carimbam em nucleos a sigla do núcleo ou o código do subnúcleo designado.

Comentário do Trabalho (work_item_comments)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
workItemIdUUID, FK → work_items (CASCADE)Sim—
authorUserIdUUID, FK → users (RESTRICT)NãoSempre a identidade autenticada; nunca vem do corpo.
authorKindenum user, machine ou systemNãoNatureza do autor.
authorTokenIdUUID, FK → api_tokens (SET NULL)NãoCredencial de integração autora.
bodytextSim1 a 10000 caracteres na entrada.
editedAttimestamptz(3)NãoPreenchido na primeira edição.
createdAttimestamptz(3)——

Comentário é conteúdo que o autor edita e apaga, por isso tem tabela. O adiamento fez o caminho oposto: virou registro do histórico unificado, que já guarda data anterior, data nova, motivo e autor, e não admite alteração.

Modelo de Trabalho (work_templates)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
codevarchar(32), únicoNãoCódigo curto para quem cita o Modelo de fora; até 32 caracteres; repetição responde 409.
namevarchar(255)SimNome no seletor.
kindenum activity ou appointmentSimTipo do Trabalho gerado.
categoryenum, nove valoresSimPrecisa pertencer ao kind (CHK_work_templates_category_kind).
titleTemplatevarchar(255)NãoTítulo sugerido; quem cria pode substituir.
bodyTemplatetextNãoDescrição sugerida.
guidelineIdUUID, FK → guidelines (SET NULL)NãoOrientação herdada pelo Trabalho gerado.
daysintegerNãoExige countingRule (CHK_work_templates_counting_rule) e precisa ser maior que zero (CHK_work_templates_days_positive).
countingRuleenum, três regrasCondicionalSubstitui a regra derivada da categoria.
priorityenum, quatro valoresNãoPrioridade sugerida.
durationMinintegerNãoDuração sugerida, para Modelo de Compromisso.
pendingFieldstext[], padrão {}—Campos que a interface deve solicitar; a ordem é o dado.
defaultPeoplejsonb, padrão []—Designações padrão sugeridas; cada item tem role, targetType e targetId. A compatibilidade entre papel e natureza é conferida ao gravar o Modelo.
orgUnitIdUUID, FK → org_units (SET NULL)NãoSetor a que o Modelo pertence.
ownerUserIdUUID, FK → users (SET NULL)NãoQuem cadastrou; fica nulo se o usuário sai, e o Modelo continua servindo.
enabledboolean, padrão true—false tira o Modelo do seletor sem apagá-lo.
createdAt, updatedAttimestamptz(3)——

days e countingRule são lidos no instante da criação do Trabalho, e apenas de Modelo habilitado: alterar o Modelo depois não retroage ao prazo já calculado. É esse par que tira a definição do prazo de uma constante no código e a põe no cadastro. Título, descrição, orientação, prioridade, duração e designações padrão são sugestões para a interface e não são copiados pelo servidor na criação.

Visão salva (saved_views)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
ownerUserIdUUID, FK → users (CASCADE)SimTitular; sempre o ator, nunca o corpo.
namevarchar(120)SimNome que a pessoa dá à visão.
foldervarchar(120)NãoAgrupamento livre entre as visões do titular.
positionnumeric(20,10), padrão 0—Ordenação fracionária entre as visões do titular.
kindenum manual ou querySimNão muda depois de criada.
categoryenum, nove valoresNãoPré-filtro por categoria de Trabalho.
queryJsontextCondicionalExigido na visão de consulta e proibido na manual (CHK_saved_views_query_json); até 4000 caracteres, JSON válido, guardado e devolvido sem interpretação.
labelsvarchar(64)[], padrão {}—Rótulos pessoais da visão.
itemIdsUUID[], padrão {}—Trabalhos da lista manual, na ordem do array e sem repetição; referências opacas, sem chave estrangeira.
createdAt, updatedAttimestamptz(3)——

As referências de itemIds são opacas de propósito: a lista de alguém não quebra porque um Trabalho foi para a lixeira. O índice (ownerUserId, folder, position) atende à apresentação do painel pessoal.

Feriado (holidays)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
dateKeychar(10)SimData civil YYYY-MM-DD; é a chave usada pelo motor de prazo.
titlevarchar(200)SimDescrição do feriado.
holidayTypeenum, padrão feriado—Distingue feriado de ponto facultativo e congêneres.
jurisdictionvarchar(20)NãoAbrangência declarada.
cityvarchar(60)NãoMunicípio, quando municipal.
stateCodechar(2)NãoUnidade federativa, quando estadual.
yearintegerSimAno derivado da data; sustenta a leitura por faixa de anos.
sourcevarchar(120)NãoOrigem do dado na importação.
enabledboolean, padrão true—false retira o dia do cálculo sem apagar o registro.
createdAt, updatedAttimestamptz(3)——

O índice único (dateKey, jurisdiction, city) torna a importação idempotente: rodar o comando duas vezes não duplica feriado. O calendário entra hoje por comando de importação; não há rota de administração.

Cobertura do calendário (deadline_calendar_coverage)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
scopeenum national, state ou citySimTerritório da cobertura declarada.
stateCodechar(2)CondicionalNulo no nacional; preenchido no estadual e no municipal (CHK_coverage_state_code).
ibgeCodevarchar(7)CondicionalPreenchido apenas no municipal (CHK_coverage_ibge_code).
effectiveFromdateSimInício do período conferido.
effectiveTodateNãoFim do período; nulo significa cobertura aberta. Não pode anteceder o início (CHK_coverage_period).
curatedByUUID, FK → users (RESTRICT)SimQuem conferiu o período.
createdAt, updatedAttimestamptz(3)——

A tabela existe porque a lista de feriados sozinha não distingue "este território não tem feriado neste período" de "ninguém cadastrou este período", e essa indistinção faz o motor devolver uma data com aparência de conferida. A recusa de prazo sobre período sem cobertura ainda não está implementada.

Situação do quadro (status_labels)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
nucleusSiglavarchar(16)SimNúcleo dono da Situação.
namevarchar(60)SimÚnico por núcleo (nucleusSigla, name); repetição responde 409.
canonicalStatusenum de estado canônicoSimDiz a que estado do Trabalho a Situação corresponde.
positioninteger, padrão 0—Define a ordem do avanço.
enabledboolean, padrão true—A sequência devolve apenas as habilitadas.
createdAt, updatedAttimestamptz(3)——

Orientação (guidelines)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
titlevarchar(255)Sim—
bodytextNãoAté 100000 caracteres na entrada.
shortcutvarchar(40)NãoAtalho de busca.
kindenum, padrão both—Diz a que tipo de trabalho a orientação serve.
ownerUserIdUUID, FK → usersNãoAutor do cadastro.
createdAt, updatedAttimestamptz(3)——

Grupo de Trabalho (work_groups) e membro (work_group_members)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
namevarchar(120)Sim—
descriptionvarchar(500)Não—
ownerUserIdUUID, FK → users (SET NULL)NãoDono do grupo; sempre a identidade que o criou e sempre membro.
enabledboolean, padrão true—Desligar corta o alcance coletivo sem apagar os membros.
createdAt, updatedAttimestamptz(3)——

O membro fica em work_group_members, com id, workGroupId e userId (ambos CASCADE). O par é único, então o mesmo vínculo não se repete. A alteração dos membros substitui a lista inteira, mantendo o dono.

Agenda (agendas)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
namevarchar(120)SimNome da agenda.
ownerUserIdUUID, FK → users (CASCADE)SimTitular; sempre a identidade autenticada.
positiondouble precision, padrão 0—Ordem entre as agendas do titular.
createdAt, updatedAttimestamptz(3)——

Lista da agenda (agenda_lists)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
agendaIdUUID, FK → agendas (CASCADE)SimAgenda da lista; a lista só muda para outra agenda do mesmo titular.
namevarchar(120)SimNome da lista.
ownerUserIdUUIDSimTitular, igual ao da agenda.
positiondouble precision, padrão 0—Ordem dentro da agenda.
listKindenum manual ou querySimLista de Trabalhos escolhidos ou lista de consulta.
activityTypeenum task, judicial_deadline ou extrajudicial_deadlineNãoPré-filtro por categoria de Atividade.
queryJsontextNãoCritérios da lista de consulta; até 4000 caracteres e JSON válido na entrada.
labelsvarchar(64)[], padrão {}—Até 32 rótulos na entrada.
createdAt, updatedAttimestamptz(3)——

Item da lista (agenda_list_items)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
listIdUUID, FK → agenda_lists (CASCADE)SimLista do item.
itemRefvarchar(64)SimReferência opaca work-items:<uuid>, sem chave estrangeira; única por lista (listId, itemRef).
positiondouble precision, padrão 0—Ordem na lista; renumerada em sequência quando duas posições ficam próximas demais.
createdAt, updatedAttimestamptz(3)——

Apagar a agenda apaga suas listas e itens; apagar a lista apaga seus itens. Os Trabalhos citados não são afetados, e a referência opaca mantém a lista válida quando um Trabalho vai para a lixeira.

Vocabulário de etiquetas (label_registries)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
ownerUserIdUUID, FK → users (CASCADE), únicoSimUm vocabulário por pessoa.
itemsjsonb, padrão []—Etiquetas com slug, name, symbol, color e lastUsedISO; até 200 itens, substituídos de uma vez.
createdAt, updatedAttimestamptz(3)——

Hábito de uso (usage_habits)

AtributoTipoObrigatórioRegra
idUUID, chave primáriaGerado—
ownerUserIdUUID, FK → users (CASCADE)SimTitular.
kindvarchar(32)SimNatureza do hábito; o prefixo lia. é reservado aos hábitos registrados pela Lia.
refvarchar(64)SimReferência usada.
countinteger, padrão 0—Soma um a cada uso registrado.
lastUsedAttimestamptz(3)SimÚltimo uso.
createdAttimestamptz(3)——

O índice único (ownerUserId, kind, ref) mantém um registro por hábito; usos repetidos incrementam a contagem.

Relações e cardinalidades

RelaçãoCardinalidadeObrigatóriaIntegridade
Trabalho → Pessoas ligadas, Comentários1:NNãoCASCADE
Trabalho → Trabalho (subtarefa e continuidade)1:NNãoSET NULL; mesmo kind; profundidade máxima 3; sem ciclo
Trabalho → Usuário donoN:1SimRESTRICT
Trabalho → SituaçãoN:1NãoSET NULL
Trabalho → ModeloN:1NãoSET NULL; lido apenas na criação
Trabalho → OrientaçãoN:1NãoSET NULL; exclusiva com a orientação própria
Trabalho → Pessoa, Processo, Entrevista, AssociaçãoN:1NãoSET NULL
Trabalho → Núcleo ou SubnúcleoN:N por sigla ou código (nucleos)NãoSem FK; projetado das designações org_unit
Ligação → alvo (Usuário, Pessoa, Núcleo ou Subnúcleo, Grupo)N:1 polimórficaSimSem FK; existência conferida no serviço
Modelo → Orientação, Setor, UsuárioN:1NãoSET NULL
Visão salva → Usuário titularN:1SimCASCADE
Visão salva → Trabalho (itemIds)N:N por arrayNãoSem FK; referência opaca
Grupo de Trabalho → Membro1:NNãoCASCADE; par único
Grupo de Trabalho → Usuário donoN:1NãoSET NULL
Agenda → Usuário titularN:1SimCASCADE
Agenda → Lista1:NNãoCASCADE
Lista → Item1:NNãoCASCADE; (listId, itemRef) único
Item da lista → Trabalho (itemRef)N:1SimSem FK; referência opaca
Vocabulário de etiquetas → Usuário1:1SimCASCADE; titular único
Hábito de uso → UsuárioN:1SimCASCADE; (ownerUserId, kind, ref) único
Cobertura do calendário → Usuário curadorN:1SimRESTRICT
Atendimento → Trabalho (service_records.appointment_id)N:1NãoSET NULL
Solicitação → Trabalho (service_request_activity_links.activity_id)N:1NãoRESTRICT

Ciclo de vida

O Trabalho é criado, alterado e encerrado indefinidamente. A exclusão é suave: deletedAt tira o registro das listas e o mantém na lixeira, de onde ele volta pela restauração. Não há exclusão física por rota, e as duas chaves estrangeiras que vêm de fora — do Atendimento e da Solicitação — preservam o histórico dessas áreas.

Os cadastros de apoio seguem a mesma lógica de permanência: o Modelo e o Grupo de Trabalho são desabilitados, não apagados, porque Trabalhos já criados continuam citando seus identificadores. A Visão salva, a agenda e suas listas são exceções: são preferências de uso, e por isso são apagadas de verdade, sem lixeira. O Grupo de Trabalho desabilitado deixa de dar alcance aos Trabalhos em que está ligado.

Camadas do domínio