core PK: id 13 required 1 unique

Description

A logged interaction between a peer mentor and a contact — home visits, phone calls, group meetings, or any other peer mentoring engagement. Activities are the core operational unit of the platform: they feed Bufdir compliance reports, drive reimbursement flows, power statistics dashboards, and form the audit trail that organizations submit to government funders. Activities can be created directly by peer mentors, registered by coordinators on behalf of mentors (proxy), or created in bulk for recurring group events.

26
Attributes
9
Indexes
10
Validation Rules
34
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key. Globally unique identifier for the activity record.
PKrequiredunique
organization_id uuid Foreign key to organizations. Enforces multi-tenant data isolation — every query must scope to this column.
required
local_association_id uuid Foreign key to local_associations. Scopes the activity to the local branch within an organization for coordinator-level reporting and access control.
-
user_id uuid Foreign key to users. The peer mentor who performed (or is credited with) the activity. In proxy registration, this is the mentor being reported for, not the submitting coordinator.
required
contact_id uuid Foreign key to contacts. The contact person who received support during this activity. May be null for group activities where no single contact is applicable.
-
activity_type enum Categorizes the type of peer mentor interaction. Used for Bufdir field mapping and mutual-exclusivity validation.
required
date datetime The date and time when the activity took place. Defaults to the current date on the client. Used for calendar sync, Bufdir period filtering, and statistics aggregation.
required
duration_minutes integer Duration of the activity in minutes. Default is 30 minutes. Used for hours-based statistics, coordinator team reports, and Bufdir reporting.
required
summary text Free-text description of the activity. Optional but encouraged. Supports speech-to-text input on mobile. Not included in Bufdir exports directly but retained for internal audit.
-
status enum Lifecycle state of the activity through the review and approval workflow.
required
is_proxy boolean True if the activity was registered by a coordinator on behalf of a peer mentor. Stored for audit trail and Bufdir attribution.
required
proxy_user_id uuid Foreign key to users. The coordinator who submitted the activity on behalf of the peer mentor. Non-null only when is_proxy = true.
-
is_bulk boolean True if this activity was created as part of a bulk registration operation. Links to bulk_operation_id for batch traceability.
required
bulk_operation_id uuid Groups all activity records created in a single bulk registration transaction. Non-null only when is_bulk = true. Supports rollback and audit.
-
location string Optional free-text location description for the activity (e.g., 'Mentor's home', 'Community center'). Used in formalized report structures.
-
is_flagged boolean True if this activity has been flagged for review as a suspected duplicate or non-compliant entry. Separate from status to allow flagging of already-approved activities.
required
flag_reason text Human-readable explanation for why the activity was flagged. Set by coordinator or by the automatic duplicate detection service.
-
flagged_by_user_id uuid Foreign key to users. The coordinator or system process that raised the flag. Null for system-initiated flags only if flagging logic stores 'system' sentinel.
-
rejection_reason text Reason provided by the reviewer when status is set to 'rejected'. Required for all rejection decisions.
-
reviewed_by_user_id uuid Foreign key to users. The coordinator or org admin who last performed an approval or rejection action.
-
reviewed_at datetime Timestamp of the most recent review action (approve/reject). Null if no review has occurred.
-
version integer Optimistic locking version counter. Incremented on every update. Used by approval service to prevent concurrent modification conflicts.
required
calendar_event_id string External calendar event ID from device or Google Calendar. Populated by Calendar Sync Service when an activity is pushed to an external calendar. Enables bidirectional sync.
-
metadata json Extensible JSON blob for organization-specific fields, custom activity attributes, or future Bufdir format extensions without schema migrations.
-
created_at datetime Timestamp of record creation. Set automatically on insert. Used for feed ordering, statistics bucketing, and audit logs.
required
updated_at datetime Timestamp of the most recent record update. Auto-maintained by trigger or ORM. Used for sync conflict detection.
required

Database Indexes

idx_activity_org_created
btree

Columns: organization_id, created_at

idx_activity_user_date
btree

Columns: user_id, date

idx_activity_local_assoc_created
btree

Columns: local_association_id, created_at

idx_activity_contact
btree

Columns: contact_id

idx_activity_status
btree

Columns: status

idx_activity_org_status
btree

Columns: organization_id, status

idx_activity_bulk_operation
btree

Columns: bulk_operation_id

idx_activity_flagged
btree

Columns: organization_id, is_flagged

idx_activity_date_type
btree

Columns: organization_id, date, activity_type

Validation Rules

required_fields_present error

Validation failed

date_not_in_future error

Validation failed

duration_positive_nonzero error

Validation failed

proxy_fields_consistency error

Validation failed

bulk_fields_consistency error

Validation failed

rejection_reason_required error

Validation failed

flag_reason_required error

Validation failed

org_id_immutable error

Validation failed

activity_type_valid_enum error

Validation failed

summary_length_limit error

Validation failed

Business Rules

tenant_isolation
always

Every activity record must be scoped to an organization_id. All queries — reads, aggregations, exports — must include a WHERE organization_id = :orgId clause. Cross-tenant access is never permitted, even for coordinators.

proxy_requires_coordinator_role
on_create

An activity with is_proxy = true must have proxy_user_id set to a user who holds the Coordinator role within the same organization. Peer Mentors cannot register activities for other users.

proxy_scope_restriction
on_create

A coordinator can only register proxy activities for peer mentors within their own local association(s). Cross-association proxy registration is forbidden.

bulk_atomicity
on_create

All activities created within a single bulk_operation_id must be inserted atomically. If any single insert fails, the entire batch is rolled back. No partial bulk registrations are permitted.

status_transition_guard
on_update

Activity status transitions must follow the defined workflow: draft → pending_review → approved/rejected. Approved activities cannot be moved back to pending_review without creating a correction record. Only Coordinators and Org Admins can trigger status changes.

optimistic_locking
on_update

Updates to an activity record must include the current version value. If the version in the update request does not match the database version, the update is rejected with a conflict error to prevent concurrent approval race conditions.

bufdir_approved_only
always

Only activities with status = 'approved' are included in Bufdir report generation. Draft, pending, rejected, and flagged activities are excluded from all compliance exports.

duplicate_detection
on_create

When a new activity is created, the system checks for existing activities with the same (user_id, contact_id, date, activity_type) within a configurable deduplication window per organization. Suspected duplicates are auto-flagged with is_flagged = true.

soft_delete_only
on_delete

Activities must never be hard-deleted. If deletion is required, the status is set to 'rejected' with a system rejection reason, preserving the full audit trail for compliance purposes.

assignment_threshold_trigger
on_update

For organizations using assignment-based honorarium tiers (Blindeforbundet), each activity completion event must be forwarded to the Threshold Tracking Service to evaluate whether honorarium thresholds have been crossed.

offline_queue_precedence
on_create

Activities created while offline are persisted to the local SQLite sync queue. When connectivity is restored, they are submitted to the REST API in the order they were created, preserving chronological integrity.

calendar_sync_push
on_create

When an activity is created or updated and Calendar Sync is enabled for the user, the activity is pushed to the linked device or Google Calendar. The external event ID is stored in calendar_event_id.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
by_date
Retention
Permanent Storage

Components Managing This Entity

service Permission Validation Middleware ["backend"] data Activity Store ["mobile"] data Activity Store ["mobile"] service Activity Service ["mobile"] service Activity Service ["mobile"] data Activity Store ["mobile"] service Activity Service ["mobile"] service Wizard State Manager ["mobile"] service Wizard State Manager ["mobile"] service Calendar Event Mapper ["mobile"] service Calendar Sync Service ["mobile"] service Calendar Sync Service ["mobile"] service Proxy Registration Service ["mobile"] service Proxy Registration Service ["mobile","backend"] service Proxy Scope Validator ["mobile"] infrastructure Bulk Transaction Handler ["backend"] service Bulk Processing Service ["mobile"] service Bulk Processing Service ["backend"] service Stats Aggregation Service ["backend"] service Stats Aggregation Service ["backend","mobile"] service Team Stats Service ["mobile","backend"] service Team Stats Service ["backend","mobile"] data Report Store ["backend"] data Report Store ["backend"] service Bufdir Report Service ["backend"] service Bufdir Report Service ["backend","mobile"] service Report Data Aggregator ["backend"] infrastructure Assignment Completion Event Listener ["backend"] service Threshold Tracking Service ["backend"] service Threshold Tracking Service ["backend"] service Summary Aggregation Service ["backend"] service Dashboard Service ["mobile"] service Dashboard Service ["mobile"] data Local SQLite Database ["mobile"] data Local SQLite Database ["mobile"] data Sync Queue ["mobile"] data Sync Queue ["mobile"] service Repository Data Source Router ["mobile"] service Background Sync Service ["mobile"] service Background Sync Service ["mobile"] service Conflict Resolution Service ["mobile"] data Analytics Store ["backend"] data Analytics Store ["backend"] service KPI Aggregation Service ["backend"] service KPI Aggregation Service ["backend"] data Activity Feed Query Builder ["backend"] service Activity Feed Service ["backend"] service Activity Feed Service ["backend"] data Approval Store ["backend"] data Approval Store ["backend"] infrastructure Optimistic Lock Adapter ["backend"] service Activity Approval Service ["backend"] service Activity Approval Service ["backend"] service Review Queue Service ["backend"] infrastructure Duplicate Detection Job ["backend"] service Activity Flagging Service ["backend"] service Activity Flagging Service ["backend"] service Duplicate Detection Service ["backend"] data Report Store ["backend"] data Report Store ["backend"] service Report Generation Service ["backend"] service Report Generation Service ["backend"] service Bufdir Export Service ["backend"] service Bufdir Export Service ["backend"] service Custom Report Service ["backend"] service Custom Report Service ["backend"]