Skip to content

Flutter full-parity production cutover ​

This is the only authorized UI cutover procedure. Backend ownership may move in additive, backward-compatible batches; public routes do not move one by one.

Release evidence ​

Record these values in the release ticket before the maintenance window:

EvidenceRequired value
Flutter commitimmutable commit on main
React rollback deploymentimmutable Cloudflare deployment ID
Supabase projectjrsgosnnyjonxaesqtln
Flutter Web Pages projectaldilaijan-app
Hermes healthhttps://hermes.aldilaijan.com/api/health
iOS buildapproved and held for manual release
Android buildsigned artifact built and verified locally from the frozen main SHA, approved and held for manual release
Route contract267 exact routes, zero broad exemptions
Operation replaypassing sanitized artifact from the final main commit
Launch flagfull_parity_launch_v1

Keep the React deployment immutable. Do not merge, rebuild, or rotate its runtime secrets during the 30-day compatibility window.

The additive migration deliberately seeds full_parity_launch_v1 disabled at 0 percent. Enabling it is a cutover action after every acceptance gate passes; preparing or applying the migration alone must never claim production moved.

Entry gate ​

All items are blocking:

  • dart run tool/run_parity_contract.dart --check
  • node tool/generate_function_ownership_manifest.mjs --check
  • localization, taxonomy, generated schema, and fixture drift checks
  • flutter analyze --no-fatal-infos
  • complete Flutter unit, widget, contract, golden, and integration suites
  • Hermes typecheck and complete test suite
  • Deno tests and typechecks for transferred Edge Functions
  • Flutter Web release build
  • signed Android release build
  • signed iOS archive from CI
  • Web, Android, and iOS critical-journey smoke tests
  • protected staging React to Flutter operation replay workflow passes on the final main commit, including audit, outbox, idempotency, duplicate safety, financial-document projections, and fixture cleanup
  • Supabase migration dry run, RLS/advisor review, then migration push
  • production-like performance budgets and crash-free baseline captured

The critical journey matrix must cover each applicable role:

  • admin
  • manager
  • admin_aldilaijan
  • admin_aldilaijan_exec
  • admin_khobara
  • agent
  • secretary
  • secretary_aldilaijan
  • secretary_khobara
  • valuer
  • inspector
  • accountant
  • hr_manager on its remaining finance/access routes
  • client
  • anonymous/public visitor

Exercise sign-in/OTP/passkey/trusted-device behavior; property duplicate submission; deal transitions; valuation workflow, applicant acknowledgement, delivery, and portals; quotation conversion and payment; tasks/reminders; documents and signing; WhatsApp/email/social actions; Hermes approval, cancellation, and revert; maps; reports/exports; public forms; offline inspection replay; notifications; and realtime portal updates.

Maintenance-window sequence ​

  1. Freeze production mutations that cannot be replayed safely.

  2. Run Full-parity domain cutover in inventory mode. Copy the emitted React canonical_deployment.id into the release ticket and confirm that exact successful production deployment is the rollback target.

  3. Pull the live schema and repair/check the replay snapshot:

    bash
    supabase db pull
    python tool/fix_snapshot_replay.py
    python tool/fix_snapshot_replay.py --check
  4. Review the exact migration diff and apply additive migrations:

    bash
    supabase db push --dry-run
    supabase db push
  5. Push the verified Flutter commit to main. Its workflows:

    • build and deploy Flutter Web;
    • transfer only allowlisted changed Edge Functions;
    • deploy the immutable Hermes release.
  6. Wait for every workflow to finish. Verify the deployed Web HTML references the commit-versioned bootstrap and Dart bundle.

  7. Attach the inventory evidence artifact to the release ticket. Then run the workflow once in cutover mode with the full Flutter commit SHA, the captured react_deployment_id, the exact domain list aldilaijan.com,app.khobara.com.kw,www.aldilaijan.com,www.khobara.com.kw, and confirmation CUTOVER:aldilaijanre->aldilaijan-app:<release_sha>:DOMAINS:aldilaijan.com,app.khobara.com.kw,www.aldilaijan.com,www.khobara.com.kw:ROLLBACK:<react_deployment_id>. The workflow rejects a partial list and requires the exact active React inventory captured at execution time. Never include the pre-existing Flutter domain app.aldilaijan.com. The workflow verifies both immutable deployments, moves every selected custom domain as one guarded operation, waits for active certificates, verifies the commit-versioned Flutter bootstrap on every hostname, and automatically restores every touched or partially moved domain if any check fails.

  8. Release the pre-approved iOS and Android builds.

  9. Confirm feature_flags.full_parity_launch_v1 is enabled at 100 percent.

  10. Unfreeze mutations and execute the production smoke matrix.

  11. Start the 72-hour enhanced-monitoring window.

No step may selectively route a production capability back to React. Either the complete Flutter surface is live or the complete domain is rolled back.

Immediate production checks ​

  • Arabic and English SEO shells, canonical/hreflang, Open Graph, JSON-LD, sitemap, robots, CSP, CORS, and Turnstile
  • install prompt, service-worker update, cache recovery, offline fallback, Web Push, deep links, AASA, and Android asset links
  • Supabase auth, RLS, stable api views, versioned RPCs, realtime, storage signed URLs, and outbox/audit writes
  • Hermes health, model enum synchronization, approval registry, cron, logs, sessions, and WhatsApp bridge
  • payment and quotation conversion
  • PDF, DOCX, XLSX, CSV, print, download, and mobile share-sheet outputs
  • no source checkout, PAT, .shared, or MONOREPO_FETCH_TOKEN dependency

Rollback decision ​

Rollback immediately for any of:

  • confirmed data corruption or cross-tenant/role data exposure;
  • authentication, OTP, trusted-device, or payment failure affecting a material cohort;
  • sustained failure of a critical journey;
  • material fatal-error or crash-free-session regression;
  • broken realtime/offline replay that risks duplicate or lost writes;
  • Hermes performing an unapproved or incorrectly scoped action.

Performance degradation without integrity impact is triaged against the pre-recorded budget. Roll back when it is sustained and materially impairs a critical journey.

Rollback procedure ​

  1. Freeze risky mutations.

  2. Restore the recorded immutable React Cloudflare deployment for every production domain as one routing change by running Full-parity domain cutover in rollback mode with the same captured react_deployment_id, the exact same domain list aldilaijan.com,app.khobara.com.kw,www.aldilaijan.com,www.khobara.com.kw, and confirmation ROLLBACK:aldilaijan-app->aldilaijanre:DOMAINS:aldilaijan.com,app.khobara.com.kw,www.aldilaijan.com,www.khobara.com.kw:<react_deployment_id>. The workflow rejects a partial list and requires the exact attached transferred inventory, excluding the pre-existing Flutter domain. The workflow restores and verifies that exact React deployment as canonical before moving any domain. Verify its retained evidence artifact.

  3. Disable full_parity_launch_v1.

  4. Halt staged mobile rollout where the stores permit it. Do not attempt a database rollback.

  5. If Hermes is implicated, deploy the recorded known-good Flutter commit:

    bash
    gh workflow run deploy-hermes-server.yml \
      --repo busami/aldilaijankhobara-app \
      --ref main \
      -f release_sha=<known-good-40-character-commit>
  6. Verify legacy endpoint versions, auth, payment, and core React journeys.

  7. Unfreeze mutations only after consistency checks pass.

  8. Preserve logs, Sentry events, audit rows, operation receipts, and outbox records for incident review.

Additive migrations and the old endpoint contracts remain in place; domain and flag reversal must be sufficient.

Monitoring and retirement ​

For 72 hours, monitor Sentry fatal/nonfatal rates, Mixpanel critical funnels, Supabase auth/database/realtime/storage health, payment failures, outbox lag, Hermes action failures/reverts, WhatsApp delivery, Web performance, and mobile crash-free sessions. Compare with the recorded React/mobile baseline.

After 72 stable hours, end enhanced monitoring but keep React immutable.

After 30 stable days:

  1. disable React deployment workflows and schedules;
  2. remove React Supabase/Hermes/Cloudflare secrets and PAT access;
  3. remove MONOREPO_FETCH_TOKEN;
  4. verify no production URL, worker, function, or scheduled job names React as owner;
  5. archive the React repository read-only;
  6. retain the release evidence and rollback incident record.

Do not perform the 30-day retirement steps early.

Aldilaijan & Khobara Real Estate Platform