derived PK: id 11 required 1 unique

Description

Derived aggregate of a peer mentor's activity, engagement, and impact metrics for a calendar year, powering the Spotify Wrapped-style 'Annual Summary (Wrapped)' feature in the Achievements & Gamification area.

19
Attributes
3
Indexes
5
Validation Rules
7
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key
PKrequiredunique
user_id uuid Foreign key to users table — the peer mentor this summary belongs to
required
year integer Calendar year this summary covers (e.g. 2024)
required
total_activities integer Total number of registered activities in the year
required
total_hours decimal Total hours logged across all activities in the year
required
total_contacts_reached integer Unique contacts the peer mentor interacted with during the year
required
total_events_attended integer Number of events the peer mentor signed up for and attended
-
activity_type_breakdown json Map of activity_type → count for the year, e.g. {"home_visit": 12, "phone_call": 40}
-
monthly_activity_counts json Array of 12 integers representing activity count per month (index 0 = January)
-
most_active_month integer Month number (1–12) with the highest activity count
-
longest_streak_days integer Longest consecutive-day streak of activity registration in the year
-
badges_earned_count integer Number of achievement badges earned during the year
-
highlight_stat_key string Key identifying the single most impressive stat to surface as the hero metric on the Wrapped screen (e.g. 'total_activities', 'total_hours')
-
highlight_stat_value string Formatted string value of the hero metric for display (e.g. '380')
-
organization_id uuid Organization context at time of generation — ensures multi-tenant isolation
required
generated_at datetime Timestamp when this summary was last computed
required
is_final boolean True once the year has closed and the summary is locked; false while the year is still in progress (interim summary)
required
created_at datetime Row creation timestamp
required
updated_at datetime Row last-updated timestamp
required

Database Indexes

idx_annual_summaries_user_year
btree unique

Columns: user_id, year

idx_annual_summaries_user_id
btree

Columns: user_id

idx_annual_summaries_organization_year
btree

Columns: organization_id, year

Validation Rules

year_range_valid error

Validation failed

non_negative_counts error

Validation failed

monthly_array_length error

Validation failed

user_exists error

Validation failed

highlight_stat_consistency warning

Validation failed

Business Rules

one_summary_per_user_per_year
on_create

Only one annual_summaries row may exist per (user_id, year) pair. Regeneration updates the existing row rather than inserting a new one.

interim_summary_allowed_current_year
on_update

For the current calendar year, is_final is false and the summary may be recomputed at any time. For past years, is_final is true and the row is immutable after finalization.

Enforced by: AnnualSummaryService
module_toggle_gate
always

Annual summaries may only be generated and displayed if the achievements-gamification module is enabled for the user's organization.

peer_mentor_only
on_create

Annual summaries are generated only for users with the Peer Mentor role. Coordinators and admins do not receive Wrapped summaries.

Enforced by: AnnualSummaryService
organization_isolation
always

A summary may only be read by the owning user or by a coordinator/admin within the same organization.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
by_user
Retention
Permanent Storage