refactor(data): split models into separate dto and schema modules

Reorganize the data layer by separating DTOs (Data Transfer Objects) from
Zod validation schemas into distinct directory structures. Previously,
all model types were imported from a single `@/data/models` barrel
file, mixing request/response classes with validation schemas.

Changes:
- Update API files (auth, chat, metrics, user) to import DTOs from
  specific paths under `@/data/dto/*` instead of the models barrel
- Move user schema to `@/data/schemas/user/user` for type-only imports
- Create dedicated Zod schema files under `@/data/schemas/*` for
  auth and chat domain models (e.g., AppleLoginRequestSchema,
  SendMessageRequestSchema, SyncMessageSchema, SttDataSchema)
- Improve discoverability and tree-shaking by co-locating schemas
  with their respective domain areas

This is a non-functional refactor that lays the groundwork for
clearer separation between transport-layer types and runtime
validation.
This commit is contained in:
2026-06-08 19:14:40 +08:00
parent 67a72783fe
commit 75e685d418
89 changed files with 1119 additions and 853 deletions
+15 -17
View File
@@ -6,23 +6,21 @@
*/
import { httpClient } from "./http_client";
import { ApiPath } from "./api_path";
import {
AppleLoginRequest,
FacebookLoginRequest,
FbIdLoginRequest,
GoogleLoginRequest,
GuestLoginRequest,
GuestLoginResponse,
LoginRequest,
LoginResponse,
LogoutResponse,
RefreshTokenRequest,
RefreshTokenResponse,
RegisterRequest,
SendCodeRequest,
User,
type UserData,
} from "@/data/models";
import { AppleLoginRequest } from "@/data/dto/auth/apple_login_request";
import { FacebookLoginRequest } from "@/data/dto/auth/facebook_login_request";
import { FbIdLoginRequest } from "@/data/dto/auth/fb_id_login_request";
import { GoogleLoginRequest } from "@/data/dto/auth/google_login_request";
import { GuestLoginRequest } from "@/data/dto/auth/guest_login_request";
import { GuestLoginResponse } from "@/data/dto/auth/guest_login_response";
import { LoginRequest } from "@/data/dto/auth/login_request";
import { LoginResponse } from "@/data/dto/auth/login_response";
import { LogoutResponse } from "@/data/dto/auth/logout_response";
import { RefreshTokenRequest } from "@/data/dto/auth/refresh_token_request";
import { RefreshTokenResponse } from "@/data/dto/auth/refresh_token_response";
import { RegisterRequest } from "@/data/dto/auth/register_request";
import { SendCodeRequest } from "@/data/dto/auth/send_code_request";
import { User } from "@/data/dto/user/user";
import type { UserData } from "@/data/schemas/user/user";
/**
* 后端统一响应包装
+9 -13
View File
@@ -6,16 +6,14 @@
*/
import { httpClient } from "./http_client";
import { ApiPath } from "./api_path";
import {
ChatHistoryResponse,
ChatSendResponse,
ChatSyncData,
ChatSyncRequest,
ImageUploadResponse,
SendMessageRequest,
SttData,
SyncMessage,
} from "@/data/models";
import { ChatHistoryResponse } from "@/data/dto/chat/chat_history_response";
import { ChatSendResponse } from "@/data/dto/chat/chat_send_response";
import { ChatSyncData } from "@/data/dto/chat/chat_sync_data";
import { ChatSyncRequest } from "@/data/dto/chat/chat_sync_request";
import { ImageUploadResponse } from "@/data/dto/chat/image_upload_response";
import { SendMessageRequest } from "@/data/dto/chat/send_message_request";
import { SttData } from "@/data/dto/chat/stt_data";
import { SyncMessage } from "@/data/dto/chat/sync_message";
/**
* 后端统一响应包装
@@ -74,9 +72,7 @@ export class ChatApi {
/**
* 同步游客消息
*/
async syncMessages(
messages: SyncMessage[]
): Promise<ChatSyncData> {
async syncMessages(messages: SyncMessage[]): Promise<ChatSyncData> {
const body = ChatSyncRequest.from({ messages });
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.chatSync, {
method: "POST",
+2 -1
View File
@@ -6,7 +6,8 @@
*/
import { httpClient } from "./http_client";
import { ApiPath } from "./api_path";
import { AppEvent, PwaEvent } from "@/data/models";
import { AppEvent } from "@/data/dto/metrics/app_event";
import { PwaEvent } from "@/data/dto/metrics/pwa_event";
/**
* 后端统一响应包装
+6 -8
View File
@@ -6,14 +6,12 @@
*/
import { httpClient } from "./http_client";
import { ApiPath } from "./api_path";
import {
CreditsData,
CreditsHistoryData,
UpdateProfileRequest,
User,
UserStatsResponse,
type UserData,
} from "@/data/models";
import { CreditsData } from "@/data/dto/user/credits_data";
import { CreditsHistoryData } from "@/data/dto/user/credits_history_data";
import { UpdateProfileRequest } from "@/data/dto/user/update_profile_request";
import { User } from "@/data/dto/user/user";
import { UserStatsResponse } from "@/data/dto/user/user_stats_response";
import type { UserData } from "@/data/schemas/user/user";
/**
* 后端统一响应包装
@@ -1,16 +1,11 @@
/**
* Apple
* Dart: AppleLoginRequest (lib/data/models/auth/auth_request.dart)
* Apple DTO
*/
import { z } from "zod";
export const AppleLoginRequestSchema = z.object({
identityToken: z.string(),
platform: z.string(),
});
export type AppleLoginRequestInput = z.input<typeof AppleLoginRequestSchema>;
export type AppleLoginRequestData = z.output<typeof AppleLoginRequestSchema>;
import {
AppleLoginRequestSchema,
type AppleLoginRequestInput,
type AppleLoginRequestData,
} from "@/data/schemas/auth/apple_login_request";
export class AppleLoginRequest {
declare readonly identityToken: string;
@@ -1,17 +1,11 @@
/**
* Facebook
* Dart: FacebookLoginRequest (lib/data/models/auth/auth_request.dart)
* Facebook DTO
*/
import { z } from "zod";
export const FacebookLoginRequestSchema = z.object({
accessToken: z.string(),
platform: z.string(),
guestId: z.string().default(""),
});
export type FacebookLoginRequestInput = z.input<typeof FacebookLoginRequestSchema>;
export type FacebookLoginRequestData = z.output<typeof FacebookLoginRequestSchema>;
import {
FacebookLoginRequestSchema,
type FacebookLoginRequestInput,
type FacebookLoginRequestData,
} from "@/data/schemas/auth/facebook_login_request";
export class FacebookLoginRequest {
declare readonly accessToken: string;
@@ -1,16 +1,11 @@
/**
* Facebook ID
* Dart: FbIdLoginRequest (lib/data/models/auth/auth_request.dart)
* Facebook ID DTO
*/
import { z } from "zod";
export const FbIdLoginRequestSchema = z.object({
fbId: z.string(),
avatarUrl: z.string().default(""),
});
export type FbIdLoginRequestInput = z.input<typeof FbIdLoginRequestSchema>;
export type FbIdLoginRequestData = z.output<typeof FbIdLoginRequestSchema>;
import {
FbIdLoginRequestSchema,
type FbIdLoginRequestInput,
type FbIdLoginRequestData,
} from "@/data/schemas/auth/fb_id_login_request";
export class FbIdLoginRequest {
declare readonly fbId: string;
@@ -1,17 +1,11 @@
/**
* Google
* Dart: GoogleLoginRequest (lib/data/models/auth/auth_request.dart)
* Google DTO
*/
import { z } from "zod";
export const GoogleLoginRequestSchema = z.object({
idToken: z.string(),
platform: z.string(),
guestId: z.string().default(""),
});
export type GoogleLoginRequestInput = z.input<typeof GoogleLoginRequestSchema>;
export type GoogleLoginRequestData = z.output<typeof GoogleLoginRequestSchema>;
import {
GoogleLoginRequestSchema,
type GoogleLoginRequestInput,
type GoogleLoginRequestData,
} from "@/data/schemas/auth/google_login_request";
export class GoogleLoginRequest {
declare readonly idToken: string;
@@ -1,15 +1,11 @@
/**
*
* Dart: GuestLoginRequest (lib/data/models/auth/auth_request.dart)
* DTO
*/
import { z } from "zod";
export const GuestLoginRequestSchema = z.object({
deviceId: z.string(),
});
export type GuestLoginRequestInput = z.input<typeof GuestLoginRequestSchema>;
export type GuestLoginRequestData = z.output<typeof GuestLoginRequestSchema>;
import {
GuestLoginRequestSchema,
type GuestLoginRequestInput,
type GuestLoginRequestData,
} from "@/data/schemas/auth/guest_login_request";
export class GuestLoginRequest {
declare readonly deviceId: string;
+40
View File
@@ -0,0 +1,40 @@
/**
* 游客登录响应 DTO
*/
import {
GuestLoginResponseSchema,
type GuestLoginResponseInput,
type GuestLoginResponseData,
} from "@/data/schemas/auth/guest_login_response";
import { User } from "@/data/dto/user/user";
export class GuestLoginResponse {
declare readonly token: string;
declare readonly deviceId: string;
declare readonly userId: string;
declare readonly isDeviceUser: boolean;
declare readonly expiresIn: number;
declare readonly user: User;
private constructor(input: GuestLoginResponseInput) {
const parsed = GuestLoginResponseSchema.parse(input);
Object.assign(this, {
...parsed,
user: parsed.user ? User.fromJson(parsed.user) : User.empty(),
});
Object.freeze(this);
}
static from(input: GuestLoginResponseInput): GuestLoginResponse {
return new GuestLoginResponse(input);
}
static fromJson(json: unknown): GuestLoginResponse {
return GuestLoginResponse.from(json as GuestLoginResponseInput);
}
toJson(): GuestLoginResponseData {
const data = GuestLoginResponseSchema.parse(this);
return data;
}
}
@@ -1,19 +1,11 @@
/**
* -
* Dart: LoginRequest (lib/data/models/auth/auth_request.dart)
* DTO
*/
import { z } from "zod";
export const LoginRequestSchema = z.object({
email: z.string().default(""),
username: z.string().default(""),
password: z.string(),
platform: z.string(),
guestId: z.string().default(""),
});
export type LoginRequestInput = z.input<typeof LoginRequestSchema>;
export type LoginRequestData = z.output<typeof LoginRequestSchema>;
import {
LoginRequestSchema,
type LoginRequestInput,
type LoginRequestData,
} from "@/data/schemas/auth/login_request";
export class LoginRequest {
declare readonly email: string;
@@ -1,18 +1,12 @@
/**
*
* Dart: LoginResponse (lib/data/models/auth/auth_response.dart)
* DTO
*/
import { z } from "zod";
import { User, UserSchema } from "../user/user";
export const LoginResponseSchema = z.object({
user: UserSchema,
token: z.string(),
refreshToken: z.string().default(""),
});
export type LoginResponseInput = z.input<typeof LoginResponseSchema>;
export type LoginResponseData = z.output<typeof LoginResponseSchema>;
import {
LoginResponseSchema,
type LoginResponseInput,
type LoginResponseData,
} from "@/data/schemas/auth/login_response";
import { User } from "@/data/dto/user/user";
export class LoginResponse {
declare readonly user: User;
@@ -21,7 +15,10 @@ export class LoginResponse {
private constructor(input: LoginResponseInput) {
const data = LoginResponseSchema.parse(input);
Object.assign(this, data);
Object.assign(this, {
...data,
user: User.fromJson(data.user),
});
Object.freeze(this);
}
@@ -1,15 +1,11 @@
/**
* 退
* Dart: LogoutResponse (lib/data/models/auth/auth_response.dart)
* 退 DTO
*/
import { z } from "zod";
export const LogoutResponseSchema = z.object({
success: z.boolean().default(true),
});
export type LogoutResponseInput = z.input<typeof LogoutResponseSchema>;
export type LogoutResponseData = z.output<typeof LogoutResponseSchema>;
import {
LogoutResponseSchema,
type LogoutResponseInput,
type LogoutResponseData,
} from "@/data/schemas/auth/logout_response";
export class LogoutResponse {
declare readonly success: boolean;
@@ -1,15 +1,11 @@
/**
* Token
* Dart: RefreshTokenRequest (lib/data/models/auth/auth_request.dart)
* Token DTO
*/
import { z } from "zod";
export const RefreshTokenRequestSchema = z.object({
refreshToken: z.string(),
});
export type RefreshTokenRequestInput = z.input<typeof RefreshTokenRequestSchema>;
export type RefreshTokenRequestData = z.output<typeof RefreshTokenRequestSchema>;
import {
RefreshTokenRequestSchema,
type RefreshTokenRequestInput,
type RefreshTokenRequestData,
} from "@/data/schemas/auth/refresh_token_request";
export class RefreshTokenRequest {
declare readonly refreshToken: string;
@@ -1,17 +1,11 @@
/**
* Token
* Dart: RefreshTokenResponse (lib/data/models/auth/auth_response.dart)
* Token DTO
*/
import { z } from "zod";
export const RefreshTokenResponseSchema = z.object({
token: z.string(),
refreshToken: z.string(),
userId: z.string(),
});
export type RefreshTokenResponseInput = z.input<typeof RefreshTokenResponseSchema>;
export type RefreshTokenResponseData = z.output<typeof RefreshTokenResponseSchema>;
import {
RefreshTokenResponseSchema,
type RefreshTokenResponseInput,
type RefreshTokenResponseData,
} from "@/data/schemas/auth/refresh_token_response";
export class RefreshTokenResponse {
declare readonly token: string;
@@ -1,19 +1,11 @@
/**
*
* Dart: RegisterRequest (lib/data/models/auth/auth_request.dart)
* DTO
*/
import { z } from "zod";
export const RegisterRequestSchema = z.object({
username: z.string(),
email: z.string(),
password: z.string(),
platform: z.string(),
guestId: z.string().default(""),
});
export type RegisterRequestInput = z.input<typeof RegisterRequestSchema>;
export type RegisterRequestData = z.output<typeof RegisterRequestSchema>;
import {
RegisterRequestSchema,
type RegisterRequestInput,
type RegisterRequestData,
} from "@/data/schemas/auth/register_request";
export class RegisterRequest {
declare readonly username: string;
@@ -1,15 +1,11 @@
/**
*
* Dart: SendCodeRequest (lib/data/models/auth/auth_request.dart)
* DTO
*/
import { z } from "zod";
export const SendCodeRequestSchema = z.object({
email: z.string(),
});
export type SendCodeRequestInput = z.input<typeof SendCodeRequestSchema>;
export type SendCodeRequestData = z.output<typeof SendCodeRequestSchema>;
import {
SendCodeRequestSchema,
type SendCodeRequestInput,
type SendCodeRequestData,
} from "@/data/schemas/auth/send_code_request";
export class SendCodeRequest {
declare readonly email: string;
@@ -1,19 +1,12 @@
/**
*
* Dart: ChatHistoryResponse (lib/data/models/chat/chat_response.dart)
* DTO
*/
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>;
import {
ChatHistoryResponseSchema,
type ChatHistoryResponseInput,
type ChatHistoryResponseData,
} from "@/data/schemas/chat/chat_history_response";
import { ChatMessage } from "./chat_message";
export class ChatHistoryResponse {
declare readonly messages: ChatMessage[];
@@ -23,7 +16,10 @@ export class ChatHistoryResponse {
private constructor(input: ChatHistoryResponseInput) {
const data = ChatHistoryResponseSchema.parse(input);
Object.assign(this, data);
Object.assign(this, {
...data,
messages: data.messages.map((m) => ChatMessage.from(m)),
});
Object.freeze(this);
}
@@ -1,18 +1,11 @@
/**
*
* Dart: ChatMessage (lib/data/models/chat/chat_response.dart)
* DTO
*/
import { z } from "zod";
export const ChatMessageSchema = z.object({
role: z.string(),
content: z.string(),
id: z.string().default(""),
createdAt: z.string().default(""),
});
export type ChatMessageInput = z.input<typeof ChatMessageSchema>;
export type ChatMessageData = z.output<typeof ChatMessageSchema>;
import {
ChatMessageSchema,
type ChatMessageInput,
type ChatMessageData,
} from "@/data/schemas/chat/chat_message";
export class ChatMessage {
declare readonly role: string;
@@ -1,32 +1,18 @@
/**
*
* Dart: ChatSendResponse (lib/data/models/chat/chat_response.dart)
* DTO
*/
import { z } from "zod";
export const ChatSendResponseSchema = z.object({
mode: z.string().default(""),
reply: z.string(),
voiceUrl: z.string().default(""),
audioUrl: z.string().default(""),
intimacyChange: z.number().default(0),
newIntimacy: z.number().default(0),
relationshipStage: z.string(),
currentMood: z.string().default(""),
messageId: z.string(),
isGuest: z.boolean().default(false),
timestamp: z.number().default(0),
});
export type ChatSendResponseInput = z.input<typeof ChatSendResponseSchema>;
export type ChatSendResponseData = z.output<typeof ChatSendResponseSchema>;
import {
ChatSendResponseSchema,
type ChatSendResponseInput,
type ChatSendResponseData,
} from "@/data/schemas/chat/chat_send_response";
export class ChatSendResponse {
declare readonly mode: string;
declare readonly reply: string;
declare readonly voiceUrl: string;
declare readonly audioUrl: string;
declare readonly intimacyChange: number;
declare readonly intimidadChange: number;
declare readonly newIntimacy: number;
declare readonly relationshipStage: string;
declare readonly currentMood: string;
@@ -1,16 +1,11 @@
/**
*
* Dart: ChatSyncData (lib/data/models/chat/chat_sync.dart)
* DTO
*/
import { z } from "zod";
export const ChatSyncDataSchema = z.object({
syncedCount: z.number(),
totalHistory: z.number(),
});
export type ChatSyncDataInput = z.input<typeof ChatSyncDataSchema>;
export type ChatSyncDataData = z.output<typeof ChatSyncDataSchema>;
import {
ChatSyncDataSchema,
type ChatSyncDataInput,
type ChatSyncDataData,
} from "@/data/schemas/chat/chat_sync_data";
export class ChatSyncData {
declare readonly syncedCount: number;
@@ -1,23 +1,22 @@
/**
*
* Dart: ChatSyncRequest (lib/data/models/chat/chat_sync.dart)
* DTO
*/
import { z } from "zod";
import { SyncMessage, SyncMessageSchema } from "./sync_message";
export const ChatSyncRequestSchema = z.object({
messages: z.array(SyncMessageSchema),
});
export type ChatSyncRequestInput = z.input<typeof ChatSyncRequestSchema>;
export type ChatSyncRequestData = z.output<typeof ChatSyncRequestSchema>;
import {
ChatSyncRequestSchema,
type ChatSyncRequestInput,
type ChatSyncRequestData,
} from "@/data/schemas/chat/chat_sync_request";
import { SyncMessage } from "./sync_message";
export class ChatSyncRequest {
declare readonly messages: SyncMessage[];
private constructor(input: ChatSyncRequestInput) {
const data = ChatSyncRequestSchema.parse(input);
Object.assign(this, data);
Object.assign(this, {
...data,
messages: data.messages.map((m) => SyncMessage.from(m)),
});
Object.freeze(this);
}
@@ -1,25 +1,13 @@
/**
*
* Dart: GuestChatQuota (lib/data/models/chat/guest_chat_quota.dart)
*
* Dart
* `process.env.NODE_ENV` Dart `AppEnvUtil.isDevelopment`
* `initial()` `needReset`
* DTO
*/
import { z } from "zod";
export const GuestChatQuotaSchema = z.object({
remaining: z.number(),
date: z.string(),
});
export type GuestChatQuotaInput = z.input<typeof GuestChatQuotaSchema>;
export type GuestChatQuotaData = z.output<typeof GuestChatQuotaSchema>;
import {
GuestChatQuotaSchema,
type GuestChatQuotaInput,
type GuestChatQuotaData,
} from "@/data/schemas/chat/guest_chat_quota";
export class GuestChatQuota {
declare readonly remaining: number;
declare readonly date: string;
// 静态常量
static readonly maxQuotaPerDay = 40;
static readonly maxQuotaPerDayTest = 4;
@@ -29,6 +17,9 @@ export class GuestChatQuota {
static readonly defaultTotalQuotaDev = 5;
static readonly quotaExhausted = 0;
declare readonly remaining: number;
declare readonly date: string;
private constructor(input: GuestChatQuotaInput) {
const data = GuestChatQuotaSchema.parse(input);
Object.assign(this, data);
@@ -43,12 +34,8 @@ export class GuestChatQuota {
return GuestChatQuota.from(json as GuestChatQuotaInput);
}
toJson(): GuestChatQuotaData {
return GuestChatQuotaSchema.parse(this);
}
/**
* 便
*
*/
static get exhausted(): number {
return GuestChatQuota.quotaExhausted;
@@ -56,7 +43,6 @@ export class GuestChatQuota {
/**
*
* `process.env.NODE_ENV` Dart `AppEnvUtil.isDevelopment`
*/
static get isDevelopment(): boolean {
return process.env.NODE_ENV !== "production";
@@ -91,7 +77,6 @@ export class GuestChatQuota {
/**
*
* @param todayString YYYY-MM-DD
*/
static initial(todayString: string): GuestChatQuota {
return new GuestChatQuota({
@@ -102,9 +87,12 @@ export class GuestChatQuota {
/**
*
* @param todayString YYYY-MM-DD
*/
needsReset(todayString: string): boolean {
return this.date !== todayString;
}
toJson(): GuestChatQuotaData {
return GuestChatQuotaSchema.parse(this);
}
}
@@ -1,22 +1,11 @@
/**
*
* Dart: ImageUploadResponse (lib/data/models/chat/image_upload_response.dart)
* DTO
*/
import { z } from "zod";
export const ImageUploadResponseSchema = z.object({
success: z.boolean().default(true),
imageId: z.string(),
thumbUrl: z.string(),
mediumUrl: z.string(),
originalUrl: z.string(),
width: z.number(),
height: z.number(),
bytes: z.number(),
});
export type ImageUploadResponseInput = z.input<typeof ImageUploadResponseSchema>;
export type ImageUploadResponseData = z.output<typeof ImageUploadResponseSchema>;
import {
ImageUploadResponseSchema,
type ImageUploadResponseInput,
type ImageUploadResponseData,
} from "@/data/schemas/chat/image_upload_response";
export class ImageUploadResponse {
declare readonly success: boolean;
@@ -1,23 +1,11 @@
/**
* - /api/chat/send
* Dart: SendMessageRequest (lib/data/models/chat/send_message_request.dart)
* DTO
*/
import { z } from "zod";
export const SendMessageRequestSchema = z.object({
message: z.string().default(""),
image: z.string().default(""),
imageId: z.string().default(""),
imageThumbUrl: z.string().default(""),
imageMediumUrl: z.string().default(""),
imageOriginalUrl: z.string().default(""),
imageWidth: z.number().default(0),
imageHeight: z.number().default(0),
useWebSocket: z.boolean().default(false),
});
export type SendMessageRequestInput = z.input<typeof SendMessageRequestSchema>;
export type SendMessageRequestData = z.output<typeof SendMessageRequestSchema>;
import {
SendMessageRequestSchema,
type SendMessageRequestInput,
type SendMessageRequestData,
} from "@/data/schemas/chat/send_message_request";
export class SendMessageRequest {
declare readonly message: string;
@@ -1,15 +1,11 @@
/**
* STT
* Dart: SttData (lib/data/models/chat/stt_response.dart)
* STT DTO
*/
import { z } from "zod";
export const SttDataSchema = z.object({
text: z.string(),
});
export type SttDataInput = z.input<typeof SttDataSchema>;
export type SttDataData = z.output<typeof SttDataSchema>;
import {
SttDataSchema,
type SttDataInput,
type SttDataData,
} from "@/data/schemas/chat/stt_data";
export class SttData {
declare readonly text: string;
@@ -1,17 +1,11 @@
/**
*
* Dart: SyncMessage (lib/data/models/chat/chat_sync.dart)
* DTO
*/
import { z } from "zod";
export const SyncMessageSchema = z.object({
role: z.string(),
content: z.string(),
timestamp: z.string(),
});
export type SyncMessageInput = z.input<typeof SyncMessageSchema>;
export type SyncMessageData = z.output<typeof SyncMessageSchema>;
import {
SyncMessageSchema,
type SyncMessageInput,
type SyncMessageData,
} from "@/data/schemas/chat/sync_message";
export class SyncMessage {
declare readonly role: string;
@@ -1,7 +1,9 @@
/**
* @file Automatically generated by barrelsby.
* DTO -
*
* API 使
* Dart: lib/data/models/
*/
export * from "./auth/apple_login_request";
export * from "./auth/facebook_login_request";
export * from "./auth/fb_id_login_request";
@@ -15,6 +17,7 @@ export * from "./auth/refresh_token_request";
export * from "./auth/refresh_token_response";
export * from "./auth/register_request";
export * from "./auth/send_code_request";
export * from "./chat/chat_history_response";
export * from "./chat/chat_message";
export * from "./chat/chat_send_response";
@@ -25,8 +28,10 @@ export * from "./chat/image_upload_response";
export * from "./chat/send_message_request";
export * from "./chat/stt_data";
export * from "./chat/sync_message";
export * from "./metrics/app_event";
export * from "./metrics/pwa_event";
export * from "./user/avatar_data";
export * from "./user/credits_data";
export * from "./user/credits_history_data";
@@ -1,17 +1,11 @@
/**
* - /api/data/report-user-info
* Dart: AppEvent (lib/data/models/metrics/app_event.dart)
* DTO
*/
import { z } from "zod";
export const AppEventSchema = z.object({
userId: z.string(),
browser: z.string(),
userAgent: z.string(),
});
export type AppEventInput = z.input<typeof AppEventSchema>;
export type AppEventData = z.output<typeof AppEventSchema>;
import {
AppEventSchema,
type AppEventInput,
type AppEventData,
} from "@/data/schemas/metrics/app_event";
export class AppEvent {
declare readonly userId: string;
@@ -1,19 +1,11 @@
/**
* PWA - /api/metrics/pwa/event
* Dart: PwaEvent (lib/data/models/metrics/pwa_event.dart)
* PWA DTO
*/
import { z } from "zod";
export const PwaEventSchema = z.object({
deviceId: z.string(),
deviceType: z.string(),
timestamp: z.number(),
pwaInstalled: z.boolean().default(false),
pwaSupported: z.boolean().default(false),
});
export type PwaEventInput = z.input<typeof PwaEventSchema>;
export type PwaEventData = z.output<typeof PwaEventSchema>;
import {
PwaEventSchema,
type PwaEventInput,
type PwaEventData,
} from "@/data/schemas/metrics/pwa_event";
export class PwaEvent {
declare readonly deviceId: string;
+31
View File
@@ -0,0 +1,31 @@
/**
* 头像数据 DTO
*/
import {
AvatarDataSchema,
type AvatarDataInput,
type AvatarDataData,
} from "@/data/schemas/user/avatar_data";
export class AvatarData {
declare readonly avatarUrl: string;
declare readonly userId: string;
private constructor(input: AvatarDataInput) {
const data = AvatarDataSchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
static from(input: AvatarDataInput): AvatarData {
return new AvatarData(input);
}
static fromJson(json: unknown): AvatarData {
return AvatarData.from(json as AvatarDataInput);
}
toJson(): AvatarDataData {
return AvatarDataSchema.parse(this);
}
}
+31
View File
@@ -0,0 +1,31 @@
/**
* 积分数据 DTO
*/
import {
CreditsDataSchema,
type CreditsDataInput,
type CreditsDataData,
} from "@/data/schemas/user/credits_data";
export class CreditsData {
declare readonly userId: string;
declare readonly dolBalance: number;
private constructor(input: CreditsDataInput) {
const data = CreditsDataSchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
static from(input: CreditsDataInput): CreditsData {
return new CreditsData(input);
}
static fromJson(json: unknown): CreditsData {
return CreditsData.from(json as CreditsDataInput);
}
toJson(): CreditsDataData {
return CreditsDataSchema.parse(this);
}
}
+33
View File
@@ -0,0 +1,33 @@
/**
* 积分历史记录 DTO
*/
import {
CreditsHistoryDataSchema,
type CreditsHistoryDataInput,
type CreditsHistoryDataData,
} from "@/data/schemas/user/credits_history_data";
export class CreditsHistoryData {
declare readonly records: Record<string, unknown>[];
declare readonly total: number;
declare readonly limit: number;
declare readonly offset: number;
private constructor(input: CreditsHistoryDataInput) {
const data = CreditsHistoryDataSchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
static from(input: CreditsHistoryDataInput): CreditsHistoryData {
return new CreditsHistoryData(input);
}
static fromJson(json: unknown): CreditsHistoryData {
return CreditsHistoryData.from(json as CreditsHistoryDataInput);
}
toJson(): CreditsHistoryDataData {
return CreditsHistoryDataSchema.parse(this);
}
}
+34
View File
@@ -0,0 +1,34 @@
/**
* 个性特征 DTO
*/
import {
PersonalityTraitsSchema,
type PersonalityTraitsInput,
type PersonalityTraitsData,
} from "@/data/schemas/user/personality_traits";
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(input: PersonalityTraitsInput) {
const data = PersonalityTraitsSchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
static from(input: PersonalityTraitsInput): PersonalityTraits {
return new PersonalityTraits(input);
}
static fromJson(json: unknown): PersonalityTraits {
return PersonalityTraits.from(json as PersonalityTraitsInput);
}
toJson(): PersonalityTraitsData {
return PersonalityTraitsSchema.parse(this);
}
}
+33
View File
@@ -0,0 +1,33 @@
/**
* 最近记忆 DTO
*/
import {
RecentMemorySchema,
type RecentMemoryInput,
type RecentMemoryData,
} from "@/data/schemas/user/recent_memory";
export class RecentMemory {
declare readonly type: string;
declare readonly content: string;
declare readonly importance: number;
declare readonly createdAt: string;
private constructor(input: RecentMemoryInput) {
const data = RecentMemorySchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
static from(input: RecentMemoryInput): RecentMemory {
return new RecentMemory(input);
}
static fromJson(json: unknown): RecentMemory {
return RecentMemory.from(json as RecentMemoryInput);
}
toJson(): RecentMemoryData {
return RecentMemorySchema.parse(this);
}
}
@@ -0,0 +1,33 @@
/**
* 更新个人资料请求 DTO
*/
import {
UpdateProfileRequestSchema,
type UpdateProfileRequestInput,
type UpdateProfileRequestData,
} from "@/data/schemas/user/update_profile_request";
export class UpdateProfileRequest {
declare readonly username: string;
declare readonly nickname: string;
declare readonly preferredLanguage: string;
declare readonly currentMood: string;
private constructor(input: UpdateProfileRequestInput) {
const data = UpdateProfileRequestSchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
static from(input: UpdateProfileRequestInput): UpdateProfileRequest {
return new UpdateProfileRequest(input);
}
static fromJson(json: unknown): UpdateProfileRequest {
return UpdateProfileRequest.from(json as UpdateProfileRequestInput);
}
toJson(): UpdateProfileRequestData {
return UpdateProfileRequestSchema.parse(this);
}
}
+59
View File
@@ -0,0 +1,59 @@
/**
* 用户 DTO
*/
import {
UserSchema,
type UserInput,
type UserData,
} from "@/data/schemas/user/user";
import { PersonalityTraits } from "./personality_traits";
export class User {
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;
private constructor(input: UserInput) {
const data = UserSchema.parse(input);
Object.assign(this, {
...data,
personalityTraits: PersonalityTraits.from(data.personalityTraits),
});
Object.freeze(this);
}
static from(input: UserInput): User {
return new User(input);
}
static fromJson(json: unknown): User {
return User.from(json as UserInput);
}
/**
* 创建一个具有空 id/username 的 User 实例(用于可选 user 字段的默认占位)
*/
static empty(): User {
return new User({ id: "", username: "" });
}
toJson(): UserData {
const { personalityTraits, ...rest } = this;
return {
...rest,
personalityTraits: personalityTraits.toJson(),
};
}
}
+51
View File
@@ -0,0 +1,51 @@
/**
* 用户统计响应 DTO
*/
import {
UserStatsResponseSchema,
type UserStatsResponseInput,
type UserStatsResponseData,
} from "@/data/schemas/user/user_stats_response";
import { PersonalityTraits } from "./personality_traits";
import { RecentMemory } from "./recent_memory";
export class UserStatsResponse {
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;
private constructor(input: UserStatsResponseInput) {
const data = UserStatsResponseSchema.parse(input);
Object.assign(this, {
...data,
personalityTraits: PersonalityTraits.from(data.personalityTraits),
recentMemories: data.recentMemories.map((m) => RecentMemory.from(m)),
});
Object.freeze(this);
}
static from(input: UserStatsResponseInput): UserStatsResponse {
return new UserStatsResponse(input);
}
static fromJson(json: unknown): UserStatsResponse {
return UserStatsResponse.from(json as UserStatsResponseInput);
}
toJson(): UserStatsResponseData {
return UserStatsResponseSchema.parse(this);
}
}
@@ -1,52 +0,0 @@
/**
* 游客登录响应
* 原始 Dart: GuestLoginResponse (lib/data/models/auth/auth_response.dart)
*/
import { z } from "zod";
import { User, UserSchema } from "../user/user";
export const GuestLoginResponseSchema = z.object({
token: z.string(),
deviceId: z.string(),
userId: z.string(),
isDeviceUser: z.boolean().default(true),
expiresIn: z.number().default(2592000),
user: UserSchema.optional(),
});
export type GuestLoginResponseInput = z.input<typeof GuestLoginResponseSchema>;
export type GuestLoginResponseData = z.output<typeof GuestLoginResponseSchema>;
export class GuestLoginResponse {
declare readonly token: string;
declare readonly deviceId: string;
declare readonly userId: string;
declare readonly isDeviceUser: boolean;
declare readonly expiresIn: number;
declare readonly user: User;
private constructor(data: GuestLoginResponseData) {
Object.assign(this, data);
Object.freeze(this);
}
static from(input: GuestLoginResponseInput): GuestLoginResponse {
const parsed = GuestLoginResponseSchema.parse(input);
return new GuestLoginResponse({
...parsed,
user: parsed.user ?? User.empty(),
});
}
static fromJson(json: unknown): GuestLoginResponse {
return GuestLoginResponse.from(json as GuestLoginResponseInput);
}
toJson(): GuestLoginResponseData {
const { user, ...rest } = this;
return GuestLoginResponseSchema.parse({
...rest,
...(user.id !== "" ? { user } : {}),
});
}
}
-17
View File
@@ -1,17 +0,0 @@
/**
* @file Automatically generated by barrelsby.
*/
export * from "./apple_login_request";
export * from "./facebook_login_request";
export * from "./fb_id_login_request";
export * from "./google_login_request";
export * from "./guest_login_request";
export * from "./guest_login_response";
export * from "./login_request";
export * from "./login_response";
export * from "./logout_response";
export * from "./refresh_token_request";
export * from "./refresh_token_response";
export * from "./register_request";
export * from "./send_code_request";
-14
View File
@@ -1,14 +0,0 @@
/**
* @file Automatically generated by barrelsby.
*/
export * from "./chat_history_response";
export * from "./chat_message";
export * from "./chat_send_response";
export * from "./chat_sync_data";
export * from "./chat_sync_request";
export * from "./guest_chat_quota";
export * from "./image_upload_response";
export * from "./send_message_request";
export * from "./stt_data";
export * from "./sync_message";
-6
View File
@@ -1,6 +0,0 @@
/**
* @file Automatically generated by barrelsby.
*/
export * from "./app_event";
export * from "./pwa_event";
-35
View File
@@ -1,35 +0,0 @@
/**
* 头像数据模型 - 对应后端 AvatarData schema
* 原始 Dart: AvatarData (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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);
}
static from(input: AvatarDataInput): AvatarData {
return new AvatarData(AvatarDataSchema.parse(input));
}
static fromJson(json: unknown): AvatarData {
return AvatarData.from(json as AvatarDataInput);
}
toJson(): AvatarDataData {
return AvatarDataSchema.parse(this);
}
}
-35
View File
@@ -1,35 +0,0 @@
/**
* 积分数据模型 - 对应后端 CreditsData schema
* 原始 Dart: CreditsData (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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);
}
static from(input: CreditsDataInput): CreditsData {
return new CreditsData(CreditsDataSchema.parse(input));
}
static fromJson(json: unknown): CreditsData {
return CreditsData.from(json as CreditsDataInput);
}
toJson(): CreditsDataData {
return CreditsDataSchema.parse(this);
}
}
@@ -1,39 +0,0 @@
/**
* 积分历史记录模型 - 对应后端 CreditsHistoryData schema
* 原始 Dart: CreditsHistoryData (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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);
}
static from(input: CreditsHistoryDataInput): CreditsHistoryData {
return new CreditsHistoryData(CreditsHistoryDataSchema.parse(input));
}
static fromJson(json: unknown): CreditsHistoryData {
return CreditsHistoryData.from(json as CreditsHistoryDataInput);
}
toJson(): CreditsHistoryDataData {
return CreditsHistoryDataSchema.parse(this);
}
}
-12
View File
@@ -1,12 +0,0 @@
/**
* @file Automatically generated by barrelsby.
*/
export * from "./avatar_data";
export * from "./credits_data";
export * from "./credits_history_data";
export * from "./personality_traits";
export * from "./recent_memory";
export * from "./update_profile_request";
export * from "./user";
export * from "./user_stats_response";
@@ -1,49 +0,0 @@
/**
* 个性特征模型
* 原始 Dart: PersonalityTraits (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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);
}
static from(input: PersonalityTraitsInput): PersonalityTraits {
return new PersonalityTraits(PersonalityTraitsSchema.parse(input));
}
static fromJson(json: unknown): PersonalityTraits {
return PersonalityTraits.from(json as PersonalityTraitsInput);
}
toJson(): PersonalityTraitsData {
return PersonalityTraitsSchema.parse(this);
}
}
-39
View File
@@ -1,39 +0,0 @@
/**
* 最近记忆模型
* 原始 Dart: RecentMemory (lib/data/models/user/recent_memory.dart)
*/
import { z } from "zod";
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);
}
static from(input: RecentMemoryInput): RecentMemory {
return new RecentMemory(RecentMemorySchema.parse(input));
}
static fromJson(json: unknown): RecentMemory {
return RecentMemory.from(json as RecentMemoryInput);
}
toJson(): RecentMemoryData {
return RecentMemorySchema.parse(this);
}
}
@@ -1,39 +0,0 @@
/**
* 更新个人资料请求
* 原始 Dart: UpdateProfileRequest (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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);
}
static from(input: UpdateProfileRequestInput): UpdateProfileRequest {
return new UpdateProfileRequest(UpdateProfileRequestSchema.parse(input));
}
static fromJson(json: unknown): UpdateProfileRequest {
return UpdateProfileRequest.from(json as UpdateProfileRequestInput);
}
toJson(): UpdateProfileRequestData {
return UpdateProfileRequestSchema.parse(this);
}
}
-77
View File
@@ -1,77 +0,0 @@
/**
* 用户模型 - 对应后端 UserData schema
* 原始 Dart: User (lib/data/models/user/user.dart)
*/
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 {
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;
private constructor(input: UserInput) {
const data = UserSchema.parse(input);
Object.assign(this, data);
Object.freeze(this);
}
static from(input: UserInput): User {
return new User(input);
}
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);
}
}
@@ -1,71 +0,0 @@
/**
* 用户统计响应
* 原始 Dart: UserStatsResponse (lib/data/models/user/user_stats_response.dart)
*/
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 {
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;
private constructor(data: UserStatsResponseData) {
Object.assign(this, data);
Object.freeze(this);
}
static from(input: UserStatsResponseInput): UserStatsResponse {
return new UserStatsResponse(UserStatsResponseSchema.parse(input));
}
static fromJson(json: unknown): UserStatsResponse {
return UserStatsResponse.from(json as UserStatsResponseInput);
}
toJson(): UserStatsResponseData {
return UserStatsResponseSchema.parse(this);
}
}
@@ -0,0 +1,13 @@
/**
* Apple 登录请求
* 原始 Dart: AppleLoginRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const AppleLoginRequestSchema = z.object({
identityToken: z.string(),
platform: z.string(),
});
export type AppleLoginRequestInput = z.input<typeof AppleLoginRequestSchema>;
export type AppleLoginRequestData = z.output<typeof AppleLoginRequestSchema>;
@@ -0,0 +1,14 @@
/**
* Facebook 登录请求
* 原始 Dart: FacebookLoginRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const FacebookLoginRequestSchema = z.object({
accessToken: z.string(),
platform: z.string(),
guestId: z.string().default(""),
});
export type FacebookLoginRequestInput = z.input<typeof FacebookLoginRequestSchema>;
export type FacebookLoginRequestData = z.output<typeof FacebookLoginRequestSchema>;
@@ -0,0 +1,13 @@
/**
* Facebook ID 登录请求
* 原始 Dart: FbIdLoginRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const FbIdLoginRequestSchema = z.object({
fbId: z.string(),
avatarUrl: z.string().default(""),
});
export type FbIdLoginRequestInput = z.input<typeof FbIdLoginRequestSchema>;
export type FbIdLoginRequestData = z.output<typeof FbIdLoginRequestSchema>;
@@ -0,0 +1,14 @@
/**
* Google 登录请求
* 原始 Dart: GoogleLoginRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const GoogleLoginRequestSchema = z.object({
idToken: z.string(),
platform: z.string(),
guestId: z.string().default(""),
});
export type GoogleLoginRequestInput = z.input<typeof GoogleLoginRequestSchema>;
export type GoogleLoginRequestData = z.output<typeof GoogleLoginRequestSchema>;
@@ -0,0 +1,12 @@
/**
* 游客登录请求
* 原始 Dart: GuestLoginRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const GuestLoginRequestSchema = z.object({
deviceId: z.string(),
});
export type GuestLoginRequestInput = z.input<typeof GuestLoginRequestSchema>;
export type GuestLoginRequestData = z.output<typeof GuestLoginRequestSchema>;
@@ -0,0 +1,18 @@
/**
* 游客登录响应
* 原始 Dart: GuestLoginResponse (lib/data/models/auth/auth_response.dart)
*/
import { z } from "zod";
import { UserSchema } from "../user/user";
export const GuestLoginResponseSchema = z.object({
token: z.string(),
deviceId: z.string(),
userId: z.string(),
isDeviceUser: z.boolean().default(true),
expiresIn: z.number().default(2592000),
user: UserSchema.optional(),
});
export type GuestLoginResponseInput = z.input<typeof GuestLoginResponseSchema>;
export type GuestLoginResponseData = z.output<typeof GuestLoginResponseSchema>;
+16
View File
@@ -0,0 +1,16 @@
/**
* 登录请求
* 原始 Dart: LoginRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const LoginRequestSchema = z.object({
email: z.string().default(""),
username: z.string().default(""),
password: z.string(),
platform: z.string(),
guestId: z.string().default(""),
});
export type LoginRequestInput = z.input<typeof LoginRequestSchema>;
export type LoginRequestData = z.output<typeof LoginRequestSchema>;
+15
View File
@@ -0,0 +1,15 @@
/**
* 登录响应
* 原始 Dart: LoginResponse (lib/data/models/auth/auth_response.dart)
*/
import { z } from "zod";
import { UserSchema } from "../user/user";
export const LoginResponseSchema = z.object({
user: UserSchema,
token: z.string(),
refreshToken: z.string().default(""),
});
export type LoginResponseInput = z.input<typeof LoginResponseSchema>;
export type LoginResponseData = z.output<typeof LoginResponseSchema>;
+12
View File
@@ -0,0 +1,12 @@
/**
* 退出登录响应
* 原始 Dart: LogoutResponse (lib/data/models/auth/auth_response.dart)
*/
import { z } from "zod";
export const LogoutResponseSchema = z.object({
success: z.boolean().default(true),
});
export type LogoutResponseInput = z.input<typeof LogoutResponseSchema>;
export type LogoutResponseData = z.output<typeof LogoutResponseSchema>;
@@ -0,0 +1,12 @@
/**
* 刷新 Token 请求
* 原始 Dart: RefreshTokenRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const RefreshTokenRequestSchema = z.object({
refreshToken: z.string(),
});
export type RefreshTokenRequestInput = z.input<typeof RefreshTokenRequestSchema>;
export type RefreshTokenRequestData = z.output<typeof RefreshTokenRequestSchema>;
@@ -0,0 +1,14 @@
/**
* 刷新 Token 响应
* 原始 Dart: RefreshTokenResponse (lib/data/models/auth/auth_response.dart)
*/
import { z } from "zod";
export const RefreshTokenResponseSchema = z.object({
token: z.string(),
refreshToken: z.string(),
userId: z.string(),
});
export type RefreshTokenResponseInput = z.input<typeof RefreshTokenResponseSchema>;
export type RefreshTokenResponseData = z.output<typeof RefreshTokenResponseSchema>;
+16
View File
@@ -0,0 +1,16 @@
/**
* 注册请求
* 原始 Dart: RegisterRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const RegisterRequestSchema = z.object({
username: z.string(),
email: z.string(),
password: z.string(),
platform: z.string(),
guestId: z.string().default(""),
});
export type RegisterRequestInput = z.input<typeof RegisterRequestSchema>;
export type RegisterRequestData = z.output<typeof RegisterRequestSchema>;
@@ -0,0 +1,12 @@
/**
* 发送验证码请求
* 原始 Dart: SendCodeRequest (lib/data/models/auth/auth_request.dart)
*/
import { z } from "zod";
export const SendCodeRequestSchema = z.object({
email: z.string(),
});
export type SendCodeRequestInput = z.input<typeof SendCodeRequestSchema>;
export type SendCodeRequestData = z.output<typeof SendCodeRequestSchema>;
@@ -0,0 +1,16 @@
/**
* 聊天历史响应
* 原始 Dart: ChatHistoryResponse (lib/data/models/chat/chat_response.dart)
*/
import { z } from "zod";
import { 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>;
+15
View File
@@ -0,0 +1,15 @@
/**
* 聊天历史中的单条消息
* 原始 Dart: ChatMessage (lib/data/models/chat/chat_response.dart)
*/
import { z } from "zod";
export const ChatMessageSchema = z.object({
role: z.string(),
content: z.string(),
id: z.string().default(""),
createdAt: z.string().default(""),
});
export type ChatMessageInput = z.input<typeof ChatMessageSchema>;
export type ChatMessageData = z.output<typeof ChatMessageSchema>;
@@ -0,0 +1,22 @@
/**
* 发送消息响应
* 原始 Dart: ChatSendResponse (lib/data/models/chat/chat_response.dart)
*/
import { z } from "zod";
export const ChatSendResponseSchema = z.object({
mode: z.string().default(""),
reply: z.string(),
voiceUrl: z.string().default(""),
audioUrl: z.string().default(""),
intimacyChange: z.number().default(0),
newIntimacy: z.number().default(0),
relationshipStage: z.string(),
currentMood: z.string().default(""),
messageId: z.string(),
isGuest: z.boolean().default(false),
timestamp: z.number().default(0),
});
export type ChatSendResponseInput = z.input<typeof ChatSendResponseSchema>;
export type ChatSendResponseData = z.output<typeof ChatSendResponseSchema>;
+13
View File
@@ -0,0 +1,13 @@
/**
* 消息同步响应
* 原始 Dart: ChatSyncData (lib/data/models/chat/chat_sync.dart)
*/
import { z } from "zod";
export const ChatSyncDataSchema = z.object({
syncedCount: z.number(),
totalHistory: z.number(),
});
export type ChatSyncDataInput = z.input<typeof ChatSyncDataSchema>;
export type ChatSyncDataData = z.output<typeof ChatSyncDataSchema>;
@@ -0,0 +1,13 @@
/**
* 消息同步请求
* 原始 Dart: ChatSyncRequest (lib/data/models/chat/chat_sync.dart)
*/
import { z } from "zod";
import { SyncMessageSchema } from "./sync_message";
export const ChatSyncRequestSchema = z.object({
messages: z.array(SyncMessageSchema),
});
export type ChatSyncRequestInput = z.input<typeof ChatSyncRequestSchema>;
export type ChatSyncRequestData = z.output<typeof ChatSyncRequestSchema>;
+13
View File
@@ -0,0 +1,13 @@
/**
* 游客每日聊天配额数据
* 原始 Dart: GuestChatQuota (lib/data/models/chat/guest_chat_quota.dart)
*/
import { z } from "zod";
export const GuestChatQuotaSchema = z.object({
remaining: z.number(),
date: z.string(),
});
export type GuestChatQuotaInput = z.input<typeof GuestChatQuotaSchema>;
export type GuestChatQuotaData = z.output<typeof GuestChatQuotaSchema>;
@@ -0,0 +1,19 @@
/**
* 图片上传响应
* 原始 Dart: ImageUploadResponse (lib/data/models/chat/image_upload_response.dart)
*/
import { z } from "zod";
export const ImageUploadResponseSchema = z.object({
success: z.boolean().default(true),
imageId: z.string(),
thumbUrl: z.string(),
mediumUrl: z.string(),
originalUrl: z.string(),
width: z.number(),
height: z.number(),
bytes: z.number(),
});
export type ImageUploadResponseInput = z.input<typeof ImageUploadResponseSchema>;
export type ImageUploadResponseData = z.output<typeof ImageUploadResponseSchema>;
@@ -0,0 +1,20 @@
/**
* 发送消息请求
* 原始 Dart: SendMessageRequest (lib/data/models/chat/send_message_request.dart)
*/
import { z } from "zod";
export const SendMessageRequestSchema = z.object({
message: z.string().default(""),
image: z.string().default(""),
imageId: z.string().default(""),
imageThumbUrl: z.string().default(""),
imageMediumUrl: z.string().default(""),
imageOriginalUrl: z.string().default(""),
imageWidth: z.number().default(0),
imageHeight: z.number().default(0),
useWebSocket: z.boolean().default(false),
});
export type SendMessageRequestInput = z.input<typeof SendMessageRequestSchema>;
export type SendMessageRequestData = z.output<typeof SendMessageRequestSchema>;
+12
View File
@@ -0,0 +1,12 @@
/**
* STT(语音转文字)响应
* 原始 Dart: SttData (lib/data/models/chat/stt_response.dart)
*/
import { z } from "zod";
export const SttDataSchema = z.object({
text: z.string(),
});
export type SttDataInput = z.input<typeof SttDataSchema>;
export type SttDataData = z.output<typeof SttDataSchema>;
+14
View File
@@ -0,0 +1,14 @@
/**
* 待同步的单条消息
* 原始 Dart: SyncMessage (lib/data/models/chat/chat_sync.dart)
*/
import { z } from "zod";
export const SyncMessageSchema = z.object({
role: z.string(),
content: z.string(),
timestamp: z.string(),
});
export type SyncMessageInput = z.input<typeof SyncMessageSchema>;
export type SyncMessageData = z.output<typeof SyncMessageSchema>;
+42
View File
@@ -0,0 +1,42 @@
/**
* Schemas - 集中导出
*
* Zod schema + 类型(Source of Truth
* 原始 Dart: lib/data/models/
*/
export * from "./auth/apple_login_request";
export * from "./auth/facebook_login_request";
export * from "./auth/fb_id_login_request";
export * from "./auth/google_login_request";
export * from "./auth/guest_login_request";
export * from "./auth/guest_login_response";
export * from "./auth/login_request";
export * from "./auth/login_response";
export * from "./auth/logout_response";
export * from "./auth/refresh_token_request";
export * from "./auth/refresh_token_response";
export * from "./auth/register_request";
export * from "./auth/send_code_request";
export * from "./chat/chat_history_response";
export * from "./chat/chat_message";
export * from "./chat/chat_send_response";
export * from "./chat/chat_sync_data";
export * from "./chat/chat_sync_request";
export * from "./chat/guest_chat_quota";
export * from "./chat/image_upload_response";
export * from "./chat/send_message_request";
export * from "./chat/stt_data";
export * from "./chat/sync_message";
export * from "./metrics/app_event";
export * from "./metrics/pwa_event";
export * from "./user/avatar_data";
export * from "./user/credits_data";
export * from "./user/credits_history_data";
export * from "./user/personality_traits";
export * from "./user/recent_memory";
export * from "./user/update_profile_request";
export * from "./user/user";
export * from "./user/user_stats_response";
+14
View File
@@ -0,0 +1,14 @@
/**
* 应用事件上报请求
* 原始 Dart: AppEvent (lib/data/models/metrics/app_event.dart)
*/
import { z } from "zod";
export const AppEventSchema = z.object({
userId: z.string(),
browser: z.string(),
userAgent: z.string(),
});
export type AppEventInput = z.input<typeof AppEventSchema>;
export type AppEventData = z.output<typeof AppEventSchema>;
+16
View File
@@ -0,0 +1,16 @@
/**
* PWA 事件上报请求
* 原始 Dart: PwaEvent (lib/data/models/metrics/pwa_event.dart)
*/
import { z } from "zod";
export const PwaEventSchema = z.object({
deviceId: z.string(),
deviceType: z.string(),
timestamp: z.number(),
pwaInstalled: z.boolean().default(false),
pwaSupported: z.boolean().default(false),
});
export type PwaEventInput = z.input<typeof PwaEventSchema>;
export type PwaEventData = z.output<typeof PwaEventSchema>;
+13
View File
@@ -0,0 +1,13 @@
/**
* 头像数据模型
* 原始 Dart: AvatarData (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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>;
+13
View File
@@ -0,0 +1,13 @@
/**
* 积分数据模型
* 原始 Dart: CreditsData (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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>;
@@ -0,0 +1,15 @@
/**
* 积分历史记录模型
* 原始 Dart: CreditsHistoryData (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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>;
@@ -0,0 +1,24 @@
/**
* 个性特征模型
* 原始 Dart: PersonalityTraits (lib/data/models/user/user.dart)
*/
import { z } from "zod";
export const PERSONALITY_TRAITS_DEFAULTS = {
cheerful: 0.5,
caring: 0.5,
playful: 0.5,
serious: 0.5,
romantic: 0.5,
} as const;
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>;
+15
View File
@@ -0,0 +1,15 @@
/**
* 最近记忆模型
* 原始 Dart: RecentMemory (lib/data/models/user/recent_memory.dart)
*/
import { z } from "zod";
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>;
@@ -0,0 +1,15 @@
/**
* 更新个人资料请求
* 原始 Dart: UpdateProfileRequest (lib/data/models/user/user.dart)
*/
import { z } from "zod";
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>;
+27
View File
@@ -0,0 +1,27 @@
/**
* 用户模型
* 原始 Dart: User (lib/data/models/user/user.dart)
*/
import { z } from "zod";
import { 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>;
@@ -0,0 +1,29 @@
/**
* 用户统计响应
* 原始 Dart: UserStatsResponse (lib/data/models/user/user_stats_response.dart)
*/
import { z } from "zod";
import { PersonalityTraitsSchema, PERSONALITY_TRAITS_DEFAULTS } from "./personality_traits";
import { 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>;
+1 -1
View File
@@ -18,7 +18,7 @@
import {
GuestChatQuotaSchema,
type GuestChatQuotaData,
} from "@/data/models";
} from "@/data/schemas/chat/guest_chat_quota";
import { z } from "zod";
import { LocalStorage } from "../local_storage";
+2 -2
View File
@@ -6,13 +6,13 @@
* 对齐 Dart 端 `IChatStorage`lib/data/services/storage/chat/ichat_storage.dart):
* - 游客每日聊天配额 + 游客总配额 两个独立字段的 CRUD
*
* 注:`GuestChatQuota` 模型见 `src/data/models/chat/guest_chat_quota.ts`
* 注:`GuestChatQuota` 模型见 `src/data/dto/chat/guest_chat_quota.ts`
* 数据形态 `{ remaining: number, date: string }`。
* 跨天重置逻辑(`needsReset`)保留在 `GuestChatQuota` 类上,存储层只做读写。
*/
import type { Result } from "../result";
import type { GuestChatQuotaData } from "@/data/models";
import type { GuestChatQuotaData } from "@/data/schemas/chat/guest_chat_quota";
export interface IChatStorage {
getGuestDailyChatQuota(): Promise<Result<GuestChatQuotaData | null>>;
+2 -2
View File
@@ -7,12 +7,12 @@
* - User 对象 / userId / avatarUrl 三个独立字段的 CRUD
* - `clearUserData()` 批量清空
*
* 注:完整 User 模型见 `src/data/models/user/user.ts`,本接口允许存 JSON 字符串,
* 注:完整 User 模型见 `src/data/dto/user/user.ts`,本接口允许存 JSON 字符串,
* 具体序列化由实现层通过 Zod schema 校验后转换为 `User` 类实例。
*/
import type { Result } from "../result";
import type { UserData } from "@/data/models";
import type { UserData } from "@/data/schemas/user/user";
export interface IUserStorage {
getUser(): Promise<Result<UserData | null>>;
+1 -1
View File
@@ -15,7 +15,7 @@
* - 单例挂在 class 静态字段,HMR 复用安全
*/
import { UserSchema, type UserData } from "@/data/models";
import { UserSchema, type UserData } from "@/data/schemas/user/user";
import { LocalStorage } from "../local_storage";
import { type Result as ResultT } from "../result";
import { StorageKeys } from "../storage_keys";