31cc1e02ce
- 新增 AffiliateProgram / AffiliateLink / AffiliateClick 规范化 Prisma 模型 取代原手写裸表 affiliate_stats / affiliate_clicks - 新增迁移 prisma/migrations/20260711000000_add_affiliate_models - 重构 affiliate.service.ts 改用 Prisma ORM,消除 $queryRawUnsafe SQL 注入 - 重构 affiliate.controller.ts 接口:programs / links(?skillId,?toolId) / stats / click - 前端 affiliate 页接入真实接口,移除硬编码 demo 数据 - 技能详情页新增「学此技能推荐使用的工具」联盟链接区块 - 新增 affiliate.service.spec.ts(4 用例通过)与幂等种子 seed-affiliate.ts - 更新 docs/progress/current.md,明确无 ICP 经营许可证下以联盟返佣为合规变现主路径 - 含此前工作区未提交改动(工具 slug 路由、支付/订单、SEO 等) Co-Authored-By: opencode <opencode@anthropic.com>
50 lines
3.1 KiB
Markdown
Executable File
50 lines
3.1 KiB
Markdown
Executable File
# 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。本文件仅在架构/约定变更时更新。
|