feat: 添加 points_audit_ledger 及 JSON 字段 Pydantic Schema 约束

This commit is contained in:
qzl
2026-04-10 12:28:18 +08:00
parent 46513829cd
commit 0ac8b81a66
34 changed files with 2595 additions and 1757 deletions
+3 -7
View File
@@ -44,21 +44,17 @@ class AgentChatMessage(BaseModel):
output_tokens: int = Field(default=0, ge=0)
cost: Decimal = Field(default=Decimal("0"))
latency_ms: int | None = Field(default=None, ge=0)
metadata: AgentChatMessageMetadata | dict[str, object] | None = None
metadata: AgentChatMessageMetadata | None = None
timestamp: datetime
def extract_user_message_attachments(
metadata: AgentChatMessageMetadata | dict[str, object] | None,
metadata: AgentChatMessageMetadata | None,
) -> list[UserMessageAttachment]:
if metadata is None:
return []
if isinstance(metadata, AgentChatMessageMetadata):
raw_value: Any = metadata.user_message_attachments
else:
raw_value = metadata.get("user_message_attachments")
raw_value: Any = metadata.user_message_attachments
if raw_value is None:
return []
@@ -0,0 +1,9 @@
from __future__ import annotations
from pydantic import BaseModel, ConfigDict
class SessionStateSnapshot(BaseModel):
model_config = ConfigDict(extra="allow")
pass
+37
View File
@@ -126,3 +126,40 @@ class ApplyPointsChangeCommand(BaseModel):
if self.biz_type != PointsBizType.CHAT or self.biz_id is None:
raise ValueError("adjust must use chat binding")
return self
class AuditLedgerMetadata(BaseModel):
model_config = ConfigDict(extra="forbid")
source: str = Field(min_length=1, max_length=64)
email_hash: str | None = Field(default=None, max_length=128)
usage_missing: bool | None = Field(default=None)
failure_kind: Literal["failed", "canceled"] | None = Field(default=None)
operator_id: str | None = Field(default=None, max_length=64)
@model_validator(mode="after")
def validate_at_least_source(self) -> "AuditLedgerMetadata":
if not self.source:
raise ValueError("source is required")
return self
class AppendAuditLedgerCommand(BaseModel):
model_config = ConfigDict(extra="forbid")
event_id: str = Field(min_length=1, max_length=64)
user_id_snapshot: UUID | None = None
user_email_snapshot: str | None = None
change_type: PointsChangeType
biz_type: PointsBizType | None = None
biz_id: UUID | None = None
direction: Literal[1, 0, -1]
amount: int = Field(ge=0)
balance_after: int = Field(ge=0)
billed_to: Literal["user", "platform"]
run_id: str | None = Field(default=None, max_length=128)
request_id: str | None = Field(default=None, max_length=128)
input_tokens: int = Field(ge=0)
output_tokens: int = Field(ge=0)
cost: Decimal = Field(ge=Decimal("0"))
metadata: AuditLedgerMetadata