Files
halobestie-clone/requirement/phase3.3-testing.md
ramadhan sjamsani 780cade3db Phase 3.3: topic sensitivity + Phase 3.4: auth foundation
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>
2026-04-24 10:15:12 +08:00

13 KiB
Raw Blame History

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 CONFLICT paths hit)
  • chat_sessions.topic_sensitivity column exists with default 'regular' and NOT NULL
  • Existing sessions (created before the migration) have topic_sensitivity = 'regular' after migration
  • session_sensitivity_log table exists with correct FKs (sessions, mitras)
  • idx_chat_sessions_topic_sensitivity index created
  • idx_session_sensitivity_log_session index created
  • app_config has sensitive_flip_confirmation_enabled = true by default
  • app_config has sensitive_flag_one_way_latch = false by 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/request body includes topic_sensitivity: regular|sensitive
  • Backend rejects request with missing topic_sensitivity (400 BAD_REQUEST)
  • Backend rejects request with invalid topic_sensitivity value (e.g., "other")
  • Created chat_sessions row has correct topic_sensitivity value

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_updated WS 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) includes topic_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_enabled to false in 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_latch to true in 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_log row with correct from_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 CLOSING session → 409 SESSION_NOT_ACTIVE
  • Mitra tries to flip flag on a COMPLETED session → 409 SESSION_NOT_ACTIVE
  • Mitra tries to flip flag on an EXPIRED session → 409 SESSION_NOT_ACTIVE
  • Invalid topic_sensitivity value 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_enabled checkbox reflects current backend value
  • sensitive_flag_one_way_latch checkbox reflects current backend value
  • PATCH /internal/config/sensitivity persists 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% not NaN

1.12 Control Center — Mitra Activity

  • Summary table has new columns: Sensitive Total, Sensitive Accepted, Sensitive Rate (%)
  • Mitra with 0 sensitive requests shows (not 0%)
  • 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 ignored in chat_request_notifications after 60s timeout
  • Request missed (another mitra accepted first) logs correctly
  • active_session_count captured 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 delivered on foreground resume
  • Messages viewed are marked read and 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 leftover Navigator.pushNamed)
  • Deep-linked screens work with canPop fallback + PopScope
  • notification_service uses go (not push) 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_updated handler)

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 missed with accepted_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 disabled
  • sensitive_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