Activities
Data Entity
Description
Core operational entity representing a logged interaction between a peer mentor and one or more contacts. Activities are the fundamental unit of work in the Meander platform — every home visit, phone call, group session, or meeting is recorded as an activity. Activities drive Bufdir reporting, personal and team statistics, expense linkage, approval workflows, and gamification metrics across all three products.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Unique identifier for the activity record | PKrequiredunique |
user_id |
uuid |
Foreign key to the peer mentor who owns/performed this activity. For proxy registrations, this is the peer mentor on whose behalf the activity was registered, not the coordinator who submitted it. | required |
contact_id |
uuid |
Foreign key to the primary contact involved in this activity. Null for group activities without a specific contact. | - |
organization_id |
uuid |
Foreign key to the organization this activity belongs to. Enforces multi-tenant data isolation. | required |
local_association_id |
uuid |
Foreign key to the local association context for this activity. Used for regional reporting and coordinator scoping. | - |
activity_type |
enum |
Category of activity performed. Determines which fields are required and how the activity counts in Bufdir reports. | required |
title |
string |
Short descriptive title for the activity. Auto-generated from activity type and contact name if not provided. | - |
description |
text |
Free-text notes about the activity. Supports speech-to-text input. Contains observation notes, follow-up items, and qualitative context. | - |
activity_date |
datetime |
Date and time when the activity took place. Defaults to current date/time for quick-log entries. | required |
duration_minutes |
integer |
Duration of the activity in minutes. Defaults to 30 minutes per quick-log widget. Must be positive. | required |
location |
string |
Location where the activity took place. Free-text or structured address. | - |
status |
enum |
Current lifecycle status of the activity in the approval workflow. | required |
is_proxy_registration |
boolean |
True if the activity was registered by a coordinator on behalf of a peer mentor. | required |
proxy_submitted_by |
uuid |
Foreign key to the coordinator who submitted this activity on behalf of the peer mentor. Null if not a proxy registration. | - |
is_bulk_registration |
boolean |
True if this activity was created as part of a bulk registration batch. | required |
bulk_batch_id |
uuid |
Identifier linking this activity to its bulk registration batch. Null for individual registrations. | - |
event_id |
uuid |
Foreign key to the event this activity is associated with. Null for non-event activities. | - |
participant_count |
integer |
Number of participants for group activities. Defaults to 1 for individual interactions. | - |
has_reimbursement |
boolean |
Whether this activity has associated expense/reimbursement claims. 60-70% of activities have no reimbursement (HLF data). | required |
calendar_event_id |
string |
External calendar event identifier for activities synced from device calendar. | - |
metadata |
json |
Flexible JSON field for organization-specific activity data, custom fields, and additional context not covered by fixed columns. | - |
synced_at |
datetime |
Timestamp of last successful sync to backend. Null if created online. Used by offline sync system. | - |
created_at |
datetime |
Timestamp when the activity record was created. | required |
updated_at |
datetime |
Timestamp of last modification to the activity record. | required |
Database Indexes
idx_activities_user_id
Columns: user_id
idx_activities_contact_id
Columns: contact_id
idx_activities_organization_id
Columns: organization_id
idx_activities_activity_date
Columns: activity_date
idx_activities_status
Columns: status
idx_activities_org_date
Columns: organization_id, activity_date
idx_activities_org_status
Columns: organization_id, status
idx_activities_user_date
Columns: user_id, activity_date
idx_activities_created_at
Columns: created_at
idx_activities_local_association
Columns: local_association_id
idx_activities_activity_type
Columns: activity_type
idx_activities_bulk_batch
Columns: bulk_batch_id
idx_activities_duplicate_detection
Columns: contact_id, activity_date, activity_type
Validation Rules
required_fields
error
Validation failed
duration_range
error
Validation failed
valid_user_reference
error
Validation failed
valid_contact_reference
error
Validation failed
proxy_fields_consistency
error
Validation failed
bulk_fields_consistency
error
Validation failed
activity_type_enum
error
Validation failed
status_enum
error
Validation failed
title_length
error
Validation failed
description_length
error
Validation failed
participant_count_positive
error
Validation failed
immutable_after_approval
error
Validation failed
Business Rules
owner_attribution_on_proxy
When a coordinator registers an activity on behalf of a peer mentor, the user_id must be set to the peer mentor (the true performer), and proxy_submitted_by must record the coordinator. The activity belongs to the peer mentor for reporting purposes.
organization_scope_isolation
All activity queries must be scoped to the requesting user's organization_id. Users must never see activities from other organizations. Coordinators see only activities within their local association scope.
duplicate_detection
When a new activity is created, the system checks for existing activities with the same contact_id, activity_date (within configurable time window), and activity_type. Detected duplicates are flagged for coordinator review rather than rejected outright.
approval_workflow_transition
Activity status transitions must follow the allowed state machine: draft → pending_review → approved/rejected/flagged. Flagged activities can transition to approved or rejected after resolution. Only coordinators and org admins can approve or reject.
bufdir_reporting_inclusion
Only activities with status 'approved' are included in Bufdir report aggregations. Draft, pending, rejected, and flagged activities are excluded from official reporting counts.
coordinator_proxy_scope
A coordinator can only register proxy activities for peer mentors within the same local association. Cross-association proxy registration is not permitted.
bulk_batch_atomicity
All activities in a bulk registration batch must be created within a single database transaction. If any individual activity in the batch fails validation, the entire batch is rolled back.
activity_date_not_future
Activities cannot be registered with a future activity_date. The system rejects dates more than 24 hours ahead of current server time to prevent accidental misregistration.
offline_sync_conflict_resolution
When an offline-created activity is synced to the backend, server-side data is authoritative. If a conflict is detected (e.g., duplicate from another device), the server version wins and the client is updated.
audit_trail_on_status_change
Every status change (approval, rejection, flagging) must generate an audit log entry recording the actor, timestamp, previous status, new status, and optional notes.
assignment_threshold_counting
Completed activities linked to assignments (via contact_id and user_id) increment the peer mentor's assignment counter for honorarium threshold tracking. Only approved activities count.