9.4 KiB
Upgrade Guide
Scope
This guide is the canonical human-facing upgrade entrypoint for the boilerplate. Use it when planning package, runtime, database, deployment, security, provider, or documentation changes that affect how maintainers move from one reviewed version to another.
For the deeper operational runbook, use docs/upgrades.md. This page summarizes the release-upgrade path and links the relevant contracts:
docs/versioning.mdfor SemVer, breaking-change, release-note, rollback, and verification expectations.docs/database.mdfor PostgreSQL and Prisma migration, backup, restore, and redacted diagnostic boundaries.docs/deployment.mdfor image, health, Coolify, manual runtime, and rollback expectations.docs/security.mdfor secret redaction, headers, CORS, authentication, Mailjet, database, Redis, and incident-response boundaries.docs/porting-verification.mdfor documentation verification, runtime wording, package-manager wording, and manual E2E policy.
This repository is pinned to pnpm@10.33.0, runs the @toolctrl/web React Router runtime in apps/web/app through root scripts, uses PostgreSQL through Prisma, uses Mailjet for transactional mail, and keeps Redis-backed worker execution optional.
Supported upgrade classes
| Upgrade class | Examples | Required review focus |
|---|---|---|
| Patch dependency or tooling update | Security patch, compiler patch, documentation-only dependency wording | Keep pnpm@10.33.0 examples, run focused non-E2E checks, confirm no runtime contract changed. |
| Minor feature or additive runtime update | New option, additive package capability, additional documented workflow | Preserve existing defaults unless docs/versioning.md records the changed default and compatibility path. |
| Major or breaking update | Removed API, renamed environment key, changed database semantics, incompatible runtime behavior | Document the migration path, rollback limits, operator action, and verification evidence before release. |
| Database or Prisma update | Prisma package update, schema migration, PostgreSQL adapter change | Follow docs/database.md, confirm backup readiness, use reviewed migrations, and preserve redacted output only. |
| Deployment or runtime update | React Router runtime, Docker image, health/readiness, Coolify path, worker behavior | Follow docs/deployment.md, keep live Docker, registry, Coolify, browser, and E2E checks manual unless explicitly approved. |
| Security or provider update | Headers, CORS, API auth, Mailjet, Redis, database secrets | Follow docs/security.md, preserve signing/auth/redaction boundaries, and record only safe correlation evidence. |
Preflight
Before changing upgrade-sensitive files, complete this preflight:
- Confirm the intended SemVer class with
docs/versioning.md. - Confirm the current package manager pin in
package.jsonand use Corepack withpnpm@10.33.0for examples and local installs. - Identify affected surfaces:
@toolctrl/webReact Router runtime inapps/web/app, packages, PostgreSQL/Prisma, Mailjet, optional Redis worker, deployment images, security headers, CORS, API auth, or documentation. - Review the current deeper runbook in
docs/upgrades.mdfor dependency, runtime, database, worker, mail, rollback, and documentation-check specifics. - Confirm that no documentation, logs, tickets, or verification summaries will include raw secrets, provider payloads, production credentials, tenant identifiers, customer data, or secret-shaped sample values.
- Decide which checks are automatic non-E2E verification and which checks are manual runtime verification.
Package and runtime upgrades
Use the pinned package manager command family for package changes:
corepack enable
corepack prepare pnpm@10.33.0 --activate
pnpm install
Do not replace repository examples with unpinned npm, yarn, or scaffold commands. Review lockfile changes together with the package changes that produced them.
Runtime upgrade notes must keep apps/web/app as the authoritative @toolctrl/web source tree, with root scripts delegating to it, unless a later verified extraction changes that contract. Treat apps/api as the runtime-wired Hono API app, apps/worker as optional worker infrastructure, and package boundaries as documented workspace surfaces rather than proof that every package is independently deployed.
When the upgrade affects generated types, Prisma client artifacts, routing, security headers, or runtime build behavior, run focused non-E2E checks that match the changed surface. Browser, Playwright, Cypress, live Docker, live registry, Coolify, and provider-console checks remain manual runtime activities unless a human explicitly approves the exact focused run.
Database migrations
Database-affecting upgrades include schema changes, Prisma package updates, PostgreSQL adapter updates, generated-client changes, and migration deployment behavior. Follow docs/database.md as the database operations contract.
Production-facing database expectations:
- Use
DATABASE_URLandDIRECT_URLas environment key names only; never paste their values. - Author migrations locally with the documented local-only Prisma workflow, then deploy reviewed migrations through
pnpm run db:migrate:deployin the approved deployment path. - Confirm backup or restore-point readiness before production migration deployment.
- Record migration evidence as command name, phase, exit code, redacted diagnostic code, and sanitized output excerpt only.
- Treat rollback after irreversible data changes as a restore or forward-fix decision, not as an automatic downgrade guarantee.
Rollout
A safe rollout has an explicit sequence:
- Land the reviewed code, migration, dependency, and documentation changes together when the upgrade requires them together.
- Confirm non-E2E verification for the affected surface before manual runtime inspection.
- Publish or select immutable SHA-derived image tags for deployable targets as described in
docs/deployment.md. - Apply database migrations only through the approved deployment path and after backup readiness is confirmed.
- Enable optional worker behavior only when
WORKER_ENABLED=trueand Redis configuration such asBULLMQ_REDIS_URLis available through the environment. - Verify Mailjet-related changes through safe provider categories, signing status, delivery status, request IDs, or job IDs without exposing payloads or credentials.
- Record release notes and rollback expectations according to
docs/versioning.md.
Rollback
Plan rollback before production rollout starts. The rollback plan must state whether the previous known-good state can be restored by redeploying a prior artifact, requires a database backup restore, requires pausing or draining worker queues, or is unsupported after a migration.
Use immutable image tags and reviewed package versions rather than mutable guesses. For database rollback, preserve only redacted evidence and use environment-owned backup or restore tooling. For worker incidents, pause or drain queues through approved operational tooling before replaying jobs. For security or Mailjet incidents, preserve signing/auth/redaction boundaries and follow docs/security.md.
If rollback evidence includes raw credentials, database or Redis URLs, provider tokens, UUID-like deployment endpoints, tenant identifiers, customer data, provider payloads, or stack traces containing secrets, treat it as a security exposure and contain it before continuing.
Non-E2E verification
Automatic upgrade verification is limited to repository-scoped, non-E2E checks. For documentation-only changes to this guide, use:
test -s docs/upgrade.md
pnpm run verify:docs-links
For broader upgrade changes, choose focused checks that match the affected files and documented surface, such as explicit Vitest files, static verifier scripts, lint on changed source files, or tc typecheck when TypeScript-sensitive code changed. Do not claim that browser automation, live provider checks, live Docker builds, registry pushes, Coolify execution, or production runtime checks ran unless a human explicitly approved and performed that exact check.
Negative documentation verification should reject a missing docs/upgrade.md, unresolved local links, unresolved anchors, forbidden backlog markers, stale package-manager examples, automatic E2E claims, and secret-shaped sample values.
Manual runtime and E2E boundary
Manual runtime verification may include rendered Markdown review, browser flows, Playwright or Cypress, live Docker smoke checks, registry push proof, Coolify execution, provider-console inspection, health endpoint inspection, and production-like request journeys. These are not auto-mode checks by default.
When manual runtime inspection is approved, record only safe evidence: target name, immutable tag, release version, health or readiness status, request ID, job ID, queue name, provider category, delivery status, signing status, and redacted diagnostic codes. Keep secrets, tokens, connection strings, customer data, tenant identifiers, provider payloads, cookies, authorization headers, and screenshots containing personal data out of documentation and release records.