""" 推送接口通用schema ## 响应相关 1. BaseResponseSchema: 所有接口响应的基础schema 2. BasePushResponseSchema: 推送接口响应的基础schema,包含push_id 3. PushResultSchema: 查询推送结果的schema ## 请求相关 4. BaseCreateRequestSchema[T]: 创建资源的基础请求schema(泛型),业务数据在data字段 5. BaseUpdateRequestSchema[T]: 更新资源的基础请求schema(泛型),业务数据在data字段 6. BaseDeleteRequestSchema: 删除资源的基础请求schema,只需resource_id 7. BulkPushRequestSchema: 批量推送请求的schema ## 说明 - 所有元数据字段(timestamp, nonce, signature, uid, push_id)在请求体最外层 - push_id使用UUIDv7格式,支持时间排序,同时作为幂等键和查询键 - 业务数据嵌套在data字段中(删除操作除外,只需resource_id) - 所有业务Schema必须继承BasePushData,确保包含project_type字段 - resource_id在外层,用于标识要操作的资源(更新/删除时必填) - 使用泛型T可快速定义各业务的请求schema,T必须继承BasePushData """ from pydantic import BaseModel, Field from typing import TypeVar, Generic, Optional, List, Dict, Any from ..project.enums import ProjectType # 定义泛型 T = TypeVar('T', bound='BasePushData') # ==================== 业务数据基类 ==================== class BasePushData(BaseModel): """ 所有推送业务数据的基类 所有业务Schema必须继承此类,确保包含project_type字段 """ project_type: ProjectType = Field(..., description="项目类型:offshore_wind/pumped_storage/photovoltaic等") # ==================== Mixin ==================== class SignatureMixin(BaseModel): """签名字段混入""" timestamp: int = Field(..., description="毫秒级 Unix 时间戳") nonce: str = Field(..., description="随机字符串,防止重放攻击") sign: str = Field(..., description="签名字符串") uid: str = Field(..., description="集团侧用户id") class PushRequestMixin(BaseModel): """推送ID字段混入""" push_id: str = Field(..., description="推送ID,客户端生成的唯一标识(UUIDv7,支持时间排序)") # ==================== 响应相关 ==================== class BaseResponseSchema(BaseModel): """所有接口响应的基础schema""" code: int = 200 message: Optional[str] = "OK" data: Optional[T] = None class BasePushResponseSchema(BaseModel): """推送接口响应的基础schema""" biz_id: str | None = Field(None, description="资源ID(create操作成功后返回新创建的ID,update/delete返回原ID)") class PushResultSchema(BaseModel): """查询推送结果的schema""" push_id: str = Field(..., description="推送ID(客户端生成的UUIDv7)") status: str = Field(..., description="推送状态:queued/processing/success/failed") result: Dict[str, Any] | None = Field(None, description="处理结果(成功时包含created_id等信息)") error: str | None = Field(None, description="错误信息(失败时)") created_at: str = Field(..., description="推送创建时间(ISO 8601格式)") updated_at: str = Field(..., description="推送更新时间(ISO 8601格式)") class PushIdsSchema(BaseModel): """支持从请求体接收的 push_ids 列表字符串(逗号拼接)""" push_ids: Optional[str] = Field(None, description="推送id字符串逗号拼接") # ==================== 请求相关 ==================== class BaseCreateRequestSchema(SignatureMixin, PushRequestMixin, BaseModel, Generic[T]): """ 创建资源的基础请求schema(泛型) 泛型T必须继承BasePushData,确保包含project_type字段 使用示例: class ProjectInputSchema(BasePushData): name: str = Field(...) capacity: float = Field(...) class ProjectCreateRequest(BaseCreateRequestSchema[ProjectInputSchema]): pass """ # 业务数据(嵌套) data: T = Field(..., description="业务数据") class BaseUpdateRequestSchema(SignatureMixin, PushRequestMixin, BaseModel, Generic[T]): """ 更新资源的基础请求schema(泛型) 泛型T必须继承BasePushData,确保包含project_type字段 resource_id在外层,用于标识要更新的资源 使用示例: class ProjectInputSchema(BasePushData): name: str = Field(...) capacity: float = Field(...) class ProjectUpdateRequest(BaseUpdateRequestSchema[ProjectInputSchema]): pass """ # 资源标识 biz_id: str = Field(..., description="要更新的资源ID,类型id,如project传project_id,unit传unit_id") # 业务数据(嵌套) data: T = Field(..., description="业务数据(只需包含要更新的字段)") class BaseDeleteRequestSchema(SignatureMixin, PushRequestMixin, BaseModel): """ 删除资源的基础请求schema 使用示例: class ProjectDeleteRequest(BaseDeleteRequestSchema): pass """ # 资源标识 biz_id: str = Field(..., description="要删除的资源ID") class BulkPushItem(PushRequestMixin, BaseModel): """ 批量推送中的单个项目 注意: - action为create时:data必填,resource_id留空 - action为update时:data和resource_id都必填 - action为delete时:resource_id必填,data留空 - data必须继承BasePushData,确保包含project_type字段 """ action: str = Field(..., description="操作类型:create/update/delete") resource_id: str | None = Field(None, description="资源ID(update/delete时必填,create时留空)") data: BasePushData | None = Field(None, description="业务数据(create/update时必填,delete时留空,必须包含project_type字段)") class BulkPushItemResult(BaseModel): """批量推送中单个项目的处理结果""" push_id: str = Field(..., description="推送ID(对应请求中的push_id)") status: str = Field(..., description="处理状态:queued/processing/success/failed") resource_id: str | None = Field(None, description="资源ID(create成功时返回新ID,update/delete返回原ID)") error: str | None = Field(None, description="错误信息(失败时)") class BulkPushRequestSchema(SignatureMixin, BaseModel): """ 批量推送请求的schema 一次请求可推送多条数据,每条都有独立的幂等键和操作类型 """ # 批量数据 items: List[BulkPushItem] = Field(..., description="批量推送的数据列表") class BulkPushResponseSchema(BaseResponseSchema): """批量推送响应的schema""" batch_id: str = Field(..., description="批量推送的批次ID") total: int = Field(..., description="总数量") results: List[BulkPushItemResult] = Field(..., description="每条数据的处理结果,包含push_id和resource_id")