Company invitation
Purpose
TBD by human
Identity & key fields
- Primary key:
id(uuid, defaultgen_random_uuid()). code(text, NOT NULL, default'') — the share token sent in the invite link.expire(timestamp, NOT NULL).email(text, NOT NULL) — invitee’s email.use(boolean, defaultfalse) — flag set when invitation is consumed.usedBy(nullable uuid, FK →users.users.id) — the platform user who accepted.declinedAt(nullable timestamp).role(enumcompany_member_invitation_roles:ADMIN,MANAGER,COACH, defaultMANAGER).inviterId(uuid, NOT NULL, FK →users.users.id).companyId(uuid, NOT NULL, FK →companies.company.id, on-delete cascade).
business meaning: TBD by human
Invariants
companyIdON DELETE CASCADE (enforced in tktspace-backend/libs/shared/data-access-db/src/lib/schema/companies.schema.ts).code,expire,email,use,role,inviterId,companyIdNOT NULL (enforced in tktspace-backend/libs/shared/data-access-db/src/lib/schema/companies.schema.ts).usedByFK has no on-delete clause declared (NO ACTION default) (enforced in tktspace-backend/libs/shared/data-access-db/src/lib/schema/companies.schema.ts).- The role enum here is a strict subset of
company_member_roles— it intentionally excludesOWNER(enforced in tktspace-backend/libs/shared/data-access-db/src/lib/schema/companies.schema.ts).
business invariants: TBD by human
Lifecycle
No status column — derived from (use, declinedAt, expire) triple at read time. transitions: TBD by human
Relationships
- Company (ENT-016) —
companyId→companies.company.id, on-delete cascade. N:1. - User (inviter) (ENT-021) —
inviterId→users.users.id. N:1. - User (accepted by) (ENT-021) —
usedBy→users.users.id. N:1, optional. - On acceptance, a Company member row is created — application-side, no DB-level FK between these tables.
API surfaces
| Surface | Exposed | Notes |
|---|---|---|
| client | no | — |
| business | inferred yes — managed via libs/features/companies/src/lib/companies-admin.module.ts; no dedicated Invitation* DTO visible in business.openapi.yaml audit extract | Swagger UI |
| super-admin | no | — |
Known gotchas / open questions
codedefaults to empty string''rather than NULL — non-default code values must be generated by the application.OWNERrole is intentionally not invitable (enum subset).- OPEN: is there a uniqueness constraint per
(companyId, email)for active invitations? Not enforced at DB level.