Write Operations
Write Operations
Relevant source files
The following files were used as context for generating this wiki page:
The Repository class provides a set of methods for single-row modifications. These operations are designed with a "safety-first" philosophy, featuring automatic audit stamping, version incrementing, and mandatory RETURNING * hydration to ensure the JavaScript entity remains synchronized with the database state.
Overview of Write Lifecycle
Every write operation in the DAL follows a structured lifecycle to maintain data integrity and auditability:
- Metadata Resolution: The system inspects the
@Entityfor primary keys and auditable fields src/repository/repository.ts:159-161. - Actor Stamping: If the entity is auditable, the
actorprovided inAuditableWriteOptionsis applied tocreated_byorupdated_bysrc/repository/repository.ts:316-324. - SQL Generation: Parameterized SQL is built, targeting either the primary key or a specific column defined by
matchBysrc/repository/repository.ts:100-116. - Execution & Hydration: The query is executed with
RETURNING *, and the resulting row is hydrated back into the JS entity type src/repository/repository.ts:281-285. - Audit Dispatch: If an
AuditPortis configured, a delta is calculated and the audit event is fired src/repository/repository.ts:335-343.
Data Flow: Single-Row Write
The following diagram illustrates how a write request flows from the Repository through metadata resolution to SQL execution.
Write Operation Flow
Code
Sources: src/repository/repository.ts:148-150, src/repository/repository.ts:95-116, src/repository/repository.ts:335-343, src/meta/entity-meta.ts:60-65
Core Write Methods
add (Insert)
Inserts a new record. It automatically handles uuid generation (if defined), version initialization to 1, and audit stamping for created_by and updated_by.
- Logic: Validates that at least one column is being inserted src/repository/repository.ts:273-275.
- Audit: Stamps
created_at,updated_at,created_by, andupdated_byif the entity supports them src/repository/repository.ts:316-324.
update (Update by Key)
Updates a record by matching a specific column (defaulting to the @Key).
- Match Logic: Uses
matchByfromMatchByOptionsto determine theWHEREclause. The match value is extracted from the update object and removed from theSETclause src/repository/repository.ts:122-135. - Concurrency: Automatically increments the
versioncolumn if present src/repository/repository.ts:468-470. - Audit: Calculates a delta between the old and new record and dispatches it to the
AuditPortsrc/repository/repository.ts:494-502.
upsert (Insert on Conflict)
Performs an INSERT ... ON CONFLICT operation.
- Conflict Target: Uses the primary key as the conflict target src/repository/repository.ts:384-386.
- Behavior: If a conflict occurs, it updates the existing record, increments the version, and updates the
updated_by/updated_atfields src/repository/repository.ts:405-410.
delete and restore (Soft-Delete)
The DAL favors soft-deletion over physical deletion for auditable entities.
- delete: Sets
deleted_atto the current timestamp anddeleted_byto the provided actor src/repository/repository.ts:553-561. - restore: Reverses a soft-delete by setting
deleted_atanddeleted_byback tonullsrc/repository/repository.ts:603-608.
hardDelete (Physical Delete)
Performs a physical DELETE FROM query. This is irreversible and should be used with caution src/repository/repository.ts:646-654.
Sources: src/repository/repository.ts:264-353, src/repository/repository.ts:370-435, src/repository/repository.ts:446-519, src/repository/repository.ts:532-583, src/repository/repository.ts:594-633, src/repository/repository.ts:646-668
Code Entity Mapping
This diagram maps natural language operations to the specific internal functions and classes responsible for executing them.
Entity Mapping: Natural Language to Code
Code
Sources: src/repository/repository.ts:148-150, src/repository/repository.ts:95-116, src/repository/repository.ts:53-64, src/meta/entity-decorators.ts:74-84
Write Options and Auditing
AuditableWriteOptions
All write methods accept an options object extending AuditableWriteOptions.
| Option | Type | Description |
|---|---|---|
actor | string | Required. The identity of the user/system performing the write. |
auditPort | AuditPort | Optional override for the global audit port. |
matchBy | string | For updates/deletes: specify which property to use in the WHERE clause. |
Delta Calculation
When an update occurs, the Repository uses calculateDelta to compare the oldEntity (fetched via the RETURNING clause or prior state) with the newEntity src/repository/repository.ts:53-64.
Code
Sources: src/repository/repository.ts:53-64, src/types/types.ts:106-115
Error Handling in Writes
Write operations may throw the following DAL-specific errors:
NotFoundError: Thrown duringupdateordeleteif thematchBycriteria finds no rows src/repository/repository.ts:485-487.ValidationError: Thrown if anaddoperation contains no columns or if amatchByvalue is missing src/repository/repository.ts:274-276, src/repository/repository.ts:128-131.UnknownColumnError: Thrown if thematchByproperty does not exist on the entity src/repository/repository.ts:103-105.
Sources: src/errors/errors.ts:1-25, src/repository/repository.ts:100-116