Organization
Data Entity
Description
Core tenant unit in the Meander multi-tenant platform. Represents a member organization (e.g. NHF, Blindeforbundet, HLF) that subscribes to the platform. All operational data — users, activities, contacts, reports — is scoped to an organization. Supports hierarchical structures (national federation → region → local association) and per-organization configuration of terminology, feature flags, and integrations.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Surrogate primary key. Generated on insert. | PKrequiredunique |
name |
string |
Full legal or display name of the organization (e.g. 'Hørselsforbundet'). | required |
slug |
string |
URL-safe, lowercase, hyphenated identifier used in API paths and deep links (e.g. 'horselsforbundet'). | requiredunique |
org_type |
enum |
Structural role of this organization in the hierarchy. | required |
parent_org_id |
uuid |
FK to organizations.id. NULL for top-level organizations. Enables multi-organization hierarchy (e.g. NHF has 12 landsforeninger, 9 regions, 1400 lokallag). | - |
bufdir_org_id |
string |
External reference ID assigned by Bufdir for grant reporting. Used to correlate Bufdir reports with the funding agency's system. | unique |
contact_email |
string |
Primary administrative contact email for the organization. | required |
contact_phone |
string |
Primary contact phone number in E.164 format. | - |
website_url |
string |
Public website URL for the organization. | - |
logo_url |
string |
URL to the organization's logo stored in object storage. Displayed in the admin portal and mobile app headers. | - |
primary_color |
string |
Hex color code for organization branding (#RRGGBB). Used for org-specific theming where supported. | - |
locale |
string |
Default locale for the organization (BCP-47 language tag). Drives default UI language for org members. | required |
timezone |
string |
IANA timezone identifier for the organization. Used for report period boundaries and scheduled notifications. | required |
max_users |
integer |
Maximum number of active users allowed for this organization under their subscription plan. NULL means unlimited. | - |
plan_tier |
enum |
Subscription plan tier determining which features and limits apply. | required |
is_active |
boolean |
Whether the organization is currently active on the platform. Inactive organizations cannot log in or access data. | required |
is_pilot |
boolean |
Marks organizations participating in the early pilot program (TestFlight phase). Used to route feedback and enable pre-release features. | required |
accounting_system |
enum |
Accounting system integrated with this organization for expense reimbursement exports (Xledger for Blindeforbundet, Dynamics for HLF). | - |
metadata |
json |
Flexible JSON bag for org-specific configuration not covered by typed columns (e.g. Dynamics tenant ID, custom API endpoints). Validated against a JSON Schema at the application layer. | - |
deactivated_at |
datetime |
Timestamp of deactivation. NULL if the organization is active. Soft-delete pattern — records are retained for audit purposes. | - |
created_at |
datetime |
Record creation timestamp (UTC). | required |
updated_at |
datetime |
Last modification timestamp (UTC). Updated by trigger on any column change. | required |
Database Indexes
idx_organizations_slug
Columns: slug
idx_organizations_bufdir_org_id
Columns: bufdir_org_id
idx_organizations_parent_org_id
Columns: parent_org_id
idx_organizations_is_active
Columns: is_active
idx_organizations_plan_tier
Columns: plan_tier
idx_organizations_org_type_parent
Columns: org_type, parent_org_id
Validation Rules
slug_format
error
Validation failed
contact_email_format
error
Validation failed
primary_color_hex_format
warning
Validation failed
locale_allowlist
error
Validation failed
timezone_valid_iana
error
Validation failed
max_users_positive
error
Validation failed
name_length
error
Validation failed
parent_exists_when_set
error
Validation failed
accounting_system_requires_integration_config
warning
Validation failed
deactivated_at_consistency
error
Validation failed
Business Rules
tenant_data_isolation
All queries against user, activity, contact, event, expense, notification, and report data MUST be scoped by organization_id. Cross-tenant data access is forbidden. Global admins manage system configuration only — they do not access org operational data by default.
soft_delete_only
Organizations must never be hard-deleted. Setting is_active=false and deactivated_at=now() is the only permitted removal mechanism. All related data is retained for audit and Bufdir compliance purposes.
no_circular_hierarchy
An organization's parent_org_id chain must not form a cycle. Before setting parent_org_id, the system traverses the ancestor chain and rejects the update if it would create a loop.
hierarchy_type_ordering
Organization type must be compatible with parent type. national_federation may have no parent; regional_branch must have a national_federation parent; local_association must have a regional_branch or national_federation parent; independent has no parent.
bufdir_id_uniqueness
If set, bufdir_org_id must be globally unique across all organizations. Prevents duplicate Bufdir grant reporting.
max_users_enforcement
When max_users is set, the platform must reject new user invitations once the active user count for the organization reaches the limit.
deactivation_cascade
When an organization is deactivated, all active sessions for its users are revoked, push device tokens are invalidated, and scheduled jobs (cron, reminders) for that org are suspended.
audit_all_org_changes
Every create/update/deactivate operation on an organization record must produce an audit_log entry with actor identity, changed fields (before/after), and timestamp.
feature_flags_inherit_from_platform
When a feature flag is not explicitly configured for an organization, the platform-level default applies. Organization-level overrides take precedence.
terminology_fallback_to_defaults
If no terminology override exists for a label key for the organization, the platform default terminology is served. Ensures no empty labels appear in the UI.