1"""Service-side models for relay billing.
2
3Contains the configuration carrier and metadata/audit code constants used
4by :mod:`lexigram.ai.governance.relay_billing.service`. Value types that
5cross package boundaries live in the contracts package; this module holds
6only governance-internal configuration and codes.
7"""
8
9from __future__ import annotations
10
11from dataclasses import dataclass
12
13__all__ = [
14 "DEFAULT_CURRENCY",
15 "USAGE_MISSING",
16 "RelayBillingConfig",
17]
18
19DEFAULT_CURRENCY = "USD"
20"""Default ISO currency code for relay charges."""
21
22USAGE_MISSING = "usage_missing"
23"""Loss/metadata code recorded when a settlement has no usage object."""
24
25
26@dataclass(frozen=True, slots=True)
27class RelayBillingConfig:
28 """Configuration for the relay billing lifecycle service.
29
30 Attributes:
31 currency: ISO currency code used for reservation and settled
32 charges. Defaults to ``USD``.
33 latency_units: Structured event latency unit; reserved for
34 future audit-event emission.
35 """
36
37 currency: str = DEFAULT_CURRENCY
38 latency_units: str = "ms"
39 metadata_codes: tuple[str, ...] = (USAGE_MISSING,)
40
41 def __post_init__(self) -> None:
42 """Reject an empty currency code."""
43 if not self.currency:
44 raise ValueError("currency must be non-empty")