# 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 `CreditCostConfig` for 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_COSTS` constants; raises `CreditCalculationError` for unknown operations. - Legacy variable costs: content_generation per 100 words, optimization per 200 words, image_generation per image, idea_generation per idea. - Balance enforcement: - `check_credits`/`check_credits_legacy` raise `InsufficientCreditsError` when balance insufficient. - `deduct_credits_for_operation` computes cost, checks balance, builds a default description per operation when not supplied, then calls `deduct_credits`. - Deduction (`deduct_credits`): - Atomic: decrements `Account.credits`, writes `CreditTransaction` with negative amount and balance_after, writes `CreditUsageLog` capturing operation_type, cost_usd/model/tokens/related object references, metadata. - Add credits (`add_credits`): - Atomic: increments `Account.credits`, writes `CreditTransaction` with positive amount and balance_after. - Logging: - `CreditTransaction` is the authoritative ledger; `CreditUsageLog` tracks per-operation usage for analytics and summaries. - `CreditCostConfig` tracks `previous_cost` on save when cost changes. - Reporting endpoints (modules/billing): - `CreditBalanceViewSet.list`: returns current credits, plan monthly credits, credits used this month (from `CreditUsageLog`), 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_cost` computes cost → `check_credits` ensures balance → `deduct_credits` mutates balance and writes ledger + usage → upstream operation proceeds (AI/content). - Balance/usage endpoints read from `Account`, `CreditUsageLog`, `Plan` to present current balances, month-to-date usage, summaries, and limits. ## Cross-Module Interactions - AI/automation/planner/writer services call `CreditService` before 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 raises `InsufficientCreditsError` (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 seed `CreditCostConfig`. - Include amount (words/items/images) when calling `deduct_credits_for_operation` so unit-based pricing applies. - Use balance/usage endpoints for UI/analytics; avoid custom queries that bypass account scoping.