Files
smart-org/services/billing-worker
mjalmoudy94 717e53a7ce نسخهٔ وب مستقل — پلتفرم نیروی کار هوش مصنوعی
مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت.
تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
2026-10-13 00:39:28 +03:30
..

@agy/billing-worker

Rolls the usage ledger into draft invoices — one invoice per organization per billing period.

pnpm --filter @agy/billing-worker run     # one pass, then exit (cron shape)
pnpm --filter @agy/billing-worker dev     # long-running loop

What it does

For every organization, for the requested period:

  1. Skip the organization if the period already has an invoice (idempotent — a cron job that fires twice must not bill twice).
  2. Otherwise sum the usage ledger for the period.
  3. Skip if the total is zero — no $0 drafts littering the table.
  4. Otherwise create a draft invoice carrying the ledger's total.

What it deliberately does not do

  • It never invents an amount. The ledger is the source of truth; the worker only snapshots it. See docs/architecture/overview.md §8.
  • It never moves money. Charging a card is BillingService.settle_payment, behind an authenticated API call — not a background job.

Implementation

apps/api/app/workers/billing.py. The service wiring comes from apps/api/app/application/container.py, so this worker and the API compose services identically. Tests: apps/api/tests/test_workers.py.

Extracting this into its own process

The worker already opens its own database sessions and holds no request state, so extraction is a deployment change, not a code change: run python -m app.workers billing --loop as its own process with the same DATABASE_URL, and point the cron/loop interval at your billing cycle.