# AGENTS.md — 项目知识库（AI 专用）

宇之然 AI 工具指南与技能练习平台。前端 Next.js 14，后端 NestJS，另有独立的 uni-app 移动端。

## 仓库结构（monorepo，各自独立 `npm install`）

| 目录 | 技术栈 | 端口 | 说明 |
|------|--------|------|------|
| `frontend/` | Next.js 14 App Router | 3000 | SSG 静态导出（`output: 'export'`），构建产物到 `out/` |
| `backend/` | NestJS + Prisma + MySQL | 4000 | API 前缀 `/api/v1`，JWT + Passport 认证 |
| `mobile/` | uni-app (Vue3) | — | 微信小程序/H5，**与 Web 端无代码共享**，改动它需单独评估 |

## 常用命令

```bash
# 前端
cd frontend && npm run dev          # predev 会自动 rm -rf out
cd frontend && npm run build        # next build + 自动生成 sitemap（输出到 out/）
cd frontend && npm run typecheck    # tsc --noEmit
cd frontend && npm test             # vitest（src/**/*.{test,spec}.{ts,tsx}）
cd frontend && npm run test:e2e     # playwright，BASE_URL 默认 localhost:3000

# 后端
cd backend && npm run start:dev     # nest start --watch
cd backend && npm test              # jest（*.spec.ts）；单文件：npx jest <path>.spec.ts
cd backend && npx jest --config jest-e2e.json   # e2e（test/app.e2e-spec.ts，无 npm script）
cd backend && npm run prisma:generate | prisma:migrate | prisma:seed   # prisma 工具
```

## 前端约定（agent 容易踩坑）

- **国际化**：用 `useT()`（来自 `@/i18n`），翻译 key 在 `src/i18n/locales/`，中文默认、英文同步。不要硬编码用户可见文本。
- **颜色**：禁用 `text-gray-*` / `bg-gray-*` / `border-gray-*` 硬编码，统一用 CSS 变量（`text-foreground`/`text-muted-foreground`、`bg-card`/`bg-muted`/`bg-accent`、`border-border`、hover 用 `hover:bg-accent` 等）。
- **容器**：内容页 `max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12`；长文本页 `max-w-3xl`。

## 已验证的坑（改代码前注意）

- **搜索 API 返回 `{ results, total }`，不是 `items`**（`backend/src/modules/search/search.service.ts`）。写前端/测试时勿用错字段名。
- **前端是 SSG**（`output: 'export'`）。`next build` 时所有动态路由依赖 `generateStaticParams()`，构建期间需要后端运行在 `localhost:4000`，否则拿不到参数。图片用 `unoptimized: true`。
- **ESLint 循环引用**已在 `next.config.js` 用 `eslint: { ignoreDuringBuilds: true }` 绕过 —— 构建不报 lint 错，需单独 `npm run lint` / `npm run typecheck`。
- **不要同时创建 `public/favicon.ico` 和 `src/app/favicon.ico`**，Next 导出会 500。
- 后端 jest/ts-jest 的 `@/` 别名指向 `src/`（`moduleNameMapper`）。

## 技能广场（marketplace）数据模型

- `Skill` 有 `price` 字段：`null`=免费，`>0`=付费；`UserSkill` 记录购买；`Order.metadata` 存 `skillId`。
- 购买流程：`POST /orders/create`（`planType:'SKILL'`, `skillId`）→ mock 支付自动建 `UserSkill` → 广场显示"已拥有"。

> 进度追踪见 `docs/progress.md`；架构细节见 `docs/技术架构设计.md`、README.md。本文件仅在架构/约定变更时更新。
