Activity Type
Data Entity
Description
A classification category for activities defining the nature of the interaction (e.g., home visit, phone call, group event, online meeting). Activity types determine which fields are required, whether a home visit report structure is triggered, and how data maps to Bufdir reporting fields.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Surrogate primary key, generated server-side (UUID v4) | PKrequiredunique |
organization_id |
uuid |
Foreign key to the owning organization. Activity types are fully scoped to an organization — no cross-tenant visibility. | required |
name |
string |
Human-readable display name for the activity type as shown in the mobile app. May be overridden by the organization labels system (e.g., 'Home Visit', 'Phone Call', 'Group Event'). | required |
slug |
string |
URL-safe, machine-readable identifier used in API responses, deep links, and Bufdir mapping keys. Must be unique within an organization. | required |
description |
text |
Optional coordinator-facing description explaining when to use this activity type. Not shown to peer mentors in the selection UI. | - |
is_home_visit |
boolean |
When true, selecting this activity type injects the Structured Home Visit Report step into the activity wizard (Blindeforbundet requirement). Checked synchronously by HomeVisitActivityTypeDetector. | required |
bufdir_field_mapping |
json |
JSON object mapping this activity type to the corresponding Bufdir grant-reporting field identifiers. Used by BuffdirFieldMapperService to aggregate activities into the correct Bufdir report columns. Example: {"bufdir_category": "individuell_kontakt", "bufdir_subcategory": "hjemmebesok", "count_as": "visit"} | - |
required_fields |
json |
JSON array of field identifiers that are mandatory when registering an activity of this type. Controls wizard step visibility and validation. Example: ["contact_id", "duration_minutes", "home_visit_report"] | - |
is_active |
boolean |
Soft-delete / visibility flag. Inactive types are hidden from the selection screen and are excluded from new activity creation, but historical activities referencing them remain intact. | required |
display_order |
integer |
Ascending sort order for display in the activity type selection screen. Lower numbers appear first. Allows organizations to surface their most-used types at the top. | - |
icon_name |
string |
Optional identifier referencing a Material/Cupertino icon key displayed next to the activity type name in the selection UI. Falls back to a default icon when null. | - |
created_at |
datetime |
Server-side timestamp of record creation. Not editable after insert. | required |
updated_at |
datetime |
Server-side timestamp updated on every write. Used for cache invalidation on the mobile client. | required |
Database Indexes
idx_activity_type_organization_id
Columns: organization_id
idx_activity_type_org_slug_unique
Columns: organization_id, slug
idx_activity_type_org_active
Columns: organization_id, is_active
idx_activity_type_is_home_visit
Columns: organization_id, is_home_visit
idx_activity_type_org_display_order
Columns: organization_id, display_order
Validation Rules
name_non_empty
error
Validation failed
slug_format
error
Validation failed
organization_id_exists
error
Validation failed
bufdir_field_mapping_valid_json
error
Validation failed
required_fields_valid_json_array
warning
Validation failed
display_order_non_negative
error
Validation failed
Business Rules
org_scoped_visibility
An activity type is visible only to users whose active organization_id matches the activity type's organization_id. No cross-tenant leakage is permitted. The multi-tenancy infrastructure enforces this at the request level before any query reaches the repository.
home_visit_report_injection
When a peer mentor selects an activity type where is_home_visit = true, the WizardStateManager must inject the Structured Home Visit Report step into the activity wizard before the Summary step. This is enforced synchronously via HomeVisitActivityTypeDetector so the UI reacts without a network round-trip.
bufdir_mapping_required_for_reporting
Any activity type that can be selected for new activity creation and belongs to an organization that submits Bufdir reports MUST have a non-null bufdir_field_mapping before it can be marked is_active = true. The organization-settings-service enforces this at save time.
no_hard_delete_when_activities_exist
An activity type that is referenced by one or more activity records cannot be hard-deleted. The organization-settings-service must enforce a soft-delete (is_active = false) instead, preserving historical report integrity.
slug_unique_within_org
The slug must be unique per organization_id to allow deterministic lookups and stable Bufdir field mapping references. The database-level unique index on (organization_id, slug) is the enforcement point; the service layer should provide a readable error message on conflict.
offline_cache_invalidation_on_update
When any activity type record is created, updated, or soft-deleted, the updated_at timestamp must be bumped so that mobile clients detect staleness on next sync and refresh the local activity_types cache. HomeVisitActivityTypeDetector loads this cache on startup.
CRUD Operations
Storage Configuration
Entity Relationships
An activity type classifies many activities and determines required fields and Bufdir mappings
An organization defines and owns the set of activity types available to its members