نسخهٔ وب مستقل — پلتفرم نیروی کار هوش مصنوعی

مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت.
تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
This commit is contained in:
mjalmoudy94
2026-10-13 00:39:28 +03:30
commit 717e53a7ce
185 changed files with 39910 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
"""Audit and usage-ledger ports.
``AuditPort`` writes the immutable trail; ``UsageLedgerPort`` is the billing
source of truth. Both are append-only by contract.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from typing import Protocol, runtime_checkable
from app.domain.ai_control.models import RateUnit
from app.domain.audit.models import AuditEvent
@dataclass(slots=True, kw_only=True)
class UsageRecord:
organization_id: str
unit: RateUnit
quantity: float
unit_price: float = 0.0
internal_cost_estimate: float = 0.0
total_price: float = 0.0
project_id: str | None = None
user_id: str | None = None
employee_id: str | None = None
run_id: str | None = None
metadata_json: dict = field(default_factory=dict)
@dataclass(slots=True, kw_only=True)
class UsageAggregate:
unit: RateUnit
quantity: float = 0.0
total_price: float = 0.0
internal_cost_estimate: float = 0.0
@dataclass(slots=True, kw_only=True)
class UsageBreakdown:
"""Grouped totals for the billing dashboard."""
by_unit: list[UsageAggregate] = field(default_factory=list)
by_employee: dict[str, float] = field(default_factory=dict)
by_project: dict[str, float] = field(default_factory=dict)
total_price: float = 0.0
total_cost: float = 0.0
@runtime_checkable
class AuditPort(Protocol):
async def record(self, *, event: AuditEvent) -> AuditEvent: ...
async def list_for_organization(
self, *, organization_id: str, limit: int = 100, offset: int = 0
) -> list[AuditEvent]: ...
@runtime_checkable
class UsageLedgerPort(Protocol):
async def record(self, *, usage: UsageRecord) -> None:
"""Append one usage event. Never raises for business reasons — a failed
ledger write is an infrastructure error and must surface loudly."""
...
async def breakdown(
self,
*,
organization_id: str,
since: datetime | None = None,
until: datetime | None = None,
) -> UsageBreakdown: ...