invoice_payment_means records root with composites into payment-means summary and invoice totals.
Read access today: this object is readable via the universal
POST /v1/records/query endpoint with root: "invoice_payment_means". A dedicated GET /v1/invoice-payment-means endpoint is Planned.API operations
Data model
Attributes
Relationships
System-computed
- id is generated via gen_random_uuid() PostgreSQL function, set as the column defaultRaw in the MikroORM entity definition. It is unique and stable for the lifetime of the row, including after soft-delete.
- created_at is set exactly once on INSERT via MikroORM onCreate: () => new Date(). It is never updated after creation.
- updated_at is set on INSERT (onCreate: () => new Date()) and refreshed on every UPDATE (onUpdate: () => new Date()). Because onCreate is present, updated_at is never null after row creation; the column is declared nullable in the DDL (timestamptz null) to allow the optional TypeScript type, but the onCreate hook ensures it is populated on insert.
- deleted_at is null on active rows. Setting it to a non-null timestamp constitutes a soft-delete. Hard DELETE is never used; the junction row is retained for audit and historical query purposes. The partial index idx_invoice_payment_means_invoice_active (WHERE deleted_at IS NULL) is maintained to optimize hot Hasura array_relationship traversals on the invoice_pk column while excluding soft-deleted rows from the index.
- Three indexes are maintained on the table: idx_invoice_payment_means_invoice (invoice_pk, full) and idx_invoice_payment_means_payment_means (payment_means_pk, full) were added in Migration20260415150000_invoice_payment_means_and_transactions_indexes. The partial index idx_invoice_payment_means_invoice_active (invoice_pk, WHERE deleted_at IS NULL) was added later in Migration20260506140000_perf_indexes_round7 during a hot-path performance round. All three are declared via @Index decorators on the entity class.
- The entity is a pure junction table with no workspace_pk column of its own. Tenant isolation is enforced transitively: Hasura RLS on the invoice or payment_means parent tables scopes access, and application-layer queries always join through the parent entity carrying the workspace predicate.
- The entity has no workspace-direct FK by design (it is scoped through its Invoice parent). It is registered in allEntities in database/entities/index.ts.
- The records root invoice_payment_means exposes composites via composites.yml: invoice.composite_total_amount_currency (display_type: currency_amount, source_fields: invoice.invoice_id, invoice.grand_total, invoice.local_currency) and payment_means.composite_payment_means_summary (display_type: payment_means_summary) and payment_means.company.composite_logo_name (display_type: company_logo_name). These composites are read-only, pipeline-resolved at query time by the composite-reconstructor.
Example
apps/api/src/database/entities/InvoicePaymentMeans.ts · domain: financial-graph · tier: Supporting