Event
Data Entity
Description
A structured group activity with multiple participants, distinct from single-contact activities. Events represent recurring sessions, café meetings, guided tours, or exercise groups and contribute participant counts directly to Bufdir reporting calculations.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Globally unique identifier for the event record, generated server-side at insert time. | PKrequiredunique |
created_by |
uuid |
Foreign key referencing the users table. The user who created this event — typically a peer mentor or coordinator acting on behalf of a mentor. | required |
organization_id |
uuid |
Foreign key referencing the organizations table. Scopes the event to a specific member organization for RLS enforcement and Bufdir report attribution. | required |
title |
string |
Human-readable name for the event (e.g., 'Weekly Tuesday Exercise Group', 'Café Meeting – Oslo East'). Displayed in lists and reports. | required |
event_type |
enum |
Categorical classification of the event type, used for Bufdir activity type mapping and coordinator filtering. | required |
event_date |
datetime |
The date and start time of the event in UTC. Used as the primary key dimension for Bufdir reporting period assignment and deduplication checks. | required |
duration_minutes |
integer |
Duration of the event in minutes. Used in Bufdir aggregate hour calculations and honors the same minimum/maximum constraints as single activities. | required |
location |
string |
Free-text description of the physical or virtual location where the event took place (e.g., 'Oslo Handikaplaget, Møterom A', 'Zoom'). Optional for digital events. | - |
summary |
text |
Free-text narrative summary of the event, dictated or typed by the event creator. Supports speech-to-text input. Used for coordinator oversight and Bufdir audit documentation. | - |
participant_count |
integer |
Denormalized count of confirmed participants for this event, kept in sync with the event_participants join table via database trigger. Used directly in Bufdir report aggregation without requiring an extra join. | required |
status |
enum |
Lifecycle status of the event record. Only 'completed' events are included in Bufdir reporting aggregations. 'Cancelled' events are retained for audit purposes. | required |
max_participants |
integer |
Optional upper bound on attendance. When set, the Event Participants Widget prevents adding participants beyond this limit. Null means unlimited. | - |
is_recurring |
boolean |
Flags whether this event is part of a recurring series (e.g., weekly exercise group). Recurring events may share a recurrence_group_id for coordinator grouping. | required |
recurrence_group_id |
uuid |
Optional identifier grouping recurring event instances together. Null for one-off events. Used by coordinator dashboards to display series-level statistics. | - |
activity_type_id |
uuid |
Foreign key referencing the activity_types table. Maps the event to the organizational activity taxonomy used in Bufdir reporting and coordinator statistics. | - |
bufdir_period_id |
uuid |
Foreign key referencing the report_periods table. Assigned automatically at completion time to associate the event with the correct Bufdir reporting period. Null until event is completed. | - |
coordinator_notes |
text |
Internal notes added by coordinators when reviewing or correcting the event record. Not visible to the peer mentor who created the event. | - |
rejection_reason |
text |
Populated when a coordinator rejects or flags the event during the approval workflow. Displayed to the original creator with instructions to correct and resubmit. | - |
created_at |
datetime |
Server-set UTC timestamp of record creation. Used for audit trails and deduplication window calculations. | required |
updated_at |
datetime |
Server-set UTC timestamp updated on every mutation via a database trigger. Used for cache invalidation and sync log comparisons. | required |
Database Indexes
idx_events_created_by
Columns: created_by
idx_events_organization_id
Columns: organization_id
idx_events_event_date
Columns: event_date
idx_events_status
Columns: status
idx_events_organization_date
Columns: organization_id, event_date
idx_events_organization_status_date
Columns: organization_id, status, event_date
idx_events_bufdir_period
Columns: bufdir_period_id
idx_events_recurrence_group
Columns: recurrence_group_id
idx_events_created_by_date
Columns: created_by, event_date
Validation Rules
title_not_empty
error
Validation failed
event_date_not_future_at_completion
error
Validation failed
duration_positive_integer
error
Validation failed
event_type_valid_enum
error
Validation failed
organization_id_membership_check
error
Validation failed
summary_length_limit
error
Validation failed
location_length_limit
error
Validation failed
max_participants_positive
error
Validation failed
recurrence_group_consistency
error
Validation failed
activity_type_id_org_scoped
error
Validation failed
Business Rules
organization_scope_required
Every event must be associated with an organization_id. Supabase RLS policies use auth.uid() and JWT org claims to restrict event reads and writes to members of the owning organization only. Cross-organization reads are blocked at the database level.
creator_must_be_authenticated_member
The created_by value must match a user who holds an active membership in the organization specified by organization_id. Coordinators may create events on behalf of mentors they supervise; global admins may create events in any organization.
completed_events_contribute_to_bufdir
Only events with status='completed' are included in Bufdir reporting aggregations. The Bufdir Report Generator Service queries events by organization_id, bufdir_period_id, and status='completed', summing participant_count across all matching records.
participant_count_sync
The denormalized participant_count field must always equal the actual count of rows in event_participants for this event. A database trigger increments/decrements participant_count on event_participants insert/delete to maintain consistency without requiring application-layer aggregation.
min_one_participant_for_completion
An event may not transition to status='completed' unless participant_count >= 1. A completed event with zero participants would generate invalid Bufdir data. This rule is enforced in Event Service before the status transition is written.
max_participants_ceiling
When max_participants is set on an event, the Event Participants Widget and Event Service must reject attempts to add participants once the ceiling is reached. The check is performed both client-side (for UX feedback) and server-side (for integrity).
cancelled_events_immutable
Once an event reaches status='cancelled', no further attribute updates are permitted except for coordinator_notes and rejection_reason. Attempts to update other fields return an error. The record is retained permanently for audit purposes.
bufdir_period_assignment_on_completion
When an event is transitioned to status='completed', the Event Service must resolve and assign the correct bufdir_period_id based on event_date and the organization's configured reporting periods. Events whose event_date falls outside any open reporting period are flagged with a warning but not blocked.
coordinator_approval_for_correction
Coordinators may correct event records submitted by peer mentors. All corrections must include a non-empty rejection_reason or coordinator_notes explaining the change. The Activity Approval Service enforces this before persisting the correction.
duplicate_detection_on_create
Before persisting a new event, the Duplicate Detection Service checks for existing events with the same created_by, event_date (within ±15 minutes), and activity_type_id. A high-confidence match surfaces a warning dialog. The user must explicitly confirm to override.
CRUD Operations
Storage Configuration
Entity Relationships
An event records multiple participant attendance entries for Bufdir participant counting
Events are scoped to an organization for RLS enforcement and Bufdir reporting attribution
A user creates group event records representing multi-participant activities