Chat-screen performance (customer + mitra): - Parent screens have zero `ref.watch` — only `ref.listen` for side effects - Body extracted into its own `ConsumerStatefulWidget`; AppBar parts split into narrow `.select` consumers (mode, sensitivity, timer) - Per-second timer ticks routed to dedicated providers (`chatRemainingSecondsProvider` + new `mitraChatRemainingSecondsProvider`) so WS `session_tick` frames don't invalidate the rest of the chat state Dispose-in-ref bug fix: - `home_screen.dart`, `payment_screen.dart`, `mitra_chat_screen.dart` — ref-using cleanup moved from `dispose()` to `deactivate()`. Modern Riverpod invalidates `ref` the moment `dispose()` runs; the resulting silent error corrupts the widget-tree finalize and the next screen appears frozen - `halo_lints` package added at repo root with `no_ref_in_dispose` rule to catch this pattern in CI / IDE analysis - `custom_lint` activated in both apps' `analysis_options.yaml` (was installed but never wired in — also brings `riverpod_lint`'s `avoid_ref_inside_state_dispose` online) - CLAUDE.md Pitfalls section added to client_app + mitra_app Phase 4 §3 retryable blast-failure (Option A): - Backend `expirePairingRequest` + all-rejected use `recordIntermediateFailure` instead of `failPaymentSession` so the payment session stays `confirmed` for re-blast - WS `pairing_failed` payload carries `is_terminal: false` on the retryable paths; client parses the flag and exposes `retryBlast()` - "Coba cari lagi" CTA on S7 Timeout now re-blasts on the same payment - Pairing service test updated to reflect the new semantics Customer waiting-payment screen navigation patch: - `_navigateTerminal` uses `Future.microtask` + `addPostFrameCallback` redundancy after a release-mode bug where polling stopped but `context.go` never fired, leaving the screen visually stuck on "menunggu pembayaran" See requirement/resume-2026-05-15.md for next-day pickup checklist (mitra release rebuild + S21 Ultra install + retest is the gating item). Bundles unrelated in-flight Phase 4 §2.x work that was already on disk (ESP screen removal, USP one-time gate scaffolding, bestie-availability public route, OTP service edits, Maestro flow tweaks) — kept together to avoid a partial-rebase mess. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
79 lines
5.7 KiB
Markdown
79 lines
5.7 KiB
Markdown
# Resume — 2026-05-15
|
|
|
|
> Cross-device pickup note. Mirror of the local Claude memory `project_resume_next.md` so this is reachable on any machine that clones the repo. Delete this file when fully resumed.
|
|
|
|
Paused **2026-05-14 evening**. Chat-screen perf refactor done in code on both apps; release rebuild + install + retest on mitra is the gating step that didn't complete (S21 Ultra unplugged before the final build could finish).
|
|
|
|
## What needs doing tomorrow — in order
|
|
|
|
### 1. Rebuild + install mitra release on S21 Ultra
|
|
|
|
Code is on disk in `mitra_app/lib/features/chat/screens/mitra_chat_screen.dart` (full refactor) and `mitra_app/lib/core/chat/mitra_chat_notifier.dart` (timer-extraction provider). The APK currently on the S21 Ultra only has the timer-extraction fix — NOT the full body/AppBar split.
|
|
|
|
```bash
|
|
# Plug the S21 Ultra, authorize USB debugging if needed:
|
|
adb devices # confirm device shows as `device`, not `unauthorized`
|
|
|
|
# Build + install + run:
|
|
cd mitra_app
|
|
flutter run -d <S21_DEVICE_ID> --release --dart-define=API_BASE_URL=http://<DEV_MACHINE_IP>:3000
|
|
```
|
|
|
|
Yesterday's IDs (will differ on a new host):
|
|
- S21 Ultra: `RRCR100NN7Z`
|
|
- Customer SM-A530F: `52002a5db8e0c46b`
|
|
- Dev machine static IP: `192.168.88.247`
|
|
|
|
Backend dev server (`cd backend && npm run dev`) needs to be running first. The dev `API_BASE_URL` defaults to production if you forget the dart-define.
|
|
|
|
### 2. Test mitra chat under release
|
|
|
|
After install: open a chat session, send a few messages, watch the partner type. Expected:
|
|
- Timer ticks every 1s rebuild ONLY the timer pill in the AppBar.
|
|
- Sending/receiving messages rebuilds ONLY the body widget.
|
|
- Typing pulses don't cause whole-screen flicker.
|
|
|
|
Bar: it should feel as snappy as the customer app does now (which is the reference point).
|
|
|
|
### 3. Verify customer waiting_payment_screen navigation patch
|
|
|
|
Yesterday the customer app got stuck on "menunggu pembayaran" after a payment was confirmed (polling stopped but `addPostFrameCallback(context.go(...))` never fired). Patched with belt-and-suspenders in `waiting_payment_screen.dart::_navigateTerminal` — `Future.microtask` + `addPostFrameCallback` redundancy.
|
|
|
|
End-to-end test path:
|
|
1. Customer app: tap "aku mau curhat" → pick tier → create payment.
|
|
2. SQL-confirm the payment (or use the dev confirm endpoint).
|
|
3. Watch the waiting screen — should advance off "menunggu pembayaran" into notif-gate → searching within ~3s (one poll cycle).
|
|
|
|
If still stuck: I added `print` instrumentation would surface debug-mode only; consider running customer in debug to capture log output.
|
|
|
|
### 4. If mitra chat is still laggy after #1
|
|
|
|
Next suspect: message-list rebuilds on every state change re-iterate visible ListView.builder items. Try:
|
|
- Convert `_MessageBubble` to `const` constructor (immutable inputs).
|
|
- Wrap bubbles in `RepaintBoundary` to isolate paint.
|
|
|
|
Don't touch until #1 confirms whether the body-extraction refactor was sufficient.
|
|
|
|
## What landed today (already on disk / committed)
|
|
|
|
- **Dispose-in-ref fix** in `home_screen.dart`, `payment_screen.dart` (customer), `mitra_chat_screen.dart` (mitra). Pattern: ref-using cleanup goes in `deactivate()`, not `dispose()`. Symptom of regression: next screen looks frozen after navigation, even though app is alive.
|
|
- **`halo_lints`** package at repo root with `no_ref_in_dispose` rule. Wired into both apps' `analysis_options.yaml`. Also activates the already-installed `riverpod_lint` package (which ships `avoid_ref_inside_state_dispose` for the same case).
|
|
- **CLAUDE.md Pitfalls section** added to `client_app/CLAUDE.md` and `mitra_app/CLAUDE.md` documenting the dispose-ref landmine.
|
|
- **Customer chat refactor** — `chat_screen.dart` split into `_ChatHeader` + `_ChatBodySection` + `_TimerBanner`. Parent has zero `ref.watch`.
|
|
- **Mitra chat refactor** — `mitra_chat_screen.dart` mirrors customer pattern: `_MitraChatBodyContent`, `_MitraChatTopicToggle`, `_MitraChatVoicePill`, `_MitraChatTimerAction`. Plus the `mitraChatRemainingSecondsProvider` for per-second ticks.
|
|
- **Customer waiting screen nav** — `Future.microtask` + `addPostFrameCallback` redundancy at terminal status.
|
|
- **Phase 4 Option A retryable blast-failure** — backend `expirePairingRequest` + all-rejected use `recordIntermediateFailure` instead of `failPaymentSession`; WS payload has `is_terminal: false`; client carries `topicSensitivity` through `PairingFailedData`; "coba cari lagi" CTA re-blasts on the same payment via `retryBlast()`. Test updated to match new semantics.
|
|
|
|
## Hazards / gotchas to remember
|
|
|
|
- **Release mode is the bar.** Debug-mode JIT on both phones (SM-A530F + S21 Ultra) was unusably laggy. Always rebuild release to test real perf.
|
|
- **`node --watch` doesn't pick up newly-added module files.** When you add a brand-new route file or service, kill + restart the backend dev server. Don't trust the auto-reload for new files.
|
|
- **AVD on the dev host is unusable for interactive rendering** — use the physical devices.
|
|
- **`.claude/settings.local.json` + `.claude/agent-memory/` + `client_app/devtools_options.yaml`** stay modified — local-only, never commit.
|
|
|
|
## Decisions explicitly deferred
|
|
|
|
- **CI integration** — user raised the topic but we punted. Scope to gather when resuming: GitHub Actions vs other; per-PR triggers; which projects (backend vitest + control_center playwright + client/mitra flutter analyze + dart run custom_lint); APK build artifacts; Maestro Cloud or self-hosted device runner.
|
|
- **Phase 4 §2.1 real-device verification** — still pending from before today. See `requirement/phase3.4-testing.md` §1.5.1 for the runbook.
|
|
- **`backend/test/services/session-timer.service.test.js`** — 2 pre-existing failures (uuid-string fixture bug). Unrelated to anything we touched.
|