# Clinical rotation backend rollback - isolated draft

Status: clinical-only runtime retirement prepared after explicit user
confirmation. The owner subsequently authorized commit/push to dev. Generic
scheduling is protected and unchanged. This document records pre-release
verification, not a claim of live retirement or deployment completion.

## Source and synchronization

- Reviewed and fetched `origin/dev` on 2026-09-16.
- Base: `cdae89b3017d4a7b61f50559dd7e437a2fc7bac5`.
- Main local checkout was fast-forwarded from `204d10a` to that base. Its branch
  name remains `codex/phase1-e2e-fixtures`; existing untracked files were preserved.
- Draft branch: `codex/revert-clinical-rotation`, isolated worktree
  `/private/tmp/timetabler-be-clinical-rollback.sbmiEG`.
- Original backend path was introduced by `9e53d61` and subsequently extended by
  feature-specific runtime/deployment and resource-handling fixes.

## Already-prepared runtime removal

- Removed the three clinical preview-request, schedule-request and status views
  and URL registrations under `/api/admin/clinical-rotation/`.
- Removed clinical plan/apply/cache/response/reconcile/sync/delivery services,
  Kafka worker scripts, five management commands, deployment helpers, PM2
  ecosystem definition and activation workflow.
- Removed clinical environment/settings blocks, permission aliases and labels.
  The shared permission backend is unchanged, with an empty alias registry.
- Removed only clinical input/dispatch clauses from the shared deployment
  workflow; normal deployment jobs and their steps remain unchanged.
- Replaced feature-specific tests with ten retirement regression checks. No
  generic workflow test was removed or changed.

## Deliberately preserved historical schema

All seven clinical ORM model files, their imports and all existing migrations
are byte-identical to the fetched base. There is no new migration. Review found
that even a state-only deletion would alter generic deletion behavior: removing
the ORM relations loses Django's PROTECT checks for historically referenced
Activities, Student Sets, Activity Templates, academic terms, modules and users,
while the retained SQL foreign keys would still reject deletion. Keeping this
metadata therefore preserves existing generic behavior, data, audit history and
the migration graph. Passive model definitions do not register an API, worker or
scheduler path. Do not remove them as superficial search-result cleanup.

No database was modified. The existing database capability row is not changed by
this draft, but it cannot restore deleted routes or services. Any later schema
retirement, archival, or deletion needs separate explicit authorization and data
retention review. Do not reverse applied migration `0109` or delete its history.

## Verification

Executed with Python 3.12 and the repository's pinned Django 5.2.4 dependencies:

```text
manage.py test api.tests.test_clinical_rotation_retirement api.tests.test_legacy_api
  --settings=backend.test_settings -v 2
14 tests: passed (10 retirement checks plus 4 legacy API checks)

manage.py check --settings=backend.test_settings
No issues

makemigrations api --check --dry-run, with the real migration graph enabled
No changes detected

git diff --check
Passed
```

The retirement checks prove endpoints are absent even with stale enabled feature
flags, management commands and runtime modules are absent, old environment
variables do not reconstruct runtime configuration, deployment activation is
gone, generic schedule/preschedule routes retain their original view classes,
and historical ORM relations retain their original PROTECT deletion behavior.

Full draft suite: **250 tests, 3 errors, 4 skipped**. All three errors are
`test_term_projection_backfill` using PostgreSQL `current_database()` against the
SQLite test backend. Current pristine origin baseline: **298 tests, 40 errors,
5 skipped**, including those same three backfill errors and 37 clinical errors.
The full suite is therefore not claimed green. No generic code was modified to
mask those baseline failures.

Verified zero diff for generic schedule/preschedule/unschedule views, the shared
permission backend, integration services, normal Kafka `tt_response`, its PM2
definition/restart script, all ORM models, and all migrations. Remaining clinical
references in runtime source are only passive ORM definitions and historical
migration declarations.

## Operational retirement needed before any deployment

This list is a plan only; no live operations were performed.

1. Review the final clinical-only cross-repository diff and separately coordinate
   deployment authority. The user has confirmed clinical-only code removal;
   nothing else may be changed.
2. Record deployed revisions and active clinical operation/lease states. Disable
   clinical intake in the old Agent and backend first. Do not send pending
   clinical messages through the generic scheduler.
3. Resolve or audit pending clinical claims, already-applied timetable writes,
   synchronization receipts and unresolved operations. Historical scheduled
   activities must not be silently unscheduled or deleted by this rollback.
4. Stop and remove only the exact clinical PM2 definitions after confirming their
   executable paths belong to the intended backend deployment:
   `clinical-rotation-delivery`, `clinical-rotation-response`,
   `clinical-rotation-reconcile-response`, `clinical-rotation-sync`, and
   `clinical-rotation-reconciler`. Save the scoped supervisor state and verify
   they cannot auto-respawn. Never use `pm2 stop all` or `pm2 delete all`.
5. Verify engine clinical primary/reconcile workers are stopped independently;
   coordinate this with the engine owner. Keep generic engine workers,
   `tt_response`, generic Kafka topics/groups and integration publishers intact.
6. Retire the clinical-only enabled flags, credentials and workflow variables
   after audit/recovery is settled. Keep generic Kafka credentials and brokers
   intact. Preserve historical Kafka/Redis/SQL records unless a separate retention
   decision authorizes their cleanup.
7. Deploy the approved Agent/frontend/backend rollback together, verify the
   clinical endpoints return 404 and no command invokes them, then smoke-test
   normal scheduling. Removing code alone does not terminate a Python process
   that is already running old imported code.

The `.venv/` in this temporary worktree is a disposable local test environment,
not a deliverable; do not stage it.
