Subscription Admin Detail
- Learner Name
- Bounmy Keodara
- bounmy.keodara@example.com
- Product
- Basic Digital Skills · Lifetime
- Start Date
- 2026-02-10
- Expiry Date
- — (Lifetime)
- Status
- Active
| Reference No. | Amount (LAK) | Payment Date | Payment Channel | Result |
|---|---|---|---|---|
| TXN-2026-0210-4821 | ₭ 450,000 | 2026-02-10 14:32 | BCEL One | success |
Screen Flow (from uc-bil-06-revoke-subscription.flow.puml):
📝 Spec notes — UC-BIL.06 / SCR-BIL.11 + SCR-BIL.12 (fields, actions, requirements)
- Screen: SCR-BIL.11 — Subscription Admin Detail
- Use case: UC-BIL.06 — Revoke Subscription
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.
learner_name"Learner Name" — computed (User.firstname + " " + User.lastname) · always · read-onlylearner_email"Email" — text · data_ref: User.email · always · read-onlyproduct_name"Product" — text · data_ref: Product.name · always · read-onlysubscription_started_at"Start Date" — date · data_ref: Subscription.started_at · always · read-onlysubscription_expiry_date"Expiry Date" — date · data_ref: Subscription.expiry_date · always · read-onlysubscription_status"Status" — enum (new/pending/active/cancelled/revoked) · data_ref: Subscription.status · always · read-onlytx_ref_code"Reference No." — text · data_ref: Transaction.ref_code · always · read-onlytx_amount"Amount" — number · data_ref: Transaction.amount · always · read-onlytx_paid_at"Payment Date" — datetime · data_ref: Transaction.callback_received_at · always · read-onlytx_gateway"Payment Channel" — text · data_ref: Transaction.gateway · always · read-onlylast_changed_at"Status Changed At" — datetime · data_ref: Subscription.status_changed_at · visible when status_changed_by != null · read-onlylast_changed_by"Changed By" — text · data_ref: Subscription.status_changed_by · visible when status_changed_by != null · read-onlylast_change_comment"Comment" — text · data_ref: Subscription.status_change_comment · visible when status_changed_by != null · read-onlyrevoked_at"Revoked At" — datetime · data_ref: Subscription.revoked_at · visible when subscription_status == revoked · read-onlyrevoked_by"Revoked By" — text · data_ref: Subscription.revoked_by · visible when subscription_status == revoked · read-onlyrevoke_reason_display"Reason Category" — computed display label from Subscription.revoke_reason_category · visible when revoked · read-onlyrevoke_comment_display"Details" — text · data_ref: Subscription.revoke_comment · visible when revoked · read-onlyrevoke_reference_display"Reference" — text · data_ref: Subscription.revoke_reference · visible when revoked && revoke_reference != null · read-only
edit_status"Edit Status" — always enabled · opens SCR-BIL.12 dialog · triggers UC-BIL.06-M-6back"Back" — always enabled · navigates to SCR-BIL.07
- RBAC — Sale Admin (ACT-12) or Super Administrator (ACT-04); reject 403 + log security event. [refs: NFR-10]
- "Edit Status" button always enabled regardless of current status — including revoked; each change requires confirmation in SCR-BIL.12. [refs: —]
- Payment history shows all Transactions linked to this subscription, newest first; if none: "No transactions recorded". [refs: —]
- "Status Change History" section visible only when Subscription.status_changed_by != null. [refs: —]
- "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]
- 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]
- Responsive — desktop primary; mobile stacks vertically; "Edit Status" button always accessible. [refs: NFR-08]
- Security — TLS 1.2+; subscription/learner PII must not be browser-cached. [refs: NFR-03]
↳ Embedded dialog: SCR-BIL.12 — Edit Status Dialog
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.
learner_info"Learner" — computed (User.email) · always · read-onlyproduct_name"Product" — text · data_ref: Product.name · always · read-onlystatus_current"Current Status" — enum · data_ref: Subscription.status · always · read-onlystatus_new"New Status" — enum (new/pending/active/cancelled/revoke) · data_ref: Subscription.status · visible in form state · required · pre-select current statuscomment"Additional Details" — textarea · data_ref: Subscription.status_change_comment · visible in form state · required · min 1, max 1000revoke_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 revokerevoke_comment"Additional Details" — textarea · data_ref: Subscription.revoke_comment · visible in form state when status_new == revoke · required when revoke · min 5, max 1000revoke_reference"Reference" — text · data_ref: Subscription.revoke_reference · visible in form state when status_new == revoke · optional · max 255confirm_status_change"Status (before → after)" — computed · visible in confirmation state · read-onlyconfirm_comment"Additional Details" — computed · visible in confirmation state when status_new != revoke · read-onlyconfirm_reason_category"Reason Category" — computed · visible in confirmation state when status_new == revoke · read-onlyconfirm_revoke_comment"Additional Details" — computed · visible in confirmation state when status_new == revoke · read-onlyconfirm_reference"Reference" — computed · visible in confirmation state when revoke && reference not empty · read-only
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 viewcancel_form"Cancel" — always enabled · dismisses dialogconfirm"Confirm" — always enabled in confirmation state · triggers UC-BIL.06-M-12 → save + audit trailcancel_confirmation"Cancel" — always enabled in confirmation state · triggers UC-BIL.06-A-12A-1 → returns to form state (resume at step 7)
- status_new pre-selected with current Subscription.status when dialog opens. [refs: SS-BIL.05]
- 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]
- "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: —]
- 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]
- RBAC: Sale Admin (ACT-12) only; reject 403 and log security event if role is incorrect. [refs: NFR-10]