core PK: id 10 required 1 unique

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.

14
Attributes
5
Indexes
9
Validation Rules
15
CRUD Operations

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
btree

Columns: organization_id

idx_mentor_program_session_coordinator_id
btree

Columns: coordinator_id

idx_mentor_program_session_org_start_date
btree

Columns: organization_id, start_date

idx_mentor_program_session_status
btree

Columns: organization_id, status

idx_mentor_program_session_updated_at
btree

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
on_create

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
on_create

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
on_update

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.

Enforced by: Mentor Program Service
completed_session_structural_lock
on_update

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.

Enforced by: Mentor Program Service
archived_session_full_lock
on_update

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
always

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
on_delete

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
on_create

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.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
No Partitioning
Retention
archive_after_1year

Entity Relationships

workshop_participant
outgoing one_to_many

A mentor program session has many participant records tracking attendance per session day

required cascade delete