Appearance
Entity: organisation
Entity Type: Database table
Description: A legal entity or natural person associated with a client (a subject, Czech subjekt). The organisation registry is the single source of truth for subject data referenced across buildings (as owner, manager, delegated manager) and gauges (as subscriber). Every client is itself the first organisation in its own registry. Corresponds to Person in the Data Model high-level overview.
Schema placement decision (2026-07-28). The organisation table is tenant-side — it lives in the tenant application schema and mirrors the building/gauge template (tenant_id NOT NULL + row-level security policy). The former clientId attribute has been removed from the model: it is derivable via tenant.client_id (client : tenant = 1 : 0..1), so a stored column would be redundant. This executes the rewrite agreed in the client/tenant relationship decision of 2026-06-25. API routes are top-level /v1/organisations within the tenant context, not nested under /v1/clients/:id.
Invoicing attributes — type finalisation pending. The fields invoicePaymentMethod and invoiceDeliveryMethod are stored as plain strings in v1. Their allowed values (e.g. bankTransfer, email, dataBox) will be formalised as enums in the Invoicing feature epic. Until then, treat them as free-text fields with no application-layer validation beyond non-empty. Implement as VARCHAR — no migration will be required when the Invoicing epic converts them to enum columns.
Data Attributes Table
| Attribute Name | Description | Data Type | Default Value | Required (= Nullable) | Unique | Format | Validations | Index | Example |
|---|---|---|---|---|---|---|---|---|---|
| id | Primary key. | UUID | Generated in code (app layer) | Yes | Yes | UUID v7 | - | Primary Key | 018ed0b3-c298-7c7a-96d5-8b36f5a7f8d2 |
| tenantId | Tenant this record belongs to. | UUID | - | Yes | No | UUID v7 | Foreign Key → tenant; must exist | name: idx_organisation_tenantId, type: btree | 018fa51f-fda1-79f4-8461-2cb8f1cabc10 |
| name | Official name of the organisation or full name of the natural person. | String | - | Yes | No | - | Non-empty; max 255 chars. | name: idx_organisation_name, type: btree | Stavební s.r.o. |
| ico | Czech company tax ID (IČO). Null for natural persons without IČO. | String | - | No | No | 8-digit string | Nullable; if set must be 8 digits. | - | 27082440 |
| dic | VAT number (DIČ). | String | - | No | No | - | Nullable. | - | CZ27082440 |
| legalForm | Legal form of the organisation (e.g. s.r.o., a.s., fyzická osoba). | String | - | No | No | - | Nullable. | - | s.r.o. |
| pxeIdentifier | PXE exchange identifier (energy market). | String | - | No | No | - | Nullable. | - | PXE-12345 |
| dataBoxId | Czech data box ID (datová schránka). | String | - | No | No | - | Nullable. | - | ab3cd4e |
| isSelf | Marks the one organisation row, per tenant, that represents the tenant's own client. | Boolean | false | Yes | No | - | At most one true row per tenant (partial unique index, active rows only). Never writable through any DTO — create-only, set only by tenant provisioning. | name: uq_organisation_self, type: unique btree (partial: WHERE isSelf = true AND deletedAt IS NULL) | false |
| The subject's own e-mail (e.g. info@…), independent of the contact-person users. | String | - | No | No | Nullable; max 254 chars; valid e-mail format. | - | info@stavebni.cz | ||
| registeredStreet | Registered address — street and house number. | String | - | No | No | - | Nullable. | - | Náměstí Svobody 8 |
| registeredCity | Registered address — city. | String | - | No | No | - | Nullable. | - | Brno |
| registeredZip | Registered address — postal code. | String | - | No | No | - | Nullable. | - | 602 00 |
| billingAddressSameAsRegistered | When true, billing address equals the registered address. | Boolean | true | Yes | No | - | - | - | true |
| billingStreet | Billing address — street and house number. Used only when billingAddressSameAsRegistered = false. | String | - | No | No | - | Nullable. | - | Poštovská 3 |
| billingCity | Billing address — city. | String | - | No | No | - | Nullable. | - | Brno |
| billingZip | Billing address — postal code. | String | - | No | No | - | Nullable. | - | 602 00 |
| bankAccount | Bank account number for invoicing. | String | - | No | No | - | Nullable. | - | 123456789/0800 |
| invoicePaymentTermDays | Standard payment term in days for invoices issued to this organisation. | Integer | - | No | No | - | Nullable; positive integer. | - | 30 |
| invoicePaymentMethod | Preferred payment method. Stored as free text in v1 — will be converted to an enum in the Invoicing feature epic. See panel note above. | String | - | No | No | - | Nullable. | - | bankTransfer |
| invoiceDeliveryMethod | How invoices are delivered. Stored as free text in v1 — will be converted to an enum in the Invoicing feature epic. See panel note above. | String | - | No | No | - | Nullable. | - | |
| contactEnmsUserId | User acting as EnMS contact for this organisation. | UUID | - | No | No | UUID v7 | No database foreign key exists; validated at the application layer only (plain nullable UUID). | - | 018ed0b3-c298-7c7a-96d5-8b36f5a7f8d2 |
| contactBillingUserId | User acting as billing contact for this organisation. | UUID | - | No | No | UUID v7 | No database foreign key exists; validated at the application layer only (plain nullable UUID). | - | 018ed0b3-c298-7c7a-96d5-8b36f5a7f8d2 |
| contactTechnicalUserId | User acting as technical contact for this organisation. | UUID | - | No | No | UUID v7 | No database foreign key exists; validated at the application layer only (plain nullable UUID). | - | 018ed0b3-c298-7c7a-96d5-8b36f5a7f8d2 |
| contactRegulatoryUserId | User acting as regulatory contact for this organisation. | UUID | - | No | No | UUID v7 | No database foreign key exists; validated at the application layer only (plain nullable UUID). | - | 018ed0b3-c298-7c7a-96d5-8b36f5a7f8d2 |
| createdAt | Timestamp of when the record was created. Immutable after insert. | Timestamp with time zone | now() — set in code | Yes | No | ISO 8601 — YYYY-MM-DDTHH:mm:ss.SSSZ | Cannot be null; cannot be modified after creation. | - | 2025-03-16T18:00:00Z |
| updatedAt | Timestamp of the last update to the record. | Timestamp with time zone | now() — set in code | Yes | No | ISO 8601 — YYYY-MM-DDTHH:mm:ss.SSSZ | Cannot be null. | - | 2025-03-16T18:00:00Z |
| deletedAt | Timestamp of soft deletion. Null means the record is active. Once set, immutable. | Timestamp with time zone | - | No | No | ISO 8601 — YYYY-MM-DDTHH:mm:ss.SSSZ | Immutable once set. Active records: WHERE deletedAt IS NULL | - | 2025-06-01T09:00:00Z |
| createdBy | Identifier of the actor who created the record. | String | - | Yes | No | type:actor | Non-empty. | - | user:018ed0b3-c298-7c7a-96d5-8b36f5a7f8d2 |
| updatedBy | Identifier of the actor who last updated the record. | String | - | Yes | No | type:actor | Non-empty. | - | system:migration-v25 |
Deferred attributes
Attributes that are not part of the v1 implementation. Retained here for documentation purposes, as on the source page.
| Attribute Name | Description | Data Type | Example | Reason to defer | Notes |
|---|---|---|---|---|---|
| roleAtClient | Primary role of this organisation in relation to the client (free text label). | String | Správce nemovitostí | Replaced by derived roles. | Not stored. The roles are derived from live references (owner, manager, delegated manager, subscriber) and isSelf — see Organisation & Distribution Registry. |
| clientId | Client this organisation belongs to (was: UUID, required, FK → client, idx_organisation_clientId). | UUID | 018fa51f-fda1-79f4-8461-2cb8f1cabc10 | Removed by the schema-placement decision (2026-07-28). | Derivable via tenant.client_id (client : tenant = 1 : 0..1) — a stored column would be redundant. See the schema placement decision panel above. |
Audited fields
Recorded on created (in full), updated (changed only) and deleted (in full): name, ico, dic, legalForm, pxeIdentifier, dataBoxId, isSelf, email, registeredStreet, registeredCity, registeredZip, billingAddressSameAsRegistered, billingStreet, billingCity, billingZip, bankAccount, invoicePaymentTermDays, invoicePaymentMethod, invoiceDeliveryMethod, contactEnmsUserId, contactBillingUserId, contactTechnicalUserId, contactRegulatoryUserId.
Excluded: none.
isSelf is create-only — absent from every update path, so it appears in a created entry but never in an updated entry's changed fields.
A reference to an organisation from building (ownerId/managerId/delegatedManagerId) or from gauge (subscriberId/supplierOrganisationId) is recorded only as a changed field on that referencing entity's own entry — never as a subject pin here. organisation's own history shows only its own row's changes.
Correction: the four contact-user-id rows above previously claimed an enforced foreign key with onDelete SET NULL; no such constraint exists in the database — corrected to plain application-validated UUIDs.
Registered for entityName resolution — resolves to name (architecture 61-audit-log.md §7.4 in the code repo).