Data Model Conventions (Config & App Tables)
This document captures the platform contract for configuration and transactional tables. Individual tables may predate these rules; agents should migrate toward consistency when touching schema or APIs.
Standard identifier & lifecycle columns
Each app or config table should expose a common head:
| Column | Purpose |
|---|---|
| id | Surrogate primary key (integer or bigint as per table). |
| code | Stable business key for configuration rows (e.g. pgc_code, dv_code patterns in app usage). Human reference and URL-safe identifier. |
| description | Human-readable label / summary. |
| tenant_id | Tenant scope; mandatory for tenant-owned rows. |
| status | Active/inactive/draft/etc. (numeric or string per table legacy). |
| is_deleted | Soft delete flag (boolean or tinyint). Note: codebases sometimes use isDeleted in TypeScript — DB often is_deleted. |
JSON payload columns
Following the head, rows carry extensible payloads:
| Column | Typical content |
|---|---|
config or *_config | Primary configuration JSON: layout, columns, graph, bindings. |
audit or *_audit | Audit JSON: who/when/what changed, IP/client, correlation ids, approval steps. |
add_dtls or *_add_dtls | Additional structured metadata not yet promoted to first-class columns. |
Audit placement rule
- Do not add parallel
created_by,updated_by,created_at,updated_atcolumns on new tables if the standard is audit JSON. - Existing tables with legacy scalar audit columns should be documented in migrations; new work prefers JSON audit payloads for consistency across the low-code model.
Naming note: is_deleted vs isDeleted
- Database: conventionally
is_deleted. - API / frontend models: may camel-case. Entity layer should map consistently — verify in middleware entity serializers when changing shapes.
Registry & profile driven storage
Physical tables store rows, but behavior (which fields are visible, validations, operations) is driven by:
app_object_registries— registry object definition; key columnobj_codeidentifies that object in the registry (not the generic CRUD URL segment).app_object_profiles— operational profile over a registry object. Columnprf_codeis what the platform uses asentity_codein/api/entity/:entity_code/.... Columnprf_obj_codepoints at the parent registry row andprf_obj_code=obj_codethere.
Summary: prf_code = entity_code, prf_obj_code = obj_code, and obj_code ≠ prf_code.
Therefore, agents should assume field-level differences are often data-driven, not hardcoded per React component.
Transaction vs configuration
| Class | Examples | Lifespan |
|---|---|---|
| Configuration | Page layout, dataview definition, workflow definition | Versioned, deployed, cached. |
| Transaction | Order, ticket, approval instance | Created/updated frequently, workflow-attached. |
Both should still honor tenant_id + RBAC and prefer entity routes for CRUD.