Modelo de dados
Núcleo de identidade e multi-tenancy — User, Customer, Tenant, App, os vínculos M:N (UserTenant, OrganizationTenant) e AuditLog.
Este documento cobre o núcleo de identidade e multi-tenancy do schema Prisma
(prisma/schema.prisma, PostgreSQL): Customer, App, Tenant, User, os
vínculos M:N UserTenant e OrganizationTenant, e AuditLog. A Organization
(cooperativa) e suas tabelas aparecem aqui apenas de forma resumida — o detalhe
está nos endpoints de organizations. As entidades de negócio usam soft delete
(deletedAt).
Os dois vínculos M:N são a base da trava de acesso por tenant: um usuário só
enxerga as cooperativas (e documentos) dos tenants dos quais faz parte
(UserTenant), limitado às cooperativas alcançadas por esses tenants
(OrganizationTenant).
Diagrama de entidades
Entidades
User
Perfil local vinculado a uma identidade Keycloak.
| Campo | Tipo | Observações |
|---|---|---|
id | uuid | PK |
idIdentity | string | Único; o sub do Keycloak |
name | string | |
email | string | Único |
type | string | Admin | Technician | Cooperative |
customerId | uuid? | Customer opcional (FK) |
createdAt/updatedAt/deletedAt | datetime | deletedAt = soft delete |
Customer
Cliente/empresa. Raiz do multi-tenancy.
| Campo | Tipo | Observações |
|---|---|---|
id | uuid | PK |
federalTaxId | varchar(14) | Único (CPF/CNPJ) |
name | string | |
alias | string? | |
email | string? | |
phone | string? | |
logoPath | string? | |
active | boolean | Padrão true |
Tenant
Instância de um App para um Customer.
| Campo | Tipo | Observações |
|---|---|---|
id | uuid | PK |
customerId | uuid | FK → Customer (indexado) |
appId | uuid | FK → App (indexado) |
name | string | |
active | boolean | Padrão true |
metadata | json? | Dados livres |
keycloakClientId | string? | Único; client Keycloak para auth de serviço |
allowedScopes | json? | Escopos permitidos no fluxo app-to-app |
App
Aplicação registrada (ex.: app1, app2).
| Campo | Tipo | Observações |
|---|---|---|
id | uuid | PK |
name | string | Único |
UserTenant
Vínculo M:N entre User e Tenant (membership) — a quais tenants o usuário
pertence. Chave composta, sem soft delete (desvincular remove a linha).
| Campo | Tipo | Observações |
|---|---|---|
userId | uuid | PK + FK → User |
tenantId | uuid | PK + FK → Tenant |
active | boolean | Padrão true; membership só conta se ativa |
Gerenciado via /api/users/:userId/tenants (POST/DELETE/GET).
OrganizationTenant
Vínculo M:N entre Organization (cooperativa) e Tenant — quais tenants
alcançam cada cooperativa. Uma cooperativa pode pertencer a vários tenants.
Chave composta, sem soft delete.
| Campo | Tipo | Observações |
|---|---|---|
organizationId | uuid | PK + FK → Organization |
tenantId | uuid | PK + FK → Tenant |
Gerenciado via /service/organizations/:organizationId/tenants (POST/DELETE) e
consultado via /api/tenants/:tenantId/organizations (GET).
AuditLog
Registro de auditoria gravado em operações de escrita (via @AuditLog).
| Campo | Tipo | Observações |
|---|---|---|
id | uuid | PK |
timestamp | datetime | |
action | string | read | create | update | delete |
entity | string | Entidade afetada |
entityId | string? | Id do registro afetado |
metadata | json? | |
userId | string | Autor da ação |