Skip to main content
CYPEX Documentation
Support
v2.0.0 Latest stable release View changelog ->

Pre-upgrade checklist

3 min read

Run through this checklist before applying the v2.0.0 migration scripts. Each item links to the page that explains why it matters.

1. Backups

  • Full logical backup with pg_dump:

    ```bash
    pg_dump --no-owner --no-privileges -Fc -f cypex-pre-v2.dump cypex
    ```
    
  • Filesystem snapshot of the PostgreSQL data directory, if your infrastructure supports it.

  • Backup of .env / secrets — the migration does not modify these, but you want a clean restore point.

2. Version check

  • Confirm the current CYPEX version is v1.9.3 or later. Earlier versions may lack the prerequisite migrations the v2.0.0 upgrade depends on.
  • Confirm the PostgreSQL version is supported by v2.0.0 (see the release notes for the supported range).

3. Inventory

  • List every CYPEX module:

    ```sql
    SELECT id, module_name, schema_name FROM cypex.t_module;
    ```
    
  • List every CYPEX role:

    ```sql
    SELECT rolname FROM pg_roles WHERE rolcanlogin;
    ```
    
  • List every CYPEX user:

    ```sql
    SELECT id, login FROM cypex.t_user;
    ```
    

The migration maps every role and module to the Default Organization, but the inventory gives you a baseline for post-upgrade verification.

4. Customizations to review

  • Custom RLS policies — if any tenant-scoped table already has RLS enabled with custom policies, the v2.0.0 migration will add new policies on top. Review pg_policies for conflicts:

    ```sql
    SELECT schemaname, tablename, policyname FROM pg_policies
    WHERE schemaname IN ('cypex', 'cypex_log');
    ```
    
  • Custom password policy — the v2.0.0 migration inserts a default policy only if none exists (ON CONFLICT DO NOTHING). If you already have a stricter policy, it will be preserved:

    ```sql
    SELECT value FROM cypex.t_config WHERE key = 'password_policy';
    ```
    
  • Custom integrations — anything that connects to the database directly using cypex_user credentials and writes to tenant-scoped tables will fail after the upgrade. Identify these before the upgrade window.

  • External JWT verifiers — gateways, reverse proxies, or SSO integrations that validate CYPEX JWTs need to accept the new claims: isOrganizationAdmin, isSuperAdmin, organization_ids, org_id. See Breaking changes.

5. Maintenance window

  • Schedule a maintenance window.
  • Notify users in advance.
  • Enable maintenance mode in CYPEX (if your deployment supports it).

6. Staging rehearsal

  • Replicate production to staging (logical or physical).
  • Run the migration end-to-end on staging first. The migrations are forward-only; rehearse them.
  • Run the verification queries from RLS impact on existing data.
  • Confirm session / RLS behavior on staging after the migration. In particular, exercise the JWT claims flow that the new RLS policies rely on: log in as a non-admin user mapped to one organization and confirm row visibility matches RLS impact on existing data.

7. Role verification

  • Every existing role that should retain write access must be a member of cypex_admin, not just cypex_user:

    ```sql
    SELECT r.rolname, m.rolname AS member_of
    FROM pg_roles r
    JOIN pg_auth_members am ON am.member = r.oid
    JOIN pg_roles m ON m.oid = am.roleid
    WHERE m.rolname IN ('cypex_admin', 'cypex_user');
    ```
    
  • No role should rely on SUPERUSER privileges for application traffic. The migration assumes application connections are non-superuser so that RLS policies apply.

8. Rollback plan

  • Read Rollback constraints before the upgrade window, not after.
  • Confirm your backup from step 1 can be restored in a reasonable time.
  • Decide the rollback trigger: which failure mode causes you to roll back versus fix forward.

Sign-off

  • DBA sign-off
  • Tech lead sign-off
  • Operations sign-off (maintenance window, monitoring, on-call rotation)

When every box is checked, proceed to the upgrade. Track the actual sequence in your incident log so the post-mortem has the same shape.