Activity Type
Data Entity
Description
Defines a category of peer mentor activity within an organization's catalogue. Each type has metadata flags controlling travel expense eligibility, whether a post-session report form is required, and the Bufdir reporting category code it maps to. Activity types are organization-scoped and managed by administrators through the admin portal.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Immutable primary key generated at record creation. Stable foreign key referenced by activity records, cache entries, and Bufdir mapping configurations. | PKrequiredunique |
organization_id |
uuid |
Foreign key to the organizations table. Scopes each activity type to a single tenant. All reads must filter on this field; Supabase RLS enforces it at the database level. | required |
name |
string |
Human-readable display name for this activity type within the organization's catalogue. May differ from the Bufdir category label. Unique within the organization. | required |
description |
text |
Optional longer description providing administrators context about when this activity type should be used. Not shown in the registration wizard. | - |
is_travel_expense_eligible |
boolean |
When true, activities of this type allow peer mentors to attach a travel expense claim. Drives conditional rendering of the expense registration flow after activity submission. | required |
requires_report_form |
boolean |
When true, completing an activity of this type triggers the structured post-session report form (e.g., Blindeforbundet home-visit activities). The registration wizard surfaces the report prompt upon confirmation. | required |
triggers_reimbursement |
boolean |
When true, submission initiates the reimbursement approval workflow. Must not be true unless is_travel_expense_eligible is also true — enforced by service-layer validation. | required |
bufdir_category_code |
string |
The Bufdir reporting category code this activity type maps to for grant reporting exports. Activities with a null code are flagged as warnings during export generation. Must match Bufdir's official reporting schema codes. | - |
is_active |
boolean |
Soft-delete flag. When false the activity type is hidden from the registration wizard and admin catalogue but remains referenced by historical activity records. Never physically deleted. | required |
display_order |
integer |
Ordinal position in the activity type list rendered in the registration wizard and admin catalogue. Lower values appear first. Defaults to insertion order when not explicitly set. | - |
metadata |
json |
Extensible JSONB column for additional organization-specific flags not covered by the fixed boolean columns. Parsed exclusively by ActivityTypeMetadataResolver into a typed struct. Example keys: office_honorarium_threshold, report_form_schema_id. | - |
created_at |
datetime |
UTC timestamp set automatically by the database on insert. Used for audit logging. | required |
updated_at |
datetime |
UTC timestamp updated automatically by a Supabase trigger on every mutation. Used to detect staleness in the client-side cache and for audit trails. | required |
created_by_user_id |
uuid |
User ID of the organization administrator who created this activity type. Nullable for types seeded during organization onboarding. | - |
Database Indexes
idx_activity_type_org_id
Columns: organization_id
idx_activity_type_org_name_unique
Columns: organization_id, name
idx_activity_type_org_active
Columns: organization_id, is_active
idx_activity_type_bufdir_code
Columns: bufdir_category_code
idx_activity_type_org_display_order
Columns: organization_id, display_order
Validation Rules
name_not_empty
error
Validation failed
organization_id_exists
error
Validation failed
bufdir_code_format
error
Validation failed
metadata_valid_json
error
Validation failed
reimbursement_flag_consistency
error
Validation failed
display_order_non_negative
error
Validation failed
unique_name_within_org_on_update
error
Validation failed
bufdir_code_unmapped_warning_on_export
warning
Validation failed
Business Rules
organization_scoping
Every activity type belongs to exactly one organization. Supabase RLS policies inject the session organization_id into all queries. Cross-organization reads are blocked at the database level regardless of application-layer filtering.
soft_delete_only
Activity types are never physically deleted because historical activity records reference them. Deactivation sets is_active=false, hiding the type from the registration wizard while preserving referential integrity for Bufdir reporting and statistics.
reimbursement_requires_travel_eligibility
triggers_reimbursement=true is only permitted when is_travel_expense_eligible=true. A type that triggers the reimbursement workflow but does not permit expense claims is logically inconsistent and causes downstream failures in the approval workflow.
name_unique_per_organization
An organization cannot have two activity types with identical names. The unique index on (organization_id, name) prevents ambiguity in the registration wizard and Bufdir export mapping.
bufdir_code_required_for_export
Activity types without a bufdir_category_code cannot contribute correctly to Bufdir report exports. The export pipeline flags all activities of unmapped types as warnings in the export preview, allowing coordinators to resolve the gap before submission.
cache_invalidation_on_mutation
Any create, update, or soft-delete must invalidate the ActivityTypeCacheProvider for the affected organization. The cache is populated at app startup; stale data causes incorrect wizard options and Bufdir mapping errors.
active_types_only_in_wizard
The registration wizard presents only activity types where is_active=true. The ActivityTypeCacheProvider and ActivityTypeSelectionScreen filter on this flag. Inactive types remain queryable for historical activity resolution and reporting.
metadata_json_schema_validation
The metadata JSONB column is parsed by ActivityTypeMetadataResolver before use. Malformed or schema-violating metadata is rejected at save time to prevent resolver panics at runtime.
CRUD Operations
Storage Configuration
Entity Relationships
Every activity record references the organization-specific activity type that determines its Bufdir category and reimbursement eligibility
Each organization maintains its own catalogue of activity types with organization-specific names and Bufdir mappings