> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# ADR-002: CL-PM Cross-Core Foreign Keys

> Status: Accepted Date: 2026-02-25 Decision Makers: Platform Architecture Team

**Status:** Accepted\
**Date:** 2026-02-25\
**Decision Makers:** Platform Architecture Team

***

## Context

CL (Clinical) tables such as `cl_progress_notes`, `cl_group_sessions`, and `cl_peer_encounters` reference the encounter entity via an `encounter_id` (or equivalent) column pointing to `pm_encounters.id`. The encounter is owned by PM and is the canonical entity linking scheduling, clinical documentation, and billing.

Current practice uses UUID columns with no database foreign key constraint; validation is done at the application layer. This creates data integrity risk: if an encounter is deleted (or the reference is mistyped), clinical records can be left with orphaned or invalid references. There is no database-level guarantee that `encounter_id` points to an existing row in `pm_encounters`.

## Decision

**Allow a scoped exception: CL tables MAY add a database foreign key from their encounter reference column to `pm_encounters.id` with `ON DELETE RESTRICT`.**

* **Scope:** Only the encounter entity. Only CL tables that reference `pm_encounters` may use this FK. No other cross-core foreign key is permitted without a separate ADR.
* **Constraint:** `ON DELETE RESTRICT` so that an encounter with linked clinical documentation cannot be deleted until those links are removed or the documentation is reassigned.
* **Indexes:** The FK column MUST be indexed (per constitution §5.2).
* **RLS:** Tenant isolation remains enforced by RLS on both CL and PM tables; the FK does not bypass RLS.

## Rationale

1. **Encounter is the fundamental joint** between clinical documentation and revenue cycle. Every major EHR/PM system treats this as a tight coupling point; allowing a single, well-defined FK reflects that reality without relaxing the broader no-cross-core-import rule.

2. **Referential integrity** prevents orphaned clinical notes and avoids silent data corruption. Application-layer checks can be missed; a database constraint cannot.

3. **RESTRICT over CASCADE** ensures we never automatically delete or null out clinical documentation when an encounter is removed. Deletion of encounters with documentation must be an explicit, controlled workflow.

4. **Narrow scope** keeps the exception from becoming a precedent for other cross-core FKs. Other cross-core references (e.g., referrals, schedules) remain UUID-only unless a future ADR approves them.

## Consequences

### Positive

* Referential integrity between CL documentation and PM encounters
* Impossible to delete an encounter that still has linked progress notes, group sessions, or peer encounters without explicit handling
* Clear, single exception documented for implementers and reviewers

### Negative

* Deployment ordering: PM migrations that define or alter `pm_encounters` must run before CL migrations that add the FK
* Cross-core dependency at the database level (mitigated by keeping it to one entity and one direction: CL → PM)

### Mitigations

* Document migration order in PM/CL deployment runbooks
* Constitution §5.2.7 and this ADR make the rule and its scope explicit
* No other cross-core FK is permitted without a new ADR

## Related Documents

* [Constitution §1.2](../../../constitution.md) – Cross-core database references and CL-PM exception
* [Constitution §5.2.7](../../../constitution.md) – Cross-Core Database References
* [CL-PM Encounter-to-Billing](../integrations/CL-PM-ENCOUNTER-TO-BILLING.md) – Encounter lifecycle and event contracts
* [ADR-005](./ADR-005-cross-core-fk-pm-patients.md) – `pm_patients` cross-core FKs
* [ADR-006](./ADR-006-cross-core-fk-hr-employees.md) – `hr_employees` cross-core FKs
* [ADR Template](../../../specs/_templates/ADR_TEMPLATE.md) – Format for future ADRs
