Local Association
Data Entity
Description
A local chapter or branch within an organization — the primary operational unit for peer mentors and coordinators. Up to 1,400 local associations exist under the four organizations. All activity data, reimbursements, and user assignments are ultimately scoped to a local association.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Globally unique primary key for the local association record, generated server-side on creation. | PKrequiredunique |
organization_id |
uuid |
Foreign key referencing the parent organization (NHF, Blindeforbundet, HLF, Barnekreftforeningen). Every local association belongs to exactly one organization. This is the multi-tenancy anchor for all data scoped through this entity. | required |
region_id |
uuid |
Optional foreign key referencing the intermediate regional tier. NHF uses 9 regions; other organizations may not use regional grouping. Must reference a region that belongs to the same organization as this association. | - |
name |
string |
Human-readable display name of the local association (e.g. 'NHF Oslo og Akershus'). Shown in selection lists, context switcher, reports, and all coordinator-facing views. | required |
code |
string |
Short alphanumeric identifier for the local association, unique within its parent organization. Used in Bufdir report exports, accounting integrations (Xledger, Dynamics), and internal API references. Typically assigned during initial data seeding from existing organizational records. | required |
status |
enum |
Operational status of the association. Active associations appear in selection lists and accept new activity registrations. Inactive associations are hidden from peer mentor selection but retain historical data. Archived associations are read-only for historical reporting only. | required |
address |
string |
Street address of the local association's physical office or meeting place. Used optionally for geographic map display and coordinator context. | - |
city |
string |
City where the local association operates. Used for geographic matching and display in map views for peer mentor assignment. | - |
postal_code |
string |
Norwegian postal code (postnummer) for the association's primary location. 4-digit format. Feeds into geocoding for map-based peer mentor matching. | - |
country |
string |
ISO 3166-1 alpha-2 country code. Defaults to 'NO' (Norway). Included for future internationalization readiness. | - |
contact_email |
string |
Primary contact email address for the local association's administrative contact. Used for coordinator notifications and Bufdir-related correspondence. | - |
contact_phone |
string |
Contact phone number for the local association. Stored as a string to accommodate international formatting and leading zeros. | - |
honorarium_threshold_enabled |
boolean |
Whether this local association uses assignment-count-based honorarium threshold tracking (Blindeforbundet-specific). When true, the threshold_tracking_service monitors assignment counts and fires notifications at configured tier boundaries. | required |
settings |
json |
Association-level configuration overrides stored as a JSONB object. May include local reporting preferences, feature flag overrides inherited from the parent organization, or Bufdir-specific field mappings. Falls back to parent organization settings when absent. | - |
created_at |
datetime |
UTC timestamp when this local association record was first created. Immutable after creation. | required |
updated_at |
datetime |
UTC timestamp of the most recent update to any field on this record. Automatically updated by the database on every write. | required |
deleted_at |
datetime |
Soft-delete timestamp. When set, the association is excluded from all active queries, selection lists, and reporting. Historical data (activities, reimbursements, assignments) linked to this association is retained for Bufdir audit compliance. | - |
Database Indexes
idx_local_association_organization_id
Columns: organization_id
idx_local_association_region_id
Columns: region_id
idx_local_association_org_code
Columns: organization_id, code
idx_local_association_status
Columns: status
idx_local_association_deleted_at
Columns: deleted_at
idx_local_association_org_status
Columns: organization_id, status
Validation Rules
name_required_and_bounded
error
Validation failed
code_alphanumeric_format
error
Validation failed
organization_id_references_existing_organization
error
Validation failed
region_id_references_same_organization
error
Validation failed
postal_code_norwegian_format
error
Validation failed
contact_email_valid_format
error
Validation failed
settings_valid_json_schema
error
Validation failed
deleted_at_only_set_once
error
Validation failed
Business Rules
single_organization_ownership
A local association must belong to exactly one organization and cannot be reassigned to a different organization after creation. The organization_id is immutable post-creation to preserve data scoping integrity across all linked activities, users, and reimbursements.
region_same_organization_constraint
When region_id is provided, the referenced region must belong to the same organization as the local association. Cross-organization region assignments are rejected to prevent hierarchy corruption.
code_unique_within_organization
The association code must be unique within its parent organization. The same code may exist across different organizations (e.g., two organizations may each have an association coded 'OSLO'). Enforced at the database level via a unique composite index on (organization_id, code).
soft_delete_only_when_no_active_dependencies
A local association cannot be soft-deleted while it has active (non-deleted, non-paused) peer mentors, pending reimbursement claims, or open encrypted assignments linked to it. Coordinators must resolve all active dependencies before an association can be archived.
active_only_in_selection_lists
Only associations with status='active' and deleted_at=NULL are surfaced in user-facing selection lists (onboarding, association context switcher, proxy registration). Inactive and archived associations are hidden from selection but remain readable for historical reporting.
tenant_scoping_on_all_queries
Every query touching data scoped to a local association (activities, reimbursements, user roles, assignments) must include the local_association_id filter derived from the authenticated user's JWT claims or active context. The multi-tenancy infrastructure enforces this at the request middleware level.
max_five_associations_per_user
A single user may hold membership in at most five local associations simultaneously (NHF requirement). The membership service enforces this limit when adding new user_organization_role records linking a user to a new association.
honorarium_threshold_requires_configuration
When honorarium_threshold_enabled is set to true on a local association, at least one honorarium_threshold configuration record must exist for that association before assignment tracking can fire. The threshold tracking service validates this precondition before processing assignment count events.
status_change_audit_required
Any change to the status field (active → inactive, inactive → archived, etc.) must produce an audit log entry recording the actor, previous status, new status, and timestamp. Status changes cannot occur without an authenticated actor context.
bufdir_report_scoping
Bufdir reports aggregate activity data at the local association level before rolling up to region and organization. The report aggregation service must scope all activity counts to individual local associations and only then aggregate upward through the hierarchy. No cross-organization aggregation is permitted.
CRUD Operations
Storage Configuration
Entity Relationships
A local association owns all activities registered by its members, enabling team reports and Bufdir aggregation
A local association configures its own honorarium threshold tiers for assignment-count-based compensation
A local association has many peer mentors operating within it
A local association scopes user role assignments for coordinators and peer mentors operating within it
An organization owns all its local associations directly, supporting direct org-to-association queries bypassing region
A region contains multiple local associations (chapters/branches)