Skip to content

Migration and Upgrade Guide

FieldValue
ProductPlystra
Versionv1.0
Document TypeOperations guide
ScopeMigrations, upgrades, Ent drift, production safety
StatusActive guide

This guide explains how to apply migrations, verify schema state, and upgrade Plystra Core safely.

Plystra v1.0 uses Ent inside the Core repository, but production upgrades must use versioned migrations.

Production must not rely on Ent auto migration.

The primary goals are:

avoid schema drift
avoid accidental destructive changes
ensure Core code matches database schema
ensure upgrades are repeatable
ensure operators can recover from failed upgrades

Rule 1: Use Versioned Migrations in Production

Section titled “Rule 1: Use Versioned Migrations in Production”

Production upgrades must use:

Terminal window
plystractl migrate up

Do not use Ent auto migration as the production upgrade mechanism.

Always run:

Terminal window
plystractl migrate verify
plystractl ent check
plystractl doctor

Always back up PostgreSQL before applying production migrations.

Do not manually edit schema to match the latest code.

Use project-provided migrations.

AuditLog is append-only.

Never manually mutate audit records unless following an emergency recovery procedure approved by maintainers.


Backend OS Alpha includes an inspectable template setup command. It creates a local application directory from an official template manifest and writes the operational files needed to launch, inspect, back up, and upgrade the app.

Terminal window
plystractl templates list
plystractl templates describe auth-ready-saas
plystractl templates create --template auth-ready-saas --name "Acme SaaS" --out ./acme-saas

The generated directory contains:

FilePurpose
README.mdStart and operation commands for the generated app.
.env.exampleProduction-oriented environment template with placeholder secrets only.
docker-compose.ymlCore, PostgreSQL, and required official plugin sidecar services for the selected template.
plystra/template-installation.jsonTemplate manifest, deployment profile, preview, required plugins, and capability requirements.
plystra/install-explanation.mdHuman-readable install explanation, defaults, operator actions, and limitations.

The command is intentionally transparent rather than magical. It does not generate real secrets, does not create the first instance super admin, does not run migrations automatically, and does not imply a public marketplace. Review the generated files, copy .env.example to .env, set strong secrets, then start and verify:

Terminal window
docker compose --env-file .env up -d postgres
docker compose --env-file .env run --rm plystra-core plystractl migrate up
docker compose --env-file .env run --rm plystra-core plystractl migrate verify
docker compose --env-file .env run --rm plystra-core plystractl doctor
docker compose --env-file .env up -d

For templates that require Complete Auth, configure the plugin database settings in plugin_auth_settings before enabling public auth flows. Production email delivery must use an independent email capability provider.


Terminal window
plystractl migrate up

Expected behavior:

connects to configured database
detects current migration version
applies pending migrations in order
records applied migration versions
returns clear success or failure result
Terminal window
plystractl migrate verify

Expected behavior:

checks migration table
checks expected schema state
checks migration integrity where supported
reports missing or failed migrations
Terminal window
plystractl ent check

Expected behavior:

compares Ent schema expectations with database schema
reports drift if schema and code are inconsistent
returns zero only when no drift exists
Terminal window
plystractl doctor

Expected behavior:

checks configuration
checks database connectivity
checks migration state
checks schema readiness
checks runtime readiness
returns actionable diagnostics

In development, maintainers may use Ent tools to iterate.

Recommended workflow:

1. Modify ent/schema.
2. Generate Ent code.
3. Generate versioned migration.
4. Apply migration to local database.
5. Run tests.
6. Run ent check.
7. Commit schema, generated code, and migration together.

Example:

Terminal window
go generate ./ent
plystractl migrate diff
plystractl migrate up
plystractl ent check
go test ./...

Exact commands may differ depending on project tooling.

The invariant remains:

Ent schema, generated code, and migrations must be committed together.

CI must validate:

generated Ent code is current
migrations are current
migrations apply to empty database
migrations apply from previous release schema
authz conformance tests pass after migration

Recommended CI jobs:

codegen-check
migration-diff-check
migration-apply-empty-db
migration-apply-upgrade-db
authz-conformance-test

Example:

Terminal window
go generate ./ent
git diff --exit-code

Example:

Terminal window
plystractl migrate diff --check

or equivalent Atlas/Ent command.

Expected:

no uncommitted migration diff

Example:

Terminal window
createdb plystra_empty_test
PLYSTRA_DATABASE_URL=... plystractl migrate up
PLYSTRA_DATABASE_URL=... plystractl migrate verify

Example:

Terminal window
restore previous release schema
PLYSTRA_DATABASE_URL=... plystractl migrate up
PLYSTRA_DATABASE_URL=... plystractl migrate verify
PLYSTRA_DATABASE_URL=... go test ./...

Follow this procedure for production upgrades.

Review:

release notes
migration notes
breaking changes
compatibility notes
known limitations
Terminal window
curl -s http://localhost:8080/api/v1/version

Record:

Core version
schema version
trace version
build metadata
Terminal window
plystractl doctor

Do not upgrade if doctor reports critical issues.

Example:

Terminal window
pg_dump "$DATABASE_URL" > plystra-backup-before-v1.0.sql

Recommended:

store backup outside the server
encrypt backup if it contains sensitive data
verify backup file is non-empty
record backup timestamp
record current app version
record current schema version

For production-critical deployments, test restore on a staging database.

Terminal window
createdb plystra_restore_test
psql plystra_restore_test < plystra-backup-before-v1.0.sql

Depending on deployment:

Terminal window
docker compose stop plystra-core

or put the application in maintenance mode.

Terminal window
git fetch --tags
git checkout v0.0.1

or update Docker image tag.

Terminal window
plystractl migrate up
Terminal window
plystractl migrate verify
plystractl ent check
Terminal window
docker compose up -d plystra-core
Terminal window
plystractl doctor

Run smoke tests:

Terminal window
curl -s http://localhost:8080/api/v1/health
curl -s http://localhost:8080/api/v1/ready
curl -s http://localhost:8080/api/v1/version

Run authorization smoke tests:

authz/check allow case
authz/check deny case
authz/explain allow case
authz/explain deny case

Check logs:

Terminal window
docker compose logs --tail=200 plystra-core

Check AuditLog:

recent allow decision
recent deny decision
request_id correlation
trace snapshot shape

Plystra production mode intentionally rejects unsafe Ent auto apply behavior.

This is not a bug.

Ent auto migration can be useful in development, but production upgrades require:

reviewable migration files
repeatable upgrade process
CI validation
backup planning
rollback planning
operator visibility

Therefore production should use:

Terminal window
plystractl migrate up

not automatic schema mutation.

If an unsafe Ent apply command is attempted in production, the system should return a clear error:

Ent auto migration is disabled in production.
Use versioned migrations through plystractl migrate up.

Release notes and upgrade docs must mention this behavior.


Rollback depends on migration type.

If migrations are backward-compatible:

Terminal window
docker compose stop plystra-core
git checkout previous-version
docker compose up -d plystra-core

or use previous Docker image.

If migrations are not backward-compatible, restore from backup.

Example:

Terminal window
dropdb plystra
createdb plystra
psql plystra < plystra-backup-before-upgrade.sql

Before rollback:

identify failed component
preserve logs
preserve error output
preserve current database snapshot if useful
confirm backup availability
stop write traffic if possible
restore app and DB consistently
run doctor after rollback

AuditLog records created during failed upgrade windows should be preserved if possible.

If database restore removes them, document the operational event outside Plystra.


Each migration should document:

purpose
affected tables
new columns
removed columns if any
indexes
constraints
data backfill if any
rollback strategy
compatibility notes

Migrations that affect these areas require extra review:

UserMember
MemberRole
Permission
Resource
AuditLog
Group path
Deny code fields
Trace schema fields

Data migrations must be separate from schema migrations when practical.

Examples:

backfill UserMember.is_primary
backfill Resource.status
backfill AuditLog.deny_code
normalize Group paths
seed system permissions

Data migrations should be:

idempotent where possible
logged
tested on staging data
safe to retry when possible
documented

Possible causes:

migration not applied
migration file missing
manual DB change
generated Ent code stale
wrong database URL
wrong environment

Recommended steps:

Terminal window
echo $PLYSTRA_DATABASE_URL
plystractl migrate verify
plystractl ent check
go generate ./ent
git diff

Possible causes:

schema version mismatch
missing column
old migration state
wrong database
stale Docker image

Recommended steps:

Terminal window
curl -s /api/v1/version
plystractl doctor
plystractl migrate verify
docker compose logs --tail=200 plystra-core

11.3 Symptom: Authz Results Are Wrong After Upgrade

Section titled “11.3 Symptom: Authz Results Are Wrong After Upgrade”

Possible causes:

seed data changed
RolePermission missing
MemberRole scope anchor missing
Resource group_id missing
UserMember revoked/expired
Group path changed
candidate permission filtering bug

Recommended checks:

verify actor context
verify Resource record
verify MemberRole.scope_anchor_group_id
verify Permission resource/action/scope
verify Group path
run Finance Reviewer demo
run authz/explain

Minimum backup:

Terminal window
pg_dump "$DATABASE_URL" > plystra-backup.sql

Recommended production backup strategy:

scheduled PostgreSQL backups
off-server storage
encrypted backups
restore tests
retention policy
pre-upgrade backup
post-upgrade verification

Backup should include:

Core tables
AuditLog
Resource Registry records
migration version table
plugin metadata if present

If future plugins own separate tables, plugin-owned data must also be included.


After every production upgrade, run:

health endpoint
ready endpoint
version endpoint
doctor command
migrate verify
ent check
authz/check allow
authz/check deny
authz/explain
Resource Registry query
AuditLog query
request ID correlation

Minimum command examples:

Terminal window
curl -s http://localhost:8080/api/v1/health
curl -s http://localhost:8080/api/v1/ready
curl -s http://localhost:8080/api/v1/version
plystractl doctor
plystractl migrate verify
plystractl ent check

Before publishing a release:

all migrations committed
generated Ent code committed
migration tests pass
ent drift check passes
doctor passes
authz conformance tests pass
OpenAPI updated
release notes updated
upgrade guide updated
Docker image built
tag created
clean install verified
upgrade install verified

Plystra v1.0 treats migrations as a production safety boundary.

Use Ent for schema modeling and code generation inside Core.

Use versioned migrations for production upgrades.

Always verify:

migration state
Ent drift
doctor output
authz correctness
AuditLog correctness

Never rely on production Ent auto apply.