core PK: id 19 required 1 unique

Description

A logged interaction between a peer mentor and a contact — home visit, phone call, meeting, group event, or other support activity. The primary operational record of peer mentor work, driving Bufdir reporting, statistics, reimbursement, and oversight workflows.

31
Attributes
9
Indexes
8
Validation Rules
36
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key, generated on client for offline-first creation
PKrequiredunique
organization_id uuid Tenant isolation — the organization this activity belongs to
required
user_id uuid The peer mentor who performed the activity (author of record)
required
proxy_reporter_id uuid Coordinator who registered this activity on behalf of the peer mentor (null if self-reported)
-
contact_id uuid The contact (person receiving support) this activity was performed for. Null for group activities with no single contact.
-
activity_type_id uuid Foreign key to activity_types — categorizes the kind of interaction
required
activity_date datetime Date and time the activity actually took place (not when it was registered)
required
duration_minutes integer Duration of the activity in minutes. Default 30.
required
summary text Free-text summary of the activity content, entered by the peer mentor. May be dictated via speech-to-text.
-
status enum Lifecycle state of the activity record
required
is_proxy_reported boolean True if a coordinator registered this activity on behalf of the peer mentor
required
is_bulk_registration boolean True if created via bulk registration flow (coordinator registering multiple at once)
required
has_expense boolean True if a reimbursement expense is linked to this activity. Denormalized for fast query.
required
has_report boolean True if a formalized home-visit report (activity_reports) is linked. Denormalized for fast query.
required
has_attachments boolean True if one or more document attachments (activity_attachments) are linked. Denormalized.
required
location string Optional free-text location description (e.g. 'Home visit', 'Telephone', 'Community center')
-
participant_count integer Number of participants for group activities. Null for 1:1 interactions.
-
approval_status enum Administrative approval state, separate from lifecycle status
required
approved_by_user_id uuid Coordinator or admin who approved the activity. Null if auto-approved or pending.
-
approved_at datetime Timestamp of approval action
-
rejection_reason text Admin-provided reason if activity was rejected. Required when approval_status = rejected.
-
flag_reason text Reason text when activity is flagged for review by an admin
-
flagged_by_user_id uuid Admin or coordinator who flagged the activity
-
duplicate_of_activity_id uuid References the canonical activity if this record is identified as a duplicate
-
bufdir_eligible boolean Whether this activity qualifies for inclusion in Bufdir grant reports, determined by activity type and org configuration
required
source enum How the activity was created — for audit and analytics
required
offline_created boolean True if the activity was first created offline and synced later
required
client_created_at datetime Timestamp when the record was created on the client device (may predate server created_at due to offline queue)
required
metadata json Extensible JSON bag for org-specific fields, calendar event IDs, STT transcript references, and future extensions
-
created_at datetime Server-side record creation timestamp
required
updated_at datetime Last server-side update timestamp
required

Database Indexes

idx_activities_org_user_date
btree

Columns: organization_id, user_id, activity_date

idx_activities_org_status
btree

Columns: organization_id, status

idx_activities_org_approval_status
btree

Columns: organization_id, approval_status

idx_activities_contact_id
btree

Columns: contact_id

idx_activities_activity_type_id
btree

Columns: activity_type_id

idx_activities_activity_date
btree

Columns: activity_date

idx_activities_bufdir_eligible
btree

Columns: organization_id, bufdir_eligible, activity_date

idx_activities_duplicate_of
btree

Columns: duplicate_of_activity_id

idx_activities_created_at
btree

Columns: created_at

Validation Rules

duration_positive_integer error

Validation failed

activity_type_exists_in_org error

Validation failed

contact_belongs_to_org error

Validation failed

summary_required_for_formalized_report_type error

Validation failed

participant_count_required_for_group_type error

Validation failed

client_created_at_not_future error

Validation failed

metadata_valid_json error

Validation failed

approved_by_required_when_approved error

Validation failed

Business Rules

activity_date_not_future
on_create

An activity cannot be logged with a date in the future. Peer mentors register activities after they happen.

proxy_reporter_must_be_coordinator
on_create

If proxy_reporter_id is set, that user must hold the Coordinator or Org Admin role within the same organization.

tenant_isolation
always

All reads and writes are scoped to organization_id. A user may only access activities belonging to their own organization.

duplicate_detection_on_submit
on_update

On status transition to 'submitted', the system checks for near-duplicate activities (same user_id, contact_id, activity_type_id, activity_date ± 60 minutes) and flags them for coordinator review.

approval_required_for_expense_reimbursement
always

If has_expense is true, the activity must reach approval_status = 'approved' before the linked expense can be processed for reimbursement.

bulk_registration_peer_mentor_scope
on_create

Bulk-registered activities (is_bulk_registration = true) must all belong to peer mentors within the coordinator's own organization.

Enforced by: Bulk Activity Service
bufdir_eligibility_derived_from_type
on_create

bufdir_eligible is computed from the linked activity_type's bufdir_reportable flag at create time. It may be overridden by an Org Admin.

rejection_requires_reason
on_update

Setting approval_status = 'rejected' requires rejection_reason to be non-null and non-empty.

status_transition_forward_only
on_update

Status transitions follow a directed graph: draft → submitted → approved/rejected/flagged. Approved or rejected activities cannot revert to draft without an explicit admin correction action that creates an audit entry.

offline_sync_id_deduplication
on_create

Activities created offline use client-generated UUIDs. On sync, the server detects duplicate UUIDs and returns the existing record rather than creating a second row.

audit_trail_on_admin_action
on_update

Any approval, rejection, flagging, or duplicate-marking action by an admin or coordinator is written to audit_logs with the acting user_id, action, and timestamp.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
by_date
Retention
Permanent Storage