Swasti · mForm V2→V3

19 — Production go-live checklist

The operational contract between the Release owner (Abhijit) and DevOps for putting Swasti V3 into production. Read alongside note 14 — Repos & deployment (env/branch map) and note 15 — Release runbook (the staging mechanics).

Two repos, two halves:

  • Mobile appfrappe_mform_swasti_app. DevOps builds the prod AAB off main and uploads it to the Play Store.
  • Backendfrappe_mform_swasti. Deployed to swasti.mform.in.

Legend: 👤 = Release owner · 🛠️ = DevOps · [ ] = gate to tick.

Credentials are NOT in this document. Prod Frappe admin login and the Play-review login are shared separately/securely — this KB page is a shared link.


🚨 0. Pre-build blockers (fix BEFORE the prod build)

These are real, currently-open in the repo. The prod build is not shippable until all three are cleared.

  • 🛠️ Release signing key. The Gradle wiring is now in place — android/app/build.gradle.kts loads an upload keystore from android/key.properties and only falls back to debug signing when that file is absent. Remaining (DevOps): generate the upload keystore, drop in android/key.properties (gitignored, DevOps-held), build the signed AAB, and enrol in Play App Signing. Full steps in Appendix B below. Reuse the same upload key for every future release — and back it up (losing it blocks app updates).
  • 👤 Prod API URL — done. env/prod.json now points to https://swasti.mform.in (was a placeholder). Reaches main via the promotion flow.
  • google-services.json — not required. The com.google.gms.google-services Gradle plugin is not applied, so the build never consumes it and Firebase isn’t wired into the app at runtime. Firebase is used only for App Distribution (staging/uat tester drops, via CLI); prod ships via the Play Store, so no prod google-services.json / prod Firebase app is needed.

1. Pre-go-live gates (all green before promoting)

  • 👤 UAT verified + sign-off captured (PM/client). Link the sign-off.
  • 👤 All prod-scope SWF tickets closed or explicitly deferred; no open blockers.
  • 👤 Known-open items accepted in writing (e.g. any SWF still pending — call them out so they’re not a surprise in prod).
  • 👤 Version decided. versionName + versionCode. Play Store requires versionCode strictly greater than the last production upload. (App reads pubspec version via appVersionProvider — never hardcode.)
  • 👤 “What’s new” / release notes drafted (per locale).

2. Code freeze & promotion to main (👤)

  • App: uatmain PR raised, reviewed, merged. main is the prod source of truth (PR-only — never push straight to main/uat).
  • Tag the app prod commit (e.g. v1.0.0) so the exact build is reproducible.
  • Backend: confirm the prod commit on frappe_mform_swasti (deploys off development per branch policy) and tag it.
  • No dev/staging-only artefacts in prod: the pre-filled test surveyor login is dev/staging only — confirm it does not appear in the prod build. Debug logging off; no test flags.

3. Prod build configuration (🛠️ — off main)

  • Repo/branch: frappe_mform_swasti_app @ main.
  • Flavor: prod → applicationId com.dhwani.swasti, app name “Swasti” (confirmed in build.gradle.kts).
  • Artifact: AAB (Android App Bundle) — flutter build appbundle --flavor prod --release --dart-define-from-file=env/prod.json. ⚠️ --dart-define-from-file=env/prod.json is MANDATORY — the backend URL is a --dart-define (String.fromEnvironment('FRAPPE_URL')), and without it the app silently defaults to http://swasti.local:8000 (local bench) and is completely broken (login fails / points nowhere). Same applies to flutter run. (Not an APK; Play Store needs the bundle.)
  • Signing: real upload keystore (§0), versionCode bumped, Play App Signing enrolled.
  • env/prod.jsonhttps://swasti.mform.in (§0) is what got built.
  • src/prod/google-services.json present (or confirmed not needed) (§0).
  • INTERNET permission in android/app/src/main/AndroidManifest.xml ✓ (already present — release builds need it in the main manifest).
  • R8/minify + resource shrink as configured; smoke-test the release build so obfuscation doesn’t crash anything.

4. Backend prod deploy (🛠️)

  • DB backup taken before any migrate.
  • Deploy to swasti.mform.in: pull the prod commit + bench migrate; verify migrate EXIT 0 and run any required patches.
  • Offline-mode gate: Mobile Configuration enabled=1 + offline_enabled=1 on prod — otherwise saves go server-only and never persist offline (known trap).
  • Roles present: Swasti Surveyor (data perms) and Mobile User (mobile-control login gate) — see note 16.
  • Masters seeded: geography (state→village), schemes, document masters, option masters, donors/partners.
  • 🔑 Geography scoping per surveyor: every prod surveyor MUST have Frappe User Permission rows for their assigned geography. Without them, Frappe applies no restriction and a surveyor can pull all members/data via bulk-fetch. Provision and verify per surveyor before they log in.
  • mobile-control app installed + configured on prod (auth + bulk-fetch endpoints).

5. Play Store listing — assets & metadata (👤 provides → 🛠️ uploads)

Everything DevOps needs to create/update the Play Console listing. Almost all of it is provided below — only the two items marked ⏳ still need input. Full copy in Appendix C; assets in Appendix D.

Store listing text

  • App name: Swasti mForm
  • Short description: Offline-first field app for Swasti surveyors — members, health, schemes & more.
  • Full description: drafted (Appendix C).
  • Category: Business · Tags: data collection, field work, NGO
  • Contact email + website: DevOps-managed (set in Play Console).
  • Privacy policy URL: the DevOps-managed standard Dhwani privacy policy.

Graphic assets

  • App icon 512×512: https://swasti-kb-7930d5fc.pages.dev/store-assets/icon-512.png
  • Feature graphic 1024×500: https://swasti-kb-7930d5fc.pages.dev/store-assets/feature-1024x500.png
  • Phone screenshots: 3 drafts linked (Appendix D) — ⏳ re-shoot clean from a uat/prod build before submission.
  • (optional) tablet screenshots / promo video — not needed.

Play Console declarations (🛠️ fills using these answers)

  • Content rating (IARC): Utility / Productivity; no violence, sexual content, profanity, gambling, or user-generated content → Everyone / PEGI 3.

  • Data safety: collected = personal info, demographic, health info, photos/documents — all for app functionality, not shared with third parties, not sold, encrypted in transit, deletion on request. Geography is manually selected — no precise/GPS location. (Full table in Appendix C; must match the privacy policy.)

  • Target audience & content: adults (18+) — internal work app for authorised field staff (not a children’s app).

  • App access (review login): prod demo surveyor created → playstore.review@swasti.mform.in. Password shared separately with DevOps (not in this public doc) for the Play Console “App access” field. Verified: logs in via the mobile-control endpoint (mobile_control.api.api_auth.login → HTTP 200 + access token). ⚠️ Scope to a demo geography or disable before real beneficiary data lands at go-live (currently no geography restriction; prod has 0 members today).

    Mobile-login account recipe (confirmed — no special perms beyond these): enabled User + password + roles Mobile User (the actual mobile-login gate — MOBILE_USER_ROLES) + Swasti Surveyor (data perms). 2FA must be off (it is, on prod). That’s the complete set — nothing else is required to log in. See note 16 — surveyor onboarding.

  • Ads: none · Countries: India · Pricing: Free.

  • Sensitive permissions / government app: none applicable. App uses INTERNET + camera/storage (document photos); no SMS, call-log, precise-location, or other sensitive permissions; not a government app.

6. Release rollout (🛠️)

  • Upload AAB → track: internal → closed → production (or production with staged rollout, recommend 10–20% to start)
  • “What’s new” notes attached per locale
  • Submit for review (the first production release can take hours–days for Google review)

7. Post-go-live verification (👤 + 🛠️)

  • Install from the Play Store on a clean device
  • App shows correct version (appVersionProvider)
  • Login as a prod surveyor
  • Create a member → sync → verify on swasti.mform.in
  • Geography scoping: surveyor sees only their geography’s members
  • Offline-first: airplane-mode save → reconnect → sync drains
  • Smoke each module: Member, Scheme, Health, Livelihood, Document + a follow-up (visit numbering)
  • Crashlytics/monitoring: no startup crashes; watch the first hours

8. Rollback / incident

  • Play Store: halt the staged rollout; roll back to the previous production release (you can’t instantly “unpublish” — halt + hotfix)
  • Backend: restore the pre-migrate DB backup / redeploy the previous commit
  • Comms: notify PM/client + testers

9. Sign-off

GateOwnerStatusDate
Pre-build blockers cleared (§0)👤/🛠️
UAT sign-off👤
Prod build off main (signed AAB)🛠️
Backend deployed + provisioned🛠️
Play Store assets + declarations👤/🛠️
Submitted to production🛠️
Post-go-live verification👤/🛠️

Appendix — what DevOps needs from the Release owner (quick handover list)

  1. main prod commit/tag (app) + backend prod commit/tag.
  2. Upload keystore + key.properties (or confirm Play App Signing key) — held by DevOps, never in the repo.
  3. env/prod.json = https://swasti.mform.in + src/prod/google-services.json (or confirm not needed).
  4. All Play Store assets (icon, feature graphic, screenshots) + listing text. (Privacy policy URL is the DevOps-managed standard Dhwani policy.)
  5. Data safety + content rating answers.
  6. Review login (prod/demo surveyor) — shared separately.
  7. Prod Frappe admin creds — shared separately (not in this doc).

Appendix B — Create the release signing key & build a signed AAB

The Gradle config already supports a real release key — android/app/build.gradle.kts loads android/key.properties and signs release with it; it falls back to the debug key only when that file is absent (so dev/staging builds are unaffected). DevOps does the following on the prod build machine.

1. Generate the upload keystore (one-time)

keytool -genkey -v -keystore ~/swasti-upload.jks \
  -keyalg RSA -keysize 2048 -validity 10000 -alias swasti-upload
  • Use strong, distinct store + key passwords; store them in the DevOps secret vault.
  • Back up the .jks + passwords off-machine. If lost, you cannot publish app updates (barring a Play App Signing key reset).

2. Create android/key.properties (gitignored — never commit)

storePassword=<store password>
keyPassword=<key password>
keyAlias=swasti-upload
storeFile=/absolute/path/to/swasti-upload.jks

(key.properties, *.jks, *.keystore are already in .gitignore.)

3. Build the signed AAB (off main, prod flavor)

flutter build appbundle --flavor prod --release --dart-define-from-file=env/prod.json

⚠️ The --dart-define-from-file=env/prod.json is mandatory — it sets FRAPPE_URL=https://swasti.mform.in. Omit it and the build silently defaults to http://swasti.local:8000 (local bench) and won’t work.

build/app/outputs/bundle/prodRelease/app-prod-release.aab. Because key.properties is present, this is signed with the upload key, not debug. (Sanity check: keytool -printcert -jarfile <aab> should show the upload cert, not the Android debug cert.)

4. Play App Signing (first release)

  • On the first upload to Play Console, opt into Play App Signing: Google holds the app signing key; your keystore is the upload key.
  • Every later release must be signed with the same upload key. versionCode must strictly increase.

Appendix C — Play Store listing content (DRAFT — 👤 to confirm, 🛠️ to upload)

Drafted copy + form answers. Review/adjust before upload. Anything in [brackets] needs a real value from PM/leadership.

Store listing text

  • App name (≤30): Swasti mForm (alt: “Swasti Field App”)
  • Short description (≤80): Offline-first field app for Swasti surveyors — members, health, schemes & more.
  • Full description (≤4000):

Swasti mForm is the field data-collection app for Swasti’s community programs. It lets authorised field surveyors register members and run program workflows even with no network — data is saved on the device and syncs automatically when a connection is available.

Built for the field • Works fully offline; auto-syncs when back online • One member profile feeds every program • Fast, guided forms with built-in validation

Programs supported • Member registration & profiling • Scheme applications + follow-ups (eligibility-aware) • Health screening, follow-up visits & re-screening • Livelihood (goat-rearing / FPCL) applications & repayment tracking • Document applications & follow-ups

Access: This is a tool for authorised Swasti field staff only and requires a login provided by the program. It is not a consumer app.

  • Category: Business (alt: Productivity) · Tags: data collection, field work, NGO
  • Contact email: [support email — confirm] · Website: [https://… — confirm]
  • Privacy policy URL: the standard Dhwani privacy policymanaged by DevOps (they supply/maintain the URL).

Content rating (IARC questionnaire)

  • Category: Utility / Productivity / Communication
  • No violence, sexual content, profanity, gambling, or user-to-user content → expected rating Everyone / PEGI 3.

Data safety form (Play Console)

The app collects and transmits the following on behalf of the program:

Data typeCollectedPurposeShared w/ 3rd parties
Personal info (name, DOB, gender, phone, address)YesApp functionality (program delivery)No
Demographic (caste, religion, occupation, income)YesApp functionalityNo
Health info (screening readings, conditions)YesApp functionalityNo
Photos/Documents (uploaded evidence)YesApp functionalityNo
Location (geography is manually selected, not GPS/precise)No precise locationNo
  • Encryption in transit: Yes (HTTPS).
  • Data deletion: users can request deletion via [contact].
  • Data is not sold; it is stored in Swasti’s own Frappe backend and used only for program delivery/M&E.
  • ⚠️ Confirm these answers with PM — they must match the privacy policy exactly or Play rejects the submission.

App access (for Google review)

Login is required → provide a working review login (a prod/demo surveyor) in the Play Console “App access” section. Shared separately, not in this doc.


Appendix D — Outstanding assets & blockers (status)

ItemStatusOwnerNote
App name + descriptions✅ Drafted (Appendix C)👤 confirm
Content rating + data safety answers✅ Drafted (Appendix C)👤 confirmmust match privacy policy
App icon 512×512Created👤 reviewstore-assets/icon-512.png (also linked below). On-brand placeholder (magenta + leaf, bold “S”) — the prior launcher icon was the stock Flutter logo. Swap for the official brand icon if one exists.
Feature graphic 1024×500Created👤 reviewstore-assets/feature-1024x500.png. On-brand placeholder; swap for a designed version if preferred.
Phone screenshots (2–8)⏳ DRAFTS captured👤3 draft shots from the dev build (1080×2280) linked below — they carry a “DEV” ribbon (and Home shows a test-data sync banner), so re-capture from a clean uat/prod build before submission. Target set: (1) Home, (2) Members, (3) Member detail tabs, (4) a form (e.g. Health screening), (5) a follow-up with Visit Number.
Privacy policy URL✅ Dhwani policy (DevOps-managed)🛠️Standard Dhwani privacy policy, managed by DevOps — they provide the URL for the listing. No app-specific policy needed.
Contact email + website❓ Confirm👤For the store listing.

Asset downloads (public KB):

  • Icon 512×512 — https://swasti-kb-7930d5fc.pages.dev/store-assets/icon-512.png
  • Feature graphic 1024×500 — https://swasti-kb-7930d5fc.pages.dev/store-assets/feature-1024x500.png
  • Screenshots — DRAFT (dev build; re-shoot clean before submission):
    • https://swasti-kb-7930d5fc.pages.dev/store-assets/screenshots/01-home.png
    • https://swasti-kb-7930d5fc.pages.dev/store-assets/screenshots/02-members.png
    • https://swasti-kb-7930d5fc.pages.dev/store-assets/screenshots/03-member-detail.png

Last updated 2026-05-04