Validation, deployment, and maintenance records
Validate application behavior after a future update, plan deployment, handle failures, and distinguish public release notes from internal maintenance records.
Use this article after evaluating your update's goal and completing the necessary merges. If you do not currently need an update, keep your existing project. There is no need to deploy, create tags, or perform database operations.
1. Define the acceptance criteria
Focus validation on the changes and their actual effects. Checking only the home page is not enough, but an unrelated copy change does not require testing every third-party feature either.
| Change | Representative scenarios to validate |
|---|---|
| Sign-in, sessions, or email verification | New and existing accounts, valid and invalid sessions, incorrect verification codes, and required step-up verification |
| Permissions and product rules | Standard accounts and accounts with purchases, historical grants, and behavior after expiration or revocation |
| Payments and webhooks | Test purchases, duplicate deliveries, delayed or out-of-order events, and old plan associations |
| Data structures | Reading and writing existing data, constraints, empty database initialization, and existing database upgrades |
| Queues or Reaction | Successful execution, retryable failures, duplicate messages, and execution records saved before the upgrade |
| Content and languages | Navigation, body content, search, enabled languages, and missing text |
| Resources and domain names | Binding targets, cookies, callbacks, Cron, and runtime logs |
In development mode, emails appear as terminal previews. A successful preview does not validate actual delivery. When using Stripe test mode, also confirm that the connection, Price, and webhook belong to the same test environment.
2. Complete local checks
After completing your code changes, run:
npm run verifyThe template runs ESLint, TypeScript type checking, tests for the application and scripts, and a production build in sequence. You must also resolve content or type errors generated during these checks. A screenshot of the final successful build alone is not sufficient.
To inspect the built pages locally, you can use:
npm run previewA local preview does not prove that production resources, email services, or third-party callbacks work. If you need to validate integrations online, first prepare isolated resources and explicit test configuration. The current template does not automatically provide a complete staging environment.
3. Confirm the actual deployment target
Record the commit you plan to deploy, site URL, Worker, resource IDs, migration files, and configuration changes. Confirm that the original master key and other credentials needed for recovery remain securely stored. Record only their storage locations or update status.
If production data will change, confirm that backups or recovery points are available and assess whether related writes need to be restricted during deployment. A Git tag alone does not protect database or external service state.
For a normal update, use:
npm run deploy:updateThis command deploys the current working directory. It does not download or merge the template. Its sequence includes production checks, type generation, full validation, remote migrations, Worker deployment, KV synchronization, and page health checks.
Because it already includes verify, there is no need to repeat the same checks immediately before deployment just to complete a process. However, if you have changed code since an earlier validation, those results do not prove that the current version is valid.
For deployment details, see Initial deployment and subsequent updates.
4. Determine what happened before recovering from a failure
| Where execution stopped | Possible current state | Recovery approach |
|---|---|---|
Configuration checks or verify | This update's remote migrations and deployment have not run | Fix the failures, then continue the update |
| Database migration | Some earlier migrations or migrations for the other database may have completed | Check migration records and schemas to determine the corrective SQL |
| Worker deployment | Migrations may have completed, and old code may still be live | Ensure the old code is compatible with the current schema and fix deployment |
| KV synchronization | The new Worker is live, but content has not been fully synchronized | Resume synchronization using the correct version |
| Health checks | All preceding steps may have completed | Inspect actual pages and logs to locate application or entry-point issues |
Do not delete resources, clear databases, or repeat initial deployment just because a command fails. For more detailed troubleshooting, see Deployment, resources, and domain names.
Rolling back code does not restore the whole system
If only application code changed, with no changes to data formats, configuration semantics, or external state, you can consider redeploying a previously validated version. This approach does not apply directly if a migration has removed old fields or the new version has written data that the old version cannot recognize.
Restoring a database may undo legitimate data changes made after the recovery point. Completed Stripe payments, sent emails, and the effects of processed Queue messages do not disappear when you roll back Git history. They require separate reconciliation.
The project has no command that automatically rolls back the entire system. Design recovery for the specific change. Document what to restore, the basis for that decision, the execution order, and any business operations that need follow-up processing after recovery.
5. Validate the affected features after deployment
Once page health checks pass, validate the representative cases prepared before deployment. Check existing accounts and historical data. Do not rely only on a successful result from a newly created account.
For background work, continue checking Event, Command, and consumer results. For payments, confirm that transactions and entitlements agree. After the first successful result, continue watching for delayed callbacks or scheduled tasks over the relevant business cycle. A short period without errors does not mean every path has been validated.
Once the update is stable, remove temporary logic, test configuration, and old references that are no longer needed. Do not delete unused resources based solely on similar names. First confirm that nothing reads or writes them and that they are not needed for recovery.
6. Keep an internal maintenance record
Internal records explain implementation and recovery. Public release notes explain what users received. They serve different purposes.
You can copy the following record template when you have an actual update to make. Fill in the placeholders with the facts of that update. This is not a record of an upgrade that has already happened:
# Change record: <change-name>
- Status: under evaluation / pending release / released / recovered
- Reason for the update:
- Original application commit and version:
- Original and target template sources:
- Changes included in this update:
- Template changes retained or excluded, with reasons:
- Database migration files and validation results:
- Configuration, variable, and resource changes:
- Manual operations on third-party platforms:
- Automated checks and business validation results:
- Deployed commit, deployment time, and target Worker:
- Recovery conditions, targets, and steps in case of failure:
- Post-deployment observations:
- Unresolved issues:Do not store Secrets, cookies, tokens, complete production data, or email verification codes in these records. Store database backups separately and securely as well. Do not commit them to the repository with the documentation.
Even if you defer an update, you can record the target version and the reason for postponing it. This avoids having to reconstruct that information from scratch during the next evaluation.
7. Maintain public release notes
The current template's changelog page reads a static array in src/components/server/Changelog/entries.ts. It does not automatically turn Git commits or the package.json version into announcements.
Entries currently use these fields:
| Field | Purpose |
|---|---|
commit | Text identifying the associated commit |
date, displayDate | Date and display date |
type, title, description | Update category, title, and description |
icon | An icon name supported by the current component |
items | A list of changes, each with kind and copy |
Entry content currently uses the English strings in the array directly. Only the surrounding page text uses language keys such as pages.changelog. Editing language JSON alone does not translate titles or entries in entries.ts. If you need multilingual release note content in the future, connect it to the appropriate resources through the project's existing internationalization mechanism.
An initialized product should not automatically adopt the template's history as its own release history. When you make an actual release, record the changes you have delivered to users. If nothing has changed, do not invent a new version to fill the page.
Describe concrete results. For example, “Fixed an issue where notifications continued going to the old address after an email address change” is more useful than “Improved the email module.” Keep internal resource IDs, recovery points, sensitive data, and details of specific security controls in access-controlled maintenance records.
8. Tags, source archives, and deployment are independent
npm run release:tag creates a tag and pushes it to origin. It is not a local read-only operation and does not deploy the Worker. release:archive generates a source archive from a specified Git tree and excludes uncommitted changes.
The template maintainer's commit script is removed from published source archives. Do not assume an initialized project provides the same one-command commit workflow.
Your own version management process should determine whether to use these release commands. If you do not need a release now, you do not need to create tags or archives in advance. Keep records that let you trace the project's state.