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
+23 -23
View File
@@ -1,35 +1,35 @@
/**
* 头像数据模型 - 对应后端 AvatarData schema
* 原始 Dart: AvatarData (lib/data/models/user/user.dart)
*
* 注:原始 Dart 中 `avatarUrl` 为 `String?`,按"全部非空"约定兜底为空串。
*/
export class AvatarData {
readonly avatarUrl: string;
readonly userId: string;
import { z } from "zod";
constructor(params: { avatarUrl?: string; userId: string }) {
this.avatarUrl = params.avatarUrl ?? "";
this.userId = params.userId;
export const AvatarDataSchema = z.object({
avatarUrl: z.string().default(""),
userId: z.string(),
});
export type AvatarDataInput = z.input<typeof AvatarDataSchema>;
export type AvatarDataData = z.output<typeof AvatarDataSchema>;
export class AvatarData {
declare readonly avatarUrl: string;
declare readonly userId: string;
private constructor(data: AvatarDataData) {
Object.assign(this, data);
Object.freeze(this);
}
toJson(): Record<string, unknown> {
return {
avatarUrl: this.avatarUrl,
userId: this.userId,
};
static from(input: AvatarDataInput): AvatarData {
return new AvatarData(AvatarDataSchema.parse(input));
}
static fromJson(json: Record<string, unknown>): AvatarData {
const userId = json.userId;
if (typeof userId !== "string") {
throw new Error("AvatarData.userId is required and must be a string");
}
return new AvatarData({
userId,
avatarUrl:
typeof json.avatarUrl === "string" ? json.avatarUrl : undefined,
});
static fromJson(json: unknown): AvatarData {
return AvatarData.from(json as AvatarDataInput);
}
toJson(): AvatarDataData {
return AvatarDataSchema.parse(this);
}
}
+23 -23
View File
@@ -2,34 +2,34 @@
* 积分数据模型 - 对应后端 CreditsData schema
* 原始 Dart: CreditsData (lib/data/models/user/user.dart)
*/
export class CreditsData {
readonly userId: string;
readonly dolBalance: number;
import { z } from "zod";
constructor(params: { userId: string; dolBalance: number }) {
this.userId = params.userId;
this.dolBalance = params.dolBalance;
export const CreditsDataSchema = z.object({
userId: z.string(),
dolBalance: z.number(),
});
export type CreditsDataInput = z.input<typeof CreditsDataSchema>;
export type CreditsDataData = z.output<typeof CreditsDataSchema>;
export class CreditsData {
declare readonly userId: string;
declare readonly dolBalance: number;
private constructor(data: CreditsDataData) {
Object.assign(this, data);
Object.freeze(this);
}
toJson(): Record<string, unknown> {
return {
userId: this.userId,
dolBalance: this.dolBalance,
};
static from(input: CreditsDataInput): CreditsData {
return new CreditsData(CreditsDataSchema.parse(input));
}
static fromJson(json: Record<string, unknown>): CreditsData {
const userId = json.userId;
const dolBalance = json.dolBalance;
if (typeof userId !== "string") {
throw new Error("CreditsData.userId is required and must be a string");
}
if (typeof dolBalance !== "number") {
throw new Error(
"CreditsData.dolBalance is required and must be a number"
);
}
return new CreditsData({ userId, dolBalance });
static fromJson(json: unknown): CreditsData {
return CreditsData.from(json as CreditsDataInput);
}
toJson(): CreditsDataData {
return CreditsDataSchema.parse(this);
}
}
+27 -45
View File
@@ -1,57 +1,39 @@
/**
* 积分历史记录模型 - 对应后端 CreditsHistoryData schema
* 原始 Dart: CreditsHistoryData (lib/data/models/user/user.dart)
*
* 注:原始 Dart 中 `records` 为 `List<Map<String, dynamic>>`
* 迁移为 `Record<string, unknown>[]`。
*/
export class CreditsHistoryData {
readonly records: Record<string, unknown>[];
readonly total: number;
readonly limit: number;
readonly offset: number;
import { z } from "zod";
constructor(params: {
records: Record<string, unknown>[];
total: number;
limit: number;
offset: number;
}) {
this.records = params.records;
this.total = params.total;
this.limit = params.limit;
this.offset = params.offset;
export const CreditsHistoryDataSchema = z.object({
records: z.array(z.record(z.string(), z.unknown())),
total: z.number(),
limit: z.number(),
offset: z.number(),
});
export type CreditsHistoryDataInput = z.input<typeof CreditsHistoryDataSchema>;
export type CreditsHistoryDataData = z.output<typeof CreditsHistoryDataSchema>;
export class CreditsHistoryData {
declare readonly records: Record<string, unknown>[];
declare readonly total: number;
declare readonly limit: number;
declare readonly offset: number;
private constructor(data: CreditsHistoryDataData) {
Object.assign(this, data);
Object.freeze(this);
}
toJson(): Record<string, unknown> {
return {
records: this.records,
total: this.total,
limit: this.limit,
offset: this.offset,
};
static from(input: CreditsHistoryDataInput): CreditsHistoryData {
return new CreditsHistoryData(CreditsHistoryDataSchema.parse(input));
}
static fromJson(json: Record<string, unknown>): CreditsHistoryData {
const requireNumber = (key: string): number => {
const v = json[key];
if (typeof v !== "number") {
throw new Error(
`CreditsHistoryData.${key} is required and must be a number`
);
}
return v;
};
const rawRecords = json.records;
const records: Record<string, unknown>[] = Array.isArray(rawRecords)
? (rawRecords as Record<string, unknown>[])
: [];
return new CreditsHistoryData({
records,
total: requireNumber("total"),
limit: requireNumber("limit"),
offset: requireNumber("offset"),
});
static fromJson(json: unknown): CreditsHistoryData {
return CreditsHistoryData.from(json as CreditsHistoryDataInput);
}
toJson(): CreditsHistoryDataData {
return CreditsHistoryDataSchema.parse(this);
}
}
+37 -36
View File
@@ -1,48 +1,49 @@
/**
* 个性特征模型
* 原始 Dart: PersonalityTraits (lib/data/models/user/user.dart)
*
* 注:所有 double 字段在 Dart 中使用 @Default(0.5)。
*/
export class PersonalityTraits {
readonly cheerful: number;
readonly caring: number;
readonly playful: number;
readonly serious: number;
readonly romantic: number;
import { z } from "zod";
constructor(params: {
cheerful?: number;
caring?: number;
playful?: number;
serious?: number;
romantic?: number;
}) {
this.cheerful = params.cheerful ?? 0.5;
this.caring = params.caring ?? 0.5;
this.playful = params.playful ?? 0.5;
this.serious = params.serious ?? 0.5;
this.romantic = params.romantic ?? 0.5;
export const PERSONALITY_TRAITS_DEFAULTS: PersonalityTraitsData = {
cheerful: 0.5,
caring: 0.5,
playful: 0.5,
serious: 0.5,
romantic: 0.5,
};
export const PersonalityTraitsSchema = z.object({
cheerful: z.number().default(0.5),
caring: z.number().default(0.5),
playful: z.number().default(0.5),
serious: z.number().default(0.5),
romantic: z.number().default(0.5),
});
export type PersonalityTraitsInput = z.input<typeof PersonalityTraitsSchema>;
export type PersonalityTraitsData = z.output<typeof PersonalityTraitsSchema>;
export class PersonalityTraits {
declare readonly cheerful: number;
declare readonly caring: number;
declare readonly playful: number;
declare readonly serious: number;
declare readonly romantic: number;
private constructor(data: PersonalityTraitsData) {
Object.assign(this, data);
Object.freeze(this);
}
toJson(): Record<string, unknown> {
return {
cheerful: this.cheerful,
caring: this.caring,
playful: this.playful,
serious: this.serious,
romantic: this.romantic,
};
static from(input: PersonalityTraitsInput): PersonalityTraits {
return new PersonalityTraits(PersonalityTraitsSchema.parse(input));
}
static fromJson(json: Record<string, unknown>): PersonalityTraits {
return new PersonalityTraits({
cheerful: typeof json.cheerful === "number" ? json.cheerful : undefined,
caring: typeof json.caring === "number" ? json.caring : undefined,
playful: typeof json.playful === "number" ? json.playful : undefined,
serious: typeof json.serious === "number" ? json.serious : undefined,
romantic: typeof json.romantic === "number" ? json.romantic : undefined,
});
static fromJson(json: unknown): PersonalityTraits {
return PersonalityTraits.from(json as PersonalityTraitsInput);
}
toJson(): PersonalityTraitsData {
return PersonalityTraitsSchema.parse(this);
}
}
+27 -47
View File
@@ -1,59 +1,39 @@
/**
* 最近记忆模型
* 原始 Dart: RecentMemory (lib/data/models/user/recent_memory.dart)
*
* 注:原始 Dart 中 `createdAt` 为 `String?`,按"全部非空"约定兜底为空串。
*/
export class RecentMemory {
readonly type: string;
readonly content: string;
readonly importance: number;
readonly createdAt: string;
import { z } from "zod";
constructor(params: {
type: string;
content: string;
importance: number;
createdAt?: string;
}) {
this.type = params.type;
this.content = params.content;
this.importance = params.importance;
this.createdAt = params.createdAt ?? "";
export const RecentMemorySchema = z.object({
type: z.string(),
content: z.string(),
importance: z.number(),
createdAt: z.string().default(""),
});
export type RecentMemoryInput = z.input<typeof RecentMemorySchema>;
export type RecentMemoryData = z.output<typeof RecentMemorySchema>;
export class RecentMemory {
declare readonly type: string;
declare readonly content: string;
declare readonly importance: number;
declare readonly createdAt: string;
private constructor(data: RecentMemoryData) {
Object.assign(this, data);
Object.freeze(this);
}
toJson(): Record<string, unknown> {
return {
type: this.type,
content: this.content,
importance: this.importance,
createdAt: this.createdAt,
};
static from(input: RecentMemoryInput): RecentMemory {
return new RecentMemory(RecentMemorySchema.parse(input));
}
static fromJson(json: Record<string, unknown>): RecentMemory {
const requireString = (key: string): string => {
const v = json[key];
if (typeof v !== "string") {
throw new Error(
`RecentMemory.${key} is required and must be a string`
);
}
return v;
};
const importance = json.importance;
if (typeof importance !== "number") {
throw new Error(
"RecentMemory.importance is required and must be a number"
);
}
return new RecentMemory({
type: requireString("type"),
content: requireString("content"),
importance,
createdAt:
typeof json.createdAt === "string" ? json.createdAt : undefined,
});
static fromJson(json: unknown): RecentMemory {
return RecentMemory.from(json as RecentMemoryInput);
}
toJson(): RecentMemoryData {
return RecentMemorySchema.parse(this);
}
}
+27 -35
View File
@@ -1,47 +1,39 @@
/**
* 更新个人资料请求
* 原始 Dart: UpdateProfileRequest (lib/data/models/user/user.dart)
*
* 注:原始 Dart 中所有字段为 `String?`,按"全部非空"约定兜底为空串。
*/
export class UpdateProfileRequest {
readonly username: string;
readonly nickname: string;
readonly preferredLanguage: string;
readonly currentMood: string;
import { z } from "zod";
constructor(params: {
username?: string;
nickname?: string;
preferredLanguage?: string;
currentMood?: string;
}) {
this.username = params.username ?? "";
this.nickname = params.nickname ?? "";
this.preferredLanguage = params.preferredLanguage ?? "";
this.currentMood = params.currentMood ?? "";
export const UpdateProfileRequestSchema = z.object({
username: z.string().default(""),
nickname: z.string().default(""),
preferredLanguage: z.string().default(""),
currentMood: z.string().default(""),
});
export type UpdateProfileRequestInput = z.input<typeof UpdateProfileRequestSchema>;
export type UpdateProfileRequestData = z.output<typeof UpdateProfileRequestSchema>;
export class UpdateProfileRequest {
declare readonly username: string;
declare readonly nickname: string;
declare readonly preferredLanguage: string;
declare readonly currentMood: string;
private constructor(data: UpdateProfileRequestData) {
Object.assign(this, data);
Object.freeze(this);
}
toJson(): Record<string, unknown> {
return {
username: this.username,
nickname: this.nickname,
preferredLanguage: this.preferredLanguage,
currentMood: this.currentMood,
};
static from(input: UpdateProfileRequestInput): UpdateProfileRequest {
return new UpdateProfileRequest(UpdateProfileRequestSchema.parse(input));
}
static fromJson(json: Record<string, unknown>): UpdateProfileRequest {
return new UpdateProfileRequest({
username: typeof json.username === "string" ? json.username : undefined,
nickname: typeof json.nickname === "string" ? json.nickname : undefined,
preferredLanguage:
typeof json.preferredLanguage === "string"
? json.preferredLanguage
: undefined,
currentMood:
typeof json.currentMood === "string" ? json.currentMood : undefined,
});
static fromJson(json: unknown): UpdateProfileRequest {
return UpdateProfileRequest.from(json as UpdateProfileRequestInput);
}
toJson(): UpdateProfileRequestData {
return UpdateProfileRequestSchema.parse(this);
}
}
+63 -114
View File
@@ -1,128 +1,77 @@
/**
* 用户模型 - 对应后端 UserData schema
* 原始 Dart: User (lib/data/models/user/user.dart)
*
* 注:原始 Dart 中 `email`/`personalityTraits`/`preferredLanguage`/`createdAt`/
* `lastMessageAt`/`avatarUrl` 为可空字段,按"全部非空"约定统一兜底:
* - 字符串字段 → 空串 ""
* - PersonalityTraits → 默认实例(全 0.5
*/
import { PersonalityTraits } from "./personality_traits";
import { z } from "zod";
import {
PersonalityTraits,
PersonalityTraitsSchema,
PERSONALITY_TRAITS_DEFAULTS,
} from "./personality_traits";
export const UserSchema = z.object({
id: z.string(),
username: z.string(),
email: z.string().default(""),
platform: z.string().default("web"),
intimacy: z.number().default(0),
dolBalance: z.number().default(0),
relationshipStage: z.string().default("密友"),
currentMood: z.string().default("happy"),
personalityTraits: PersonalityTraitsSchema.default(
PERSONALITY_TRAITS_DEFAULTS
),
preferredLanguage: z.string().default(""),
createdAt: z.string().default(""),
lastMessageAt: z.string().default(""),
avatarUrl: z.string().default(""),
loginProvider: z.string().default("email"),
isGuest: z.boolean().default(false),
});
export type UserInput = z.input<typeof UserSchema>;
export type UserData = z.output<typeof UserSchema>;
export class User {
readonly id: string;
readonly username: string;
readonly email: string;
readonly platform: string;
readonly intimacy: number;
readonly dolBalance: number;
readonly relationshipStage: string;
readonly currentMood: string;
readonly personalityTraits: PersonalityTraits;
readonly preferredLanguage: string;
readonly createdAt: string;
readonly lastMessageAt: string;
readonly avatarUrl: string;
readonly loginProvider: string;
readonly isGuest: boolean;
declare readonly id: string;
declare readonly username: string;
declare readonly email: string;
declare readonly platform: string;
declare readonly intimacy: number;
declare readonly dolBalance: number;
declare readonly relationshipStage: string;
declare readonly currentMood: string;
declare readonly personalityTraits: PersonalityTraits;
declare readonly preferredLanguage: string;
declare readonly createdAt: string;
declare readonly lastMessageAt: string;
declare readonly avatarUrl: string;
declare readonly loginProvider: string;
declare readonly isGuest: boolean;
constructor(params: {
id: string;
username: string;
email?: string;
platform?: string;
intimacy?: number;
dolBalance?: number;
relationshipStage?: string;
currentMood?: string;
personalityTraits?: PersonalityTraits;
preferredLanguage?: string;
createdAt?: string;
lastMessageAt?: string;
avatarUrl?: string;
loginProvider?: string;
isGuest?: boolean;
}) {
this.id = params.id;
this.username = params.username;
this.email = params.email ?? "";
this.platform = params.platform ?? "web";
this.intimacy = params.intimacy ?? 0;
this.dolBalance = params.dolBalance ?? 0;
this.relationshipStage = params.relationshipStage ?? "密友";
this.currentMood = params.currentMood ?? "happy";
this.personalityTraits = params.personalityTraits ?? new PersonalityTraits({});
this.preferredLanguage = params.preferredLanguage ?? "";
this.createdAt = params.createdAt ?? "";
this.lastMessageAt = params.lastMessageAt ?? "";
this.avatarUrl = params.avatarUrl ?? "";
this.loginProvider = params.loginProvider ?? "email";
this.isGuest = params.isGuest ?? false;
private constructor(input: UserInput) {
const data = UserSchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
toJson(): Record<string, unknown> {
return {
id: this.id,
username: this.username,
email: this.email,
platform: this.platform,
intimacy: this.intimacy,
dolBalance: this.dolBalance,
relationshipStage: this.relationshipStage,
currentMood: this.currentMood,
personalityTraits: this.personalityTraits.toJson(),
preferredLanguage: this.preferredLanguage,
createdAt: this.createdAt,
lastMessageAt: this.lastMessageAt,
avatarUrl: this.avatarUrl,
loginProvider: this.loginProvider,
isGuest: this.isGuest,
};
static from(input: UserInput): User {
return new User(input);
}
static fromJson(json: Record<string, unknown>): User {
const requireString = (key: string): string => {
const v = json[key];
if (typeof v !== "string") {
throw new Error(`User.${key} is required and must be a string`);
}
return v;
};
return new User({
id: requireString("id"),
username: requireString("username"),
email: typeof json.email === "string" ? json.email : undefined,
platform: typeof json.platform === "string" ? json.platform : undefined,
intimacy: typeof json.intimacy === "number" ? json.intimacy : undefined,
dolBalance:
typeof json.dolBalance === "number" ? json.dolBalance : undefined,
relationshipStage:
typeof json.relationshipStage === "string"
? json.relationshipStage
: undefined,
currentMood:
typeof json.currentMood === "string" ? json.currentMood : undefined,
personalityTraits: json.personalityTraits
? PersonalityTraits.fromJson(
json.personalityTraits as Record<string, unknown>
)
: undefined,
preferredLanguage:
typeof json.preferredLanguage === "string"
? json.preferredLanguage
: undefined,
createdAt:
typeof json.createdAt === "string" ? json.createdAt : undefined,
lastMessageAt:
typeof json.lastMessageAt === "string" ? json.lastMessageAt : undefined,
avatarUrl:
typeof json.avatarUrl === "string" ? json.avatarUrl : undefined,
loginProvider:
typeof json.loginProvider === "string"
? json.loginProvider
: undefined,
isGuest: typeof json.isGuest === "boolean" ? json.isGuest : undefined,
});
static fromJson(json: unknown): User {
return User.from(json as UserInput);
}
/**
* 创建一个具有空 id/username 的 User 实例,用于可选 user 字段的默认占位。
* 调用方可通过 `user.id === ""` 判定"无用户数据"。
*/
static empty(): User {
return new User({ id: "", username: "" });
}
toJson(): UserData {
return UserSchema.parse(this);
}
}
+57 -142
View File
@@ -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);
}
}