6.1 KiB
6.1 KiB
Credit System
Purpose
Detail how credits are priced, checked, deducted, logged, and reported across the platform.
Code Locations (exact paths)
- Credit logic:
backend/igny8_core/business/billing/services/credit_service.py - Credit costs config:
backend/igny8_core/business/billing/models.py(CreditCostConfig) - Ledger and usage logs:
backend/igny8_core/business/billing/models.py(CreditTransaction,CreditUsageLog) - API endpoints:
backend/igny8_core/modules/billing/views.py(CreditBalanceViewSet,CreditUsageViewSet) - Constants and exceptions:
backend/igny8_core/business/billing/constants.py,exceptions.py - Plan included credits:
backend/igny8_core/auth/models.py(Plan.included_credits,Account.credits)
High-Level Responsibilities
- Compute operation costs (configurable per operation and unit) and enforce sufficient balance before AI/content actions.
- Deduct or add credits atomically while writing both transaction and usage log records.
- Provide balance, usage history, summaries, and limits endpoints for clients.
- Allow admin-configurable cost overrides via
CreditCostConfig.
Detailed Behavior
- Cost resolution (
CreditService.get_credit_cost):- First checks
CreditCostConfigfor the operation (active records). Supports units:per_request,per_100_words,per_200_words,per_item,per_image. Applies amounts when provided (e.g., words, items, images). - Falls back to hardcoded
CREDIT_COSTSconstants; raisesCreditCalculationErrorfor unknown operations. - Legacy variable costs: content_generation per 100 words, optimization per 200 words, image_generation per image, idea_generation per idea.
- First checks
- Balance enforcement:
check_credits/check_credits_legacyraiseInsufficientCreditsErrorwhen balance insufficient.deduct_credits_for_operationcomputes cost, checks balance, builds a default description per operation when not supplied, then callsdeduct_credits.
- Deduction (
deduct_credits):- Atomic: decrements
Account.credits, writesCreditTransactionwith negative amount and balance_after, writesCreditUsageLogcapturing operation_type, cost_usd/model/tokens/related object references, metadata.
- Atomic: decrements
- Add credits (
add_credits):- Atomic: increments
Account.credits, writesCreditTransactionwith positive amount and balance_after.
- Atomic: increments
- Logging:
CreditTransactionis the authoritative ledger;CreditUsageLogtracks per-operation usage for analytics and summaries.CreditCostConfigtracksprevious_coston save when cost changes.
- Reporting endpoints (modules/billing):
CreditBalanceViewSet.list: returns current credits, plan monthly credits, credits used this month (fromCreditUsageLog), and remaining credits.CreditUsageViewSet.list: paginated usage logs filtered by operation_type and date range, account-scoped.CreditUsageViewSet.summary: aggregates credits and USD cost by operation and model over a date range (defaults to current month).CreditUsageViewSet.limits: returns plan limits (users/sites/industries/author profiles) and current usage counts, plus credits info; returns empty limits if account/plan missing.
Data Structures / Models Involved (no code)
CreditCostConfig: operation_type, credits_cost, unit, display_name, description, is_active, previous_cost, updated_by, timestamps.CreditTransaction: transaction_type (purchase/subscription/refund/deduction/adjustment), amount (+/-), balance_after, description, metadata, reference_id, created_at.CreditUsageLog: operation_type (clustering/idea_generation/content_generation/image_generation/reparse/legacy names), credits_used, cost_usd, model_used, tokens_in/out, related object type/id, metadata, created_at.Account.credits: current balance;Plan.included_credits: monthly included credits.
Execution Flow
- Caller requests an operation →
get_credit_costcomputes cost →check_creditsensures balance →deduct_creditsmutates balance and writes ledger + usage → upstream operation proceeds (AI/content). - Balance/usage endpoints read from
Account,CreditUsageLog,Planto present current balances, month-to-date usage, summaries, and limits.
Cross-Module Interactions
- AI/automation/planner/writer services call
CreditServicebefore expensive operations; automation aggregates credits used per stage from AI task logs, while billing logs capture actual deductions at AI call sites. - Plan limits (users/sites/industries/authors) referenced in billing limits endpoint inform account management elsewhere.
State Transitions
- Balance changes recorded per transaction; usage accumulates per operation. Cost configs can be toggled active/inactive and updated with audit of previous cost.
Error Handling
- Unknown operation types raise
CreditCalculationError; insufficient balance raisesInsufficientCreditsError(mapped to HTTP 402 in callers). - Balance/usage endpoints fall back to zeros/empty when account/plan missing rather than erroring.
Tenancy Rules
- All credit operations and queries are account-scoped; viewsets filter by
request.account/request.user.account. No cross-tenant access.
Billing Rules
- Costs derived from
CreditCostConfig> constants; units must match supplied amount. Ledger and usage logs are mandatory for every deduction/addition.
Background Tasks / Schedulers
- None dedicated; credit usage often originates from AI Celery tasks but logging happens at the service call site.
Key Design Considerations
- Centralized credit math and atomic DB updates prevent drift between balance, ledger, and usage logs.
- Configurable costs allow runtime tuning without code changes.
- Reporting endpoints are read-only and tolerant of missing plan data to keep dashboards resilient.
How Developers Should Work With This Module
- Always route credit checks/deductions/additions through
CreditService. - When adding new AI operations, register operation_type in
CreditUsageLog/constants and optionally seedCreditCostConfig. - Include amount (words/items/images) when calling
deduct_credits_for_operationso unit-based pricing applies. - Use balance/usage endpoints for UI/analytics; avoid custom queries that bypass account scoping.