K1 Krat One Structure Atlas ENV · lab
Fundação/Modelo de Dados
Core #3 · Data Conventions

Modelo de Dados

O "código civil" das tabelas — o que garante que 5 pilares construídos ao longo de meses pareçam um sistema só.

UUIDv7dinheiro = bigintRLS por workspaceparticionamento por tempo
A

As convenções

RegraConvenção
IDsUUIDv7 (time-ordered) + ID público com prefixo — cont_7f3a…
TemporaisSempre timestamptz em UTC; conversão de fuso só na apresentação
Soft-deletedeleted_at universal; archived_at ≠ delete; hard-delete só p/ LGPD
Dinheirobigint em unidades menores + moeda — nunca float
Enumstext + CHECK (não pg enum, doloroso de alterar)
JSONBSó p/ settings/meta/custom; dado consultável = coluna
ConcorrênciaColuna version p/ optimistic lock
Alto volumeParticionamento por tempo em audit/event/métricas
Custom fieldscustom_field_def tipado + valores em custom jsonb (GIN)
MigrationsDrizzle, forward-only, expand-contract p/ zero-downtime
B

Base Table Template

A assinatura que toda tabela de negócio herda.

-- lei do Core: workspace_id + RLS em toda tabela de negócio
CREATE TABLE <entity> (
  id           uuid PRIMARY KEY DEFAULT uuidv7(),   -- time-ordered
  workspace_id uuid NOT NULL REFERENCES workspace(id),
  client_id    uuid REFERENCES client(id),          -- quando aplicável
  -- … colunas de negócio …
  custom       jsonb NOT NULL DEFAULT '{}',          -- custom fields tipados
  meta         jsonb NOT NULL DEFAULT '{}',
  version      int  NOT NULL DEFAULT 1,              -- optimistic lock
  created_at   timestamptz NOT NULL DEFAULT now(),   -- UTC
  updated_at   timestamptz NOT NULL DEFAULT now(),
  deleted_at   timestamptz                          -- soft-delete
);
ALTER TABLE <entity> ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON <entity>
  USING ( workspace_id = current_setting('app.workspace_id')::uuid );
CREATE INDEX ON <entity> (workspace_id) WHERE deleted_at IS NULL;

Os módulos só acrescentam suas colunas de negócio. Veja o modelo do CRM como primeiro exemplo aplicado.

C

Profundidade do dado D9 · 2026-07-12

Decisão: "profundidade HubSpot" desde já — o dado modela qualquer vertical sem gambiarra. Ver Decisões.

RecursoO que é
lifecycle + lead status (2 eixos)lifecycle_stage (lead·mql·sql·customer) — onde está na jornada — e lead_status (new·attempting·connected·qualified·unqualified) — estado operacional. Separados, como no HubSpot.
Custom objectsAlém dos campos custom: entidades próprias por vertical (ex.: "Imóvel", "Protocolo", "Franquia") com object_def + associações — modela qualquer nicho.
Propriedades calculadas / scoreCampos derivados (fórmula) e lead score (sinais + AI/KRATUS) — priorização automática.
Histórico de campoAuditoria de mudança por propriedade (quem, quando, de→para) — na timeline e no audit_log.
Associações com rótuloscontact↔company↔deal com papéis (decision_maker, champion…) e empresa primária.