Contact
Data Entity
Description
A person receiving support from a peer mentor within an organization. Contacts are the central subject of activities, notes, event registrations, and encrypted assignment dispatches. They are not app users — they are the people being helped.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key, globally unique contact identifier | PKrequiredunique |
organization_id |
uuid |
Foreign key to the organization this contact belongs to. Enforces tenant isolation. | required |
first_name |
string |
Contact's given name | required |
last_name |
string |
Contact's family name | required |
date_of_birth |
datetime |
Date of birth, used for demographic reporting and Bufdir statistics | - |
gender |
enum |
Gender identity, used for Bufdir demographic reporting | - |
phone_number |
string |
Primary phone number in E.164 format | - |
email |
string |
Email address for contact | - |
address_street |
string |
Street address line | - |
address_city |
string |
City | - |
address_postal_code |
string |
Norwegian postal code (4 digits) | - |
address_region |
string |
Region or county, used for geographic matching and Bufdir reporting | - |
preferred_contact_method |
enum |
How the contact prefers to be reached | - |
language_preference |
string |
BCP-47 language tag for communication preference (e.g. 'nb', 'nn', 'se' for Northern Sami) | - |
disability_category |
string |
High-level disability or health category used for peer mentor matching and Bufdir classification. Free text, not an enum, to support diverse org taxonomies. | - |
accessibility_needs |
json |
Structured accessibility requirements (e.g. requires screen reader support, large print, sign language) used to inform peer mentor matching | - |
primary_peer_mentor_id |
uuid |
Optional FK to the users table — the peer mentor primarily responsible for this contact | - |
assigned_coordinator_id |
uuid |
Optional FK to the users table — the coordinator overseeing this contact's follow-up | - |
consent_given |
boolean |
Whether the contact has given GDPR consent for their data to be stored and processed | required |
consent_date |
datetime |
Timestamp when consent was recorded | - |
consent_method |
enum |
How consent was obtained | - |
is_active |
boolean |
Whether this contact is currently receiving support. False = archived, not deleted. | required |
is_sensitive |
boolean |
Marks the contact record as containing sensitive personal data (e.g. health/crisis cases). Triggers screen reader readout warnings. | required |
internal_notes |
text |
Free-text internal notes visible only to coordinators. Not shown to peer mentors. | - |
external_reference_id |
string |
ID in the organization's external member system (e.g. HLF portal, NHF member registry). Used for sync and deduplication. | - |
created_by |
uuid |
FK to users.id — the user who created this contact record | required |
created_at |
datetime |
Timestamp of record creation | required |
updated_at |
datetime |
Timestamp of last modification | required |
deleted_at |
datetime |
Soft delete timestamp. NULL = active. Set instead of physical deletion to preserve activity/report history. | - |
Database Indexes
idx_contacts_organization_id
Columns: organization_id
idx_contacts_org_name
Columns: organization_id, last_name, first_name
idx_contacts_primary_peer_mentor
Columns: primary_peer_mentor_id
idx_contacts_assigned_coordinator
Columns: assigned_coordinator_id
idx_contacts_active
Columns: organization_id, is_active
idx_contacts_deleted_at
Columns: deleted_at
idx_contacts_external_ref
Columns: organization_id, external_reference_id
idx_contacts_phone
Columns: phone_number
Validation Rules
first_and_last_name_required
error
Validation failed
at_least_one_contact_method
error
Validation failed
phone_number_format
error
Validation failed
email_format
error
Validation failed
postal_code_format
error
Validation failed
date_of_birth_not_future
error
Validation failed
consent_date_set_with_consent
error
Validation failed
organization_id_must_exist
error
Validation failed
language_preference_valid_bcp47
warning
Validation failed
accessibility_needs_valid_json
error
Validation failed
Business Rules
tenant_isolation
A contact always belongs to exactly one organization. Queries MUST always filter by organization_id. Peer mentors can only see contacts within their own organization. Coordinators can only manage contacts within their assigned local association scope.
soft_delete_only
Contacts must never be physically deleted. Set deleted_at to current timestamp instead. All queries must filter WHERE deleted_at IS NULL by default. Preserves activity history for Bufdir reporting.
gdpr_consent_required_before_sensitive_data
If is_sensitive is set to true, consent_given must also be true. Sensitive contacts without consent cannot be created or updated to sensitive status.
screen_reader_warning_for_sensitive_contacts
If is_sensitive is true, the UI must display a readout warning before any screen reader can announce the contact's personal fields. Enforced in the detail and edit screens.
peer_mentor_read_only_access
Peer Mentors can read contact details but cannot delete contacts or modify organization_id, created_by, or internal_notes fields. Only coordinators and org admins may write internal_notes.
coordinator_scope_restriction
A coordinator can only create, update, or view contacts whose assigned_coordinator_id matches them, or contacts with no assigned coordinator within their organization. Prevents cross-coordinator data leakage.
deactivation_instead_of_deletion
When a contact no longer receives support, set is_active = false rather than deleting. Deactivated contacts are excluded from new activity registration flows but remain queryable for historical reporting.
external_reference_uniqueness_per_org
If external_reference_id is set, it must be unique within the organization. Used to prevent duplicate imports from HLF Dynamics portal or NHF member registry.