mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-30 19:36:25 +02:00
Stories were written for a subscription SaaS model, but SurfSense is a self-hosted product with BYOK + optional PAYG page packs via Stripe. Key corrections: - Story 3.5: Not "remove BYOK + token billing" → actual gap is adding HTTP-layer quota pre-check before document upload enqueue - Story 5.1: Pricing UI already exists (Free/PAYG/Enterprise) → gap is wiring "Get Started" button to existing Stripe checkout endpoint - Story 5.2: mode=payment PAYG already works → needs verification/hardening not a subscription checkout rewrite - Story 5.3: Webhook already handles checkout.session.completed correctly → no subscription events needed, gap is idempotency test + purchase history UI - Story 5.4: PageLimitService + enforcement in tasks/connectors already exists → gap is HTTP-layer pre-check, quota UI indicator, and 402 frontend handling Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.7 KiB
3.7 KiB
Story 3.5: Enforce Page Quota tại Document Upload API
Status: ready-for-dev
Context / Correction Note
⚠️ Story gốc bị sai hướng. Story gốc mô tả việc xóa BYOK và dùng system API keys — đây là sai với kiến trúc thực tế của SurfSense. SurfSense là self-hosted product, BYOK (Bring-Your-Own-Key) là tính năng cốt lõi và cần giữ nguyên. Hệ thống quota thực tế dùng pages (document processing), không phải tokens LLM.
Story
As a Người dùng, I want nhận thông báo rõ ràng khi tôi đã dùng hết pages quota, so that tôi biết cần mua thêm page packs trước khi upload thêm tài liệu.
Actual Architecture (as-is)
- LLM: BYOK via
NewLLMConfig— user tự cấu hình API key của từng provider (OpenAI, Anthropic, etc.). Giữ nguyên, không thay đổi. - Quota:
pages_limit/pages_usedtrên bảngUser— track lượng pages đã ETL - PageLimitService:
surfsense_backend/app/services/page_limit_service.py— đã implement đầy đủcheck_page_limit(),update_page_usage(),get_page_usage() - Enforcement đã có: trong
document_tasks.py(Celery), các connector indexers (Google Drive, OneDrive, Dropbox, Notion, etc.) - Enforcement còn thiếu: tại HTTP API layer trước khi enqueue task
Acceptance Criteria
- Khi user upload document và
pages_used >= pages_limit, API trả về HTTP 402 với message rõ ràng trước khi queue Celery task. - Frontend bắt lỗi 402 từ upload API và hiển thị toast/modal hướng user đến trang Pricing để mua thêm pages.
- Endpoint
GET /api/v1/users/me(hoặc equivalent) trả vềpages_usedvàpages_limitđể FE hiển thị quota indicator.
Tasks / Subtasks
- Task 1: Thêm quota check vào Document Upload API route
- Subtask 1.1: Tại route xử lý document upload (tìm trong
surfsense_backend/app/routes/), injectPageLimitServicevà gọicheck_page_limit()với estimated pages trước khi enqueue Celery task. - Subtask 1.2: Raise
HTTPException(status_code=402, detail="Page quota exceeded. Please purchase more pages.")khi bị vượt giới hạn.
- Subtask 1.1: Tại route xử lý document upload (tìm trong
- Task 2: Frontend xử lý lỗi 402
- Subtask 2.1: Trong component upload document, bắt HTTP 402 response và render toast/alert "Bạn đã hết page quota. Mua thêm tại /pricing".
- Subtask 2.2: Link trong toast/alert dẫn đến
/pricing.
- Task 3: Hiển thị quota indicator (nice-to-have)
- Subtask 3.1: Thêm
pages_used/pages_limitvào response của current user endpoint. - Subtask 3.2: Hiển thị progress bar nhỏ trong UI.
- Subtask 3.1: Thêm
Dev Notes
What Already Works (Don't Re-Implement)
PageLimitService.check_page_limit()— dùng trực tiếp, không cần viết lại- Quota enforcement trong Celery tasks và connectors — đã có, giữ nguyên
pages_limittự động tăng khi user mua page pack (xemstripe_routes.py:_fulfill_completed_purchase)
What Needs to Change
- Chỉ cần thêm 1 check tại HTTP layer (trước khi enqueue) để user nhận feedback ngay, thay vì đợi task chạy xong mới biết bị reject.
References
surfsense_backend/app/services/page_limit_service.pysurfsense_backend/app/tasks/celery_tasks/document_tasks.py(xem cách dùng PageLimitService ở đây làm mẫu)
Dev Agent Record
Agent Model Used
TBD
File List
surfsense_backend/app/routes/(document upload route — cần tìm file cụ thể)surfsense_backend/app/services/page_limit_service.py(đọc, không sửa)- Frontend upload component (cần tìm file cụ thể)