Use a PostgreSQL deployment with pgvector available and a separate administrator connection for maintenance. Set RALTI_DATABASE_ADMIN_URL only in the trusted maintenance environment. Web and worker processes receive DATABASE_URL for a restricted runtime role. Ralti rejects superusers, table owners, and roles that bypass row-level security.
npm run database -- migrate
npm run database -- provision --role ralti_app --output .env.postgresMigrations under migrations/postgres/ run in order under an advisory lock and record checksums. Modify the schema with a new migration; do not edit an already applied migration. Provisioning generates a credential unless an explicit private runtime password is supplied, refuses an existing role or output file, and writes the connection privately. Transfer it to your deployment secret store.
Rehearse before cutover#
npm run database -- import-sqlite --source .atlas/atlas.sqlite --backup-dir ../ralti-private-backups/rehearsalThe importer first takes a SQLite online backup, including committed WAL data, then checks integrity and foreign keys. It requires an empty destination and verifies imported tables by row counts and canonical content hashes before committing. IDs, timestamps, history, deduplication keys, and encrypted credentials are preserved; unknown source tables or mismatches fail the import.
- Run the imported copy in an isolated environment with outbound workers disabled.
- Check sign-in, records, roles, history, files, and retrieval. Make and restore-verify a PostgreSQL backup.
- For final cutover, stop application and worker writes, repeat the consistent import into a fresh destination, copy private files, and retain the original snapshot.
- Point web and worker processes at the same runtime database, preserve the encryption key, and complete signed-in acceptance checks.
Once PostgreSQL accepts new writes, the old SQLite file is stale. The tooling does not offer a lossless PostgreSQL-to-SQLite reverse migration.