Phase 3.3 — Session Topic Sensitivity (complete): - Backend: topic_sensitivity column + session_sensitivity_log, sensitivity service (flip with one-way-latch + audit), PATCH /api/shared/chat/sessions/:id/topic, topic carried in pairing + extension WS payloads, CC filter + sensitive stats + per-mitra sensitive columns on activity page - client_app: TopicSelectionBottomSheet before pricing, topic flows through pairing request, silent WS handler for session_topic_updated - mitra_app: SensitivityBadge + SensitivityTheme + sensitivityConfigProvider, overlay badge + yellow accent, chat screen app-bar toggle with configurable confirmation + latch, extension card shows current flag, history + transcript yellow theme - control_center: Sensitivitas Topik settings section, topic filter + column with inline audit log, sensitive stats dashboard card, mitra activity sensitive columns with QC flag Phase 3.4 — Self-Managed Auth (foundation only): - Migration: auth_sessions + otp_requests tables, social identity columns on customers, password_hash + lockout on control_center_users, OTP + CC lockout app_config keys - New services: password (bcrypt + complexity), token (JWT HS256 + refresh rotation, session_id claim pre-wires future Valkey revocation), social-identity (Google + Apple JWKS), OTP (Fazpass stub — real API TBD) - Constants: AuthProvider + OtpChannel - Middleware, auth route rewrites, WS auth update, Firebase → FCM isolation still pending (next chunk); Fazpass docs + Apple Developer setup still required before E2E testing Docs: - requirement/phase3.3.md, phase3.3-plan.md, phase3.3-testing.md - requirement/phase3.4.md, phase3.4-plan.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 KiB
13 KiB
Phase 3.3 Testing & Outstanding Regression Checklist
This is a reminder document — consolidated testing work for Phase 3.3 plus every outstanding test item carried over from earlier Phase 3 iterations.
Tick boxes as you verify.
Part 1 — Phase 3.3: Session Topic Sensitivity
1.1 Database / Migration
- Migration runs cleanly on an existing dev DB (no errors, all
IF NOT EXISTS/ON CONFLICTpaths hit) chat_sessions.topic_sensitivitycolumn exists with default'regular'and NOT NULL- Existing sessions (created before the migration) have
topic_sensitivity = 'regular'after migration session_sensitivity_logtable exists with correct FKs (sessions, mitras)idx_chat_sessions_topic_sensitivityindex createdidx_session_sensitivity_log_sessionindex createdapp_confighassensitive_flip_confirmation_enabled = trueby defaultapp_confighassensitive_flag_one_way_latch = falseby default
1.2 Customer Flow (client_app)
Topic selection bottom sheet
- Tap "Mulai Curhat" → topic selection bottom sheet appears
- Sheet cannot be dismissed by tapping outside
- Sheet cannot be dismissed by swiping down
- System back button cancels entire "Mulai Curhat" flow (does NOT open pricing)
- Copy matches PRD (title, body, sub-question, helper line)
- "Topik umum" button styling is primary
- "Topik sensitif" button styling is secondary but equal weight (not de-emphasized)
Request submission
- Tap "Topik umum" → pricing sheet opens with topic pre-selected as regular
- Tap "Topik sensitif" → pricing sheet opens with topic pre-selected as sensitive
- After pricing confirm →
POST /api/client/chat/requestbody includestopic_sensitivity: regular|sensitive - Backend rejects request with missing
topic_sensitivity(400 BAD_REQUEST) - Backend rejects request with invalid
topic_sensitivityvalue (e.g.,"other") - Created
chat_sessionsrow has correcttopic_sensitivityvalue
Customer UI after request
- Chat screen stays pink (no yellow), regardless of flag
- Customer history screen: no badge on any row regardless of flag
- Customer transcript screen: stays pink
- Customer receives
session_topic_updatedWS message after mitra flip → no UI change, no error, no crash
1.3 Mitra Flow — Incoming Request (mitra_app)
- Regular request: overlay has no badge, no yellow accent
- Sensitive request: overlay shows "Topik sensitif" badge + yellow accent
- Overlay payload from WS includes
topic_sensitivity - Overlay payload from FCM fallback includes
topic_sensitivity(or app fetches on open) - Overlay payload from
getPendingRequestsForMitra(app-resume path) includestopic_sensitivity - Mitra accepts sensitive request → lands in active chat screen with correct flag
1.4 Mitra Flow — Active Chat Screen
- Sensitive active session: yellow doodle background
- Regular active session: pink doodle (unchanged behavior)
- Header banner shows "Topik sensitif" label only when sensitive
- App-bar toggle icon visible (flag / flag_outlined depending on state)
Flip toggle — confirmation enabled (default)
- Tap toggle regular → sensitive → dialog appears: "Tandai sesi ini sebagai sensitif?"
- "Batal" cancels, no state change, no audit log entry, no WS broadcast
- "Tandai" flips, background turns yellow instantly, log entry created
- Tap toggle sensitive → regular → dialog: "Tandai sesi ini sebagai topik umum?"
Flip toggle — confirmation disabled (via CC config)
- Toggle
sensitive_flip_confirmation_enabledtofalsein CC - Flip happens immediately, toast "Sesi ditandai sensitif" / "Sesi ditandai topik umum"
- No dialog appears
One-way latch — disabled (default)
- Can flip regular → sensitive → regular → sensitive freely
One-way latch — enabled (via CC config)
- Toggle
sensitive_flag_one_way_latchtotruein CC - Session that was regular: can flip to sensitive; toggle then disabled
- Session that was already sensitive at latch-enable time: toggle disabled with tooltip
- Attempt to flip sensitive → regular with latch on: API returns 409
SENSITIVITY_LATCHED - Error dialog shown: "Sesi sudah ditandai sensitif dan tidak bisa diubah kembali."
Audit trail
- Every successful flip creates a
session_sensitivity_logrow with correctfrom_value,to_value,changed_by_mitra_id - No-op flip (e.g., tap confirm but value didn't actually change) does NOT create a log row
- Log entries ordered correctly (ascending
created_at)
1.5 Mitra Flow — Extension
- Customer requests extension on regular session → mitra extension card has no badge
- Customer requests extension on sensitive session → mitra extension card shows "Topik sensitif" badge + yellow accent
- Mitra flipped session mid-chat regular → sensitive, then customer requests extension → extension card reflects current sensitive flag
- Extension accepted → flag carries over unchanged to extended session
1.6 Mitra Flow — History & Transcript
- Mitra history list row shows "Topik sensitif" badge for sensitive sessions
- Mitra history list row has no badge for regular sessions
- Mitra transcript view: sensitive session → yellow doodle background
- Mitra transcript view: regular session → pink doodle
- Customer-side history and transcript: always pink, no badge
1.7 Mitra Flow — Edge Cases
- Mitra tries to flip flag on a session they don't own → 403 FORBIDDEN
- Mitra tries to flip flag on a
CLOSINGsession → 409 SESSION_NOT_ACTIVE - Mitra tries to flip flag on a
COMPLETEDsession → 409 SESSION_NOT_ACTIVE - Mitra tries to flip flag on an
EXPIREDsession → 409 SESSION_NOT_ACTIVE - Invalid
topic_sensitivityvalue sent to PATCH endpoint → 400 BAD_REQUEST - Customer tries to call PATCH endpoint → 403 FORBIDDEN (only mitra allowed)
1.8 Control Center — Settings
- Settings page has new "Sensitivitas Topik" section
sensitive_flip_confirmation_enabledcheckbox reflects current backend valuesensitive_flag_one_way_latchcheckbox reflects current backend value- PATCH
/internal/config/sensitivitypersists changes - Changes take effect immediately on next mitra flip (no app restart needed on mitra side, if mitra fetches config dynamically)
1.9 Control Center — Sessions Page
- Sessions list has new filter dropdown (All / Umum / Sensitif)
- Filter "Sensitif" returns only sessions with
topic_sensitivity = 'sensitive' - Filter "Umum" returns only
regular - Filter "All" returns everything (backward-compatible)
- Filter works combined with existing status filter
- Session list has new "Topik" column showing badge (green "Umum" / yellow "Sensitif")
1.10 Control Center — Session Detail
- Session detail page shows current
topic_sensitivity - Session detail shows sensitivity audit trail timeline: "Mitra {name} menandai topik sebagai {from→to} pada {timestamp}"
- Timeline ordered ascending
- Sessions with no flips show empty timeline (no error)
1.11 Control Center — Dashboard
- Dashboard shows "Sesi Sensitif" card with total count + 30-day % breakdown
- Percentage math correct (sensitive / total × 100, rounded to 1 decimal)
- Edge case: 0 sessions in last 30 days → shows
0%notNaN
1.12 Control Center — Mitra Activity
- Summary table has new columns: Sensitive Total, Sensitive Accepted, Sensitive Rate (%)
- Mitra with 0 sensitive requests shows
—(not0%) - Sensitive rate computed correctly (sensitive_accepted / sensitive_total × 100)
- Detail log table: optional new "Topik" column with badge
- Date range filter still works with new columns
1.13 Control Center — Integration Regression
- Existing settings (anonymity, free-trial, extension-timeout, early-end, mitra-ping, price-tiers) still work
- Existing sessions filter (by status) still works
- Existing dashboard cards still render
Part 2 — Outstanding Items From Phase 3.2
Carried over from project_phase3_testing_status.md (2026-04-15):
2.1 Chat Request Overlay
- Multiple concurrent chat requests — verify queue behavior (one shown at a time, next appears when current resolved)
- Stale request: "cancelled by customer" message shown + requires acknowledge (no auto-dismiss)
- Stale request: "accepted by other bestie" message shown + requires acknowledge
- Stale request: "expired" message shown + requires acknowledge
- Swipe-to-dismiss (ignore) does NOT send reject to backend
- Ignored request eventually logs as
ignoredinchat_request_notificationsafter 60s timeout - Request
missed(another mitra accepted first) logs correctly active_session_countcaptured correctly at notification creation
2.2 End-to-End Flows
- Full chat flow: pair → chat → extension → closure (customer + mitra)
- Goodbye flow: session expires → closing → both submit goodbye → completed
- Extension accepted mid-flow → session resumes, timer extends, no grace timer lingering
- Extension rejected → session moves to closing, both see closure UI
- Extension timeout (no mitra response) → closing
2.3 iOS Coverage (still partially untested)
- OTP login on iOS (customer)
- OTP login on iOS (mitra)
- Push notifications on iOS (customer + mitra)
- FCM token registration on iOS
- Chat screen rendering on iOS
- Back button behavior on iOS (deep-link pop fallback)
- Overlay on iOS (from
project_phase3_testing_status: iOS setup started but incomplete) - Splash screen on iOS
- Onboarding carousel on iOS
- Keyboard handling on iOS (chat input, goodbye form)
Part 3 — Outstanding Items From Phase 3 / 3.1
3.1 Session Lifecycle
- Server restart mid-session: session timer is restored from DB (
restoreActiveTimers) - Stale active sessions auto-complete on restart
- Closing sessions with stale grace timers auto-complete on restart
- Session expired from customer side (5-min countdown display)
- Abandoned session during closure grace period → auto-completes
- Known limitation: multi-instance backend sessions not supported until Valkey keyspace notifications implemented (out of scope, just confirm single-instance behavior)
3.2 Chat Mechanics
- Message status transitions (sent → delivered → read) work correctly
- Typing indicator shows/hides correctly on both sides
- Messages received while backgrounded are marked
deliveredon foreground resume - Messages viewed are marked
readand the read receipt propagates back to sender - Unread badge on home screen updates correctly (client_app + mitra_app)
3.3 Navigation / UI
- All navigation uses
GoRouter.context.push/go(no leftoverNavigator.pushNamed) - Deep-linked screens work with
canPopfallback +PopScope notification_serviceusesgo(notpush) for terminal states- Splash screen hides auth loading flash on both apps
- Goodbye views use
SingleChildScrollView(no keyboard overflow)
3.4 Control Center Settings
- Free trial config: toggle + duration edit
- Extension timeout: edit seconds
- Early end: toggle mitra / customer independently
- Mitra ping: toggle require + interval
- Price tiers: add / edit / remove tiers and verify client_app pricing sheet reflects changes
Part 4 — Cross-Cutting / Pre-Release
4.1 Regression Checks (do after Phase 3.3 merge)
- Existing customer auth flow still works (welcome → OTP → register → home)
- Existing mitra auth flow still works
- Existing control center login still works (admin@halobestie.com)
- Pairing flow (mulai curhat → matched) still works end-to-end
- All existing WS messages still processed (no regressions from new
session_topic_updatedhandler)
4.2 Platform Coverage
- Android: customer app on emulator (Medium_Phone_API_36.1)
- Android: mitra app on physical device (SM-A530F, 52002a5db8e0c46b)
- iOS: customer app (Mac + simulator / physical)
- iOS: mitra app (Mac + simulator / physical)
- Control center: Chrome latest
- Control center: Firefox / Safari (if required)
4.3 Load / Concurrency (sanity)
- 2 concurrent customers requesting chat at the same time — both find a mitra (or one waits)
- 1 customer, 5 mitras online — blast notification reaches all 5
- Mitra accepts after another mitra already accepted → receives
missedwithaccepted_by_other - Backend restart with active sessions → timers restored, no data loss
4.4 Config Flag Interactions
sensitive_flag_one_way_latch = true+ existing sensitive session → toggle disabledsensitive_flip_confirmation_enabled = false+ rapid flips → no race, all logged in order- Both config flags toggled together → no conflict
4.5 Known Blockers / Deferred
Not tests — tracked here so they don't get forgotten:
- Valkey keyspace notifications — required for multi-instance session timers (noted in memory as future work)
- Mitra QC auto-flag — auto-flagging high-rejection mitras on CC (future phase)
- Merge-on-link for social login (currently reject-on-existing)
- Phase 3.4 auth migration — separate phase, not blocking 3.3 testing