Mentor Program Session
Data Entity
Description
A structured mentorship or career workshop session specific to Blindeforbundet's group mentoring program. Stores session metadata (title, dates, location), rich-text notes, embedded to-do checklists as JSON, and links to participants. Supports multi-day workshop organization.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Immutable primary key, generated on creation (UUID v4) | PKrequiredunique |
organization_id |
uuid |
FK to organizations table. Scopes the session to a specific member organization (e.g. Blindeforbundet). Enforces multi-tenancy โ sessions are never visible across organizational boundaries. | required |
coordinator_id |
uuid |
FK to users table. The coordinator who owns and manages this workshop session. Must hold Coordinator or higher role within the same organization. | required |
title |
string |
Human-readable session title, e.g. 'Karriereverksted Hรธst 2025 โ Oslo'. Displayed as the primary identifier in session lists. | required |
start_date |
datetime |
UTC timestamp marking the start of the first day of the workshop session. Used for chronological sorting and calendar display. | required |
end_date |
datetime |
UTC timestamp marking the end of the last day of the workshop session. Must be >= start_date. Equal to start_date for single-day sessions. | required |
location |
string |
Free-text location or venue description, e.g. 'Blindeforbundet Oslo, Konferanserommet 2'. Optional โ some sessions may be held remotely. | - |
notes_json |
json |
Structured rich-text session notes stored as a JSON document. Supports day-based note organisation for multi-day workshops. Schema: { days: [{ day_index: number, date: ISO-string, content: string (rich-text markdown or delta), updated_at: ISO-string }] }. Null when no notes have been written yet. | - |
todos_json |
json |
Embedded to-do checklist as a JSON array. Each item tracks a task with completion state. Schema: [{ id: uuid-string, text: string, completed: boolean, created_at: ISO-string, completed_at: ISO-string | null }]. Allows coordinators to track follow-up actions without a separate task entity. | - |
status |
enum |
Lifecycle status of the session. Controls visibility and editability. 'draft' sessions are unpublished. 'active' sessions are in progress or upcoming. 'completed' sessions are locked from structural edits but notes remain editable. 'archived' sessions are hidden from default views. | required |
duration_days |
integer |
Computed and stored count of calendar days spanned by the session (inclusive). Minimum 1. Used by the participant list widget to render per-day attendance columns. Recalculated on start_date or end_date update. | required |
created_at |
datetime |
UTC timestamp set automatically on row insertion. Never updated. | required |
updated_at |
datetime |
UTC timestamp updated on every modification via a database trigger or ORM hook. Used for optimistic concurrency checks and cache invalidation. | required |
archived_at |
datetime |
UTC timestamp set when the session is archived. Null for non-archived sessions. Together with status='archived', this supports soft-delete semantics and enables audit queries. | - |
Database Indexes
idx_mentor_program_session_org_id
Columns: organization_id
idx_mentor_program_session_coordinator_id
Columns: coordinator_id
idx_mentor_program_session_org_start_date
Columns: organization_id, start_date
idx_mentor_program_session_status
Columns: organization_id, status
idx_mentor_program_session_updated_at
Columns: updated_at
Validation Rules
title_not_blank
error
Validation failed
start_date_not_in_past_for_draft
warning
Validation failed
notes_json_schema_valid
error
Validation failed
todos_json_schema_valid
error
Validation failed
notes_json_day_index_within_bounds
error
Validation failed
location_max_length
error
Validation failed
organization_id_exists
error
Validation failed
coordinator_id_exists
error
Validation failed
duration_days_minimum_one
error
Validation failed
Business Rules
coordinator_org_membership_required
The coordinator_id must belong to a user who holds a Coordinator or higher role within the same organization as organization_id. Prevents cross-organization session creation and ensures only authorized staff manage workshop sessions.
start_date_before_or_equal_end_date
start_date must be less than or equal to end_date. Violations are rejected at the service layer before reaching the database constraint. The workshop-session-form also enforces this as a client-side validation to give immediate feedback.
duration_days_sync
duration_days must always equal CEIL((end_date - start_date) / 86400) + 1. Recalculated and persisted by mentor-program-service whenever start_date or end_date changes. Keeps the participant attendance matrix column count consistent without runtime computation.
completed_session_structural_lock
Once a session reaches status='completed', its title, start_date, end_date, location, and duration_days fields are locked and cannot be changed. Only notes_json and todos_json remain editable to allow post-workshop documentation. Updates to locked fields are rejected with a descriptive error.
archived_session_full_lock
Once a session reaches status='archived', all fields are immutable. The session and its participant records remain visible to authorized users for audit purposes but cannot be modified. archived_at is set to NOW() at the moment of archival.
organization_scope_enforcement
All read and write operations on mentor_program_sessions are scoped to the requesting user's active organization_id derived from the JWT claims. Queries without a matching organization_id must return zero results, never a 403, to avoid leaking existence of other organizations' sessions.
soft_delete_only
Sessions are never hard-deleted from the database. Instead, they transition to status='archived' and archived_at is set. This preserves participant attendance records and historical notes for coordinator review and potential Bufdir-adjacent compliance queries.
todos_json_item_id_uniqueness
Each object in todos_json must have a unique 'id' field within the array. mentor-program-service generates a UUID for each new to-do item before persisting. Prevents merge conflicts when two edits add items simultaneously.
CRUD Operations
Storage Configuration
Entity Relationships
A mentor program session has many participant records tracking attendance per session day