# Pilot Plant migration preflight

Run from apps/api against the existing database before the Pilot Plant migration:

```text
npm run prisma:preflight:pilot-plant
```

The command runs fixed SELECT statements only. Prefer a database account granted
SELECT and no write privileges. It does not migrate, seed, reset, repair, fetch
photos, or print connection credentials. JSON output contains record IDs and
duplicate names for operator review; treat it as operational data.

Exit codes: 0 = all checks clear, 2 = conflicts requiring review, 1 = checks could
not finish. A failed check is not evidence of readiness. Reads are diagnostic,
not a lock against new writes: quiesce affected writers and rerun immediately
before migration. The final database constraints still enforce uniqueness.

Resolve findings explicitly before continuing:

- Duplicate names: decide which names to change within each scope, including
  archived records; MySQL's existing collation governs comparison.
- Invalid/whitespace names: approve normalized names and check duplicates again.
- Multiple WOs per report: review history and choose a supported migration plan;
  never delete historical WOs automatically to satisfy the new unique key.
- Invalid hierarchy: correct unit/parent/level/archive relationships with an
  approved data repair; this tool does not reparent or archive records.
- Legacy photos: plan explicit migration to managed storage; never download
  arbitrary stored URLs automatically. Only IDs are emitted, not URL secrets.
- Legacy reviewed reports: recover reviewer/time/reason from authoritative
  history and decide state/link mapping. Do not invent reviewer attribution or
  acceptance replay hashes. All non-OPEN reports or existing links require review.
- Mismatched report/WO links: resolve the business relationship before migration.

A clear report verifies the checked rows only. Backups, an isolated MySQL test
database, migration rehearsal, and deployed storage configuration remain separate
release requirements.
