Commit Graph

3 Commits

Author SHA1 Message Date
fcb8eaa505 App ID + launcher icon rename: halobestie.* → mybestie
- Customer: com.halobestie.client.client_app → com.mybestie
- Mitra:    com.halobestie.mitra.mitra_app  → com.mybestie.mitra
- iOS bundle IDs renamed to match (no .clientApp/.mitra camelCase legacy)

Mechanical rename touches Android build.gradle/Manifest/MainActivity
package, iOS pbxproj/Info.plist bundle IDs, Firebase configs
(google-services.json + GoogleService-Info.plist + firebase_options.dart),
new HaloBestie/Mitra launcher icons via flutter_launcher_icons (pubspec
config + adaptive-icon resources + AppIcon imageset), and the appId
references in every customer maestro flow + both .maestro/config.yaml
files. brandLogoBg (#FF699F) added to halo_tokens for the launcher pink.

Followup: re-register apps in Firebase consoles using the new package IDs;
strategy memo at project-firebase-env-strategy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 11:13:47 +08:00
770f61074c Phase 4 Stage 9: real-device sweep, 4 flows green + 2 shipping bugs fixed
Stage 9 sweep on Client_Phone AVD + physical mitra phone:
- 01_smoke 
- 02_onboarding_verified 
- 03_onboarding_anon 
- 04_payment_expired 
- 05_searching_timeout: in progress when wrap-up began
- 06–08: not yet attempted

## Real shipping bugs fixed (would have hit prod)

1. **Router carve-out too narrow** (router.dart). The AuthAnonymousData
   carve-out only protected /auth/display-name. On refreshListenable
   notify after loginAnonymous resolves, GoRouter re-evaluates the
   *bottom* of the navigation stack (/welcome — also an auth route),
   and the AuthAnonymousData fallback redirected to /home, tearing down
   the verif sheet before it could open. Loosened to allow any auth
   route under AuthAnonymousData.

2. **Phase 4 multi-screen payment never called startSearch**
   (searching_screen.dart). The legacy single-screen /payment did
   `pairing.startSearch()` on confirm. The Phase 4 flow is
   waiting → notif-gate → /chat/searching with no intermediate that
   owned the call — customers would land on the searching screen with
   no pairing in flight and never get matched. Added the kickoff to
   searching_screen::initState when state is PairingInitialData and
   paymentDraft.paymentId is set.

## Test infrastructure

- Self-contained Maestro flows 04 + 05 with inline verified-onboarding
  prelude, distinct test phones per flow, robust waits.
- 02 + 03 fixed: malformed `extendedWaitUntil` (visible: + notVisible:
  true → Maestro parsed as compound predicate); now use proper
  notVisible: block.
- New dev-only POST /internal/_test/force-confirm-payment so flows can
  advance past the waiting-payment screen without going through Xendit.
- /internal/_test/reset-phone now cascades through chat_messages →
  chat_sessions → payment_sessions → auth_sessions before deleting the
  customer row (FK 23503 was blocking re-runs).
- /internal/_test/force-pairing-timeout now accepts both
  `searching` and `pending_acceptance` states (mitra-online dev means
  the chat_session transitions through searching very quickly).
- mark_latest_payment_paid.js helper script for Stage 5+ flows.

## Maestro YAML quirks documented in flows

- text: matches anchored regex against the FULL content-desc — need .*
  wildcards for substring, e.g. "mulai.*Rp.*" not "mulai".
- The middot `·` and other special unicode break naive matching;
  always use .* anchors when the source string contains them.
- runFlow `when:` evaluates immediately; pair with waitForAnimationToEnd
  or a preceding extendedWaitUntil before branching.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 22:11:05 +08:00
f170d54535 Phase 4 Stage 5: pairing UX upgrades (searching + match + targeted-wait)
Searching screen: soft-prompt card reskin, pulsing-dots panel replaces
the spinner, inline 5-min timeout panel with `coba cari lagi` (resets
pairing notifier + routes to /payment/entry for a fresh funnel — the
server-side payment is failed_pairing at that point so a stale retry
isn't valid) and `kembali ke home` ghost CTA.

Bestie-found screen: S9 Match-V4 reskin — HaloOrb + status dot +
'halo, aku bestie {name}' + `mulai sesi {N} menit →` with N pulled from
the active session's duration_minutes.

Targeted-wait overlay (new) at /chat/waiting-targeted/:mitraId. Three
sub-states from pairingProvider's PairingTargetedWaitingData:
waiting (20s countdown) / accepted (routes to chat) / declined (stubbed
BestieOfflinePopup with a TODO pointing to Stage 8). Reached via
payment_screen._routeToSearchOnConfirmed when the confirm carried a
targetedMitraId — keeps the mandatory payment-before-pairing invariant.

Dev-only POST /internal/_test/force-pairing-timeout drives the 5-min
timeout shortcut for the Maestro flow without waiting live.

Maestro 05_searching_timeout.yaml + force_pairing_timeout.js helper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 16:49:07 +08:00