Tốt! Giờ tôi đã rõ hoàn toàn. Database có reports_limit = 1 cho Free, nhưng dashboard hiển thị 0/3 vì code dùng fallback ?? 3. Và cần thêm cột billing_period (lifetime vs monthly) vào DB. Hãy đọc code dashboard và pricing để sửa đồng thời:
Giờ tôi đã thấy rõ toàn bộ. Cần đọc pricing page và kiểm tra user_subscriptions để hiểu cách reports_used được tính:
Bây giờ tôi đã nắm đầy đủ. Có 2 vấn đề cần sửa:
1. Dashboard - dòng const reportsLimit = (subscription?.subscription_plans as any)?.reports_limit ?? 3 — fallback là 3 nhưng Free Trial trong DB là 1. Khi user chưa có subscription row, nó dùng 3. Cần sửa fallback thành 1 VÀ tiêu đề "Lượt phân tích tháng này" phải thay đổi cho Free (vì là lifetime, không phải monthly).
2. Pricing page - dòng {plan.reports_limit} lượt / tháng cho gói Free — phải đổi thành 1 lượt / đăng ký.
3. Database - cần thêm cột billing_type hoặc đơn giản hơn là update features của Free plan để phản ánh "1 lần/đăng ký".
Giờ tôi sẽ sửa đồng thời cả 3 chỗ:
Tốt. Giờ sửa dashboard (fallback ?? 3 → ?? 1, và nhãn "tháng này" → "của bạn" cho Free):
Bây giờ sửa nhãn banner quota để hiển thị đúng "Lượt phân tích" thay vì "tháng này" cho gói Free:
Cuối cùng sửa pricing page — thay lượt / tháng thành lượt / đăng ký cho gói Free:
Đã sửa xong 3 chỗ cùng lúc:
features của Free Trial đã cập nhật từ "1 lượt AI/tháng" → "1 lượt AI / đăng ký"?? 3 → ?? 1 để khớp với giá trị DB; nhãn banner đổi thành "Lượt phân tích của bạn" (thay vì "tháng này") khi user ở gói Free1 lượt / tháng → 1 lượt / đăng kýẢnh cho thấy trang báo cáo đang ở trạng thái "XEM TRƯỚC" (preview/locked) với nút "Mở khóa Báo cáo" — mặc dù user gói Free lẽ ra phải được xem đầy đủ sau khi đã phân tích. Tôi sẽ tìm logic kiểm tra quyền xem báo cáo.
Tôi thấy rõ vấn đề ngay rồi. Dòng 71-73 của preview/page.tsx:
if (report.report_unlocked || report.payment_status === 'paid') {
redirect(`/audit/${id}`)
}Logic chỉ unlock nếu report_unlocked = true HOẶC payment_status = 'paid'. Gói Free Trial chưa được tính. Bây giờ tôi cần kiểm tra nơi trang audit [id]/page.tsx redirect về preview, và cách fix:
Tôi đã thấy đủ vấn đề rồi. Logic unlock hiện tại chỉ check report_unlocked = true hoặc payment_status = 'paid'. Gói Free Trial không bao giờ được set 2 field này nên luôn redirect về preview.
Cần sửa để: nếu user là chủ báo cáo VÀ thuộc gói Free (hoặc bất kỳ gói paid subscription), báo cáo tự động được coi là unlocked. Hãy xem API audit route để hiểu data trả về:
Bây giờ tôi đã hiểu toàn bộ. API GET /api/audit/[id] chỉ trả về raw report data, không trả về thông tin subscription. Client-side check trong [id]/page.tsx (dòng 180-188) chỉ dựa vào report_unlocked và payment_status.
Giải pháp đúng nhất: Khi analyze xong thành công (/api/analyze route), set report_unlocked = true ngay cho user có subscription hợp lệ (kể cả Free Trial). Kiểm tra analyze route để xem nó set gì sau khi phân tích xong:
Rõ ràng rồi: /api/analyze không bao giờ set report_unlocked = true. Vì thế sau khi phân tích xong, báo cáo vẫn bị redirect về preview.
Giải pháp: Trong API /api/analyze, sau khi lưu kết quả phân tích, set report_unlocked = true ngay cho user có subscription hợp lệ (bao gồm Free Trial). Hãy đọc phần cuối analyze route để tìm chỗ update report:
Tìm thấy rồi! Dòng 916 là chỗ update report cuối cùng, và dòng 957 increment reports_used. Hãy đọc đoạn đó:
Tôi đã thấy chính xác vấn đề. Dòng 916-947: update report không có report_unlocked: true. Sau khi phân tích xong, report_unlocked vẫn là false nên client redirect về /preview. Fix đơn giản: thêm report_unlocked: true vào update block này — vì nếu phân tích chạy thành công, user đã dùng 1 lượt, báo cáo phải được mở:
Bây giờ cần xử lý báo cáo đã phân tích trước đó (như trong ảnh user đang thấy) — chúng đã status = 'verified'/'ai_completed' nhưng report_unlocked = false. Cần update DB để unlock tất cả báo cáo đã completed:
You can send messages while the preview loads