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>
274 lines
13 KiB
Markdown
274 lines
13 KiB
Markdown
# 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
|