refactor(data): add I*Repository interfaces and depend on them in stores
为 /src/data/repositories/ 下每个仓库类增加对应的接口契约,
接口文件存放在独立的 interfaces/ 子目录中。
改动:
- 新建 4 个接口文件 (iauth_repository / ichat_repository /
imetrics_repository / iuser_repository),纯 type-only,方法签名
与实现类完全一致
- 4 个实现类加 implements I{Name}Repository 子句,编译器自动校验契约
- 3 个 stores 文件 (auth / chat / user state machines) 改为依赖接口
类型:通过 `const xxxRepo: I{Name}Repository = xxxRepository` 局部别名,
actor 内部调用全部走别名
- barrelsby.json 加入 interfaces/ 目录,让自动 barrel 能覆盖
- Auto-regenerated repositories/index.ts 与 interfaces/index.ts
参照 storage 层已有的 IAuthStorage / IChatStorage / IUserStorage 模式。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,7 @@ 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 { Result } from "@/utils/result";
|
||||
import type { IAuthRepository } from "@/data/repositories/interfaces/iauth_repository";
|
||||
import { AuthStorage } from "@/data/storage/auth/auth_storage";
|
||||
import type { IAuthStorage } from "@/data/storage/auth/iauth_storage";
|
||||
import { UserStorage } from "@/data/storage/user/user_storage";
|
||||
@@ -35,7 +36,7 @@ import type { IUserStorage } from "@/data/storage/user/iuser_storage";
|
||||
/** 硬编码平台名,对齐 Dart `PlatformUtil.platformName.toLowerCase()`(Web 平台)。 */
|
||||
const WEB_PLATFORM = "web";
|
||||
|
||||
export class AuthRepository {
|
||||
export class AuthRepository implements IAuthRepository {
|
||||
constructor(
|
||||
private readonly api: AuthApi,
|
||||
private readonly storage: IAuthStorage,
|
||||
|
||||
@@ -21,10 +21,11 @@ import { ChatMessage } from "@/data/dto/chat/chat_message";
|
||||
import { ChatSendResponse } from "@/data/dto/chat/chat_send_response";
|
||||
import { SendMessageRequest } from "@/data/dto/chat/send_message_request";
|
||||
import { Result } from "@/utils/result";
|
||||
import type { IChatRepository } from "@/data/repositories/interfaces/ichat_repository";
|
||||
import { LocalChatStorage } from "@/data/storage/chat/local_chat_storage";
|
||||
import { LocalMessage } from "@/data/storage/chat/local_message";
|
||||
|
||||
export class ChatRepository {
|
||||
export class ChatRepository implements IChatRepository {
|
||||
constructor(
|
||||
private readonly api: ChatApi,
|
||||
private readonly localStorage: LocalChatStorage,
|
||||
|
||||
@@ -6,3 +6,7 @@ export * from "./auth_repository";
|
||||
export * from "./chat_repository";
|
||||
export * from "./metrics_repository";
|
||||
export * from "./user_repository";
|
||||
export * from "./interfaces/iauth_repository";
|
||||
export * from "./interfaces/ichat_repository";
|
||||
export * from "./interfaces/imetrics_repository";
|
||||
export * from "./interfaces/iuser_repository";
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* IAuthRepository 接口
|
||||
*
|
||||
* 对齐 Dart 端 `AuthRepository` 抽象(lib/data/repositories/auth_repository.dart):
|
||||
* - 登录 / 登出 / 刷新 token / 第三方 OAuth 登录的公共契约
|
||||
* - 登出强制清本地态(无论 API 成败)
|
||||
* - `getCurrentUser` 成功后尽力写本地 User 缓存(best-effort)
|
||||
* - 所有方法返回 `Promise<Result<T>>`,与 Dart `Future<Result<T>>` 对齐
|
||||
*
|
||||
* 注:仓库内私有方法(`_socialLogin` / `_saveLoginData`)不暴露在接口上。
|
||||
* 原始 Dart: lib/data/repositories/auth_repository_impl.dart
|
||||
*/
|
||||
|
||||
import type { Result } from "@/utils/result";
|
||||
import type { GuestLoginResponse } from "@/data/dto/auth/guest_login_response";
|
||||
import type { LoginResponse } from "@/data/dto/auth/login_response";
|
||||
import type { RefreshTokenResponse } from "@/data/dto/auth/refresh_token_response";
|
||||
import type { User } from "@/data/dto/user/user";
|
||||
|
||||
export interface IAuthRepository {
|
||||
/** 用户注册。注册成功不会自动登录(与 Dart 行为一致)。 */
|
||||
register(input: {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
guestId?: string;
|
||||
}): Promise<Result<void>>;
|
||||
|
||||
/** 邮箱/用户名 + 密码登录。 */
|
||||
emailLogin(input: {
|
||||
email?: string;
|
||||
username?: string;
|
||||
password: string;
|
||||
guestId?: string;
|
||||
}): Promise<Result<LoginResponse>>;
|
||||
|
||||
/** 发送邮箱验证码。 */
|
||||
sendCode(email: string): Promise<Result<void>>;
|
||||
|
||||
/**
|
||||
* 退出登录:先调 API 注销服务端会话,**无论成败**都清本地登录态。
|
||||
*/
|
||||
logout(): Promise<Result<void>>;
|
||||
|
||||
/** 游客登录:使用 deviceId 换取 guest token。 */
|
||||
guestLogin(deviceId: string): Promise<Result<GuestLoginResponse>>;
|
||||
|
||||
/** Google 登录。 */
|
||||
googleLogin(input: {
|
||||
idToken: string;
|
||||
guestId?: string;
|
||||
}): Promise<Result<LoginResponse>>;
|
||||
|
||||
/** Facebook 登录(accessToken 流程)。 */
|
||||
facebookLogin(input: {
|
||||
accessToken: string;
|
||||
guestId?: string;
|
||||
}): Promise<Result<LoginResponse>>;
|
||||
|
||||
/** Facebook ID 登录(v7.0 新增,fbId 流程)。 */
|
||||
facebookIdLogin(input: {
|
||||
fbId: string;
|
||||
avatarUrl?: string;
|
||||
}): Promise<Result<LoginResponse>>;
|
||||
|
||||
/** Apple 登录。 */
|
||||
appleLogin(identityToken: string): Promise<Result<LoginResponse>>;
|
||||
|
||||
/** 刷新 token:先读本地的 refresh token,空则返回错误。 */
|
||||
refreshToken(): Promise<Result<RefreshTokenResponse>>;
|
||||
|
||||
/** 获取当前登录用户。成功后尽力写本地 User 缓存。 */
|
||||
getCurrentUser(): Promise<Result<User>>;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* IChatRepository 接口
|
||||
*
|
||||
* 对齐 Dart 端 `ChatRepository` 抽象(lib/data/repositories/chat_repository.dart):
|
||||
* - 远程:发送消息、获取历史
|
||||
* - 本地:写入 / 批量覆盖 / 读取 / 清空 / 计数
|
||||
*
|
||||
* 私有助手(`_chatToLocal` / `_localToChat` / `_mapLocalStorageResult`)不暴露。
|
||||
* 原始 Dart: lib/data/repositories/chat_repository_impl.dart
|
||||
*/
|
||||
|
||||
import type { Result } from "@/utils/result";
|
||||
import type { ChatHistoryResponse } from "@/data/dto/chat/chat_history_response";
|
||||
import type { ChatMessage } from "@/data/dto/chat/chat_message";
|
||||
import type { ChatSendResponse } from "@/data/dto/chat/chat_send_response";
|
||||
|
||||
export interface IChatRepository {
|
||||
/** 发送一条消息。 */
|
||||
sendMessage(
|
||||
message: string,
|
||||
options?: { image?: string; useWebSocket?: boolean },
|
||||
): Promise<Result<ChatSendResponse>>;
|
||||
|
||||
/** 获取聊天历史,分页参数默认 limit=50, offset=0。 */
|
||||
getHistory(limit?: number, offset?: number): Promise<Result<ChatHistoryResponse>>;
|
||||
|
||||
/** 把一条消息写入本地存储。 */
|
||||
saveMessageToLocal(message: ChatMessage): Promise<Result<void>>;
|
||||
|
||||
/** 批量覆盖写入:先清空本地存储,再写入新列表。 */
|
||||
saveMessagesToLocal(messages: readonly ChatMessage[]): Promise<Result<void>>;
|
||||
|
||||
/** 读取所有本地消息,按 dbId 升序。 */
|
||||
getLocalMessages(): Promise<Result<ChatMessage[]>>;
|
||||
|
||||
/** 清空本地消息。 */
|
||||
clearLocalMessages(): Promise<Result<void>>;
|
||||
|
||||
/** 获取本地消息数量。 */
|
||||
getLocalMessageCount(): Promise<Result<number>>;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* IMetricsRepository 接口
|
||||
*
|
||||
* 对齐 Dart 端 `MetricsRepository` 抽象(lib/data/repositories/metrics_repository.dart):
|
||||
* - 纯远程 fire-and-forget 上报,无本地状态
|
||||
*
|
||||
* 原始 Dart: lib/data/repositories/metrics_repository_impl.dart
|
||||
*/
|
||||
|
||||
import type { Result } from "@/utils/result";
|
||||
|
||||
export interface IMetricsRepository {
|
||||
/** 上报 PWA 事件。自动注入当前秒级时间戳。 */
|
||||
reportPwaEvent(input: {
|
||||
deviceId: string;
|
||||
deviceType: string;
|
||||
pwaInstalled: boolean;
|
||||
pwaSupported: boolean;
|
||||
}): Promise<Result<void>>;
|
||||
|
||||
/** 上报用户环境信息(浏览器、UA 等)。 */
|
||||
reportUserInfo(input: {
|
||||
userId: string;
|
||||
browser: string;
|
||||
userAgent: string;
|
||||
}): Promise<Result<void>>;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @file Automatically generated by barrelsby.
|
||||
*/
|
||||
|
||||
export * from "./iauth_repository";
|
||||
export * from "./ichat_repository";
|
||||
export * from "./imetrics_repository";
|
||||
export * from "./iuser_repository";
|
||||
@@ -0,0 +1,37 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* IUserRepository 接口
|
||||
*
|
||||
* 对齐 Dart 端 `UserRepository` 抽象(lib/data/repositories/user_repository.dart):
|
||||
* - 纯远程调用,不直接写本地 storage(持久化由 AuthRepository 在登录流程中处理)
|
||||
*
|
||||
* 原始 Dart: lib/data/repositories/user_repository_impl.dart
|
||||
*/
|
||||
|
||||
import type { Result } from "@/utils/result";
|
||||
import type { CreditsData } from "@/data/dto/user/credits_data";
|
||||
import type { CreditsHistoryData } from "@/data/dto/user/credits_history_data";
|
||||
import type { UpdateProfileRequest } from "@/data/dto/user/update_profile_request";
|
||||
import type { User } from "@/data/dto/user/user";
|
||||
import type { UserStatsResponse } from "@/data/dto/user/user_stats_response";
|
||||
|
||||
export interface IUserRepository {
|
||||
/** 获取用户统计信息。 */
|
||||
getUserStats(): Promise<Result<UserStatsResponse>>;
|
||||
|
||||
/** 获取当前登录用户信息。 */
|
||||
getCurrentUser(): Promise<Result<User>>;
|
||||
|
||||
/** 更新个人资料。 */
|
||||
updateProfile(request: UpdateProfileRequest): Promise<Result<User>>;
|
||||
|
||||
/** 查询积分余额。 */
|
||||
getCredits(): Promise<Result<CreditsData>>;
|
||||
|
||||
/** 查询积分操作历史,分页参数默认 limit=50, offset=0。 */
|
||||
getCreditsHistory(
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
): Promise<Result<CreditsHistoryData>>;
|
||||
}
|
||||
@@ -11,8 +11,9 @@ import { MetricsApi, metricsApi } from "@/data/services/api";
|
||||
import { AppEvent } from "@/data/dto/metrics/app_event";
|
||||
import { PwaEvent } from "@/data/dto/metrics/pwa_event";
|
||||
import { Result } from "@/utils/result";
|
||||
import type { IMetricsRepository } from "@/data/repositories/interfaces/imetrics_repository";
|
||||
|
||||
export class MetricsRepository {
|
||||
export class MetricsRepository implements IMetricsRepository {
|
||||
constructor(private readonly api: MetricsApi) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,8 +15,9 @@ 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 { Result } from "@/utils/result";
|
||||
import type { IUserRepository } from "@/data/repositories/interfaces/iuser_repository";
|
||||
|
||||
export class UserRepository {
|
||||
export class UserRepository implements IUserRepository {
|
||||
constructor(private readonly api: UserApi) {}
|
||||
|
||||
/** 获取用户统计信息。 */
|
||||
|
||||
Reference in New Issue
Block a user