PrimeBrickPrimeBrick
  • Docs
  • Contact
  • MIT License
  • Documentation
  • MCP Server
  • API Catalog
  • Services
  • Libraries
PrimeBrickPrimeBrick

© 2026 PrimeBrick. MIT License. v3.8.0

github
DAL Library
    Getting startedArchitectureEntities & decoratorsQuery DSLRepositoryConnections & transactionsAudit trailOptimistic Locking & ConcurrencyCloneChangelogAPI reference
SDK Library
powered by Zudoku
DAL Library

Clone

Repository.clone() copies an entity record by UUID. It fetches the source record (including soft-deleted rows), builds a new row, and inserts it with a fresh UUID.

How it works

The clone operation:

  1. Fetches the source record by UUID (including soft-deleted rows).
  2. Excludes the PK column (DB auto-generates) and all @Unique columns (including uuid — a new UUID is generated).
  3. Sets the @CloneField column to the source UUID (so the clone knows its origin).
  4. Resets audit fields: created_at = now, created_by = actor, updated_at = now, updated_by = actor, version = 1.
  5. Resets deletable fields: deleted_at = null, deleted_by = null.
  6. Copies all other fields from the source.
  7. Inserts the new row with RETURNING *.

No audit log is written for the clone itself (matches backend behavior — clone does not audit).

Use cases

  • Template-based record creation — clone a "template" customer with pre-filled defaults, then edit the clone.
  • Duplicate-and-edit — let a user copy an existing record instead of re-typing all fields.
  • Soft-delete recovery — clone a soft-deleted record (the clone fetches soft-deleted rows too) to restore its data into a fresh, live row.
  • Branching workflows — clone a record before applying a risky change so the original is preserved.

Usage

The entity must implement IAuditableEntity and IClonableEntity, and have at least one @CloneField column:

Code
import { Entity, Column, Key, Unique, AuditableField, DeletableField, CloneField } from "@primebrick/dal-pg"; import type { IAuditableEntity, IDeletableEntity, IClonableEntity } from "@primebrick/dal-pg"; @Entity("customers") export class CustomerEntity implements IAuditableEntity, IDeletableEntity, IClonableEntity { @Key() @Column({ pgType: "bigint" }) id!: bigint; @Unique() @Column({ pgType: "uuid" }) uuid!: string; @Column({ pgType: "text" }) name!: string; @Column({ pgType: "text" }) email!: string; @AuditableField({ type: "createdAt" }) @Column({ pgType: "timestamptz" }) created_at!: Date; @AuditableField({ type: "createdBy" }) @Column({ pgType: "text" }) created_by!: string; @AuditableField({ type: "updatedAt" }) @Column({ pgType: "timestamptz" }) updated_at!: Date; @AuditableField({ type: "updatedBy" }) @Column({ pgType: "text" }) updated_by!: string; @AuditableField({ type: "version" }) @Column({ pgType: "integer" }) version!: number; @DeletableField({ type: "deletedAt" }) @Column({ pgType: "timestamptz", nullable: true }) deleted_at!: Date | null; @DeletableField({ type: "deletedBy" }) @Column({ pgType: "text", nullable: true }) deleted_by!: string | null; @CloneField() @Column({ pgType: "uuid", nullable: true }) cloned_from!: string | null; }
Code
import { Repository } from "@primebrick/dal-pg"; const repo = new Repository(pool); const cloned = await repo.clone( CustomerEntity, sourceCustomerUuid, { actor: userUuid }, ); // cloned is a full CustomerEntity with: // - new id (auto-generated) // - new uuid (randomUUID()) // - cloned_from = sourceCustomerUuid // - created_at/updated_at = now, created_by/updated_by = userUuid // - version = 1 // - deleted_at/deleted_by = null // - name, email copied from source

Signature

Code
repo.clone<TEntity>( entity: EntityClass & { new (): TEntity }, sourceUuid: string, options: AuditableWriteOptions, ): Promise<TEntity>

AuditableWriteOptions requires an actor (the UUID of the user performing the clone). The audit and logger options are accepted but no audit log is written for the clone operation itself.

Errors

  • NotFoundError — no record found with the given sourceUuid.
  • Error — the entity has no uuid column (no @Unique column found).
  • Error — the INSERT returned no rows (clone failed).

Error handling with try/catch

Code
import { NotFoundError } from "@primebrick/dal-pg"; async function cloneCustomer(sourceUuid: string, actor: string) { try { const cloned = await dal.clone(CustomerEntity, sourceUuid, { actor }); return cloned; } catch (err) { if (err instanceof NotFoundError) { // err.code === "NOT_FOUND" — the source UUID doesn't exist throw new Error(`Cannot clone: customer ${sourceUuid} not found`); } // UnknownColumnError, ValidationError, etc. — rethrow for the boundary to map throw err; } }

Next steps

  • Audit trail — automatic field-level audit logging for write operations.
  • Optimistic locking — the version guard on auditable writes.
  • Repository — the full write API.
  • Entities & decorators — the @CloneField decorator and IClonableEntity interface.
Last modified on July 26, 2026
Optimistic Locking & ConcurrencyChangelog
On this page
  • How it works
  • Use cases
  • Usage
  • Signature
  • Errors
    • Error handling with try/catch
  • Next steps
TypeScript
TypeScript
TypeScript
TypeScript