core PK: id 10 required 1 unique

Description

A free-text or structured note created by a peer mentor or coordinator, optionally linked to a contact. Notes capture follow-up observations, home visit summaries, personal reminders, and assignment-related context. Autosaved drafts are supported to prevent data loss on mobile.

16
Attributes
8
Indexes
7
Validation Rules
20
CRUD Operations

Data Structure

Name Type Description Constraints
id uuid Primary key — unique note identifier
PKrequiredunique
user_id uuid FK to users — the peer mentor or coordinator who authored the note
required
organization_id uuid FK to organizations — enforces tenant isolation so notes are never cross-visible between organizations
required
contact_id uuid FK to contacts — the contact this note is about. Nullable for general notes not tied to a specific contact.
-
title string Optional short title or subject line for the note. Max 255 characters.
-
content text Main body of the note. Supports plain text; entered via keyboard or speech-to-text. Required on publish, nullable while in draft.
-
note_type enum Categorises the note's purpose to allow filtering and structured display in the notes list
required
status enum Lifecycle state of the note. Drafts are autosaved locally and server-side but not shown in the primary list view until published.
required
is_pinned boolean Whether the note is pinned to the top of the notes list for this user
required
is_private boolean If true, only the author can read this note. If false, coordinators with access to the linked contact may also read it.
required
structured_data json Optional JSON blob for structured home visit report fields (Blindeforbundet): health_status, course_interest, assistive_device_situation, way_forward. Null for general notes.
-
autosave_version integer Incremented monotonically on each autosave. Used by the client to detect stale local drafts and resolve last-write-wins conflicts.
required
created_at datetime UTC timestamp when the note record was first created (including initial draft save)
required
updated_at datetime UTC timestamp of the most recent update, including autosaves
required
published_at datetime UTC timestamp when status transitioned from draft to published. Null for drafts.
-
deleted_at datetime Soft-delete timestamp. Null means the record is active. Non-null means logically deleted and excluded from all standard queries.
-

Database Indexes

idx_notes_user_id
btree

Columns: user_id

idx_notes_contact_id
btree

Columns: contact_id

idx_notes_organization_id
btree

Columns: organization_id

idx_notes_user_status
btree

Columns: user_id, status

idx_notes_contact_status
btree

Columns: contact_id, status

idx_notes_updated_at
btree

Columns: user_id, updated_at

idx_notes_deleted_at
btree

Columns: deleted_at

idx_notes_fts
gin

Columns: title, content

Validation Rules

title_max_length error

Validation failed

content_required_on_publish error

Validation failed

note_type_valid_enum error

Validation failed

structured_data_schema warning

Validation failed

contact_id_valid_uuid error

Validation failed

user_id_required error

Validation failed

offline_content_size_limit error

Validation failed

Business Rules

tenant_isolation
always

A note's organization_id must match the authenticated user's active organization context. Cross-organization note reads or writes are rejected at the API layer.

author_ownership
on_update

Only the note's author (user_id) may update or delete the note. Coordinators may read non-private notes belonging to contacts they manage, but cannot modify them.

private_note_visibility
always

When is_private is true, the note is visible only to the author regardless of role. When is_private is false, coordinators with read access to the linked contact may also read the note.

publish_requires_content
on_update

A note may only transition to status=published if the content field is non-empty and non-whitespace. Drafts with empty content remain in draft indefinitely.

soft_delete_only
on_delete

Notes are never hard-deleted from the database. Deletion sets deleted_at to the current timestamp. All queries filter WHERE deleted_at IS NULL by default.

autosave_version_monotonic
on_update

autosave_version must only ever increase. The server rejects updates with a version equal to or lower than the persisted value to prevent stale autosaves from overwriting newer content.

contact_belongs_to_same_org
on_create

When contact_id is provided, the referenced contact must belong to the same organization as the note author. Cross-org contact linking is rejected.

published_at_immutable
on_update

Once published_at is set it cannot be changed. Re-publishing an already-published note is a no-op for this field.

Enforced by: Notes Service

Storage Configuration

Storage Type
primary_table
Location
main_db
Partitioning
by_user
Retention
Permanent Storage