Files
TradeMate Dev 31cc1e02ce feat: 联盟返佣系统规范化并打通技能广场(无 ICP 证合规变现主路径)
- 新增 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>
2026-07-11 14:47:41 +08:00

50 lines
3.1 KiB
Markdown
Executable File
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.
# 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 # vitestsrc/**/*.{test,spec}.{ts,tsx}
cd frontend && npm run test:e2e # playwrightBASE_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 # e2etest/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。本文件仅在架构/约定变更时更新。