Files
halobestie-clone/requirement/phase3.1.md
ramadhan sjamsani d15b2f05fc Phase 3.1 WIP: Riverpod migration (client_app Auth + ChatOpening)
- Add phase3.1 requirement and implementation plan docs
- Add Riverpod dependencies to both client_app and mitra_app
- Wrap both app roots with ProviderScope
- Migrate client_app AuthBloc → AuthNotifier (@riverpod annotation)
- Migrate client_app ChatOpeningBloc → chatPricingProvider (FutureProvider)
- Update router to use Riverpod-based auth state for redirects
- Update all auth screens (display name, register, OTP, force register)
- Update home screen and pricing bottom sheet
- Add android:usesCleartextTraffic for dev HTTP access on both apps
- mitra_app prepared with ProviderScope + ApiClient provider (blocs next)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 13:51:17 +08:00

4.2 KiB

PRD: Phase 3 Stabilization & State Management Migration

Overview

Goal: Stabilize Phase 3 (Chat Engine) through end-to-end testing and migrate Flutter state management from BLoC to Riverpod + flutter_hooks

Success looks like: All Phase 3 features are verified working end-to-end across client_app, mitra_app, and control_center. Both Flutter apps use Riverpod as their sole state management solution.

Background

  • Phase 3 (Chat Engine) is fully scaffolded but has not been end-to-end tested
  • Current Flutter apps use BLoC pattern; Riverpod is preferred for maintainability and reduced boilerplate
  • Migration should happen before Phase 4 to avoid compounding tech debt

FCM fallback for Chat Engine

Mitra Pairing

  • Add configuration on Control center to configure Mitra's app require to ping or not.
  • When Control Center allow non ping, application or backend will not force mitra to ping and allow them to keep online even when the app is closed or in backround
  • Modify Mitra Pairing confirmation to send notification through FCM when websocket to Mitra is closed

Bi-Directional Chat (WebSocket + FCM)

Mitra App

  • When there is new unread message, mitra app must shows badge on active session
  • When there is new unread message, mitra app must shows badge on the chat active session inside active session page
  • Unread badge on each active session will be cleared when the message has been read
  • Unread badge on active session button on main page will be cleared when the message has been read

Customer App

  • When there is new unread message, Customer app must shows badge on active session
  • Unread badge will be cleared when unread message has been cleared

Chat Closure & Extension

  • When chat closure called, backend will send closure signal to both Mitra and Customer
  • Backend will use FCM if the websocket connection is down

Control Center

  • Control center shows configuration for ping from mitra

Riverpod Migration

Scope

  • Migrate all BLoC classes in client_app and mitra_app to Riverpod annotation-based providers
  • Replace flutter_bloc with flutter_riverpod, riverpod_annotation, flutter_hooks, and hooks_riverpod
  • Add riverpod_generator + build_runner as dev dependencies for code generation
  • No backend or control_center changes

Migration Strategy

  • Add Riverpod dependencies (flutter_riverpod, hooks_riverpod, riverpod_annotation) and dev dependencies (riverpod_generator, build_runner, custom_lint, riverpod_lint)
  • Wrap app root with ProviderScope
  • Migrate one Bloc at a time, starting with the simplest (e.g. AuthBloc)
  • For each migrated Bloc:
    1. Replace Bloc/Cubit class with @riverpod annotated Notifier or AsyncNotifier (extending _$ClassName)
    2. Replace BlocEvent + emit() pattern with notifier methods that update state directly
    3. Run dart run build_runner build to generate .g.dart files
    4. Replace BlocProvider with generated provider (e.g. authProvider)
    5. Replace BlocBuilder widgets with ConsumerWidget + ref.watch()
    6. Replace BlocListener with ref.listen() inside widget or provider
    7. Use HookConsumerWidget where flutter_hooks are needed (e.g. useTextEditingController, useEffect)
  • Run E2E verification after each migration to catch regressions
  • Remove flutter_bloc dependency only after all Blocs are migrated

Affected Blocs

  • client_app — AuthBloc, PairingBloc, ChatBloc, ChatOpeningBloc, SessionClosureBloc
  • mitra_app — AuthBloc, OnlineStatusBloc, MitraChatBloc, ExtensionBloc

Non-Functional Requirement

  • WebSocket reconnects gracefully after network interruption (within 5s on stable network)
  • Use FCM to send command or message when websocket is down
  • No message loss during brief disconnects — undelivered messages sync on reconnect
  • Chat screen maintains scroll position and input draft on app lifecycle events (background/foreground)
  • Riverpod migration introduces zero new UI bugs — feature parity with BLoC implementation

Tech Stack

  • State management: Riverpod + flutter_hooks (replacing flutter_bloc)
  • No backend changes expected — migration is Flutter-only