refactor(models): migrate 28 data models to Zod schema-driven pattern
This commit is contained in:
@@ -1,156 +1,71 @@
|
||||
/**
|
||||
* 用户统计响应
|
||||
* 原始 Dart: UserStatsResponse (lib/data/models/user/user_stats_response.dart)
|
||||
*
|
||||
* 注:原始 Dart 中 `lastMessageAt`/`accountCreatedAt`/`currentMood` 为 `String?`,
|
||||
* `personalityTraits` 为 `PersonalityTraits?`,按"全部非空"约定兜底:
|
||||
* - 字符串 → ""
|
||||
* - PersonalityTraits → 默认实例
|
||||
* - recentMemories 缺失或 null 时使用 []
|
||||
*/
|
||||
import { PersonalityTraits } from "./personality_traits";
|
||||
import { RecentMemory } from "./recent_memory";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
PersonalityTraits,
|
||||
PERSONALITY_TRAITS_DEFAULTS,
|
||||
PersonalityTraitsSchema,
|
||||
} from "./personality_traits";
|
||||
import { RecentMemory, RecentMemorySchema } from "./recent_memory";
|
||||
|
||||
export const UserStatsResponseSchema = z.object({
|
||||
userId: z.string(),
|
||||
username: z.string(),
|
||||
platform: z.string(),
|
||||
intimacy: z.number(),
|
||||
relationshipStage: z.string(),
|
||||
dolBalance: z.number(),
|
||||
totalMessages: z.number(),
|
||||
lastMessageAt: z.string().default(""),
|
||||
accountCreatedAt: z.string().default(""),
|
||||
currentMood: z.string().default(""),
|
||||
personalityTraits: PersonalityTraitsSchema.default(
|
||||
PERSONALITY_TRAITS_DEFAULTS
|
||||
),
|
||||
recentMemories: z.array(RecentMemorySchema).default([]),
|
||||
promptTokensTotal: z.number().default(0),
|
||||
completionTokensTotal: z.number().default(0),
|
||||
cacheHitTokensTotal: z.number().default(0),
|
||||
tokensTotal: z.number().default(0),
|
||||
});
|
||||
|
||||
export type UserStatsResponseInput = z.input<typeof UserStatsResponseSchema>;
|
||||
export type UserStatsResponseData = z.output<typeof UserStatsResponseSchema>;
|
||||
|
||||
export class UserStatsResponse {
|
||||
readonly userId: string;
|
||||
readonly username: string;
|
||||
readonly platform: string;
|
||||
readonly intimacy: number;
|
||||
readonly relationshipStage: string;
|
||||
readonly dolBalance: number;
|
||||
readonly totalMessages: number;
|
||||
readonly lastMessageAt: string;
|
||||
readonly accountCreatedAt: string;
|
||||
readonly currentMood: string;
|
||||
readonly personalityTraits: PersonalityTraits;
|
||||
readonly recentMemories: RecentMemory[];
|
||||
readonly promptTokensTotal: number;
|
||||
readonly completionTokensTotal: number;
|
||||
readonly cacheHitTokensTotal: number;
|
||||
readonly tokensTotal: number;
|
||||
declare readonly userId: string;
|
||||
declare readonly username: string;
|
||||
declare readonly platform: string;
|
||||
declare readonly intimacy: number;
|
||||
declare readonly relationshipStage: string;
|
||||
declare readonly dolBalance: number;
|
||||
declare readonly totalMessages: number;
|
||||
declare readonly lastMessageAt: string;
|
||||
declare readonly accountCreatedAt: string;
|
||||
declare readonly currentMood: string;
|
||||
declare readonly personalityTraits: PersonalityTraits;
|
||||
declare readonly recentMemories: RecentMemory[];
|
||||
declare readonly promptTokensTotal: number;
|
||||
declare readonly completionTokensTotal: number;
|
||||
declare readonly cacheHitTokensTotal: number;
|
||||
declare readonly tokensTotal: number;
|
||||
|
||||
constructor(params: {
|
||||
userId: string;
|
||||
username: string;
|
||||
platform: string;
|
||||
intimacy: number;
|
||||
relationshipStage: string;
|
||||
dolBalance: number;
|
||||
totalMessages: number;
|
||||
lastMessageAt?: string;
|
||||
accountCreatedAt?: string;
|
||||
currentMood?: string;
|
||||
personalityTraits?: PersonalityTraits;
|
||||
recentMemories?: RecentMemory[];
|
||||
promptTokensTotal?: number;
|
||||
completionTokensTotal?: number;
|
||||
cacheHitTokensTotal?: number;
|
||||
tokensTotal?: number;
|
||||
}) {
|
||||
this.userId = params.userId;
|
||||
this.username = params.username;
|
||||
this.platform = params.platform;
|
||||
this.intimacy = params.intimacy;
|
||||
this.relationshipStage = params.relationshipStage;
|
||||
this.dolBalance = params.dolBalance;
|
||||
this.totalMessages = params.totalMessages;
|
||||
this.lastMessageAt = params.lastMessageAt ?? "";
|
||||
this.accountCreatedAt = params.accountCreatedAt ?? "";
|
||||
this.currentMood = params.currentMood ?? "";
|
||||
this.personalityTraits =
|
||||
params.personalityTraits ?? new PersonalityTraits({});
|
||||
this.recentMemories = params.recentMemories ?? [];
|
||||
this.promptTokensTotal = params.promptTokensTotal ?? 0;
|
||||
this.completionTokensTotal = params.completionTokensTotal ?? 0;
|
||||
this.cacheHitTokensTotal = params.cacheHitTokensTotal ?? 0;
|
||||
this.tokensTotal = params.tokensTotal ?? 0;
|
||||
private constructor(data: UserStatsResponseData) {
|
||||
Object.assign(this, data);
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
return {
|
||||
userId: this.userId,
|
||||
username: this.username,
|
||||
platform: this.platform,
|
||||
intimacy: this.intimacy,
|
||||
relationshipStage: this.relationshipStage,
|
||||
dolBalance: this.dolBalance,
|
||||
totalMessages: this.totalMessages,
|
||||
lastMessageAt: this.lastMessageAt,
|
||||
accountCreatedAt: this.accountCreatedAt,
|
||||
currentMood: this.currentMood,
|
||||
personalityTraits: this.personalityTraits.toJson(),
|
||||
recentMemories: this.recentMemories.map((m) => m.toJson()),
|
||||
promptTokensTotal: this.promptTokensTotal,
|
||||
completionTokensTotal: this.completionTokensTotal,
|
||||
cacheHitTokensTotal: this.cacheHitTokensTotal,
|
||||
tokensTotal: this.tokensTotal,
|
||||
};
|
||||
static from(input: UserStatsResponseInput): UserStatsResponse {
|
||||
return new UserStatsResponse(UserStatsResponseSchema.parse(input));
|
||||
}
|
||||
|
||||
static fromJson(json: Record<string, unknown>): UserStatsResponse {
|
||||
const requireString = (key: string): string => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "string") {
|
||||
throw new Error(
|
||||
`UserStatsResponse.${key} is required and must be a string`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const requireNumber = (key: string): number => {
|
||||
const v = json[key];
|
||||
if (typeof v !== "number") {
|
||||
throw new Error(
|
||||
`UserStatsResponse.${key} is required and must be a number`
|
||||
);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
const rawMemories = json.recentMemories;
|
||||
const recentMemories: RecentMemory[] = Array.isArray(rawMemories)
|
||||
? (rawMemories as Record<string, unknown>[]).map((m) =>
|
||||
RecentMemory.fromJson(m)
|
||||
)
|
||||
: [];
|
||||
return new UserStatsResponse({
|
||||
userId: requireString("userId"),
|
||||
username: requireString("username"),
|
||||
platform: requireString("platform"),
|
||||
intimacy: requireNumber("intimacy"),
|
||||
relationshipStage: requireString("relationshipStage"),
|
||||
dolBalance: requireNumber("dolBalance"),
|
||||
totalMessages: requireNumber("totalMessages"),
|
||||
lastMessageAt:
|
||||
typeof json.lastMessageAt === "string"
|
||||
? json.lastMessageAt
|
||||
: undefined,
|
||||
accountCreatedAt:
|
||||
typeof json.accountCreatedAt === "string"
|
||||
? json.accountCreatedAt
|
||||
: undefined,
|
||||
currentMood:
|
||||
typeof json.currentMood === "string" ? json.currentMood : undefined,
|
||||
personalityTraits: json.personalityTraits
|
||||
? PersonalityTraits.fromJson(
|
||||
json.personalityTraits as Record<string, unknown>
|
||||
)
|
||||
: undefined,
|
||||
recentMemories,
|
||||
promptTokensTotal:
|
||||
typeof json.promptTokensTotal === "number"
|
||||
? json.promptTokensTotal
|
||||
: undefined,
|
||||
completionTokensTotal:
|
||||
typeof json.completionTokensTotal === "number"
|
||||
? json.completionTokensTotal
|
||||
: undefined,
|
||||
cacheHitTokensTotal:
|
||||
typeof json.cacheHitTokensTotal === "number"
|
||||
? json.cacheHitTokensTotal
|
||||
: undefined,
|
||||
tokensTotal:
|
||||
typeof json.tokensTotal === "number" ? json.tokensTotal : undefined,
|
||||
});
|
||||
static fromJson(json: unknown): UserStatsResponse {
|
||||
return UserStatsResponse.from(json as UserStatsResponseInput);
|
||||
}
|
||||
|
||||
toJson(): UserStatsResponseData {
|
||||
return UserStatsResponseSchema.parse(this);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user