## Section 1: Use Case & Participants

### 1.1 Who are the users?
- Patients only
- Providers / staff / partners (clients or outside vendors) only
- Both

### 1.2 What is your organizational structure?
- Single organization
- Multiple locations of one organization
- Multiple independent organizations (MSO-style)
- Departments or service lines within one organization
- Combination

## Section 2: Multi-tenancy

Isolation uses **compartments** (`meta.compartment`) matched by parameterized access policies.

**Design principle:** Push complexity into enrollment Bots, not policies. Each patient is tagged with their tenant(s); each practitioner's `ProjectMembership.access` lists every tenant they work in.

### 2a Tenant Modeling

**Questions:**
- Internal term for tenants? (clinics, programs, sites, accounts)
- Grouping is organizational, functional, or per-patient?
- Is there an organizational hierarchy (e.g., region → clinic)?

| Situation                                                   | Approach                |
|------------------------------------------------------------|-------------------------|
| Clinics, practices, locations (MSO)                        | `Organization`          |
| Service lines, departments                                   | `HealthcareService`     |
| Dedicated team per patient                                   | `CareTeam` per patient  |

### 2b Patient and Practitioner Sharing

**Questions:**
- Can a patient be enrolled in more than one tenant at a time?
- Are practitioners isolated to their tenant, or visible across all tenants (global directory)?

| Situation                                                   | Approach                                                    |
|------------------------------------------------------------|-------------------------------------------------------------|
| One tenant per patient                                      | Single compartment on the Patient                          |
| Patient shared across tenants                               | Multiple compartments, one per tenant                      |
| Practitioners shared (global directory)                     | Leave unassigned; policy reads without `_compartment` filter |
| Practitioners isolated per tenant                           | Tag with tenant compartment; policy filters by `_compartment` |

## Section 3: Roles & Permissions

For each role: name it, scope it (which tenants, if multi-tenant), say what resources it touches, and narrow as needed.

### 3a Role Inventory & Scope

**Questions:**
- What are the role names? (physician, RN, MA, front desk, billing, care coordinator, medical director)
- _If multi-tenant:_ for each role, which tenants does it cover? (one, several, all)
- Any oversight roles that need visibility across all tenants without per-tenant enrollment?

| Role scope                                                | Modeling approach                                       |
|----------------------------------------------------------|--------------------------------------------------------|
| One tenant                                              | Single `ProjectMembership.access` entry parameterized with that tenant |
| Multiple tenants, combined view                          | One `access` entry per tenant, same policy            |
| Org-wide / cross-tenant oversight                        | Unparameterized policy, no `_compartment` filter       |
| Tenants contractually can't share data (e.g., locum across competitor clinics) | Separate logins per tenant — see callout below

### 3b Permission Mechanics

**Questions:**
- For each role: which resource types does it read / write / search / delete?
- Any partial FHIR interactions? (create-only, read-without-search, etc.)

| Situation                                                 | Approach                                      |
|----------------------------------------------------------|-----------------------------------------------|
| Full CRUD on a resource                                   | Standard `resource` entry, no `interaction` restriction |
| Read-only                                                | `readonly: true`                           |
| Partial interactions                                      | Explicit `interaction` array                 |

### 3c Narrowing What a Role Can Do

**Field-level** — partial field access (e.g., billing sees Patient minus diagnoses):

| Situation                                                 | Approach                                   |
|----------------------------------------------------------|--------------------------------------------|
| Readable but not writable                                 | `readonlyFields`                            |
| Not visible                                              | `hiddenFields` (masks output only)        |

#### Additional Write constraints

| Situation                                                 | Approach                                   |
|----------------------------------------------------------|--------------------------------------------|
| Prevent field change in terminal state                    | `writeConstraint` on `%before`            |
| Require field at transition                               | `writeConstraint` on `%after` + field presence |
| Update-only                                              | Prefix with `%before.exists() implies ...` |
| Create-only                                              | Prefix with `%before.exists().not() implies ...` |

## Section 4: Admin Structure

**Questions:**
- Who invites/removes users and manages memberships?
- Who manages Bots, ClientApplications, AccessPolicies?
- Any super admin needs? (project creation via API, overwriting protected fields)
- Should admins be blocked from clinical data?

| Situation                                                 | Approach                             |
|----------------------------------------------------------|--------------------------------------|
| Standard admin                                          | `ProjectMembership.admin`            |
| Admin with narrowed clinical access                       | Admin flag + dedicated AccessPolicy   |
| Admin blocked from clinical content                       | Admin flag + `hiddenFields` on clinical resources |
| Project creation, overwriting protected fields            | Super admin — server operators only  |
| Separate "user manager" vs. "tech admin"              | Two AccessPolicies stacked on admin flag |

# Appendix: Additional Decisions

## A. Open Registration & Caregivers

**Questions:**
- Self-registration or staff-invite?
- Are caregivers / proxies needed? (parents, adult children, guardians)
- One caregiver with multiple patients? One patient with multiple caregivers?
- How is the caregiver relationship established and revoked?

| Situation                                                  | Approach                                     |
|-----------------------------------------------------------|----------------------------------------------|
| Invite-only                                              | Standard `ProjectMembership` with patient policy |
| Open self-registration                                     | Set `Project.defaultPatientAccessPolicy`; enable open registration |
| Patient sees own data                                      | Parameterized policy with `%patient` on clinical resources |
| Single caregiver, single patient                           | One `access` entry with `%patient`         |
| One caregiver, multiple patients                           | Multiple `access` entries, different `%patient` |
| Multiple caregivers per patient                            | Each caregiver has their own ProjectMembership |
| Revoke caregiver                                           | Remove the corresponding `access` entry    |
| Time-bound caregiver access (e.g., expires at age 18)    | Application-layer enforcement — not native |

## B. SMART on FHIR

**Questions:**
- Patient-context launch, provider-context launch, or standalone?
- Which scopes?
- Offline access needed?

| Situation                                                 | Approach                             |
|----------------------------------------------------------|---------------------------------------|
| Your own frontend                                       | Not SMART — standard ClientApplication + AccessPolicy |
| Third-party, patient-context                            | SMART 2.0.0, `launch/patient`         |
| Third-party, provider-context                           | SMART 2.0.0, `launch`                  |
| Standalone patient app                                   | `patient/*.rs` or narrower             |
| Offline access                                           | Add `offline_access`                   |

## C. IP Access Rules

**Questions:**
- Restrict by IP range? (VPN, on-prem devices)
- Any roles that bypass?

| Situation                                                 | Approach                              |
|----------------------------------------------------------|---------------------------------------|
| VPN-only                                                | Allow VPN ranges + wildcard block     |
| On-prem only                                            | Allow clinic network + wildcard block  |
| Mixed                                                   | Different AccessPolicies per role      |

## D. Enrollment & Reassignment Workflows

**Questions:**
- When does a patient get enrolled in a tenant? (registration, first appointment, referral, insurance, geography)
- Who is authorized to move a patient between tenants?
- On transfer: do records follow the patient, stay with the original tenant, or become shared?

| Situation                                                 | Approach                               |
|----------------------------------------------------------|----------------------------------------|
| Patient enrollment                                       | Bot calls [`$set-accounts`](/content/docs/api/fhir/operations/set-accounts/index.html) on the triggering event; use `propagate: true` to tag related resources |
| Transfer, records follow                                | Update compartment with `propagate: true`; old tenant loses access |
| Transfer, records stay / shared                          | Add new compartment (don't replace); both tenants retain access |

## E. Shared vs. Tenant-Specific Resources

**Questions:**
- Terminology (CodeSystems, ValueSets) shared or tenant-specific?
- Questionnaires shared or per-tenant?
- PlanDefinitions / ActivityDefinitions global or per-tenant?
- Any resources shared across projects (not just tenants)?

| Situation                                                 | Approach                              |
|----------------------------------------------------------|---------------------------------------|
| Shared standard terminology                                | Leave unassigned; unfiltered read in policy |
| Tenant-specific Questionnaires                             | `$set-accounts` tags with tenant; filter by `_compartment` |
| Mixed (some global, some per-tenant)                     | Two resource entries in policy: one filtered, one unfiltered |
| Global Bots                                             | Leave unassigned; Bots run as ClientApplication |
| Reference data shared across multiple projects             | Super admin creates a linked project (read-only view) |

## F. Role-Aware UI

| Situation                                                 | Approach                             |
|----------------------------------------------------------|---------------------------------------|
| UI changes based on role                                 | `AccessPolicy.basedOn` + `/auth/me`  |
