Organisation Configuration
Data Entity
Description
Stores all organization-specific runtime configuration including feature flag JSONB, terminology label overrides JSONB, receipt amount threshold, auto-approval distance limit, per-km reimbursement rate, and integration credential references. This is the single configuration source of truth for how each organization customizes platform behaviour.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key — stable identifier for this configuration record, independent of organization_id to allow future multi-config scenarios | PKrequiredunique |
organization_id |
uuid |
Foreign key to the organizations table. Enforces the one-to-one relationship: each organization has exactly one configuration record | requiredunique |
labels |
json |
JSONB map of canonical label keys to organization-specific display strings. Keys are compile-time constants from LabelKeys registry (e.g. 'role.coordinator', 'role.peer_mentor'). Values are the organization's preferred terminology. Defaults to empty object — missing keys fall back to the platform default via LabelKeyResolver. | - |
features |
json |
JSONB map of feature flag keys to flag definition objects. Each entry contains: enabled (boolean), min_version (optional semver string for phased rollout), activation_date (optional ISO datetime). Known keys are declared in FeatureFlags constants: travel_reimbursement, certifications, gamification, driver_management, course_administration, annual_summary, membership_recruitment. Defaults to empty object — absent keys are treated as disabled. | - |
receipt_threshold_amount |
decimal |
Organization-specific monetary threshold (in NOK) above which a receipt image attachment is required for expense claims. Defaults to 100.00 NOK when null. Used by receipt-threshold-validator to determine if receipt capture is mandatory or optional. | - |
auto_approval_distance_km |
decimal |
Organization-specific distance threshold (kilometres) below which mileage expense claims are automatically approved without coordinator attestation. Defaults to 50 km when null. Combined with receipt_threshold_amount, both conditions must pass for auto-approval. Used by auto-approval-evaluator and threshold-evaluation-service. | - |
rate_per_km |
decimal |
Organization-specific reimbursement rate in NOK per kilometre driven. Used by mileage-calculation-service to compute gross payout. Must be positive when set. Reflects the current national rate or any organization-negotiated override. | - |
integration_credentials_refs |
json |
JSONB map of integration type keys (e.g. 'xledger', 'dynamics', 'vipps', 'bankid') to Supabase Vault secret reference IDs. Actual credential values are never stored in this table — only the vault key handles required to retrieve them at runtime via integration-credential-vault. Allows the configuration record to be read without exposing secrets. | - |
admin_portal_url |
string |
The URL of this organization's web-based admin portal, shown to global admin users who are blocked from mobile app access. Used by no-access-config-repository and access-denial-service to redirect blocked roles. | - |
benefit_multiplier_config |
json |
JSONB object containing organization-specific multipliers for the volunteer benefit calculator: cost_per_session_nok (travel cost avoided per session), health_system_offset_rate (public health cost coefficient per session hour), and any org-specific overrides. Consumed by benefit-multiplier-config-repository. | - |
sync_schedule_config |
json |
JSONB object storing preferred sync frequency and time preferences for external system integrations. Used by sync-scheduler to determine when to trigger accounting and member-system export jobs. Structure: {frequency: 'daily'|'weekly'|'manual', preferred_time_utc: 'HH:MM'}. | - |
created_at |
datetime |
UTC timestamp when this configuration record was first created, typically during organization onboarding. Set once and never updated. | required |
updated_at |
datetime |
UTC timestamp of the most recent write to any field in this record. Maintained automatically via Supabase trigger. Used by terminology-sync-service to detect stale client caches via version comparison. | required |
Database Indexes
idx_organisation_configuration_organization_id
Columns: organization_id
idx_organisation_configuration_updated_at
Columns: updated_at
idx_organisation_configuration_labels_gin
Columns: labels
idx_organisation_configuration_features_gin
Columns: features
Validation Rules
organization_id_must_reference_existing_org
error
Validation failed
receipt_threshold_non_negative
error
Validation failed
auto_approval_distance_non_negative
error
Validation failed
labels_values_must_be_strings
error
Validation failed
features_entries_must_include_enabled
warning
Validation failed
min_version_must_be_valid_semver
error
Validation failed
activation_date_must_be_iso8601
error
Validation failed
admin_portal_url_valid_format
error
Validation failed
integration_credential_refs_non_empty_string_values
error
Validation failed
updated_at_reflects_actual_change
error
Validation failed
Business Rules
one_config_per_organization
Each organization must have exactly one organisation_configuration record. The organization_id column carries a UNIQUE constraint. Creating a second config for an existing organization is rejected at the database level.
feature_flag_rollout_conditions
A feature flag is considered active only when: (1) enabled is true, (2) the client app version meets or exceeds min_version if specified, and (3) the current UTC date is on or after activation_date if specified. All three conditions must pass simultaneously. The rollout-evaluator service applies this logic at read time — the stored JSON records intent, not effective state.
auto_approval_requires_both_thresholds
Auto-approval of an expense claim applies only when both the distance is below auto_approval_distance_km AND no receipt-required expense line exceeds receipt_threshold_amount. If either condition fails the claim enters the manual coordinator attestation queue. When either threshold field is null the platform default applies (50 km and 100 NOK respectively).
rate_per_km_must_be_positive
rate_per_km must be strictly greater than zero when set. A zero or negative rate would produce incorrect reimbursement amounts and is rejected before persistence. When null the system falls back to the platform-wide default national rate.
integration_credentials_stored_in_vault_only
Raw API credentials (client secrets, tokens, passwords) must never be stored directly in the integration_credentials_refs JSONB field. Only Supabase Vault secret reference IDs are permitted as values. The integration-credential-vault component enforces this boundary at write time.
labels_keys_must_be_registered_constants
All keys in the labels JSONB should correspond to constants declared in the LabelKeys registry. Unknown keys are permitted (for forward compatibility) but emit a warning during terminology sync. This prevents typo-driven silent failures where a label is stored but never resolved.
feature_flag_keys_must_be_known
Feature flag keys written into the features JSONB must correspond to constants declared in the FeatureFlags compile-time registry. Unknown keys are silently ignored during evaluation. The feature-flag-admin-screen validates against the registry before persisting admin changes.
rls_org_scoped_access
Supabase Row Level Security policies ensure that any authenticated session can only read the organisation_configuration row whose organization_id matches the org claim embedded in the session JWT. Write operations are restricted to org_admin and super_admin roles only.
CRUD Operations
Storage Configuration
Entity Relationships
Organisation configuration embeds the features JSONB whose individual entries are logically represented as feature_flag domain objects
Organisation configuration embeds the full terminology label map whose individual entries are logically represented as organisation_label records
Each organization has exactly one configuration record containing feature flags, terminology labels, and reimbursement rate settings