Appearance
Entity: volumeCoefficient
Entity Type: Database table
Description: A versioned multiplier that corrects what a gauge reports into the quantity it actually measured — a pulse weight, a transformer ratio, or a correction for a meter's rated against actual throughput. It is a property of the meter and its installation, taken from the protocol or the installation certificate.
It is applied to the gauge's readings before consumption is written. It does not convert one quantity into another: turning a volume of fuel into energy is a property of the fuel, not of the meter, and is stated as a calorificValue.
Two histories per gauge. A gauge read both by hand and remotely can need different correction for each, because the two paths deliver the value differently — the legacy system kept exactly this separation in two tables. readingSource says which series a row corrects, and each series has its own independent validity history.
Records are append-only: no row is updated or deleted after creation. A row entered in error is voided (isVoided), which excludes it from every calculation while keeping it visible; the corrected value is written as a new row.
Data Attributes Table
| Attribute Name | Description | Data Type | Default Value | Required (= Nullable) | Unique | Format | Validations | Index | Example |
|---|---|---|---|---|---|---|---|---|---|
| id | Primary key of the entity. | UUID | Generated in code (app layer) | Yes | Yes | UUID v7 | - | Primary Key | 018f9c4d-2c11-7a3e-9b77-4f0d3a5e6b61 |
| tenantId | Tenant this record belongs to. | UUID | - | Yes | No | UUID v7 | Foreign Key → tenant; must exist | name: idx_volume_coefficient_tenantId, type: btree | 018fa51f-fda1-79f4-8461-2cb8f1cabc10 |
| gaugeId | The gauge this coefficient applies to. | UUID | - | Yes | Part of composite unique | UUID v7 | Foreign Key → gauge; must exist | Part of the unique index below | 018f6e2a-… |
| readingSource | Which reading series this coefficient corrects: values entered by hand, or values delivered by a remote connection. Each has its own history for the same gauge. | Enum | - | Yes | Part of composite unique | Enum - ReadingSource | Only manual and remote are valid: an invoiced quantity is already a quantity, and a calculated value is derived from corrected ones. | Part of the unique index below | remote |
| validFrom | The date from which this coefficient applies. It applies to every consumption computed on or after this date, up to the next non-voided row for the same gauge and reading source. | Date | - | Yes | Part of composite unique | YYYY-MM-DD | Unique per (gaugeId, readingSource, validFrom) among non-voided rows. | Part of the unique index below | 2024-01-01 |
| value | The multiplier applied to the raw value before consumption is stored. | Decimal | - | Yes | No | numeric(10,6) | Must be > 0. | - | 1.023400 |
| note | Free-text explanation of why the coefficient was set to this value. | String | null | No | No | - | Max 500 characters. | - | Protokol o výměně měřidla 2024-03 |
| isVoided | Marks a row entered in error. A voided row is ignored by every calculation and is never physically deleted. | Boolean | false | Yes | No | - | Once true, cannot be set back to false. | - | false |
| voidedAt | When the row was voided. | Timestamp with time zone | null | No | No | ISO 8601 — YYYY-MM-DDTHH:mm:ss.SSSZ | Must be set when isVoided is true and null otherwise. | - | null |
| voidedBy | Actor who voided the row. | String | null | No | No | type:actor | Must be set when isVoided is true and null otherwise. | - | null |
| legacyId | Identifier of the row this one was migrated from. | String | null | No | No | - | - | - | 48213 |
| legacySource | Which legacy table the row came from, which is how the two histories are reconstructed on migration. | String | null | No | No | - | One of the legacy coefficient tables. | - | gauge_volume_ratio |
| createdAt | Timestamp of record creation. | Timestamp with time zone | now() — set in code | Yes | No | ISO 8601 — YYYY-MM-DDTHH:mm:ss.SSSZ | Cannot be null. | - | 2024-03-01T08:00:00Z |
| updatedAt | Timestamp of the last update. | Timestamp with time zone | now() — set in code | Yes | No | ISO 8601 — YYYY-MM-DDTHH:mm:ss.SSSZ | Cannot be null. | - | 2024-03-01T08:00:00Z |
| createdBy | Actor who created the record. | String | - | Yes | No | type:actor | Non-empty. | - | user:018ed0b3-… |
| updatedBy | Actor who last updated the record. | String | - | Yes | No | type:actor | Non-empty. | - | user:018ed0b3-… |
Indexes
| Name | Columns | Type | Why |
|---|---|---|---|
uq_volume_coefficient_valid_from | tenantId, gaugeId, readingSource, validFrom where isVoided is false | Unique, partial | One coefficient per gauge, series and start date; a voided row must not block re-entering the same date. |
idx_volume_coefficient_tenantId | tenantId | btree | Tenant predicate. |
Soft deletion
This entity has no deletedAt. Its append-only pattern uses isVoided / voidedAt / voidedBy instead, because a coefficient is never removed — it is superseded, and the superseded value is still what reproduces the consumption it produced.
Audited fields
Recorded on created (in full) and on voiding (in full): gaugeId, readingSource, validFrom, value, note, isVoided.
Excluded: legacyId and legacySource — migration provenance, set once by the migration and never changed by a user.
Not registered for entityName resolution, and has no independent human-readable attribute to register — identified by its gaugeId/readingSource/validFrom scope.