# Maintenance deployment

Status (2026-10-14): following the user's explicit migration request, both Maintenance migrations were applied to `preventive_maintenance` on `localhost:3306` with Prisma CLI. `migrate status` reports up to date; `migrate diff --from-config-datasource --to-schema prisma --exit-code` reports no difference. Prisma Client was regenerated. Scheduler activation has not been performed.

## Coordinated release

Build the shared package, API and frontend together. Existing Pilot Plant work-order fields and deep links remain compatible. Maintenance adds versioned mutations and nullable history actor: `null` means an automatic system event; manual actions always use the authenticated user. Neither costs nor checkout links are introduced.

For an explicitly authorized deployment to another environment, run from apps/api:

```powershell
npm.cmd run prisma:migrate:deploy
npm.cmd run prisma:generate
npm.cmd run build
```

Migrations `20261014000200_maintenance_work_orders` and `20261014000300_maintenance_system_actor` preserve historical rows. Back up the database before deployment according to the normal operational procedure. The second migration temporarily drops and recreates the same actor FK while changing its column to nullable. Do not reset the database or use db push.

## Scheduler activation (separate deployment step)

Install a recurring job with apps/api as working directory, the application's database environment and restricted operational credentials. Invoke every minute:

```powershell
npm.cmd run maintenance:generate -- 100
```

The argument limits a run to 1–1000 processed occurrences (default 100). Missed occurrences stay behind the plan cursor for the next run; overlapping and restarted runs use row locks and the existing occurrence unique key. ONCE disables itself after generation. Paused plans produce nothing; archived targets produce an actionable error and retain their cursor. Inspect the structured `maintenance_generation` log's `errors` array and alert on nonzero exit status. If a backlog continually exhausts the batch, increase the batch within the limit or run more frequently; do not advance cursors manually. Confirm at least one due WO and its “Sistem” history after activation.

Read-only calendar requests never generate tickets. Projection uses facility timezone, preserves month-end/leap-day anchors and clamps short months. Each occurrence has separate execution history. Calendar range is at most 366 inclusive days and 5000 results; narrow oversized ranges.

## Verification and rollback

`npm.cmd run test:maintenance` creates a random isolated database, applies migration history, checks preservation/defaults/FKs and runs integration tests. It then drops only that generated database. It never deploys migrations to the configured application database.

To verify the deployment commands without deploying the application database, run `node --env-file=.env prisma/verify-maintenance-api.cjs --deploy-check`. This creates an empty disposable database, runs Prisma `migrate deploy`, `migrate status`, repeats deploy to verify no pending migrations, and invokes the scheduler CLI. These checks passed on 2026-10-14. The temporary database is dropped in `finally`.

To roll back a release, stop the scheduler and disable Maintenance writes before reverting application artifacts. Retain the additive schema, existing work and posted stock history. Correct stock through attributed ledger reversals/returns, never by deleting records. Scheduler activation remains pending explicit instruction; database migration in the local configured environment is complete.
