# 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.
