core PK: id 11 required 1 unique

Description

A structured group guidance or career workshop session facilitated by a coordinator or peer mentor, supporting Blindeforbundet's karriereverksted programme. Sessions have a lifecycle from scheduled through active to completed and archived, with notes and to-do lists.

18
Attributes
6
Indexes
11
Validation Rules
18
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key, auto-generated UUID for each workshop session
PKrequiredunique
coordinator_id uuid Foreign key referencing the users table β€” the coordinator or peer mentor facilitating this session
required
organization_id uuid Foreign key referencing the organizations table β€” scopes the session for RLS and Bufdir aggregate reporting
required
title string Human-readable title of the workshop session, e.g. 'Karriereverksted dag 1 – TromsΓΈ'
required
description text Optional longer description of the session agenda, goals, or preparation notes
-
session_type enum Classifies the type of workshop: career workshop (karriereverksted), group guidance session, mentorship session, or other
required
status enum Lifecycle state of the session following the allowed transition sequence: scheduled β†’ active β†’ completed β†’ archived
required
location string Optional free-text location description (venue name, address, or 'Remote / Video')
-
scheduled_at datetime Planned start date and time of the session in UTC. May be in the past for retrospectively created sessions
required
started_at datetime Actual timestamp when the coordinator marked the session as active (started). Set on transition from scheduled to active
-
completed_at datetime Timestamp when the session was marked as completed. Must be after started_at. Used for Bufdir reporting period aggregation
-
archived_at datetime Timestamp when the session was archived. Archived sessions are read-only
-
max_participants integer Optional cap on the number of participants that can be added to this session. Null means uncapped
-
participant_count integer Denormalized count of registered participants (mirrors COUNT on workshop_participants). Updated by trigger or service layer on participant add/remove. Used for quick Bufdir reporting queries
required
notes_count integer Denormalized count of note entries in workshop_notes for this session. Updated on note creation/deletion
required
todo_items json Ordered list of follow-up to-do items stored inline as a JSON array. Each item: {id: uuid, title: string, completed: boolean, order: integer, created_at: ISO8601}. Managed by the To-Do List Widget without a separate table
-
created_at datetime Timestamp of record creation in UTC, auto-set by Supabase
required
updated_at datetime Timestamp of the most recent update in UTC, auto-updated by Supabase trigger on every row change
required

Database Indexes

idx_workshop_sessions_coordinator_id
btree

Columns: coordinator_id

idx_workshop_sessions_organization_id
btree

Columns: organization_id

idx_workshop_sessions_status
btree

Columns: status

idx_workshop_sessions_scheduled_at
btree

Columns: scheduled_at

idx_workshop_sessions_org_status
btree

Columns: organization_id, status

idx_workshop_sessions_org_completed_at
btree

Columns: organization_id, completed_at

Validation Rules

title_required_non_empty error

Validation failed

scheduled_at_required error

Validation failed

coordinator_id_valid_user error

Validation failed

organization_id_valid error

Validation failed

completed_at_after_started_at error

Validation failed

archived_at_after_completed_at error

Validation failed

todo_items_valid_json_schema error

Validation failed

todo_items_valid_json_schema_update error

Validation failed

max_participants_positive error

Validation failed

participant_count_non_negative warning

Validation failed

description_max_length error

Validation failed

Business Rules

valid_status_transition
on_update

Status transitions must follow the defined lifecycle sequence: scheduled β†’ active β†’ completed β†’ archived. Reverse transitions and skipped states (e.g., scheduled directly to completed) are forbidden. The only exception is direct archival of a scheduled session that was cancelled before starting.

archived_session_immutable
on_update

Sessions in archived status are read-only. Any attempted mutation of title, status, description, location, todo_items, or timestamps on an archived session must be rejected. Only admin-level delete operations are permitted.

coordinator_role_required
always

Only users holding a coordinator or admin role within the session's organization may create, update, or delete workshop sessions. Peer mentors may read sessions they are participants of but cannot mutate session records.

participant_count_consistency
on_update

The denormalized participant_count must remain consistent with the actual count of rows in workshop_participants for this session. It is incremented on participant add and decremented on participant remove via the workshop-management-service. If max_participants is set, participant_count must never exceed it.

max_participants_not_exceeded
on_update

When max_participants is defined, adding a new participant to the session is rejected once participant_count equals max_participants. The Participant List Screen surfaces a capacity-reached message to the coordinator.

completed_at_set_on_completion
on_update

When a session transitions from active to completed, completed_at must be automatically set to the current UTC timestamp by the service layer if not explicitly provided. completed_at may not be null once status is completed.

organization_scoped_access
always

Workshop sessions are visible only to users whose organizational membership (user_organization_memberships) includes the session's organization_id. Supabase RLS policies enforce this at the database level using auth.uid() and JWT org claims.

bufdir_reporting_inclusion
always

Completed workshop sessions (status = completed, completed_at set) are included in Bufdir aggregate reporting counts for the organization. The participant_count field is used as the authoritative figure for the reporting period query. Archived sessions retain their participant_count for historical reporting accuracy.

todo_items_max_count
on_update

The todo_items JSON array may contain at most 50 items per session. Attempts to add a 51st item are rejected with a user-facing capacity message from the To-Do List Widget.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
No Partitioning
Retention
Permanent Storage

Entity Relationships

organizations
outgoing many_to_one

Workshop sessions are scoped to an organization for access control and aggregate Bufdir reporting

required
users
outgoing many_to_one

Each workshop session is created and facilitated by a coordinator user

required
workshop_notes
outgoing one_to_many

Each workshop session may accumulate multiple note entries created during or after the session

optional cascade delete
workshop_participants
outgoing one_to_many

A workshop session tracks attendance for multiple participants with confirmation status

optional cascade delete