The original Stage 10 plan retired chat_history_screen.dart on the
assumption that the new Chat tab Selesai sub-tab replaced it. That was
wrong: Figma has two distinct screens — `extras.jsx::SChatList` (the
Chat tab, browse-only) and `v4.jsx::BestieHistoryList` (the picker for
mermaid §4 returning-user curhat-lagi). They serve different purposes
on row tap: Selesai opens transcript, BestieHistoryList picks a past
bestie for targeted-pair.
Restoring BestieHistoryList at a new home:
- New screen `features/home/screens/bestie_history_list_screen.dart`
matching Figma `v4.jsx::BestieHistoryList`:
appBar title "bestie kamu sebelumnya"
subtitle "{N} bestie yang pernah nemenin kamu"
row: orb + "bestie {name}" + ONLINE pill + sessions count + last
date + topic + → arrow
row tap (online) → /payment with targetedMitraId (Stage-3 flow)
row tap (closing-grace) → /chat/session/$id to finish goodbye
row (offline) → dimmed, tap disabled
Drops the per-row "curhat lagi" secondary button — the row tap IS the
pick action now (cleaner, matches Figma).
- New route `/bestie/history` in router.dart; cleanly separated from the
/chat/* family (which is now exclusively the Chat tab).
- BestieChoiceSheet "bestie yang udah kenal" re-pointed from /chat to
/bestie/history.
- Stage 8 Maestro flow `08_returning_targeted.yaml` updated to assert
the new screen title + tap the row by name (uses output.MITRA_NAME
from the seed_history_session script).
- TECH_DEBT entry retired (curhat-lagi entry point restored). New
TECH_DEBT entry tracks the still-pending wire-up of the Bestie
Offline Popup variant for offline-row tap per mermaid §4.
flutter analyze clean (one pre-existing widget_test scaffolding error
unrelated to Stage 10).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.8 KiB
Tech Debt
Running list of known shortcuts, deferred hardening, and "good enough for now" decisions that need follow-up before they bite us in production.
Format: [date] short title, then enough context for someone (or future-you)
to act on it without re-deriving the discussion.
Backend
[2026-05-11] Public GET /api/public/bestie/available needs rate limiting before prod
File: backend/src/routes/public/public.bestie-availability.routes.js
Decision: The endpoint was made unauthenticated by business requirement — SHome1st renders before any JWT exists, and the CTA must reflect global mitra availability so users see whether bestie is online before committing to onboarding. Response is intentionally a single boolean (no count, no IDs).
Why it's debt: No auth + no rate limit. The 10s in-memory cache bounds DB load, but a single attacker can still hammer the endpoint to:
- run sustained traffic against the public listener (DoS surface)
- scrape
availableover time to infer mitra online/offline patterns (weak information leak — only "is anyone online", but still a signal)
Mitigation before prod:
- Per-IP rate limit (suggested: ~30 req/min/IP, headroom over the legitimate 5s client poll cadence = 12 req/min/IP).
- Implement via
@fastify/rate-limitplugin so other public endpoints can share the policy as we add them under/api/public/*. - Verify Cloud Run / NLB preserves real client IP and that
request.ipreflects it (Fastify already hastrustProxy: true).
Not required: auth, captcha, or removing the count from
/api/client/mitra-availability (that route stays authed for CC/debug).
Client app
[2026-05-11] Social-login (Google / Apple) has no entry point after S3a rewrite
Files: client_app/lib/features/auth/screens/register_screen.dart (no longer renders them); client_app/lib/core/auth/auth_providers_provider.dart (still wired).
Decision: RegisterScreen was rewritten to match Figma S3Phone 1:1
(step-dots + name greeting + privacy card + tanpa-verif ghost link). Figma
S3a shows no Google/Apple buttons, so they were removed from this screen.
Why it's debt: Google/Apple buttons used to render here when the
authProvidersProvider flags were enabled. Today both flags are false
(creds pending — see Phase 3.4 Status memory), so nothing visible is
missing. But the moment /api/shared/auth-providers flips either flag,
the buttons have nowhere to live.
Fix-when-creds-arrive:
- Decide where Google/Apple buttons belong (likely a dedicated login screen reachable from the SHome1st "masuk →" banner), or whether to bring them back to S3a as Figma-friendly tiles above the phone input.
loginGoogle/loginAppleonauthProviderare still intact, so the wiring is one button widget away.
[2026-05-12] Stage 10 — Bestie Offline Popup variant not wired on BestieHistoryList
File: client_app/lib/features/home/screens/bestie_history_list_screen.dart
Decision: Stage 10 follow-up restored BestieHistoryList as a separate
picker screen (per mermaid §4) and made offline rows un-tappable (dimmed).
Mermaid §4 actually calls for a Bestie Offline Popup (returning variant)
to surface when the user picks an offline bestie — with options "cari bestie
lain" and "tanya admin".
Why it's debt: Today the offline row is just disabled. The user gets no explicit prompt to redirect them into the blast flow or to contact admin.
Fix: wire BestieOfflinePopup with variant='returning' on offline-row
tap. The popup widget already exists from Stage 8 (Tanya Admin sheet ships
with the wiring); just needs to be triggered here.
[2026-05-12] S5 ESP screen retired from spec — code still ships it
Files: client_app/lib/features/onboarding/ (S5ESP screen + nav wiring);
screens/onboarding.jsx::S5ESP (Figma reference still in handoff); any
espSelectionProvider / espSkippedProvider Riverpod state.
Decision: Business removed the ESP multi-select step from the customer
flow on 2026-05-12. Both verified and anonymous branches now go from
VerifChoiceSheet straight to the usp_seen? gate. See
requirement/flow_customer.mermaid.md §2.
Why it's debt: Stage 2 (commit 2645bcd) shipped the ESP screen and its
state providers. The screen is still reachable in the current build. The
mermaid spec is the source of truth — the code has drifted behind by one
business decision.
Fix:
- Delete the ESP screen widget and its route registration.
- Remove
espSelectionProvider/espSkippedProviderand any nav step that routes through ESP. - Wire
VerifChoiceSheet → USPGate → (USP screen | skip → next)directly. - Drop the "ESP is decorative only" memory (it's now superseded by removal).
- Keep
screens/onboarding.jsx::S5ESPin the Figma handoff folder — it's history, not active design.