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>
This commit is contained in:
@@ -1,136 +1,49 @@
|
||||
# AGENTS.md — 项目知识库(AI 专用)
|
||||
|
||||
> 每次任务前先读此文件。维护项目关键上下文,避免重复探索。
|
||||
宇之然 AI 工具指南与技能练习平台。前端 Next.js 14,后端 NestJS,另有独立的 uni-app 移动端。
|
||||
|
||||
## 项目概览
|
||||
## 仓库结构(monorepo,各自独立 `npm install`)
|
||||
|
||||
宇之然 AI 工具指南与技能练习平台。前端 Next.js + shadcn/ui,后端 NestJS + MySQL。
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| 品牌 | 宇之然(北京宇之然科技中心) |
|
||||
| 域名 | yuzhiran.com |
|
||||
| 前端 | `frontend/`, port 3000, Next.js App Router |
|
||||
| 后端 | `backend/`, port 4000, NestJS |
|
||||
| CSS | Tailwind CSS + shadcn/ui 暗黑模式 |
|
||||
|
||||
## 技术栈约定
|
||||
|
||||
### 前端
|
||||
- **框架**: Next.js App Router (`src/app/`)
|
||||
- **UI**: shadcn/ui + Tailwind CSS (CSS 变量主题)
|
||||
- **状态管理**: React Server Components 优先, 客户端用 `useState`/`useEffect`
|
||||
- **路由**: 文件系统路由, 布局用 `layout.tsx`, 加载用 `loading.tsx`, 错误用 `error.tsx`
|
||||
- **暗黑模式**: `next-themes` + Tailwind 暗类策略 (`darkMode: 'class'`)
|
||||
|
||||
### 后端
|
||||
- **框架**: NestJS 模块化架构
|
||||
- **ORM**: Prisma + MySQL(schema 在 `prisma/schema.prisma`)
|
||||
- **认证**: JWT + Passport
|
||||
- **API 前缀**: `/api/v1`
|
||||
- **CORS**: `origin: true`, `maxAge: 0`(避免浏览器预检缓存)
|
||||
|
||||
### UI/UX 统一规则
|
||||
- **容器**: 内容页 `max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12`;法律/文本页用 `max-w-3xl`
|
||||
- **标题**: `text-3xl font-bold text-foreground`
|
||||
- **副标题**: `<p className="mt-2 text-muted-foreground">...</p>`
|
||||
- **颜色**: 全站禁用 `text-gray-*` / `bg-gray-*` / `border-gray-*` 硬编码 —— 使用 CSS 变量:
|
||||
- 前景色 → `text-foreground` / `text-muted-foreground`
|
||||
- 背景 → `bg-card` / `bg-muted/50` / `bg-accent`
|
||||
- 边框 → `border-border`
|
||||
- hover → `hover:text-foreground` / `hover:bg-accent`
|
||||
- **国际化**: 所有用户可见文本使用 `useT()` hook,翻译 key 位于 `src/i18n/locales/`。新增页面先加翻译 key 再写 UI。中文默认,英文同步维护。
|
||||
|
||||
## 2026 市场验证数据(已修正)
|
||||
|
||||
| 指标 | 数据 | 来源 |
|
||||
|------|------|------|
|
||||
| AI 教育市场 | $7-10B(2025) → $42B(2030),CAGR 40%+ | TBRC, Mordor Intelligence |
|
||||
| Prompt 工程市场 | $505M(2025) → $673M(2026) → $6.7B(2034),CAGR 33% | Fortune Business Insights |
|
||||
| Shadow AI | 75% 员工用未授权 AI,48% 把公司数据贴进公共 AI | Microsoft, Cisco |
|
||||
| 企业 IP 泄漏 | 43% 企业因员工使用外部 AI 发生过泄漏 | Bitglass/Forcepoint |
|
||||
| 学生 AI 使用率 | 86% 学生使用 AI,66% 用 ChatGPT | Digital Education Council |
|
||||
| 教师 AI 培训缺口 | 68% 城市教师未接受任何 AI 培训 | Education Week |
|
||||
|
||||
## 调整后产品路线图(基于真实数据)
|
||||
|
||||
1. **AI 工具指南(最高优先级)** ✅ — 收录优质 AI 工具,联盟返佣变现,首页展示精选工具
|
||||
2. **练习系统** ✅ — Prompt 工程市场 $673M(2026),练习+评分是已验证的付费模式
|
||||
3. **¥9.9 用量包** ✅ — 免费 5 次 → 付费 50 次,从沙盒使用量直接变现
|
||||
4. **技能广场** ✅ — 一次性购买技能,¥9.9-29.9,独立变现渠道
|
||||
5. ~~企业版~~ ↓ — 从主菜单隐藏,页面仍可通过 URL 访问,不主动运营
|
||||
6. ~~社区/圈子~~ ↓ — 从主菜单隐藏,页面仍可访问,不主动运营
|
||||
5. **内容扩充(下一个)** — 核心竞争围绕内容质量而非模型数量:增加练习场景、行业定制题、评分系统优化
|
||||
|
||||
## 关键架构决策
|
||||
|
||||
## 后端关键 API
|
||||
|
||||
| 端点 | 说明 |
|
||||
|------|------|
|
||||
| `POST /api/v1/auth/register` | 注册 |
|
||||
| `POST /api/v1/auth/login` | 登录 |
|
||||
| `GET /api/v1/search?q=xxx` | 搜索(返回 `{ results: [...] }`,**不是** `items`) |
|
||||
| `GET /api/v1/users/:id` | 用户信息 |
|
||||
| `POST /api/v1/chat/completions` | AI 流式对话 |
|
||||
| `GET /api/v1/enterprise/...` | 企业版管理 |
|
||||
| `GET /api/v1/notifications` | 通知列表(需 JWT) |
|
||||
| `GET /api/v1/notifications/unread` | 未读数(需 JWT) |
|
||||
| `PATCH /api/v1/notifications/:id/read` | 标记已读(需 JWT) |
|
||||
| `PATCH /api/v1/notifications/read-all` | 全部已读(需 JWT) |
|
||||
| `GET /api/v1/learning/analytics` | 学情分析(需 JWT,返回知识领域掌握度) |
|
||||
| `GET /api/v1/learning/path` | 学习路径进度(需 JWT,返回阶段任务完成情况) |
|
||||
| `GET /api/v1/skills` | 技能列表(支持 ?category= / ?difficulty= / ?search= 过滤) |
|
||||
| `GET /api/v1/skills/:id` | 技能详情(含 system prompt、练习任务、starter 问题,返回 purchased/locked 状态) |
|
||||
| `GET /api/v1/skills/marketplace` | 技能广场(返回所有技能含 price + purchased 状态,无需认证也可用) |
|
||||
| `GET /api/v1/skills/categories` | 技能分类列表 |
|
||||
| `GET /api/v1/skills/difficulties` | 难度等级列表 |
|
||||
|
||||
## 关键上下文(Critical Context)
|
||||
|
||||
- `search.service.ts` 返回 `results` 而非 `items` —— 写测试时注意
|
||||
- `users.service.ts` 的 `if (status)` 曾误写为 `if (params.status)`(已修复)
|
||||
- 静态构建 (`next build`) 已修复 —— 所有动态路由都通过 server wrapper 模式导出 `generateStaticParams()`(60 页面全部生成)
|
||||
- `public/favicon.ico` 和 `app/favicon.ico` 不能共存,会触发 500
|
||||
- ESLint 循环引用已在 `next.config.js` 中用 `eslint: { ignoreDuringBuilds: true }` 绕过
|
||||
- 数据库 schema 通过 Prisma migration 管理, 位于 `backend/prisma/migrations/`
|
||||
- 技能广场(marketplace): Skill 模型有 `price` 字段(null=免费, >0=付费);`UserSkill` 表记录用户购买;Order 有 `metadata` JSON 字段存 skillId
|
||||
- 技能购买流程: POST /orders/create (planType='SKILL', skillId=xxx) → mock支付自动创建 UserSkill 记录 → 技能广场显示"已拥有"
|
||||
- 第一个付费 Skill: `title-craft`(标题大师),¥9.9,seed 在 `prisma/seed-marketplace.cjs`
|
||||
- 后续 5 个付费 Skill: `payment-chaser`(回款助手 ¥19.9), `proposal-wizard`(提案智造 ¥19.9), `review-intel`(差评分析师 ¥19.9), `listing-optimizer`(商品文案大师 ¥29.9), `contract-reviewer`(合同审查助手 ¥29.9)
|
||||
|
||||
## 项目管理流程
|
||||
|
||||
每次任务遵循以下流程:
|
||||
|
||||
1. **任务开始前** — 读 AGENTS.md + docs/progress.md,了解当前进度和上下文
|
||||
2. **规划阶段** — 分析需求,拆解为 TODO 列表,按优先级排序
|
||||
3. **执行阶段** — 按 TODO 依次实施,完成后先做**代码评审修复**(检查代码风格、类型安全、边界情况、安全隐患、是否符合项目约定),再做**测试验证**(运行 lint/build + 相关测试,发现失败立即修复)
|
||||
4. **任务完成后** — 更新 docs/progress.md(更新阶段状态、补充完成项)
|
||||
5. **归档** — 旧版 progress.md 移到 `docs/archive/progress-YYYY-MM-DD.md`
|
||||
6. **提交** — 只有在用户明确要求时才创建 git commit
|
||||
| 目录 | 技术栈 | 端口 | 说明 |
|
||||
|------|--------|------|------|
|
||||
| `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
|
||||
# 前端
|
||||
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
|
||||
|
||||
# 前端构建
|
||||
cd frontend && npm run build
|
||||
|
||||
# 后端测试
|
||||
cd backend && npm test
|
||||
npm run test:e2e
|
||||
# 后端
|
||||
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 容易踩坑)
|
||||
|
||||
> 此文件仅在架构/约定变更时更新。进度追踪见 `docs/progress.md`。
|
||||
- **国际化**:用 `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`。
|
||||
|
||||
---
|
||||
## 已验证的坑(改代码前注意)
|
||||
|
||||
> 此文件仅在架构/约定变更时更新。进度追踪见 `docs/progress.md`。
|
||||
- **搜索 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。本文件仅在架构/约定变更时更新。
|
||||
|
||||
Reference in New Issue
Block a user