Sales and Products › Manage Subscription › Subscription Detail
🎬 Simulate:

Subscription Admin Detail

Subscription Overview
Learner Name
Bounmy Keodara
Email
bounmy.keodara@example.com
Product
Basic Digital Skills · Lifetime
Start Date
2026-02-10
Expiry Date
— (Lifetime)
Status
Active
Payment History
Reference No. Amount (LAK) Payment Date Payment Channel Result
TXN-2026-0210-4821 ₭ 450,000 2026-02-10 14:32 BCEL One success
Back

Screen Flow (from uc-bil-06-revoke-subscription.flow.puml):

→ back to list → Subscription Admin (SCR-BIL.07) → exit → [*]
📝 Spec notes — UC-BIL.06 / SCR-BIL.11 + SCR-BIL.12 (fields, actions, requirements)
Identity
  • Screen: SCR-BIL.11 — Subscription Admin Detail
  • Use case: UC-BIL.06 — Revoke Subscription
Brief description

Admin-facing detail page for a single subscription — displays learner name/email, product, subscription period, current status, and payment history. The "Edit Status" button opens SCR-BIL.12 (Edit Status Dialog, embedded below as modal). When status_changed_by is set, "Status Change History" section appears. When status == revoked, "Revoke Metadata" section appears.

Fields — SCR-BIL.11
  • learner_name "Learner Name" — computed (User.firstname + " " + User.lastname) · always · read-only
  • learner_email "Email" — text · data_ref: User.email · always · read-only
  • product_name "Product" — text · data_ref: Product.name · always · read-only
  • subscription_started_at "Start Date" — date · data_ref: Subscription.started_at · always · read-only
  • subscription_expiry_date "Expiry Date" — date · data_ref: Subscription.expiry_date · always · read-only
  • subscription_status "Status" — enum (new/pending/active/cancelled/revoked) · data_ref: Subscription.status · always · read-only
  • tx_ref_code "Reference No." — text · data_ref: Transaction.ref_code · always · read-only
  • tx_amount "Amount" — number · data_ref: Transaction.amount · always · read-only
  • tx_paid_at "Payment Date" — datetime · data_ref: Transaction.callback_received_at · always · read-only
  • tx_gateway "Payment Channel" — text · data_ref: Transaction.gateway · always · read-only
  • last_changed_at "Status Changed At" — datetime · data_ref: Subscription.status_changed_at · visible when status_changed_by != null · read-only
  • last_changed_by "Changed By" — text · data_ref: Subscription.status_changed_by · visible when status_changed_by != null · read-only
  • last_change_comment "Comment" — text · data_ref: Subscription.status_change_comment · visible when status_changed_by != null · read-only
  • revoked_at "Revoked At" — datetime · data_ref: Subscription.revoked_at · visible when subscription_status == revoked · read-only
  • revoked_by "Revoked By" — text · data_ref: Subscription.revoked_by · visible when subscription_status == revoked · read-only
  • revoke_reason_display "Reason Category" — computed display label from Subscription.revoke_reason_category · visible when revoked · read-only
  • revoke_comment_display "Details" — text · data_ref: Subscription.revoke_comment · visible when revoked · read-only
  • revoke_reference_display "Reference" — text · data_ref: Subscription.revoke_reference · visible when revoked && revoke_reference != null · read-only
Actions — SCR-BIL.11
  • edit_status "Edit Status" — always enabled · opens SCR-BIL.12 dialog · triggers UC-BIL.06-M-6
  • back "Back" — always enabled · navigates to SCR-BIL.07
Additional requirements — SCR-BIL.11
  1. RBAC — Sale Admin (ACT-12) or Super Administrator (ACT-04); reject 403 + log security event. [refs: NFR-10]
  2. "Edit Status" button always enabled regardless of current status — including revoked; each change requires confirmation in SCR-BIL.12. [refs: —]
  3. Payment history shows all Transactions linked to this subscription, newest first; if none: "No transactions recorded". [refs: —]
  4. "Status Change History" section visible only when Subscription.status_changed_by != null. [refs: —]
  5. "Revoke Metadata" section visible only when subscription_status == revoked; shows full record (date, actor, reason, details, reference if present); permanent audit record — cannot be deleted or modified via UI. [refs: SS-BIL.03]
  6. WCAG 2.1 AA — read-only fields use <dl>/<dt>/<dd>; conditional sections use aria-live="polite"; "Edit Status" has clear focus indicator. [refs: NFR-09]
  7. Responsive — desktop primary; mobile stacks vertically; "Edit Status" button always accessible. [refs: NFR-08]
  8. Security — TLS 1.2+; subscription/learner PII must not be browser-cached. [refs: NFR-03]
↳ Embedded dialog: SCR-BIL.12 — Edit Status Dialog
Brief description

Dialog overlaying SCR-BIL.11 with two internal states: (1) Form state — subscription context (read-only header), New Status dropdown (5 values: New/Pending/Active/Cancelled/Revoke per SS-BIL.05) pre-selected with current status, required Comment; when Revoke selected the form dynamically expands showing Reason Category (required), Additional Details (required min 5 chars), Reference (optional); (2) Confirmation state — read-only summary before save — Confirm to save with audit trail, Cancel to return to form.

Fields
  • learner_info "Learner" — computed (User.email) · always · read-only
  • product_name "Product" — text · data_ref: Product.name · always · read-only
  • status_current "Current Status" — enum · data_ref: Subscription.status · always · read-only
  • status_new "New Status" — enum (new/pending/active/cancelled/revoke) · data_ref: Subscription.status · visible in form state · required · pre-select current status
  • comment "Additional Details" — textarea · data_ref: Subscription.status_change_comment · visible in form state · required · min 1, max 1000
  • revoke_reason_category "Reason Category" — enum (refund/policy_violation/termination/other) · data_ref: Subscription.revoke_reason_category · visible in form state when status_new == revoke · required when revoke
  • revoke_comment "Additional Details" — textarea · data_ref: Subscription.revoke_comment · visible in form state when status_new == revoke · required when revoke · min 5, max 1000
  • revoke_reference "Reference" — text · data_ref: Subscription.revoke_reference · visible in form state when status_new == revoke · optional · max 255
  • confirm_status_change "Status (before → after)" — computed · visible in confirmation state · read-only
  • confirm_comment "Additional Details" — computed · visible in confirmation state when status_new != revoke · read-only
  • confirm_reason_category "Reason Category" — computed · visible in confirmation state when status_new == revoke · read-only
  • confirm_revoke_comment "Additional Details" — computed · visible in confirmation state when status_new == revoke · read-only
  • confirm_reference "Reference" — computed · visible in confirmation state when revoke && reference not empty · read-only
Actions
  • proceed "Save" — enabled when status_new selected and additional_details ≥ 1 char (+ revoke_reason_category + revoke_comment ≥ 5 when revoke) · triggers UC-BIL.06-M-10 → system displays confirmation view
  • cancel_form "Cancel" — always enabled · dismisses dialog
  • confirm "Confirm" — always enabled in confirmation state · triggers UC-BIL.06-M-12 → save + audit trail
  • cancel_confirmation "Cancel" — always enabled in confirmation state · triggers UC-BIL.06-A-12A-1 → returns to form state (resume at step 7)
Additional requirements
  1. status_new pre-selected with current Subscription.status when dialog opens. [refs: SS-BIL.05]
  2. When status_new == revoke: Revoke details region dynamically expands (no reload); collapses immediately when changed to another value. [refs: SS-BIL.03, SS-BIL.05]
  3. "Save" disabled until required fields valid: comment ≥ 1 char when not revoke; when revoke: revoke_reason_category must be selected + revoke_comment ≥ 5 chars. [refs: —]
  4. WCAG 2.1 AA: dialog uses focus trap (Tab cycles inside); focus moves to first interactive element on open; Escape closes dialog in form state only (NOT in confirmation state); focus returns to "Edit Status" button on close. [refs: NFR-09]
  5. RBAC: Sale Admin (ACT-12) only; reject 403 and log security event if role is incorrect. [refs: NFR-10]