Files
wordpress-theme-aksrt/.specs/plans/frontend-modal-orders-vip.md
T
2026-08-04 20:40:59 +08:00

8.8 KiB
Raw Blame History

Plan: Frontend Modal Orders and VIP

Architectural Decisions

  • Dependency: This plan starts only after frontend-modal-runtime Phase 2 supplies the canonical shell, loader, cache/state, cancellation, and telemetry contracts.
  • Order view model: UserOrders and OrderCenterRest return a minimal list/detail view model with server-derived allowed_actions, status version, updated time, and invalidation tags. The front end never derives payment/cancel/after-sale eligibility from local status.
  • Order query shape: Combine list/stat work where possible, batch resource decoration, and add the missing user_id/status/created_at index through AKSRT_DB_Migrator with a schema version bump. No new order table or duplicate fact store.
  • Reconciliation boundary: Gateway::reconcile_order() remains the authority for pending external orders but runs after the detail shell is visible and only when needed. A normal completed/non-external detail must not wait for remote provider HTTP.
  • VIP JSON path: Replace server-generated full HTML from VipServiceModal with a minimal JSON view model. pay-vip.js and the VIP shop in credits.js share one purchase coordinator; catalog, member state, order object, and payment attempt are reused within a request.
  • Payment safety: Payment gateways and PaymentOrchestrator stay server-side. Client polling is bounded, backoff-aware, visibility-aware, cancellable, and terminated by a terminal order state. Core price, eligibility, ledger, callback, and VIP fulfillment rules are unchanged.
  • API configuration: All order/VIP requests use the globally injected API root and REST nonce. Remove order-center.js hard-coded REST construction and do not add compatibility route aliases.
  • Release: Order and VIP rollout switches are independent. Old paths may remain inactive while a domain is not released, but each domain has one canonical implementation after its switch is permanently enabled.

Phase 1 — Order details appear before remote state reconciliation

User stories: US6, US7, US11, US13.

What to build

Optimize src/Payment/UserOrders.php and src/Payment/OrderRepositoryCore.php so the order list does not perform a fixed list plus four COUNT queries and resource rows do not cause post/meta N+1 work. Add the composite order index in src/Core/DBMigratorPart2.php and bump the schema version through the existing migrator. Shape src/Payment/OrderCenterRest.php responses around minimal list/detail view models and preserve owner checks. Update src/Payment/Gateway.php so pending external reconciliation is deferred or represented as a refresh state after the shell is visible. Replace order-center.js hard-coded siteUrl/wp-json construction with injected apiUrl/restUrl, then move detail, pay, cancel, refresh, and invalidation through AksrtModalRuntime.

Done when

  • SAVEQUERIES scenario order-list-query-count verifies that the normal first page no longer issues list + four independent COUNT queries and that resource-order decoration has no per-row post/meta N+1; empty/overflow pages remain correct.
  • DBMigratorPart2 defines the user_id/status/created_at query index and the active schema version is bumped; after migration, SHOW INDEX or the WordPress DB harness verifies the index.
  • Browser scenario order-detail-shell verifies summary skeleton first, ordinary detail does not wait for provider HTTP, pending reconciliation reports refresh state, and detail/status/list update after pay/cancel/after-sale responses.
  • order-center.js reads the injected API root, and php -l src/Payment/UserOrders.php src/Payment/OrderRepositoryCore.php src/Payment/OrderCenterRest.php src/Payment/Gateway.php src/Core/DBMigratorPart2.php plus node --check assets/js/order-center.js pass.
  • API/browser cases cover another-tab status changes, unauthorized order numbers, duplicate action clicks, timeout/retry, pagination, and no cross-user cache reuse.

Phase 2 — VIP purchase reaches payment result through one coordinator

User stories: US4, US5, US11, US13.

What to build

Change src/Content/VipServiceRest.php and src/Content/VipServiceModal.php from full HTML modal responses to a minimal JSON view model that contains the server-calculated catalog, member state, payment methods, allowed actions, and version metadata. Refactor src/Content/VipServicePurchase.php and src/Payment/PaymentOrchestrator.php to reuse the catalog/member/order context instead of reading the same data after create and again during pay. Consolidate the remote modal path in assets/js/pay-vip.js and the embedded shop path in assets/js/credits.js into one purchase/poll coordinator; keep the existing credits-vip.php and vip-tab.php entry points but route their actions through it. Replace the fixed 40 × 3-second loop with bounded backoff, visibility handling, abort, and terminal-state invalidation.

Done when

  • SAVEQUERIES scenario vip-purchase-query-count shows no duplicate member-level/catalog/order reads for modal load and purchase create/pay; VipServiceRest reuses the catalog user level instead of recomputing it.
  • pay-vip.js and credits.js share one VIP purchase/poll coordinator; git grep -n "setInterval\|pay/content/order\|pay-vip/modal" assets/js/pay-vip.js assets/js/credits.js shows no second fixed 40 × 3-second loop or old full-HTML injection path.
  • Browser scenario vip-purchase-flow covers not-enrolled, active, expired, renewal/upgrade, package/price, points exchange, gateway redirect, cancel, failure, async success, duplicate click, and return to order detail.
  • Payment response inspection confirms no gateway secret reaches the browser; existing gateway, order callback, VIP fulfillment, core price, and entitlement rules pass regression scenarios.
  • php -l src/Content/VipServiceRest.php src/Content/VipServiceModal.php src/Content/VipServicePurchase.php src/Payment/PaymentOrchestrator.php and node --check assets/js/pay-vip.js assets/js/credits.js pass.

Phase 3 — Orders and VIP are independently gray-releasable

User stories: US1–US7, US11–US14.

What to build

Connect order and VIP coordinators to the independent rollout switches, invalidate user-center order/VIP summaries after successful writes, and verify native order/after-sale operations remain the operational backend. Release orders first, measure shell/ready/error/status mismatch, then release VIP payment only after the order slice is stable. Remove each domain's old modal calls once its switch is permanently enabled.

Done when

  • Order and VIP rollout values independently select the new loaders; toggling one does not change the other or create a second order/member fact store.
  • php tools/audit-admin-contracts.php exits 0, all changed PHP files pass php -l, and node --check assets/js/order-center.js assets/js/pay-vip.js assets/js/credits.js passes.
  • Desktop/mobile scenarios verify shell/ready budgets, cache-hit and cold-load p75/p95, payment/order state synchronization, permission errors, retry behavior, focus, and no horizontal overflow.
  • Gray-release evidence shows orders reaching the agreed 100ms shell, 200ms cache-hit, p75 ≤800ms, and p95 ≤1.5s initial budgets before VIP is enabled; rollback is demonstrated by disabling only the affected domain switch.

Out of Scope

  • 修改会员价格、会员权益、支付网关规则、订单账务、退款核算、认证资格/审核政策或徽章授予条件;这些规则只允许被新的流程正确调用和展示。
  • 新增支付渠道、替换支付供应商、在浏览器保存支付凭证,或改变支付回调/异步结算机制。
  • 新增公开认证资料库、向其他用户暴露认证文档、跨用户查看订单或徽章数据。
  • 把订单、售后、认证审核或徽章运营工作台迁移进配置型 SPA;日常运营仍属于原生 WordPress 后台。
  • 全站页面导航、用户中心信息架构、品牌设计系统或所有非弹窗页面的全面重做;本期只统一弹窗运行时和四类流程所需的轻量体验。
  • 强制页面加载时预取所有弹窗数据、长期持久化敏感弹窗数据、建立订单/认证/徽章的第二套事实存储或长期保留旧新双路实现。
  • 以新增兼容别名、旧 option 双读、静默降级或数据迁移层解决旧实现问题;流程切换后以新的规范化链路为唯一实现。
  • 建立独立的数据仓库、复杂转化漏斗或第三方用户行为追踪系统;本期观测只服务于弹窗性能、错误和业务状态闭环。

Open Questions

  • 订单/支付环境是否提供现有 Server-Timing 或网关状态监控收集端;默认使用响应头和现有部署观测,不新增主题内指标表。
  • 复合订单索引在生产大表上的部署窗口需要由发布流程确认;迁移必须遵循现有 AKSRT_DB_Migrator 原子升级约束。