06 — Backend Use Cases
The backend should be organized around use cases rather than generic repositories.
Use Drizzle directly inside services and use-case functions to keep native type inference, autocomplete, SQL composition, and transaction support.
Suggested Module Structure
text
apps/backend/src/modules/entity-platform-admin/
├── model-versions.routes.ts
├── model-versions.service.ts
├── model-validation.service.ts
├── model-publishing.service.ts
│
├── entity-types/
│ ├── entity-types.routes.ts
│ ├── create-entity-type.ts
│ ├── update-entity-type.ts
│ ├── delete-entity-type.ts
│ └── clone-entity-types-to-draft.ts
│
├── properties/
│ ├── property-groups.routes.ts
│ ├── property-definitions.routes.ts
│ ├── create-property-definition.ts
│ ├── update-property-definition.ts
│ └── delete-property-definition.ts
│
├── relationships/
│ ├── relationship-definitions.routes.ts
│ ├── create-relationship-definition.ts
│ ├── update-relationship-definition.ts
│ └── delete-relationship-definition.ts
│
├── templates/
│ ├── templates.routes.ts
│ ├── create-template.ts
│ ├── update-template.ts
│ └── delete-template.ts
│
├── runtime/
│ ├── runtime-entities.routes.ts
│ ├── create-runtime-entity.ts
│ ├── update-runtime-entity.ts
│ ├── set-runtime-property.ts
│ ├── add-runtime-relationship.ts
│ └── delete-runtime-entity.ts
│
└── shared/
├── assert-draft-model.ts
├── assert-published-model.ts
├── assert-model-admin-permission.ts
├── resolve-published-model.ts
├── validate-property-value.ts
└── audit-model-event.tsUse Case: Create Draft Model
Purpose:
Create a draft model from the current published model or from an empty baseline.
Steps:
- Check
model.adminpermission. - Ensure there is not already an active draft unless multiple drafts are explicitly supported.
- Create
entity_model_versionsrow with statusdraft. - Clone published metadata into the draft, or create empty baseline metadata.
- Write audit event.
- Return draft summary.
Use Case: Create Entity Type
Steps:
- Check model admin permission.
- Verify target model version exists and is draft.
- Validate key format.
- Ensure key is unique in draft.
- Insert entity type definition.
- Optionally insert hierarchy rules.
- Write audit event.
- Return DTO.
Use Case: Create Property Definition
Steps:
- Check model admin permission.
- Verify model version is draft.
- Verify property group exists in same model version.
- Validate property key and value type.
- Validate value-type-specific validation JSON.
- Insert property definition.
- Write audit event.
- Return DTO.
Use Case: Publish Model
Publishing must be transactional.
Steps:
- Check
model.publishpermission. - Load draft metadata.
- Run full validation.
- Run compatibility analysis against runtime data.
- Require approval for destructive changes.
- Mark existing published model as archived.
- Mark draft as published.
- Write audit event.
- Invalidate model metadata caches.
- Return published model version.
Use Case: Create Runtime Entity
Steps:
- Resolve published model version.
- Resolve entity type by key.
- Check user permission and root scope.
- Validate parent rules.
- Generate entity id and path label.
- Build
ltreepath. - Validate template if provided.
- Validate property values against property definitions.
- Validate tag assignments.
- Insert entity row.
- Insert property values.
- Insert tag assignments.
- Write audit event.
- Return entity DTO.
Use Case: Update Runtime Property
Steps:
- Resolve entity.
- Check user root scope and capability.
- Resolve published property definition by key.
- Verify property is allowed for entity type.
- Validate value.
- If sensitive, route to Vault instead of property value table.
- Upsert value.
- Write audit event.
- Return updated property value.
Use Case: Add Runtime Relationship
Steps:
- Resolve source and target entities.
- Check root scope for source and target.
- Resolve relationship definition.
- Verify source type and target type match definition.
- Enforce cardinality.
- Enforce self-reference rules.
- Insert relationship.
- Write audit event.
- Return relationship DTO.
Invariants
These rules should be enforced consistently:
- Published model versions are immutable.
- Runtime CRUD uses only the current published model.
- Draft metadata never affects runtime CRUD.
- Entity hierarchy is not stored in relationship definitions.
- Sensitive values are not stored as normal property values.
- Root-scope authorization applies before runtime reads and writes.
- Deletions are soft by default.
- Destructive metadata changes require compatibility checks.
Caching
The published model should be cached in memory for fast validation.
Cache invalidation should occur on publish.
Do not cache drafts aggressively unless needed.