Bỏ qua nội dung

Lịch sử gói thuê bao của user

Feature URL
Module
subscription-package
Status
shipped
Priority
P1
Platforms
fe · be
AC progress
8 / 8
Last reviewed
2026-06-08

Mục tiêu

Cho phép user xem lại toàn bộ lịch sử các gói thuê bao mình đã mua hoặc đã hết hạn để minh bạch chi tiêu, theo dõi các mốc thời gian (bắt đầu, hết hạn) và biết gói nào có bật tự động gia hạn. Đây là một màn hình tra cứu chỉ-đọc giúp user tự đối soát quá trình sử dụng gói trả phí.

Phạm vi

Trong phạm vi (In scope):

  • API lấy lịch sử gói GET /subscriptions/me/history, yêu cầu đăng nhập (authority subscription:read).
  • Trả về Page<SubscriptionHistoryResponse> — phân trang, sắp xếp theo startedAt giảm dần (gói mới nhất lên đầu).
  • Liệt kê MỌI assignment gói của chính user: cả gói đang ACTIVE lẫn gói đã EXPIRED.
  • Mỗi dòng hiển thị thông tin snapshot tại thời điểm mua: mã/tên gói, trạng thái, mốc thời gian, giá đã trả (credits), số tháng chu kỳ + bonus, cờ tự động gia hạn.

Ngoài phạm vi (Out of scope):

  • Chi tiết quyền lợi (entitlement) của gói đang hoạt động — xem package-view (/me/entitlement).
  • Mua gói mới — xem package-purchase.
  • Đổi / nâng gói — xem package-change.
  • Gia hạn & tự động gia hạn — xem package-renewal.
  • Lịch sử gói của user khác (chỉ trả về của chính user đang đăng nhập).

User Stories

  • user, tôi muốn xem danh sách toàn bộ gói mình đã mua và đã hết hạn để biết mình đã chi bao nhiêu V-Credits cho thuê bao.
  • user, tôi muốn thấy mốc bắt đầu và hết hạn của từng gói để theo dõi thời gian sử dụng.
  • user, tôi muốn biết gói nào đang bật tự động gia hạn để chủ động quản lý chi phí.
  • user, tôi muốn lịch sử được phân trang và sắp xếp gói mới nhất lên đầu để dễ tra cứu.

Luồng chức năng

sequenceDiagram
    actor User
    participant App as FE/Mobile
    participant BE

    User->>App: Mở màn hình "Lịch sử gói"
    App->>BE: GET /subscriptions/me/history?page&size
    BE->>BE: Xác thực & kiểm tra authority subscription:read
    BE->>BE: Query toàn bộ user_packages của user (không lọc theo thời điểm)
    BE->>BE: Sắp xếp startedAt DESC, phân trang
    BE-->>App: Page<SubscriptionHistoryResponse> (ACTIVE + EXPIRED)
    App-->>User: Hiển thị danh sách lịch sử gói

Acceptance Criteria

  • AC-1: GET /subscriptions/me/history yêu cầu đăng nhập và authority subscription:read.
  • AC-2: Kết quả trả về dạng Page<SubscriptionHistoryResponse> (có phân trang).
  • AC-3: Danh sách được sắp xếp theo startedAt giảm dần (gói mới nhất lên đầu).
  • AC-4: Trả về MỌI gói của user — cả ACTIVE lẫn EXPIRED, không lọc theo thời điểm hiện tại.
  • AC-5: Chỉ trả về gói của chính user đang đăng nhập, không lộ gói của user khác.
  • AC-6: Mỗi dòng gồm: userPackageId, packageCode, packageName, status, startedAt, paidExpiredAt, expiredAt, isRenewal, bonusMonths, cycleMonths, purchasePriceCredits.
  • AC-7: purchasePriceCredits là giá snapshot tại thời điểm mua, không đổi theo catalog hiện tại.
  • AC-8: status chỉ nhận giá trị ACTIVE hoặc EXPIRED.

Quy tắc nghiệp vụ

  • Lịch sử là dữ liệu chỉ-đọc; user không thể chỉnh sửa hay xoá bản ghi từ màn hình này.
  • Mỗi dòng phản ánh snapshot tại thời điểm mua: purchasePriceCredits, cycleMonths, bonusMonths được cố định khi mua, thay đổi catalog sau đó không ảnh hưởng dòng lịch sử cũ.
  • Trạng thái lịch sử chỉ có ACTIVEEXPIRED — backend không sinh trạng thái CANCELLED.
  • Query lấy toàn bộ user_packages của user (không lọc theo cửa sổ thời gian), nên cả gói đã hết hạn từ lâu vẫn xuất hiện.
  • paidExpiredAt là mốc hết kỳ trả phí; expiredAt là mốc hết hạn thực tế (đã cộng bonusMonths nếu có).
  • isRenewal cho biết gói có bật tự động gia hạn hay không tại thời điểm ghi nhận.

Dữ liệu & Trạng thái

Entity nghiệp vụ:

  • UserPackage: bản ghi gói user đã mua, nguồn dữ liệu cho lịch sử — status, startedAt, paidExpiredAt, expiredAt, renewal, purchasePriceCredits, cycleMonths, bonusMonths.
  • SubscriptionHistoryResponse: một dòng lịch sử — userPackageId, packageCode, packageName, status, startedAt, paidExpiredAt, expiredAt, isRenewal, bonusMonths, cycleMonths, purchasePriceCredits.
  • Package: catalog gói cung cấp packageCode/packageName (định nghĩa tại package-view).

Trạng thái user-facing:

  • ACTIVE — gói đang còn hiệu lực.
  • EXPIRED — gói đã hết hạn.
  • loading — đang tải trang lịch sử.
  • empty — user chưa từng mua gói nào (lịch sử rỗng).

Liên quan