PostgreSQL - Diagrama ER y diccionario de datos
Convenciones
- Todas las tablas usan
BIGSERIALsolo para PK tecnicas, yUUIDpara las claves de negocio cuando aplique. - Campos de auditoria:
created_at,updated_at,created_by,updated_by. - Soft delete (donde aplique):
deleted_at TIMESTAMP NULL. - Timezone: todos los timestamps en
TIMESTAMPTZ(UTC).
Diagrama ER Mermaid
Diccionario de datos
Tabla partner
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Catálogo de partners o socios (GEPP, Compañía B, etc.) | id uuid | created_at, updated_at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | uuid | PK técnica | PRIMARY KEY |
partner_id | varchar(64) | Clave de negocio (GEPP, etc.) | UNIQUE NOT NULL |
name | varchar(200) | Nombre comercial | NOT NULL |
status | varchar(16) | ACTIVE / INACTIVE | NOT NULL, check in list |
default_company_id | varchar(64) | Company por defecto | NULL |
created_at | timestamptz | Alta | NOT NULL default now() |
updated_at | timestamptz | Ultima actualizacion | NOT NULL default now() |
Indices: idx_partner_status(status).
Tabla partner_configuration
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Configuracion parametrica por partner (mapeos, credencial refs, etc.) | id uuid | created_at, updated_at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | uuid | PK | PRIMARY KEY |
partner_id | uuid | FK a partner | NOT NULL REFERENCES partner(id) |
config_key | varchar(120) | Clave (ej: fusion.credentials.ref) | NOT NULL |
config_value | jsonb | Valor JSON | NOT NULL |
version | int | Version semantico de la configuracion | NOT NULL default 1 |
description | varchar(255) | NULL | |
created_at | timestamptz | NOT NULL | |
updated_at | timestamptz | NOT NULL |
Unique: UNIQUE(partner_id, config_key) (upsert por key).
Indices: GIN idx_partner_config_value ON partner_configuration USING GIN(config_value).
Tabla validation_rule
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Metadata de regla de validación | id uuid | created_at, updated_at, created_by, updated_by |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | uuid | PK | PRIMARY KEY |
code | varchar(80) | Código funcional (SUPPLIER_REQUIRED etc.) | NOT NULL |
partner_id | varchar(64) | Partner (puede ser GLOBAL) | NOT NULL |
company_id | varchar(64) | NULL indica todas las companies | NULL |
source_system | varchar(80) | NULL indica todos los sistemas | NULL |
document_types | varchar(255)[] | Tipos de documento a los que aplica | NULL |
group | varchar(16) | STRUCTURAL SYNTACTIC SEMANTIC BUSINESS | NOT NULL |
priority | int | Orden 1..9999 | NOT NULL |
status | varchar(16) | DRAFT ACTIVE INACTIVE | NOT NULL |
created_by | varchar(120) | Usuario/Service Account | NOT NULL |
updated_by | varchar(120) | NOT NULL | |
created_at | timestamptz | NOT NULL | |
updated_at | timestamptz | NOT NULL |
Indices:
UNIQUE(partner_id, company_id, source_system, code)con NULLS NOT DISTINCTidx_vrule_status(status)idx_vrule_scope(partner_id, company_id, source_system, status, priority)
Tabla validation_rule_version
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Versionado de la expresion de regla (la definicion ejecutable) | id uuid | published_at, published_by |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | uuid | PK | PRIMARY KEY |
rule_id | uuid | FK a validation_rule | NOT NULL REFERENCES validation_rule(id) |
major | int | Version mayor | NOT NULL |
minor | int | Version menor | NOT NULL |
expression_language | varchar(32) | Fijo NEXUS_RULE_DSL | NOT NULL |
expression | text | Expresion DSL (no codigo arbitrario) | NOT NULL |
severity | varchar(16) | WARNING ERROR FATAL | NOT NULL |
error_template | jsonb | Plantilla del error (ValidationError) | NOT NULL |
published_at | timestamptz | NULL | |
published_by | varchar(120) | NULL |
Unique: UNIQUE(rule_id, major, minor).
Indices: idx_vrv_rule_current(rule_id, major DESC, minor DESC).
Tabla purchase_order_request
| Propósito | Llave primaria | Audit fields |
|---|---|---|
Solicitud de OC (ciclo de vida end-to-end). La PK id es el requestId público. | id uuid | created_at, updated_at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | uuid | requestId publico | PRIMARY KEY |
partner_id | varchar(64) | Partner origen | NOT NULL |
company_id | varchar(64) | NOT NULL | |
source_system | varchar(80) | NOT NULL | |
external_reference | varchar(120) | Referencia del socio (PO-123456) | NOT NULL |
idempotency_key | varchar(128) | NOT NULL | |
document_type | varchar(32) | NOT NULL | |
status | varchar(32) | Estado actual de la maquina | NOT NULL |
attempt | int | Numero de intentos (retry) | NOT NULL default 1 |
submitted_at | timestamptz | Hora de ingreso reportada por cliente | NULL |
request_json | jsonb | Payload canónico completo | NOT NULL |
canonical_hash | uuid | Hash SHA256 del payload (duplicados funcionales) | NULL |
custom_fields | jsonb | Campos extendidos | NULL |
created_at | timestamptz | NOT NULL | |
updated_at | timestamptz | NOT NULL |
Constraints de unicidad (claves de idempotencia):
UNIQUE(partner_id, idempotency_key)(API, Idempotency-Key)UNIQUE(partner_id, source_system, external_reference)(Referencia externa por origen, preventiva)UNIQUE(canonical_hash)(opcional, activable por partner)
Indices:
idx_po_req_status(status, updated_at DESC)idx_po_req_partner(partner_id, company_id, source_system)idx_po_req_created_at(created_at)idx_po_req_external(external_reference, partner_id)
Tabla transaction_status_history
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Registro de todas las transiciones de estado del request (historial inmutable). | id bigserial | at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | bigserial | PK tecnica | PRIMARY KEY |
request_id | uuid | FK a purchase_order_request | NOT NULL |
from_status | varchar(32) | NULL | |
to_status | varchar(32) | NOT NULL | |
event_id | uuid | eventId que disparo la transicion | NULL |
component | varchar(64) | PO_API WORKER PUBLISHER MANUAL etc. | NOT NULL |
reason | varchar(255) | NULL | |
metadata | jsonb | NULL | |
at | timestamptz | NOT NULL default now() |
Indices: idx_tsh_request_id(request_id, at).
Tabla validation_result
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Resultado de ejecucion de reglas por request | id uuid | at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | uuid | PK | PRIMARY KEY |
request_id | uuid | FK | NOT NULL |
rule_version_id | uuid | FK a la version de regla que se ejecuto | NULL |
valid | boolean | Resultado final del bloque ejecutado | NOT NULL |
errors | jsonb | Array de ValidationError | NULL |
duration_ms | int | Tiempo de ejecucion | NULL |
at | timestamptz | NOT NULL default now() |
Indices: idx_vr_request(request_id, at).
Tabla purchase_order
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Orden de Compra creada en Oracle Fusion | id uuid | created_at, updated_at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | uuid | PK | PRIMARY KEY |
request_id | uuid | FK 1-1 con request | UNIQUE NOT NULL REFERENCES purchase_order_request(id) |
oracle_purchase_order | varchar(32) | Id Fusion (mostrado al cliente) | NOT NULL |
oracle_po_number | varchar(32) | Numero de PO (visible en Fusion) | NULL |
total_amount | numeric(20,6) | Total | NOT NULL |
currency_code | char(3) | ISO 4217 | NOT NULL |
oracle_created_at | timestamptz | Hora reportada por Fusion | NULL |
supplier_code | varchar(64) | NOT NULL | |
buyer_email | varchar(200) | NULL | |
fusion_payload_id | varchar(128) | RequestId Fusion (para soporte) | NULL |
created_at | timestamptz | NOT NULL | |
updated_at | timestamptz | NOT NULL |
Unique: UNIQUE(oracle_purchase_order) (cada OC de Fusion se registra una vez).
Indices: idx_po_oracle_num(oracle_po_number), idx_po_request(request_id).
Tabla purchase_order_line
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Linea de la OC en Fusion | id uuid | Sin audit fields individuales; se propaga de purchase_order. |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | uuid | PK | PRIMARY KEY |
purchase_order_id | uuid | FK | NOT NULL REFERENCES purchase_order(id) |
line_number | int | Posicion 1..N | NOT NULL |
sku | varchar(60) | SKU del articulo | NOT NULL |
upc | varchar(40) | NULL | |
description | varchar(250) | NOT NULL | |
quantity | numeric(20,6) | NOT NULL | |
uom | varchar(12) | UOM estandar | NOT NULL |
unit_price | numeric(20,6) | NOT NULL | |
line_amount | numeric(20,6) | NOT NULL | |
cost_center | varchar(40) | NULL | |
gl_code | varchar(120) | NULL | |
custom_fields | jsonb | NULL |
Unique: UNIQUE(purchase_order_id, line_number).
Indices: idx_pol_order(purchase_order_id).
Tabla integration_error
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Registro de errores de integracion (validacion, Fusion, temporales, etc.) | id bigserial | at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | bigserial | PK | PRIMARY KEY |
request_id | uuid | FK | NOT NULL |
event_id | uuid | Evento (Pub/Sub) que genero el error | NULL |
error_category | varchar(32) | Ver taxonomia 8 categorias | NOT NULL |
error_code | varchar(80) | Codigo funcional | NOT NULL |
message | text | NOT NULL | |
attempt | int | Intento al momento del error | NULL |
component | varchar(64) | WORKER / PO_API / VALIDATION_ENGINE etc. | NULL |
details | jsonb | Payload de contexto | NULL |
at | timestamptz | NOT NULL default now() |
Indices: idx_ierr_request(request_id, at), idx_ierr_cat(error_category, at).
Tabla outbox_event
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Patrón Transactional Outbox: eventos pendientes de publish a Pub/Sub. | id bigserial | created_at, processed_at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | bigserial | PK (para SKIP LOCKED polling) | PRIMARY KEY |
event_id | uuid | Id de negocio del evento | UNIQUE NOT NULL |
request_id | uuid | FK al request | NOT NULL |
topic | varchar(120) | Topic Pub/Sub destino | NOT NULL |
event_type | varchar(64) | PURCHASE_ORDER_REQUESTED, RETRY_REQUESTED, etc. | NOT NULL |
version | int | Version schema (1, 2...) | NOT NULL default 1 |
partner_id | varchar(64) | NOT NULL | |
company_id | varchar(64) | NULL | |
source_system | varchar(80) | NULL | |
ordering_key | varchar(120) | Para ordering de Pub/Sub (opcional por partner) | NULL |
payload | jsonb | Envelope completo publishable | NOT NULL |
attributes | jsonb | Attributes Pub/Sub (traceparent, etc.) | NULL |
processed | boolean | NOT NULL default false | |
retries | int | NOT NULL default 0 | |
next_process_at | timestamptz | Backoff exponencial interno | NOT NULL default now() |
instance | varchar(120) | Pod/instancia que lo procesara | NULL |
created_at | timestamptz | NOT NULL default now() | |
processed_at | timestamptz | NULL |
Indices:
idx_outbox_pending(processed, next_process_at, id)para el polling del publisher.idx_outbox_request(request_id, created_at).idx_outbox_event_id(event_id).
Tabla processed_event
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Idempotent Consumer - registro de eventos ya procesados por worker. | event_id uuid | processed_at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
event_id | uuid | PK del evento Pub/Sub | PRIMARY KEY |
request_id | uuid | FK al request | NOT NULL |
topic | varchar(120) | NOT NULL | |
consumer_instance | varchar(120) | NULL | |
outcome | varchar(32) | CREATED / FAILED / SKIPPED etc. | NULL |
processed_at | timestamptz | NOT NULL default now() |
Indices: idx_pe_request(request_id).
Tabla audit_event
| Propósito | Llave primaria | Audit fields |
|---|---|---|
| Registro inmutable de acciones relevantes (requests, reintentos, cambios de reglas, configuraciones). | id bigserial | at |
Campos:
| Campo | Tipo | Descripción | Constraints |
|---|---|---|---|
id | bigserial | PK | PRIMARY KEY |
request_id | uuid | NULL | |
rule_id | uuid | NULL | |
partner_id | varchar(64) | NULL | |
user_id | varchar(120) | Usuario o service account | NOT NULL |
component | varchar(64) | PO_API CONFIG_API WORKER OPERATOR etc. | NOT NULL |
event_code | varchar(64) | REQUEST_RECEIVED RULE_UPDATED RETRY_REQUESTED etc. | NOT NULL |
metadata | jsonb | NULL | |
at | timestamptz | NOT NULL default now() |
Indices: idx_ae_request(request_id, at), idx_ae_rule(rule_id, at), idx_ae_event(event_code, at).
Triggers y convenciones
- Todas las tablas con
updated_atdeben llevar un triggerBEFORE UPDATEque seteaupdated_at = now(). purchase_order_requestytransaction_status_historydeben ser particionables porcreated_at(mensual o semanal) cuando la volumetria lo requiera.outbox_eventyprocessed_eventcon TTL retention (TBD según política operativa), se recomiendan particiones por fecha.