refactor(models): migrate 28 data models to Zod schema-driven pattern

This commit is contained in:
2026-06-08 14:50:20 +08:00
parent 700ad0bc1a
commit d7943f5f06
36 changed files with 1204 additions and 1358 deletions
+27 -46
View File
@@ -1,60 +1,41 @@
/**
* 聊天历史响应
* 原始 Dart: ChatHistoryResponse (lib/data/models/chat/chat_response.dart)
*
* 注:原始 Dart 中 `total` 为 `int?`,按"全部非空"约定兜底为 0。
*/
import { ChatMessage } from "./chat_message";
import { z } from "zod";
import { ChatMessage, ChatMessageSchema } from "./chat_message";
export const ChatHistoryResponseSchema = z.object({
messages: z.array(ChatMessageSchema),
total: z.number().default(0),
limit: z.number(),
offset: z.number(),
});
export type ChatHistoryResponseInput = z.input<typeof ChatHistoryResponseSchema>;
export type ChatHistoryResponseData = z.output<typeof ChatHistoryResponseSchema>;
export class ChatHistoryResponse {
readonly messages: ChatMessage[];
readonly total: number;
readonly limit: number;
readonly offset: number;
declare readonly messages: ChatMessage[];
declare readonly total: number;
declare readonly limit: number;
declare readonly offset: number;
constructor(params: {
messages: ChatMessage[];
total?: number;
limit: number;
offset: number;
}) {
this.messages = params.messages;
this.total = params.total ?? 0;
this.limit = params.limit;
this.offset = params.offset;
private constructor(input: ChatHistoryResponseInput) {
const data = ChatHistoryResponseSchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
toJson(): Record<string, unknown> {
return {
messages: this.messages.map((m) => m.toJson()),
total: this.total,
limit: this.limit,
offset: this.offset,
};
static from(input: ChatHistoryResponseInput): ChatHistoryResponse {
return new ChatHistoryResponse(input);
}
static fromJson(json: Record<string, unknown>): ChatHistoryResponse {
const requireNumber = (key: string): number => {
const v = json[key];
if (typeof v !== "number") {
throw new Error(
`ChatHistoryResponse.${key} is required and must be a number`
);
}
return v;
};
const rawMessages = json.messages;
const messages: ChatMessage[] = Array.isArray(rawMessages)
? (rawMessages as Record<string, unknown>[]).map((m) =>
ChatMessage.fromJson(m)
)
: [];
return new ChatHistoryResponse({
messages,
total: typeof json.total === "number" ? json.total : undefined,
limit: requireNumber("limit"),
offset: requireNumber("offset"),
});
static fromJson(json: unknown): ChatHistoryResponse {
return ChatHistoryResponse.from(json as ChatHistoryResponseInput);
}
toJson(): ChatHistoryResponseData {
return ChatHistoryResponseSchema.parse(this);
}
}