core PK: id 14 required 2 unique

Description

A sensitive, encrypted dispatching record used by Blindeforbundet coordinators to securely send personal information (name, address, medical excerpts) to peer mentors. Assignment payloads are encrypted end-to-end using X25519 + AES-GCM and include tracking for dispatch, read confirmation, and completion status.

20
Attributes
10
Indexes
10
Validation Rules
16
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Globally unique identifier for the assignment record, generated server-side on dispatch.
PKrequiredunique
coordinator_id uuid Foreign key referencing the users table — the coordinator who created and dispatched the assignment. Must have Coordinator role or higher in the associated local association.
required
peer_mentor_id uuid Foreign key referencing the users table — the peer mentor who is the intended recipient of the encrypted assignment payload.
required
contact_id uuid Optional foreign key referencing the contacts table — the person who is the subject of the assignment (e.g., the individual whose personal data is being shared). Nullable for assignments that do not relate to a specific contact record.
-
local_association_id uuid Foreign key referencing the local_associations table. Scopes the assignment to a specific local association for honorarium threshold evaluation and coordinator visibility queries.
required
encrypted_payload text Base64-encoded AES-GCM ciphertext containing the sensitive assignment content (name, address, medical excerpts, special needs). Encrypted client-side using the recipient peer mentor's X25519 public key via ECDH key agreement. Never stored in plaintext.
required
ephemeral_public_key string Base64-encoded X25519 ephemeral public key generated by the sender for this specific assignment. Required by the recipient to derive the shared secret for AES-GCM decryption. Stored alongside the ciphertext.
required
nonce string Base64-encoded 12-byte AES-GCM nonce (IV) used during encryption of this assignment payload. Must be unique per encrypted_payload; generated using a cryptographically secure random source.
requiredunique
public_key_fingerprint string SHA-256 fingerprint (hex-encoded) of the recipient peer mentor's X25519 public key at the time of encryption. Used by the recipient to verify that their current private key corresponds to the key used during dispatch, and to detect key rotation issues.
required
status enum Current lifecycle status of the assignment. Transitions are strictly ordered and validated server-side. 'dispatched' is the initial state set at creation; 'delivered' is set when the push notification is confirmed received; 'read' is set when the peer mentor opens the assignment; 'acknowledged' is set when the peer mentor submits explicit read confirmation; 'completed' is set when the assignment work is done; 'cancelled' can be set by the coordinator at any pre-completion stage.
required
title string A non-sensitive reference label for the assignment visible to the coordinator in list views (e.g., 'Assignment #42' or a date-based reference). Must not contain personal data. Shown in coordinator dashboards without decryption.
required
honorarium_relevant boolean Indicates whether this assignment counts toward the peer mentor's honorarium threshold counter. Set to false for test, cancelled, or administrative assignments. When true and status transitions to 'completed', the threshold-tracking-service increments the peer mentor's assignment counter.
required
dispatched_at datetime UTC timestamp when the assignment was dispatched by the coordinator. Set server-side at record creation and immutable thereafter.
required
read_at datetime UTC timestamp when the peer mentor first opened and viewed the decrypted assignment content. Set server-side when status transitions to 'read'. Null until the peer mentor opens the assignment.
-
acknowledged_at datetime UTC timestamp when the peer mentor submitted explicit read confirmation via the ReadConfirmationWidget. Set server-side when status transitions to 'acknowledged'. Null until explicit confirmation is submitted.
-
completed_at datetime UTC timestamp when the assignment was marked completed. Set server-side when status transitions to 'completed'. Triggers honorarium threshold evaluation if honorarium_relevant is true.
-
cancelled_at datetime UTC timestamp when the assignment was cancelled by the coordinator. Set server-side when status transitions to 'cancelled'. Null for non-cancelled assignments.
-
expires_at datetime Optional UTC timestamp after which the assignment is considered expired and the encrypted payload should no longer be accessible. Supports GDPR-aligned data minimisation for time-limited sensitive data sharing.
-
created_at datetime UTC timestamp of record creation. Set server-side and immutable.
required
updated_at datetime UTC timestamp of the last record modification. Updated automatically on any field change.
required

Database Indexes

idx_assignment_coordinator_id
btree

Columns: coordinator_id

idx_assignment_peer_mentor_id
btree

Columns: peer_mentor_id

idx_assignment_contact_id
btree

Columns: contact_id

idx_assignment_local_association_id
btree

Columns: local_association_id

idx_assignment_status
btree

Columns: status

idx_assignment_coordinator_status
btree

Columns: coordinator_id, status

idx_assignment_peer_mentor_status
btree

Columns: peer_mentor_id, status

idx_assignment_dispatched_at
btree

Columns: dispatched_at

idx_assignment_nonce
btree unique

Columns: nonce

idx_assignment_honorarium_relevant_status
btree

Columns: peer_mentor_id, honorarium_relevant, status

Validation Rules

coordinator_id_is_valid_coordinator error

Validation failed

peer_mentor_id_references_valid_peer_mentor error

Validation failed

encrypted_payload_non_empty error

Validation failed

ephemeral_public_key_valid_format error

Validation failed

nonce_uniqueness error

Validation failed

public_key_fingerprint_matches_registered_key error

Validation failed

contact_id_coordinator_scope error

Validation failed

title_no_personal_data warning

Validation failed

expires_at_after_dispatched_at error

Validation failed

status_update_actor_authorization error

Validation failed

Business Rules

coordinator_role_required_for_dispatch
on_create

Only users with the Coordinator role or higher (Organization Administrator, Global Administrator) within the same local_association_id may create and dispatch assignments. Peer mentors cannot create assignments.

payload_must_be_encrypted_before_dispatch
on_create

The encrypted_payload field must contain a valid AES-GCM ciphertext encrypted with the recipient's X25519 public key. Plaintext payloads are rejected. Encryption is performed client-side in the Flutter app before the record is submitted to the backend.

status_transition_must_be_forward_only
on_update

Assignment status transitions must follow the defined lifecycle order: dispatched → delivered → read → acknowledged → completed. The 'cancelled' terminal state may be applied from any pre-completion status by the original coordinator. Backward transitions (e.g., read → dispatched) are rejected.

honorarium_counter_increment_on_completion
on_update

When an assignment transitions to 'completed' status and honorarium_relevant is true, the peer mentor's assignment counter is atomically incremented. The threshold-tracking-service evaluates whether a honorarium tier boundary has been crossed and emits a threshold-crossing notification event if applicable.

honorarium_counter_decrement_on_cancellation
on_update

When an assignment that was previously 'completed' is not applicable (edge case: administrative correction), or when a completed assignment count is adjusted, the assignment counter is decremented. This prevents erroneous honorarium tier escalation.

read_confirmation_requires_explicit_acknowledgement
on_update

The status transition from 'read' to 'acknowledged' requires the peer mentor to submit an explicit confirmation action through the ReadConfirmationWidget — passive scrolling or time-based triggers are not sufficient. This ensures legal certainty for Blindeforbundet's sensitive data delivery requirements.

encrypted_payload_inaccessible_after_expiry
always

If expires_at is set and the current timestamp exceeds it, the encrypted_payload field must not be returned in API responses. The backend returns a placeholder indicating the assignment payload has expired. This supports GDPR data minimisation for sensitive personal data.

only_recipient_can_decrypt
always

The encrypted_payload can only be decrypted by the peer mentor whose X25519 public key was used during encryption (identified by public_key_fingerprint). The coordinator can view assignment metadata (title, status, timestamps) but not the decrypted payload content.

peer_mentor_must_be_active
on_create

Assignments may only be dispatched to peer mentors whose status is 'active' (not paused, suspended, or deactivated). Attempting to dispatch to a paused or deactivated peer mentor returns a validation error and prompts the coordinator to check the mentor's status.

push_notification_on_dispatch
on_create

A push notification is sent to the recipient peer mentor immediately upon successful assignment dispatch, informing them that a new sensitive assignment awaits. The notification payload does not include sensitive content — only the assignment reference and a prompt to open the app.

calendar_feed_privacy_mask
always

When assignment records are included in iCal feed generation, the title, description, and contact information in the VEvent must be replaced with a generic placeholder (e.g., 'Encrypted Assignment') to prevent sensitive data leakage via third-party calendar integrations.

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
by_date
Retention
Permanent Storage

Entity Relationships

assignment_status_log
outgoing one_to_many

An assignment has an immutable log of all status transitions from dispatch through completion

required
contact
incoming one_to_many

A contact may be the subject of multiple encrypted assignments dispatched to different peer mentors

optional
peer_mentor
incoming one_to_many

A peer mentor is the recipient of many encrypted assignments dispatched by coordinators

required
user
incoming one_to_many

A coordinator (user) dispatches many encrypted assignments to peer mentors

required