expo-popcore-app/.claude/skills/repo-sdk/SKILL.md

281 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: repo-sdk
description: "@repo/sdk 使用指南。当需要调用 Loomart 平台 API、实现项目管理、模板运行、AI 生成、文件处理、社交互动等功能时使用此技能。适用于:(1) 服务端实现 Controller 接口 (2) 客户端调用 API (3) 理解接口组合使用场景 (4) 数据验证和类型定义"
---
# @repo/sdk 使用指南
## 架构概述
SDK 采用**三层分离架构**
```
@repo/sdk
├── controllers/ # 26 个业务控制器API 契约定义)
├── schemas/ # Zod 数据验证 Schema
├── types/ # TypeScript 类型定义
└── client/ # 客户端集成Better Auth 插件 + API 生成器)
```
**核心依赖**
- `@repo/core`:装饰器系统(@Controller, @Post, @Get, @Body, @Query 等)
- `zod`:数据验证
- `reflect-metadata`:元数据反射
## 推荐调用方式root.get (DI 风格)
**强烈推荐使用 `root.get` 方式**,保证完整的类型安全:
```typescript
import { root } from '@repo/core'
import { ProjectController, TemplateController, AigcController } from '@repo/sdk'
import type { CreateProjectInput, Project } from '@repo/sdk'
// 获取控制器(完整类型推导)
const projectCtrl = root.get(ProjectController)
const templateCtrl = root.get(TemplateController)
const aigcCtrl = root.get(AigcController)
// 调用方法(参数和返回值都有类型提示)
const projects = await projectCtrl.list({ page: 1, limit: 10 })
const project = await projectCtrl.create({ title: '新项目', content: {} })
```
### 其他调用方式
<details>
<summary>Better Auth 插件风格</summary>
```typescript
import { createAuthClient } from 'better-auth/client'
import { createSkerClientPlugin } from '@repo/sdk'
const auth = createAuthClient({
baseURL: 'http://localhost:3000',
plugins: [createSkerClientPlugin()]
})
const projects = await auth.sker.project.list({ page: 1, limit: 10 })
```
</details>
<details>
<summary>API 函数风格</summary>
```typescript
import { generateApiFunctions, client } from '@repo/sdk'
client.setConfig({
baseUrl: 'http://localhost:3000',
auth: async () => localStorage.getItem('token')
})
const apis = generateApiFunctions()
const projects = await apis.postLoomartProjectList({ page: 1, limit: 10 })
```
</details>
## 功能模块导航
| 模块 | 控制器 | 主要功能 |
|------|--------|----------|
| 项目管理 | ProjectController | 创建、列表、更新、删除、转移项目 |
| 模板管理 | TemplateController | 创建、列表、运行模板工作流 |
| 模板生成 | TemplateGenerationController | 生成记录管理 |
| 社交互动 | TemplateSocialController | 点赞、收藏、评论、分享 |
| AI 生成 | AigcController | 图像/视频生成任务 |
| 聊天 | ChatController | AI 对话 |
| 文件处理 | FileController | 上传、压缩、格式转换 |
| 分类标签 | CategoryController, TagController | 分类和标签管理 |
| 消息系统 | MessageController | 用户消息通知 |
| 公告 | AnnouncementController | 系统公告 |
| 权限 | PermissionController, RoleController | 权限和角色管理 |
| 支付 | AlipayController, AdminBalanceController | 支付和余额管理 |
## 核心组合使用场景
### 场景 1模板运行完整流程
```typescript
// 1. 获取模板详情
const template = await templateCtrl.get(templateId)
// 2. 运行模板(返回 generationId
const { generationId } = await templateCtrl.run({
templateId,
formData: { prompt: '生成一只猫' }
})
// 3. 轮询任务状态
let status = await aigcCtrl.getTaskStatus(taskId)
while (status.status === 'PENDING' || status.status === 'PROCESSING') {
await sleep(2000)
status = await aigcCtrl.getTaskStatus(taskId)
}
// 4. 处理生成结果(可选:转换格式)
if (status.result_url) {
const webp = await fileCtrl.convertToWebp({
videoUrl: status.result_url,
quality: 80,
loop: true
})
}
```
### 场景 2模板社交互动
```typescript
// 1. 获取模板列表(带社交状态)
const { templates } = await templateCtrl.list({ page: 1, limit: 20 })
// 2. 批量检查点赞/收藏状态
const likedStatus = await socialCtrl.checkLikedBatch({
templateIds: templates.map(t => t.id)
})
// 3. 点赞操作
await socialCtrl.like({ templateId })
// 4. 获取评论
const comments = await socialCtrl.getComments({ templateId, page: 1 })
// 5. 发表评论
await socialCtrl.createComment({
templateId,
content: '很棒的模板!'
})
```
### 场景 3项目管理与标签
```typescript
// 1. 创建项目
const project = await projectCtrl.create({
title: '我的项目',
content: { /* 项目数据 */ }
})
// 2. 创建用户标签
const tag = await projectTagCtrl.create({ name: '收藏夹' })
// 3. 给项目添加标签
await projectTagCtrl.addToProject({
projectId: project.id,
tagId: tag.id
})
// 4. 按标签筛选项目
const { projects } = await projectCtrl.list({
page: 1,
tagId: tag.id
})
```
## 参考文档
- **控制器 API 详情**:查阅 [references/controllers.md](references/controllers.md)
- **组合使用场景**:查阅 [references/workflows.md](references/workflows.md)
- **客户端集成指南**:查阅 [references/client-usage.md](references/client-usage.md)
## 权限装饰器
```typescript
// 需要登录
@RequireSession()
// 需要特定权限AND 模式)
@RequirePermissions({ project: ['create', 'update'] })
// 需要任一权限OR 模式)
@RequirePermissions({ project: ['run'], template: ['run'] }, 'OR')
```
## 复用 Zod Schema 和类型(推荐)
**强烈推荐复用 SDK 导出的 Schema 和类型**,确保前后端数据一致性:
### 导入类型
```typescript
// 从 @repo/sdk 导入类型(推荐)
import type {
// 项目
Project, CreateProjectInput, ListProjectsInput, ListProjectsResult,
// 模板
TemplateDetail, RunTemplateInput, ListTemplatesInput,
// AI 生成
AigcModel, SubmitTaskBody, GetTaskStatusResult,
// 消息
Message, ListMessagesInput, UnreadCountResult
} from '@repo/sdk'
```
### 复用 Zod Schema 验证
```typescript
import {
CreateProjectSchema,
ListProjectsSchema,
RunTemplateSchema,
SubmitTaskBodySchema
} from '@repo/sdk'
// 验证用户输入
function validateInput(data: unknown) {
return CreateProjectSchema.parse(data) // 抛出错误或返回类型安全的数据
}
// 安全验证(不抛错)
function safeValidate(data: unknown) {
const result = CreateProjectSchema.safeParse(data)
if (!result.success) {
console.error('验证失败:', result.error.flatten())
return null
}
return result.data
}
```
### 服务端实现复用类型
```typescript
import { Injectable } from '@repo/core'
import { ProjectController } from '@repo/sdk'
import type { Project, CreateProjectInput, ListProjectsInput, ListProjectsResult } from '@repo/sdk'
@Injectable()
export class ProjectControllerImpl implements ProjectController {
// 参数和返回值类型直接复用 SDK 导出的类型
async create(data: CreateProjectInput): Promise<Project> {
// 实现...
}
async list(body: ListProjectsInput): Promise<ListProjectsResult> {
// 实现...
}
}
```
### 前端表单复用 Schema
```typescript
import { CreateProjectSchema } from '@repo/sdk'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
type FormData = z.infer<typeof CreateProjectSchema>
function CreateProjectForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(CreateProjectSchema)
})
const onSubmit = async (data: FormData) => {
const projectCtrl = root.get(ProjectController)
await projectCtrl.create(data) // 类型完全匹配
}
}
```