Skip to content

Customer Self-Service Workspace Gap Mining

Customer Self-Service Workspace Gap Mining

Section titled “Customer Self-Service Workspace Gap Mining”

Scope: customer self-service behavior after reservation intake. Legacy pages are evidence only; the modern system must not copy PHP page branching. The target is an extensible workspace that derives customer-visible actions from reservation state, actor policy, payment/document facts, and immutable projections.

  • CustomerSelfServiceWorkspace: customer-owned reservation workspace projection for active, completed, cancelled, pre-reservation, and continued bookings.
  • CustomerActionAvailabilityPolicy: versioned policy that decides which customer actions are available at each booking stage.
  • CustomerReservationTimelineSnapshot: immutable read model for reservation state, service dates, branch, payment state, care team, reports, and document availability.
  • CustomerReportSubmissionWindow: date-scoped report eligibility, including first-day, in-progress, last-day, stopped-day, and assistant-caregiver report variants.
  • CustomerNotificationActionGrant: notification click action with audience, target, expiry, channel, and signed grant state.
  • CustomerReceiptAccessGrant: customer-safe payment receipt handoff backed by frozen payment facts, not live recalculation.
  • CustomerAppLaunchIntent: web/native launch target with platform, route, fallback URL, and trace id.
flowchart LR
  MyReservation[MyReservation.php]
  ReservationView[mypage/reservation*.php]
  FunctionButton[reservation_func_btn.php]
  ReportApi[api/Report.php]
  DocumentApi[api/ReservationDocument.php]
  NotificationView[notification.php]
  OpenApp[open_the_app.php]

  Workspace[CustomerSelfServiceWorkspace]
  ActionPolicy[CustomerActionAvailabilityPolicy]
  Timeline[CustomerReservationTimelineSnapshot]
  ReportWindow[CustomerReportSubmissionWindow]
  NotificationGrant[CustomerNotificationActionGrant]
  ReceiptGrant[CustomerReceiptAccessGrant]
  LaunchIntent[CustomerAppLaunchIntent]
  Supabase[(Supabase)]
  Storage[(Supabase Storage)]
  Kill Bill[Kill Bill]

  MyReservation --> Workspace --> Timeline
  ReservationView --> Timeline
  FunctionButton --> ActionPolicy
  ReportApi --> ReportWindow
  DocumentApi --> NotificationGrant --> Storage
  NotificationView --> NotificationGrant
  ReservationView --> ReceiptGrant --> Kill Bill
  OpenApp --> LaunchIntent
  Workspace --> Supabase

Source behavior:

  • Active and completed reservation tabs are hardcoded by status arrays, then each row receives report status, Saturday/holiday dates, continuation state, and service-balance check inside the controller. Evidence: source-refs/sanmopia_web/application/controllers/MyReservation.php:22-113.
  • Detail view recomputes report lists, manager ratings, assistant-caregiver report lists, virtual-account info, add-date lists, continuation state, payment result query data, and then chooses pre-reservation or normal detail by status flags. Evidence: source-refs/sanmopia_web/application/controllers/MyReservation.php:117-190.

Modern gap:

  • Replace page-specific data assembly with CustomerSelfServiceWorkspace and CustomerReservationTimelineSnapshot. Each projection row must carry a snapshot revision, reservation booking id, visible lifecycle stage, customer-safe payment facts, care-team assignment summary, report completion state, document grant state, and last mutation trace.
  • Status groups must be declarative policy sets. Adding a new lifecycle stage should require a policy row and projection test, not editing controller arrays.

Source behavior:

  • Action buttons are selected with nested STATUS_ID, payment, birth-info, report, continuation, service-end, and virtual-account-cancel checks. Evidence: source-refs/sanmopia_web/application/views/mypage/item/reservation_func_btn.php:1-190.
  • Available actions include reservation payment, birth information input, pre-reservation conversion, report writing, cancellation, extension, retry reservation, and info detail.

Modern gap:

  • Introduce CustomerActionAvailabilityPolicy with effective periods, actor constraints, lifecycle-stage predicates, payment predicates, report predicates, and command target metadata.
  • Every action exposed in UI must have a command id, idempotency key shape, required actor relation, disabled reason, and audit category. Frontend should render policy output only; it must not recreate branchy status logic.

Source behavior:

  • Report pages validate ownership, coerce date strings, calculate real service start/end, reject out-of-window dates, mark first/progress/last day, and add last-day requirement when the reservation was stopped. Evidence: source-refs/sanmopia_web/application/controllers/MyReservation.php:193-327.
  • Save endpoint rejects non-AJAX/non-POST calls, validates ownership and service window, blocks rating after 90 days, stores main or assistant-caregiver report, requires final-day manager rating, and may grant shopping-mall points after all reports are complete. Evidence: source-refs/sanmopia_web/application/controllers/api/Report.php:11-116.
  • Detail report list renders main and assistant-caregiver report lanes with completion/write actions and final-day required marks. Evidence: source-refs/sanmopia_web/application/views/mypage/item/reservation_detail_report_item.php:1-155.

Modern gap:

  • CustomerReportSubmissionWindow must be generated from service-date facts, stop facts, care-team role facts, and report-template version. It must support multiple caregivers per contract without hardcoded main/sub branches.
  • Report completion reward should emit a promotion-entitlement command; it must not be hidden inside report persistence.
  • Backend contract now emits a DailyReportCompletionRewardLedgerInstruction from the final reward grant. It preserves the once-per-reservation idempotency key and splits the legacy coupon row, user-coupon row, point row, and reservation reward flag into separate promotion_entitlement, point_credit, and completion_marker ledger lines. Backend Supabase persistence now stores a care-delivery-owned reward ledger header and line rows, so this flow does not overload the reservation-cancellation promotion outbox. Authenticated backend routes now expose readiness and submission: POST /customer-daily-report-reviews/readiness and POST /customer-daily-report-reviews; submission records the reward ledger instruction server-side after checking the Supabase actor against the review actor. The backend now enqueues each reward line on sanmopia_daily_report_completion_reward through Supabase PGMQ and records dispatch/completion/failure timestamps on the line rows. The worker writes idempotent service-role-only fulfillment facts to sanmopia_daily_report_completion_reward_fulfillments for coupon, point-credit, and completion-marker lines. Authenticated backend routes now also expose GET /customer-daily-report-reviews/{reservation_booking_id}/reward-status, which returns the customer-visible applied/missing reward components from those fulfillment facts. Remaining work is the external shopping-mall/coupon/point connector, frontend consumption, and public/private rating scope.

Source behavior:

  • Document page exposes numeric document types by service type and a special end-document visibility rule, then builds a raw download URL with a generated token. Evidence: source-refs/sanmopia_web/application/views/mypage/reservation_document.php:38-139.
  • Download endpoint resolves the token to a user, checks ownership, calls admin PDF generation by reservation id and numeric document type, and streams a result. Evidence: source-refs/sanmopia_web/application/controllers/api/ReservationDocument.php:9-48.
  • Receipt page reads payment context JSON inline and opens a KCP receipt URL using order id, transaction number, and amount. Evidence: source-refs/sanmopia_web/application/views/mypage/reservation_receipt.php:35-130.

Modern gap:

  • CustomerDocumentDownloadGrant and CustomerReceiptAccessGrant should use document/receipt type ids from a catalog, not numeric codes embedded in views. Grants must record owner, artifact version, snapshot revision, expiry, access attempts, revocation, and storage key.
  • Receipt access must use frozen payment facts created at payment closeout. Customer-visible receipt results must not change after later price policy, coupon, support-fund, or settlement edits.

Source behavior:

  • Notification list resolves notification type text plus optional JSON action data from either type default or per-user row. It interprets ALERT, POPUP, URL, and OPENURL, and appends a document download token for open URLs. Evidence: source-refs/sanmopia_web/application/models/Notification_model.php:16-68, source-refs/sanmopia_web/application/controllers/Notification.php:15-28, and source-refs/sanmopia_web/application/views/notification.php:36-140.
  • App launch page redirects directly to an Android intent URL. Evidence: source-refs/sanmopia_web/application/views/open_the_app.php:1-20.

Modern gap:

  • CustomerNotificationActionGrant must replace loosely typed notification JSON with typed target kinds, grant scopes, expiry, actor audience, channel, and trace id. Document grants should be attached by reference, not concatenated into URLs.
  • CustomerAppLaunchIntent must support web, Android, iOS, and fallback routes through configuration and analytics. Platform-specific constants belong in env or policy records, not inline templates.
  • Contract: define CustomerSelfServiceWorkspace, CustomerActionAvailabilityPolicy, CustomerReservationTimelineSnapshot, CustomerReportSubmissionWindow, CustomerNotificationActionGrant, CustomerReceiptAccessGrant, and CustomerAppLaunchIntent read/command schemas.
  • Backend: build Supabase-backed read projections from reservation booking, payment instruction, document artifact, report obligation, care-team, and notification facts.
  • Backend: make customer action availability a versioned policy with tests for payment, birth-info, report, cancellation, extension, pre-reservation conversion, and retry booking. Runtime progress now includes Supabase-backed sanmopia_customer_reservation_action_source_states, sanmopia_customer_reservation_state_mapping_catalogs, and sanmopia_customer_action_policy_rule_catalogs plus authenticated GET /customer-reservation-action-availabilities/{reservation_id} and GET /customer-new-reservation-eligibility, so frontend code can consume backend policy decisions instead of raw source status switches.
  • Backend: bind document and receipt access to signed Supabase Storage grants and frozen payment/document snapshots.
  • Frontend: render only policy-provided actions through Nanostores-backed self-service state; no local status switch duplication.
  • Workflow: use Restate to update workspace state after reservation, payment, report, document, notification, and app-launch events.