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:
| Evidence | Required value |
|---|---|
| Flutter commit | immutable commit on main |
| React rollback deployment | immutable Cloudflare deployment ID |
| Supabase project | jrsgosnnyjonxaesqtln |
| Flutter Web Pages project | aldilaijan-app |
| Hermes health | https://hermes.aldilaijan.com/api/health |
| iOS build | approved and held for manual release |
| Android build | signed artifact built and verified locally from the frozen main SHA, approved and held for manual release |
| Route contract | 267 exact routes, zero broad exemptions |
| Operation replay | passing sanitized artifact from the final main commit |
| Launch flag | full_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 --checknode 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
maincommit, 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_aldilaijanadmin_aldilaijan_execadmin_khobara- agent
- secretary
secretary_aldilaijansecretary_khobara- valuer
- inspector
- accountant
hr_manageron 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 β
Freeze production mutations that cannot be replayed safely.
Run Full-parity domain cutover in
inventorymode. Copy the emitted Reactcanonical_deployment.idinto the release ticket and confirm that exact successful production deployment is the rollback target.Pull the live schema and repair/check the replay snapshot:
bashsupabase db pull python tool/fix_snapshot_replay.py python tool/fix_snapshot_replay.py --checkReview the exact migration diff and apply additive migrations:
bashsupabase db push --dry-run supabase db pushPush the verified Flutter commit to
main. Its workflows:- build and deploy Flutter Web;
- transfer only allowlisted changed Edge Functions;
- deploy the immutable Hermes release.
Wait for every workflow to finish. Verify the deployed Web HTML references the commit-versioned bootstrap and Dart bundle.
Attach the inventory evidence artifact to the release ticket. Then run the workflow once in
cutovermode with the full Flutter commit SHA, the capturedreact_deployment_id, the exact domain listaldilaijan.com,app.khobara.com.kw,www.aldilaijan.com,www.khobara.com.kw, and confirmationCUTOVER: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 domainapp.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.Release the pre-approved iOS and Android builds.
Confirm
feature_flags.full_parity_launch_v1is enabled at 100 percent.Unfreeze mutations and execute the production smoke matrix.
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
apiviews, 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, orMONOREPO_FETCH_TOKENdependency
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 β
Freeze risky mutations.
Restore the recorded immutable React Cloudflare deployment for every production domain as one routing change by running Full-parity domain cutover in
rollbackmode with the same capturedreact_deployment_id, the exact same domain listaldilaijan.com,app.khobara.com.kw,www.aldilaijan.com,www.khobara.com.kw, and confirmationROLLBACK: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.Disable
full_parity_launch_v1.Halt staged mobile rollout where the stores permit it. Do not attempt a database rollback.
If Hermes is implicated, deploy the recorded known-good Flutter commit:
bashgh workflow run deploy-hermes-server.yml \ --repo busami/aldilaijankhobara-app \ --ref main \ -f release_sha=<known-good-40-character-commit>Verify legacy endpoint versions, auth, payment, and core React journeys.
Unfreeze mutations only after consistency checks pass.
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:
- disable React deployment workflows and schedules;
- remove React Supabase/Hermes/Cloudflare secrets and PAT access;
- remove
MONOREPO_FETCH_TOKEN; - verify no production URL, worker, function, or scheduled job names React as owner;
- archive the React repository read-only;
- retain the release evidence and rollback incident record.
Do not perform the 30-day retirement steps early.
