Skip to content
Docs

Command palette

Jump to a page or view, or find a todo by name.

Changelog

Instructors and Academies are Organizations

The repository's architectural decision, rationale and consequences.

Markdown

Status: accepted · Date: 2026-11-13 · Related: ADR-0003, ADR-0009

Enforcement: [test] instructor.procedures.test.ts (another Organization gets NOT_FOUND/CONFLICT, a non-Member FORBIDDEN) · [test] packages/db/src/rls-catalog.test.ts and db:verify-rls.

The template's tenant is the Organization, and every User gets a personal Organization at sign-up. BJJ Travel has two sides: an Instructor (one person) and an Academy (an owner plus staff).

Decision

  • Travel Role is chosen once per Organization (travel_role): instructor or academy (US-01). The Instructor's personal Organization holds instructor_profile, travel_window, visit and consent_record; an Academy is an Organization with Members (S5).
  • The network (S2) lives there too: contact, introduction (insert-only, no UPDATE grant) and intro_request (UPDATE only on status, answered_at). A Contact has no email or phone column (RN08).
  • All Instructor tables use pgTable.withRLS + tenantPolicy; history tables (visit, consent_record) get no UPDATE grant.
  • Cross-side reads (an Academy sees published windows; an Instructor sees registered Academies) are deliberate tenant crossings through asSystem(db, reason, fn), each with its own SystemReason, and return only what the visibility rules allow.
Edit on GitHubDocumentation is in English.
Cookie settings
We use essential cookies to make our app work. With your consent, we also use optional cookies to improve your experience.

Read our Cookie Policy and Privacy Policy.