Appearance
Entity: clientGroupMembership
Entity Definition
- Entity Name:
clientGroupMembership - Entity Type: Database table, platform schema (
platform.client_group_membership) - Description: The many-to-many link between client and clientGroup — a client may belong to zero, one, or several client groups, and a group holds zero or more clients up to its own
maxClientCount.clientIdreferencesplatform.clients— the platform account entity (identity, licence, modules) — not a tenant-schema record; see the scope note on clientGroup. - Not tenant data. Platform schema, no
tenantId— the same reasoning asclientGroupitself.
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 | 018fa51f-fda1-79f4-8461-2cb8f1cabc21 |
| clientId | The client that is a member of the group. | UUID | - | Yes | No | UUID v7 | Foreign Key → client (platform.clients); must exist | name: idx_client_group_membership_client_group, type: btree (composite with clientGroupId, active records) | 018fa51f-fda1-79f4-8461-2cb8f1cabc10 |
| clientGroupId | The client group the client belongs to. | UUID | - | Yes | No | UUID v7 | Foreign Key → clientGroup; must exist | name: idx_client_group_membership_client_group, type: btree (composite with clientId, active records) | 018fa51f-fda1-79f4-8461-2cb8f1cabc20 |
| createdAt | Timestamp of when the record was created. Immutable after insert. | Timestamp with time zone | now() — set in code | Yes | No | ISO 8601 | Cannot be null; cannot be modified after creation. | - | 2026-09-16T00:00:00Z |
| updatedAt | Timestamp of the last update. Set on insert (equal to createdAt); this record is never otherwise updated — a membership is either active or ended, never edited in place. | Timestamp with time zone | now() — set in code | Yes | No | ISO 8601 | Cannot be null. | - | 2026-09-16T00:00:00Z |
| deletedAt | Timestamp of soft deletion, i.e. the client left the group. Null means the record is active. Once set, immutable. | Timestamp with time zone | - | No | No | ISO 8601 | Immutable once set. Active records: WHERE deletedAt IS NULL | Indexed (active records) | - |
| createdBy | Identifier of the actor who created the record. | String | - | Yes | No | type:actor | Non-empty. | - | user:018e... |
| updatedBy | Identifier of the actor who last updated the record. | String | - | Yes | No | type:actor | Non-empty. | - | user:018e... |
Uniqueness: (clientId, clientGroupId) is unique among active (non-deleted) records, enforced by unique index uidx_client_group_membership_client_client_group, type: btree — a client cannot be linked to the same client group twice at the same time. A client may re-join a group it previously left: that is a new row, not a revival of the old one.
Capacity guard: a new row is rejected with 409 ERR_CLIENT_GROUP_FULL when the group's active membership count already equals its maxClientCount — see Client Groups API-A.
Audited fields
Recorded (created/deleted: full set; updated: n/a — see the updatedAt note above, this entity has no in-place update): clientGroupId.
Filed under subject: clientId is not duplicated in this set — every entry sets the audit row's own subjectEntityType = "client" / subjectEntityId = clientId, so one client's full client-group membership history is a single indexed read.
Excluded:
id,createdAt,updatedAt,deletedAt,createdBy,updatedBy— redundant with the audit entry's ownentityId/createdAt/createdBy, which already identify the record and the write.clientId— filed as the audit row's subject reference instead (see above).
Not registered for entityName resolution — a link record has no natural display name of its own; the audit trail's subject reference (see above) is what a reader follows to the client (architecture 61-audit-log.md §7.4 in the code repo: a valid, permanent state, not a gap).