Hint System 08 · object-level hints · delivery policy · trilingual · source from B only

Planning · v0.2
Hint content sourced from B-owned data files · ไม่พิมพ์ใน A code โดยตรง. ทุก UI object สามารถ surface hint ได้ · 3 delivery policies · trilingual parity · sensitive-surface requires domain expert review.

Context

Handoff hand-hint-system: A implement object-level hint registry + delivery policy + translation pipeline · ALL content comes from B-owned JSON files. ใช้ใน Dashboard purpose tooltips · Wizard step subtitles · Enterprise Upload panel hints · Cases portal hints · Knowledge lookup.

docs/kb/data/page_purpose.json30 pages · name/what/when in TH/EN/ZH
docs/kb/data/audience_entrypoints.jsonaudience personas + entrypoint labels
docs/kb/data/lexicon.json80 entries · trilingual definitions · glossary popover
docs/kb/data/premium_wizard.jsonsteps[*].honest_note · step purpose
docs/kb/data/hybrid_intake_workspace.json8 panel purposes
docs/kb/data/dashboard_contract.jsondashboards[*].purpose · honest_note

A-owned Runtime Boundary

B owns (read-only for A)

  • All hint content (name_th/en/zh · what · when · purpose · honest_note)
  • Trilingual parity enforcement
  • Sensitive-surface markers on specific hints
  • Lexicon term definitions

A owns (this runtime)

  • Hint registry (maps object_id → B content path)
  • Delivery policy engine (first-time / on-demand / always)
  • User-seen state (per-user per-hint dismiss log)
  • Trigger detection (hover · click · focus · viewport)
  • Render component (tooltip / popover / banner)
  • Fallback chain (zh missing → en → th)

Scope

ER Diagram

Hint System · registry + state + content cache
hints (A-owned registry) ● id (PK) object_id (unique) object_type (page/step/panel/field) content_source (JSON path) delivery_mode render_style (tip/pop/banner) max_shows_before_dismiss sensitive_flag lexicon_refs[] active last_reviewed_at user_hint_state ● user_id ● hint_id shown_count dismissed last_shown_at clicked_link locale_at_show session_ref content_cache (in-memory) page_purpose.pages.* lexicon.terms.* premium_wizard.steps.* dashboard_contract.dashboards.* hybrid_intake.panels.* audience_entrypoints.* refresh: on deploy · reload signal hint_events (analytics) shown · dismissed · clicked · lang 1..n content_ref writes

Field Mapping — Hint Registry

Source (B) A Registry Target Render Style Delivery Binding Notes
page_purpose.pages.{id}.name_{lang}Page header title labelBanneralways-availablemapped-not-boundi18n dict · fallback chain
page_purpose.pages.{id}.what_{lang}Page subtitle / introBanneralways-availablemapped-not-boundVisible without interaction
page_purpose.pages.{id}.when_{lang}"When to use" helperPopoveron-demandmapped-not-boundShown on ? icon click
premium_wizard.steps.{n}.purpose_{lang}Step subtitle in wizardTooltip + inlinealways-availableplaceholderWizard runtime consumes
premium_wizard.steps.{n}.honest_note_{lang}Step footer captionBanneralways-availableplaceholderVerbatim render · no edits
dashboard_contract.dashboards.{id}.purpose_{lang}Dashboard header tooltipTooltipon-demandmapped-not-boundOn info-icon hover
dashboard_contract.dashboards.{id}.honest_noteChart footer captionBanneralways-availablemapped-not-boundrequires_human_review=true → yellow banner
hybrid_intake_workspace.workspace_panels.{id}Panel entry hintTooltipfirst-timeplaceholder8 panels
lexicon.terms.{id}.short_def_{lang}Glossary popover on term hoverPopoveron-demandmapped-not-boundAuto-detect terms in text
audience_entrypoints.personas.*Audience label on nav cardBadge + tooltipalways-availablemapped-not-boundProduct + governance personas

API Sketch

GET/api/hints/lookup?object_id=dashboard.gmv-daily&lang=th
Resolve hint for an object · returns content + style + delivery
// response { "object_id": "dashboard.gmv-daily", "content": { "title": "GMV รายวัน", "body": "ยอดขายรวมต่อวัน · เป้า ฿1.5M · warn <฿1.2M", "footer": "source: kpi_targets Layer H" }, "render_style": "tooltip", "delivery_mode": "on-demand", "sensitive_flag": false, "fallback_used": false }
POST/api/hints/event
Log hint interaction (shown · dismissed · clicked)
// request { "hint_id": "h-dashboard-gmv", "event": "dismissed", "locale": "th", "session_ref": "SESS-..." }
POST/api/admin/hints/reload
Trigger content cache reload from B JSON · admin only

Sequence Flow first-time hint delivery + dismiss

First-time hint on wizard step · lang=th
Wizard UI Hint Service content cache user_hint_state hint_events 1 lookup(step-3, th) 2 read content (B cache) 3 has user seen? (user_id, hint_id) shown_count=0 · not dismissed 4 content + render_style=banner · first_time=true 5 increment shown_count event(shown) 6 user dismisses · mark dismissed=true + event

Dependencies

Upstream

  • Auth (user_id for per-user state)
  • Postgres
  • B data files readable at deploy
  • Content loader (startup bootstrap)

Downstream

  • Dashboard Runtime (tooltips + honest-note banners)
  • Wizard Runtime (step subtitles)
  • Tenant Runtime (panel entry hints)
  • All UIs with glossary auto-detect

Approval Gates

Risks

A-side developer types hint content inline (bypasses B)
High
CI lint rule: forbid string literals matching "hint" pattern · all hint components require registry ref
Trilingual fallback displays key instead of text
Med
Fallback chain zh→en→th · test in all locales · CI asserts at least one present per hint
B content hot-reload drops active hints
Low
Hot-reload is additive · deletions require soft-remove flag · observable via hint_events
Hint spam (every object shows hint first-time = overwhelming)
Med
Throttle first-time hints to 1-per-minute · user-level max 3 per session

Definition of Done

  1. Registry + loader + cache operational
  2. 3 render components (tooltip/popover/banner) deployed
  3. 3 delivery modes (first-time/on-demand/always) tested
  4. Trilingual fallback verified in all 3 langs
  5. Per-user dismiss state persists across sessions
  6. CI lint prevents inline hint content
  7. Analytics events emitted and queryable
  8. Sensitive-hint path requires domain sign-off

Deferred

Hint System Planning · v0.2 · Session A · A-owned ← Planning hub