core PK: id 10 required 1 unique

Description

Junction entity tracking which organizations a contact belongs to, supporting contacts who are registered across multiple local associations (up to 5 per NHF requirements). Enables organization-scoped contact visibility, duplicate-registration prevention, and primary-organization designation for routing and reporting.

12
Attributes
6
Indexes
7
Validation Rules
13
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key, globally unique membership record identifier
PKrequiredunique
contact_id uuid Foreign key referencing the contact who is a member of the organization
required
organization_id uuid Foreign key referencing the organization this contact belongs to
required
is_primary boolean Flags which organization is the contact's primary affiliation. Only one membership record per contact may be true at a time. Used to determine which org's coordinator has primary responsibility.
required
membership_type enum Characterizes the nature of the contact's relationship to the organization
required
status enum Lifecycle state of this membership record
required
enrolled_at datetime Timestamp when the contact was registered with this organization
required
unenrolled_at datetime Timestamp when the contact left or was removed from the organization. Null if still active.
-
enrolled_by uuid Foreign key to users table — the peer mentor or coordinator who registered this membership
required
notes text Optional free-text notes about the membership context (e.g. reason for transfer, cross-association coordination notes)
-
created_at datetime Record creation timestamp
required
updated_at datetime Record last modification timestamp
required

Database Indexes

idx_com_contact_id
btree

Columns: contact_id

idx_com_organization_id
btree

Columns: organization_id

idx_com_contact_org_unique
btree unique

Columns: contact_id, organization_id

idx_com_contact_primary
btree

Columns: contact_id, is_primary

idx_com_org_status
btree

Columns: organization_id, status

idx_com_enrolled_at
btree

Columns: enrolled_at

Validation Rules

valid_contact_reference error

Validation failed

valid_organization_reference error

Validation failed

valid_enrolled_by_reference error

Validation failed

unenrolled_at_after_enrolled_at error

Validation failed

membership_type_enum_constraint error

Validation failed

status_enum_constraint error

Validation failed

notes_max_length error

Validation failed

Business Rules

max_five_memberships_per_contact
on_create

A contact may belong to at most 5 organizations simultaneously. NHF requirement: contacts in multiple local associations must be bounded to prevent unbounded cross-org data sprawl.

single_primary_per_contact
on_create

Exactly one membership record per contact may have is_primary=true. Setting a new record as primary automatically demotes the previous primary to false. A contact with any memberships must always have exactly one primary.

org_scoped_read_access
always

A peer mentor or coordinator may only read membership records where organization_id matches their active organization context. Global Admins require a time-bounded support access flag to access org membership data.

soft_delete_on_transfer
on_update

When a contact transfers out of an organization, the membership status is set to transferred_out and unenrolled_at is stamped. The record is retained for audit and Bufdir reporting continuity; it is never hard-deleted.

duplicate_membership_blocked
on_create

A contact_id + organization_id pair must be unique among active records. Coordinators attempting to register the same contact for an organization they already belong to are blocked with a clear error — supports NHF duplicate-registration prevention.

coordinator_org_boundary
on_create

A coordinator may only create or modify membership records for their own organization_id. Cross-org membership manipulation (e.g. adding a contact to a sibling association) requires Org Admin privileges.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
No Partitioning
Retention
Permanent Storage