# Coaching Workspace security and operations

This template is a single-workspace deployment. Each coach or practice receives its own virtual machine, PostgreSQL database, secrets, and private upload directory. It is not a shared multi-tenant SaaS database.

## Required production configuration

- Set `NODE_ENV=production`, `PUBLIC_APP_URL` to the final HTTPS origin, and strong unique values for all database, JWT, email, and AI proxy secrets.
- Set `COACHING_UPLOAD_DIR` and `COACHING_BACKUP_DIR` to persistent private paths readable only by the application operator.
- Install ClamAV and keep its definitions current. Uploads fail closed when `clamscan` is unavailable or reports a threat.
- Set `SENTRY_DSN` for backend exception monitoring. Never attach transcript, audio, private-note, or generated-content bodies to monitoring events.
- Keep `DEMO_MODE=false` for customer workspaces. A public fictional demo must use `DEMO_MODE=true` and `NEXT_PUBLIC_DEMO_MODE=true`.
- Configure encrypted VM storage and encrypted backups in the hosting layer. The application cannot truthfully claim encryption at rest until the operator verifies both.

## Retention

The daily scheduler enforces these defaults:

- Raw audio: 30 days (`COACHING_AUDIO_RETENTION_DAYS`)
- Transcript text: 90 days (`COACHING_TRANSCRIPT_RETENTION_DAYS`)
- Deleted session memories and their action/preparation records: 30 days (`COACHING_DELETED_RECORD_RETENTION_DAYS`)
- Backup files: 30 days (`COACHING_BACKUP_EXPIRY_DAYS`)

Run the job manually with `yarn coaching:retention` from `backend`. Failures are logged and cause a non-zero exit.

## Backup and restore verification

Create database backups with the PostgreSQL credentials supplied through the production environment. Store the result in `COACHING_BACKUP_DIR`, never in a public web directory. Private uploads must be backed up separately with the same access controls and expiry.

At least monthly, restore the newest database backup into an isolated database and run migrations plus the backend test suite against it. Verify row counts for users, clients, sessions, action items, resources, consent records, and audit events without printing confidential field values. Verify a sample private upload by checksum, then destroy the isolated restore database and record the date, backup identifier, operator, and result.

Do not treat an untested backup as recoverable. A failed backup, restore, malware scan, migration, retention run, or monitoring delivery requires visible operator action.

## Release verification

Before making a deployment public:

1. Run backend tests, lint, and dependency audit.
2. Run frontend lint, typecheck, production build, dependency audit, and accessibility checks.
3. Run the role-by-route, role-by-API, object-isolation, consent, demo-mode, upload, deletion, invitation, and reminder matrices.
4. Confirm production security headers, secure cookies, no development assets, `noindex` on authenticated/demo pages, and private-file authorization.
5. Confirm public data is synthetic or explicitly approved and that legal entity/contact/effective-date fields have been reviewed before publication.
