J-15 — Configure Dynamic Pricing AI Suggestions
One-liner: GM enables AI suggestions for dynamic pricing, configures guardrails, and reviews/accepts daily suggestions.
1. Purpose
GM enables AI-driven price suggestions, configures guardrails (per-room-type min/max, day-of-week multipliers, blackout periods), and reviews daily suggestions. AI never auto-applies; GM accepts / modifies / rejects per the canonical HITL pattern. Outcome: tenant has a tunable, transparent, auditable AI pricing assist that GM trusts.
2. Persona Context
- Persona: GM / Revenue manager.
- Surface: Electron Desktop.
- Primary BFF:
bff-backoffice-service.
- Backing services:
pricing-service, ai-orchestrator-service, audit-service.
- Preconditions: Tenant has historical booking data (recommended >= 90 days; warn if less).
- Trigger: GM opens Pricing -> AI Suggestions screen.
3. Entry Points
| # | Entry | Notes |
|---|
| 1 | Pricing tab in Manager view | Default |
| 2 | Daily AI digest notification | Pre-opens suggestions |
4. Screen-by-Screen Flow
4.1 AiPricingGuardrailsScreen
- Layout: Per-room-type editor: min nightly, max nightly, day-of-week multipliers, blackout periods, override rules (event date), refresh cadence.
- Components:
Form, MoneyRangeInput, DowMultiplierMatrix, DateRangePicker.
- Offline: Editable; queued.
- AI: None on guardrails themselves.
- Errors: Min > max disallowed; multiplier out-of-range warning.
- Loading: Sub-200 ms.
- A11y: Field labels; matrix accessible.
- RTL: Mirror; numerals localised.
- Perf: <= 200 ms.
- Telemetry:
frontend.pricing.guardrails_saved.
4.2 AiSuggestionsListScreen
- Layout: Per-room-type-per-day suggestion cards: current price, suggested price, delta, confidence, rationale, model + version + prompt + trace; canonical HITL actions.
- Components:
AiSuggestionCard, Pill (confidence), Button (Accept / Modify / Reject / Why this).
- Offline: Reads from SQLite snapshot of last suggestions; banner "Today's suggestions unavailable - showing yesterday".
- AI: Suggestions generated by
ai-orchestrator-service; provenance per spec.
- Errors: Suggestion failed to generate -> "Suggestions unavailable today" banner.
- Loading: Stream suggestions in.
- A11y: Each card is a tab stop; Accept/Modify/Reject have explicit names.
- RTL: Mirror; price values stay LTR with
BidiText.
- Perf: Cards mount <= 500 ms; "Why this" panel <= 1 s.
- Telemetry:
frontend.pricing.suggestion_action { action, roomTypeId, date }.
4.3 WhyThisPanel
- Layout: Drilldown: model + version + prompt id + trace id, contributing data points (occupancy, day-of-week, recent bookings, competitor signal if any), confidence breakdown.
- Components:
ProvenanceCard, DataPointList.
- Offline: Cached per suggestion.
- A11y: Structured for screen readers.
- RTL: Mirror.
- Perf: <= 1 s.
- Telemetry:
frontend.pricing.why_this_opened { suggestionId }.
5. State Machine
6. Data Requirements
6.1 Server state
PATCH /api/v1/pricing/ai-guardrails (idempotent)
GET /api/v1/pricing/ai-suggestions?date=... (cached locally)
POST /api/v1/pricing/ai-suggestions/:id/decision (idempotent; action: accept|modify|reject + optional override)
6.2 Local persistence
- SQLite
ai_suggestions_local, outbox.
6.3 Idempotency
- All mutations carry
X-Idempotency-Key.
7. AI Behavior
| Surface | Purpose | Model | Edge / Cloud | HITL | Provenance | Fallback |
|---|
AiSuggestionsListScreen | Suggest daily prices | pricing-suggest-v1 | Cloud (P1) / edge for forecast smoothing (P2) | Canonical card | Pill: model@version, prompt, trace | "Suggestions unavailable" banner |
8. Offline Behavior
- Reads last suggestions from SQLite.
- Today's suggestions unavailable -> banner.
- Decisions queued.
9. Error States
| Error | Trigger | UX shown | Recovery | Telemetry |
|---|
MIN_GT_MAX | Bad guardrail | Inline error | User fixes | frontend.pricing.invalid_guardrail |
AI_SUGGESTIONS_UNAVAILABLE | AI service degraded | Banner: "Suggestions unavailable today" | Retry tomorrow | error.surfaced { code } |
LOW_DATA_WARNING | < 90 days history | Banner: "Suggestions improve with more data" | Continue or skip | frontend.pricing.low_data_warning |
10. E2E Test Gates
- Composite gate
G-MGR-1: guardrails saved -> suggestions listed -> accept / modify / reject -> audit log.
- Suggestions unavailable banner.
- "Why this" provenance verified.
| Metric | Target |
|---|
| Guardrails save | <= 500 ms p95 |
| Suggestions list mount | <= 500 ms |
| "Why this" open | <= 1 s |
| Decision submit | <= 500 ms p95 |
12. Accessibility Requirements
- HITL cards keyboard-completable.
- Provenance pill announceable.
- Confidence visualisations have alt text.
13. Telemetry
Frontend events
frontend.pricing.guardrails_saved
frontend.pricing.suggestion_action { action, roomTypeId, date }
frontend.pricing.why_this_opened { suggestionId }
Domain events emitted
melmastoon.pricing.guardrails.changed.v1
melmastoon.pricing.ai_suggestion.generated.v1 (server)
melmastoon.pricing.ai_suggestion.decided.v1 (with action + reviewer)
melmastoon.audit.recorded.v1
14. Success Criteria
- Suggestions never auto-apply; HITL enforced.
- Provenance visible on every suggestion.
- Decisions audited with reviewer + timestamp.
- Offline path proven (decisions queued).
- Suggestions unavailable produces correct UX (no silent failure).
References