Skip to content
Updated Sep 26, 2026 by Barča Dvořáková · Owner: analysisactiveentity Edit on GitHub

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. clientId references platform.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 as clientGroup itself.

Data Attributes Table ​

Attribute NameDescriptionData TypeDefault ValueRequired (= Nullable)UniqueFormatValidationsIndexExample
idPrimary key of the entity.UUIDGenerated in code (app layer)YesYesUUID v7-Primary Key018fa51f-fda1-79f4-8461-2cb8f1cabc21
clientIdThe client that is a member of the group.UUID-YesNoUUID v7Foreign Key → client (platform.clients); must existname: idx_client_group_membership_client_group, type: btree (composite with clientGroupId, active records)018fa51f-fda1-79f4-8461-2cb8f1cabc10
clientGroupIdThe client group the client belongs to.UUID-YesNoUUID v7Foreign Key → clientGroup; must existname: idx_client_group_membership_client_group, type: btree (composite with clientId, active records)018fa51f-fda1-79f4-8461-2cb8f1cabc20
createdAtTimestamp of when the record was created. Immutable after insert.Timestamp with time zonenow() — set in codeYesNoISO 8601Cannot be null; cannot be modified after creation.-2026-09-16T00:00:00Z
updatedAtTimestamp 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 zonenow() — set in codeYesNoISO 8601Cannot be null.-2026-09-16T00:00:00Z
deletedAtTimestamp of soft deletion, i.e. the client left the group. Null means the record is active. Once set, immutable.Timestamp with time zone-NoNoISO 8601Immutable once set. Active records: WHERE deletedAt IS NULLIndexed (active records)-
createdByIdentifier of the actor who created the record.String-YesNotype:actorNon-empty.-user:018e...
updatedByIdentifier of the actor who last updated the record.String-YesNotype:actorNon-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 own entityId/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).