From 28f4efd675ff3a88542b4a3cb61fa341edf43e50 Mon Sep 17 00:00:00 2001 From: asdfghjkoiuy Date: Sun, 23 Aug 2026 00:16:15 +0800 Subject: [PATCH] docs: initialize AIwelink project --- .gitignore | 8 + docs/architecture/technology-stack-details.md | 403 +++++++++++++++++ docs/architecture/technology-stack.md | 151 +++++++ docs/current-knowledge-and-plan.md | 307 +++++++++++++ docs/discussion-summary.md | 291 ++++++++++++ docs/project-handoff.md | 289 ++++++++++++ .../architecture/technology-stack-details.md | 424 ++++++++++++++++++ docs_old/architecture/technology-stack.md | 143 ++++++ docs_old/discussion-summary.md | 350 +++++++++++++++ docs_old/project-handoff.md | 314 +++++++++++++ 10 files changed, 2680 insertions(+) create mode 100644 .gitignore create mode 100644 docs/architecture/technology-stack-details.md create mode 100644 docs/architecture/technology-stack.md create mode 100644 docs/current-knowledge-and-plan.md create mode 100644 docs/discussion-summary.md create mode 100644 docs/project-handoff.md create mode 100644 docs_old/architecture/technology-stack-details.md create mode 100644 docs_old/architecture/technology-stack.md create mode 100644 docs_old/discussion-summary.md create mode 100644 docs_old/project-handoff.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac27259 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +docs-local/ +node_modules/ +dist/ +coverage/ +.env +.env.* +!.env.example diff --git a/docs/architecture/technology-stack-details.md b/docs/architecture/technology-stack-details.md new file mode 100644 index 0000000..4dafa7a --- /dev/null +++ b/docs/architecture/technology-stack-details.md @@ -0,0 +1,403 @@ +# AIwelink 技术实现规则 + +本文补充 [AIwelink 技术方案](./technology-stack.md)。 +文档说明请求怎样进入系统、代码怎样分层、数据怎样保存。 +文档也列出第一阶段的部署和测试要求。 + +## 1. Web 和 API 使用一个域名 + +### 1.1 请求路径 + +第一阶段对外使用一个公网域名: + +```text +https://aiwelink.com/ -> Next.js Web +https://aiwelink.com/api/v1/... -> REST API +``` + +入口代理(例如 Nginx)按路径转发: + +```text +客户端 + | + v +Nginx + |-- /api/v1/* -> api:3000 + |-- /* -> web:3000 +``` + +NestJS 设置全局前缀 `/api/v1`。代理和应用要统一路径处理方式,避免请求出现两次 `/api/v1`。 + +### 1.2 这样安排的好处 + +- 浏览器通过同域名直接访问 API,开发和生产使用相同请求路径; +- HttpOnly Cookie 的会话处理更简单; +- 分享页、公开机会页和登录后的工作台使用同一域名; +- 本地、测试和生产环境可以使用相同的请求路径; +- 将来改用 `api.aiwelink.com` 时,资源路径仍可以保持稳定。 + +### 1.3 入口代理要配置的规则 + +- Web 和 API 使用各自的超时、缓存和安全策略; +- Next.js 负责页面,业务规则统一放在 API; +- Next.js 服务端调用 API 时优先走 Docker 内网; +- 未来接入 App、第三方赛事系统或开放平台时,再单独设计 CORS、Token 和 API 子域名; +- 未来使用 SSE 时,代理关闭响应缓冲,并设置足够长的连接超时。 + +## 2. NestJS 和 Fastify + +NestJS 提供模块、依赖注入、Guard、拦截器、异常过滤器和 OpenAPI 集成。 +Fastify Adapter 负责底层 HTTP 服务。 +这个组合适合授权、项目、邀请、积分和订单等规则较多的业务。 + +代码按以下规则编写: + +- 使用兼容 Fastify 的 NestJS 插件; +- Controller 只接收请求、调用应用服务并组织响应; +- 复杂业务规则放在应用服务; +- Guard 和资源归属检查共同完成权限校验; +- 所有输入使用 DTO 校验; +- API 响应使用专门的响应类型,数据库实体只在数据访问层使用; +- 错误格式统一,并带 `requestId`; +- API 路径使用 `/api/v1`,JSON 字段使用 `camelCase`,URL 使用小写短横线。 + +推荐的目录如下: + +```text +src/ + modules/ + identity/ + users/ + profiles/ + consents/ + projects/ + opportunities/ + invitations/ + points/ + commerce/ + recommendations/ + operations/ + common/ + guards/ + filters/ + interceptors/ + decorators/ + infrastructure/ + database/ + storage/ + cache/ +``` + +## 3. REST API 规则 + +### 3.1 用资源设计路径 + +资源名使用名词和复数形式: + +```text +GET /api/v1/projects +GET /api/v1/projects/{projectId} +POST /api/v1/projects +PATCH /api/v1/projects/{projectId} +DELETE /api/v1/projects/{projectId} +``` + +明确的从属关系使用嵌套资源: + +```text +GET /api/v1/projects/{projectId}/members +POST /api/v1/projects/{projectId}/applications +``` + +生成报告等耗时动作建模为报告资源或任务资源。 +客户端先创建任务,再查询任务进度和结果。 + +### 3.2 HTTP 状态码 + +| 状态码 | 使用场景 | +| --- | --- | +| `200` | 读取或更新成功 | +| `201` | 创建资源成功 | +| `202` | 异步任务已接受 | +| `204` | 成功且没有响应内容 | +| `400` | 请求格式错误 | +| `401` | 未登录或会话失效 | +| `403` | 当前用户没有权限 | +| `404` | 资源不存在 | +| `409` | 当前资源状态不允许这次操作 | +| `422` | 字段校验失败 | +| `429` | 请求频率超过限制 | +| `500` | 服务端出现未处理异常 | + +### 3.3 响应和错误格式 + +成功响应统一使用 `data` 字段。列表响应在 `meta` 中返回游标和分页信息。 + +错误响应采用 `application/problem+json`。 +响应至少包含 `type`、`title`、`status`、`code`、`detail` 和 `requestId`。 + +### 3.4 可重复提交的写操作 + +订单创建、积分发放、邀请接受、付费权益创建和报告任务等操作支持 `Idempotency-Key`。 +服务端保存请求结果,客户端重试时返回同一结果。 + +权限由 API 服务端统一检查,前端按钮只负责展示状态。 + +## 4. Identity 身份模块 + +### 4.1 职责 + +`Identity` 负责用户身份和会话。 +个人资料、能力画像、项目经历和测评结果由其他模块管理。 + +建议的核心表: + +```text +users +user_identities +sessions +email_verifications +login_events +``` + +### 4.2 登录方式 + +- 微信扫码或授权登录作为主入口; +- 邮箱用于绑定、验证、通知和账号恢复; +- 登录方式和用户主体分开保存,同一用户可以绑定多种登录方式; +- 会话使用 HttpOnly、Secure Cookie; +- 服务端保存会话状态和撤销记录; +- 长期 Token 放在服务端会话中管理。 + +未来可以增加手机号、学校身份验证或其他第三方身份,统一挂在 `users` 用户主体下。 + +## 5. Drizzle 和原生 SQL + +### 5.1 选择规则 + +| 场景 | 访问方式 | +| --- | --- | +| 普通增删改查 | Drizzle | +| 普通事务 | Drizzle transaction | +| JSONB 复杂筛选 | Drizzle + SQL | +| `pgvector` 相似度查询 | SQL Repository | +| 推荐排序 | SQL Repository | +| 全文搜索 | SQL Repository | +| 报表和聚合 | SQL Repository | + +原生 SQL 使用参数绑定。查询条件和排序字段经过代码校验后再拼接。 + +### 5.2 数据访问顺序 + +```text +Controller + ↓ +Application Service + ↓ +Repository Interface + ↓ +Drizzle Repository 或 SQL Repository + ↓ +PostgreSQL +``` + +Controller 通过 Repository 读取数据,这样业务规则和具体数据库工具可以分别测试和替换。 + +### 5.3 数据库迁移 + +- 数据库结构用版本化迁移保存; +- 普通表由 Drizzle Schema 和迁移工具维护; +- `pgvector`、特殊索引、函数和分区可以使用手写迁移 SQL; +- 生产环境的每次表结构变化都要留下迁移记录。 + +## 6. PostgreSQL、JSONB 和 pgvector + +### 6.1 PostgreSQL 保存什么 + +PostgreSQL 保存需要事务一致性的业务数据。 +这些数据包括用户、身份、授权、项目、成员、申请、积分、订单、报告信息和推荐记录。 + +Redis 负责速度和临时状态。最终业务状态仍以 PostgreSQL 为准。 + +### 6.2 JSONB 适合保存什么 + +JSONB 适合保存: + +- 灵活的用户偏好; +- AI 输出的结构化报告内容; +- 带版本号的推荐特征快照; +- 运营可以调整的配置字段。 + +用户身份、权限、订单金额和状态,使用结构化字段。 +积分流水和项目成员关系,也使用结构化字段。 +数据库约束负责保证这些关系的一致性。 + +### 6.3 pgvector 怎样使用 + +`pgvector` 用于项目、课程、学科和公开内容的语义检索。每条向量记录至少保存: + +- 来源资源 ID; +- Embedding 模型名称; +- 模型版本; +- 向量维度; +- 生成时间; +- 来源内容版本。 + +测评原始回答等敏感数据的向量化需要单独评估,并保留可解释的推荐理由。 + +## 7. 数据表和生命周期 + +### 7.1 业务分层 + +建议按下面的业务层组织表: + +```text +身份层:users、user_identities、sessions +资料层:profile_basics、profile_preferences、public_profiles +认知层:assessment_sessions、assessment_answers、insight_snapshots +证据层:insight_evidence、project_reviews、behavior_events +授权层:consent_grants、consent_audits +项目层:opportunities、projects、project_members、applications +增长层:referral_events、point_ledger +审计层:audit_logs +``` + +### 7.2 大表处理 + +现在按业务功能拆表,方便权限、索引和数据保存周期管理。 +大型追加型表按以下顺序处理: + +1. 建立合理索引; +2. 优化时间范围查询; +3. 归档冷数据; +4. 为特殊查询建立单独的 SQL Repository; +5. 数据量持续增长后,再评估 PostgreSQL 分区。 + +## 8. Redis 的用途 + +Redis 用于: + +- 热点数据缓存; +- 请求限流; +- 短期验证码和临时状态; +- 异步任务队列; +- 幂等键状态; +- 短期排行榜。 + +最终积分余额、订单状态、授权记录和用户画像原始数据,统一从 PostgreSQL 读取。 +项目成员关系也由 PostgreSQL 保存。 + +## 9. 阿里云 OSS 文件流程 + +```text +API 创建临时凭证 + ↓ +浏览器直接上传 OSS + ↓ +上传完成后通知 API + ↓ +PostgreSQL 写入文件信息 + ↓ +按需解析、审核或建立索引 +``` + +数据库保存的文件信息包括: + +```text +fileId +ownerId +objectKey +mimeType +size +hash +visibility +createdAt +``` + +私有文件通过短期签名 URL 访问。上传流程检查文件类型、大小、哈希和归属关系。 + +## 10. ECS 和 Docker Compose + +### 10.1 第一阶段服务 + +```text +nginx +web +api +worker(AI 助手方案待决定) +postgres +redis +``` + +应用容器配置健康检查和自动重启。镜像推送到镜像仓库,生产环境使用固定版本标签。 + +### 10.2 为未来 Kubernetes 做准备 + +现在就按以下方式运行: + +- Web、API 和 Worker 分开成容器; +- 应用服务保持无状态; +- 配置通过环境变量或 Secret 注入; +- 文件放在 OSS; +- 数据库迁移独立执行; +- 服务之间通过内部 DNS 或配置发现通信。 + +### 10.3 数据服务的运维要求 + +如果 PostgreSQL 和 Redis 运行在 ECS 上,至少准备独立数据盘,并安排: + +- 自动备份; +- 备份保留周期; +- 恢复演练; +- 磁盘空间监控; +- 数据库升级和回滚方案。 + +## 11. Uptime Kuma 和测试 + +### 11.1 可用性检查 + +建议提供两个健康检查接口: + +```text +GET /api/v1/health/live +GET /api/v1/health/ready +``` + +`live` 只检查进程是否存活。`ready` 检查 PostgreSQL、Redis 和必要配置是否可用。 + +Uptime Kuma 监控首页、两个健康接口、TCP 端口和 HTTPS 证书到期时间。 + +### 11.2 测试范围 + +第一阶段至少安排: + +- TypeScript 类型检查; +- Lint; +- API 单元测试和集成测试; +- 关键流程端到端测试; +- 发布前数据库迁移检查。 + +核心流程按下面的顺序覆盖: + +```text +微信登录 +→ 绑定邮箱 +→ 创建个人资料 +→ 创建项目 +→ 发送邀请 +→ 授权共享 +→ 提交项目申请 +→ 记录积分流水 +``` + +## 12. 仍需决定的技术事项 + +以下内容等产品流程和数据量更清楚后再决定: + +- AI 助手使用的模型供应商和模型路由; +- AI 助手的对话编排框架; +- 长报告和复杂任务使用哪种队列; +- 推荐系统是否拆成独立服务; +- 是否引入专用搜索引擎; +- Kubernetes 的发行版和部署方式; +- 完整的日志、指标和链路追踪方案。 diff --git a/docs/architecture/technology-stack.md b/docs/architecture/technology-stack.md new file mode 100644 index 0000000..52f6794 --- /dev/null +++ b/docs/architecture/technology-stack.md @@ -0,0 +1,151 @@ +# AIwelink 技术方案 + +本文说明第一阶段的 Web、业务 API、数据存储、文件存储、部署和基础监控方案。 + +AI 助手的模型供应商、对话编排方式和后台任务方案列为后续技术决定。 +本文先约定接口和职责,具体实现等业务流程确定后再选。 + +## 1. 总体方案 + +第一阶段使用模块清楚、可以逐步扩展的架构: + +- Web 页面和业务 API 分开部署; +- Web 和 API 通过一个域名对外提供服务,API 统一使用 `/api/v1` 路径; +- PostgreSQL 保存需要事务保证的数据,并使用 `JSONB`、全文搜索和 `pgvector`; +- Redis 处理缓存、限流和异步任务; +- 阿里云 OSS 保存简历、作品、报告和项目附件; +- Web、API 和任务程序都运行在 Docker 容器中; +- 第一阶段使用自有 ECS 和 Docker Compose,规模增长后再迁移到 Kubernetes; +- 用户身份、个人资料、项目行为和授权记录按敏感程度分开保存; +- 初期用 Uptime Kuma 检查网站和 API 是否可访问。 + +## 2. 已确定的技术选型 + +| 领域 | 当前选择 | +| --- | --- | +| Web 前端 | Next.js + React + TypeScript | +| 业务 API | NestJS + Fastify Adapter | +| API 形式 | REST API,路径前缀 `/api/v1` | +| 数据访问 | Drizzle ORM;复杂查询使用参数化原生 SQL | +| 主数据库 | PostgreSQL | +| 向量检索 | PostgreSQL 的 `pgvector` 扩展 | +| 缓存和任务队列 | Redis | +| 文件存储 | 阿里云 OSS | +| 运行环境 | Docker | +| 第一阶段部署 | 自有 ECS + Docker Compose | +| 后续部署 | Kubernetes | +| 身份系统 | API 内部的 `Identity` 模块 | +| 初期监控 | Uptime Kuma | + +## 3. 服务怎样连接 + +```text +浏览器 + | + v +Nginx 或其他入口代理 + |-- / -> Next.js Web 容器 + |-- /api/v1/* -> NestJS + Fastify API 容器 + | + Drizzle / SQL Repository + | + PostgreSQL + pgvector + | + Redis + | + 阿里云 OSS +``` + +Next.js 负责页面和交互。 +NestJS 负责业务规则和 REST API。 +浏览器通过同一个域名下的 `/api/v1/...` 路径调用 API。 + +## 4. API 内部模块 + +API 按业务模块组织,第一阶段至少包含: + +- `Identity`:微信登录、邮箱绑定、会话和登录记录; +- `Users`:基础资料、学校、专业和年级; +- `Profiles`:个人画像、公开画像和画像版本; +- `Consents`:画像共享授权、撤销和授权记录; +- `Projects`:竞赛、项目、队伍、成员和申请; +- `Invitations`:邀请链接、接受记录和邀请关系; +- `Points`:积分流水、任务和兑换权益; +- `Commerce`:课程、API 权益、订单和退款记录; +- `Recommendations`:推荐内容、推荐理由和用户反馈; +- `Operations`:内容审核、举报、活动和运营配置。 + +AI 助手先通过独立接口接入。 +模型、任务队列和报告生成流程确定后,再决定服务是否单独部署。 + +## 5. 数据怎样分层 + +数据按业务含义和敏感程度安排存储位置: + +- 身份信息和联系方式; +- 原始测评回答; +- AI 生成的个人画像; +- 真实项目行为和合作证据; +- 用户主动公开的画像; +- 授权记录和审计记录。 + +大表先使用合理的表结构、索引和归档策略。 +数据量和查询方式出现明确需求后,再评估 PostgreSQL 分区或其他存储方式。 + +## 6. 文件和媒体 + +简历、作品、报告和项目附件保存到阿里云 OSS,流程如下: + +1. API 创建临时上传凭证; +2. 浏览器直接上传 OSS; +3. API 接收上传完成通知; +4. PostgreSQL 保存文件信息和权限关系; +5. 后台任务按需解析、审核或建立搜索索引。 + +应用服务器只处理上传授权和文件信息,不承担大文件的长期保存。 + +## 7. 部署和后续扩展 + +第一阶段用 Docker Compose 管理这些服务: + +- Web 容器; +- API 容器; +- Worker 容器,用于异步任务; +- PostgreSQL; +- Redis。 + +生产环境逐步把应用容器和 PostgreSQL、Redis 分开部署,或改用托管服务。 +同时设置备份、恢复和升级流程。 + +迁移 Kubernetes 时,应用服务保持无状态。 +配置通过环境变量或 Secret 注入,文件继续放在 OSS,数据库迁移单独执行。 + +## 8. 监控和测试 + +Uptime Kuma 负责基础可用性检查: + +- 首页是否能打开; +- `/api/v1/health/live` 是否返回进程存活; +- `/api/v1/health/ready` 是否确认 PostgreSQL、Redis 和必要配置可用; +- HTTPS 证书和端口是否正常。 + +测试单独建设,至少覆盖 TypeScript 类型检查、Lint、API 测试和关键流程端到端测试。 +发布前还要检查数据库迁移。 +核心流程包括登录、授权、邀请、项目申请和积分流水。 + +## 9. 第一阶段的工作重点 + +先完成用户登录、个人资料、自我认知、机会浏览、邀请共享、项目申请和积分记录。 +再根据真实使用数据决定以下能力的时间: + +- 微服务拆分; +- Kubernetes 生产部署; +- 独立向量数据库; +- Elasticsearch 或 OpenSearch; +- ClickHouse; +- MongoDB; +- 复杂机器学习推荐服务; +- 专门的 AI 助手编排框架。 + +这些能力都保留后续空间。 +当前开发围绕用户找到机会、组成队伍并完成项目展开。 diff --git a/docs/current-knowledge-and-plan.md b/docs/current-knowledge-and-plan.md new file mode 100644 index 0000000..ba92317 --- /dev/null +++ b/docs/current-knowledge-and-plan.md @@ -0,0 +1,307 @@ +# AIwelink 当前知识与开发安排 + +这份总览回答四个问题: + +1. AIwelink 现在要做什么; +2. 哪些事情已经确定; +3. 哪些事情还需要拍板; +4. 开发应该按什么顺序推进。 + +原来的文档已经备份到 `docs_old/`。 +当前版本放在 `docs/`,内容以容易阅读和实际执行为目标。 + +## 1. 当前状态 + +- 产品方向:帮助大学生认识自己、找到项目机会; +- 用户在真实合作中积累成长记录; +- 第一阶段从大学生竞赛和技术项目开始; +- 技术主线已经确定:Next.js、NestJS、PostgreSQL、Redis、OSS、Docker Compose; +- 代码目录处于初始化前阶段; +- AI 助手的模型、对话编排和任务队列列为待决定事项; +- 第一场重点竞赛、运营节奏和收费价格列为待安排事项; +- 商业、市场和运营资料继续放在飞书。 + +## 2. 我们已经知道什么 + +### 2.1 用户要完成的事情 + +用户进入平台后,应该可以完成下面的过程: + +```text +登录 + -> 填写资料并了解自己 + -> 看到适合的竞赛或项目 + -> 选择项目角色 + -> 邀请朋友并授权共享 + -> 生成双方的合作建议 + -> 申请加入项目 + -> 记录项目进展和队友反馈 + -> 完成复盘并更新个人画像 +``` + +平台的价值来自真实行动和结果。推荐、报告和积分都要服务于这条过程。 + +### 2.2 第一阶段的产品范围 + +第一阶段优先完成这些功能: + +- 微信登录、邮箱绑定和会话管理; +- 基础资料和个人画像; +- 自我认知助手的提问、回答和报告; +- 竞赛、项目和招募信息; +- 项目角色、成员和申请; +- 邀请链接和双方共享许可; +- 双人合作建议; +- 项目进展、队友反馈和复盘; +- 积分流水和基础兑换; +- 推荐内容和推荐理由; +- 首页工作台和公开机会页。 + +运营后台、完整商业交易、复杂推荐模型和大规模数据服务放在后续阶段安排。 + +### 2.3 数据应该留下什么 + +核心业务数据集中在 PostgreSQL: + +- 用户和登录身份; +- 基础资料和公开资料; +- 测评回答和个人画像版本; +- 项目、成员、申请和行为记录; +- 队友反馈和项目复盘; +- 邀请、共享许可和审计记录; +- 积分流水、订单和权益; +- 推荐内容、推荐理由和用户反馈。 + +Redis 处理缓存、限流、短期状态和任务队列。 +阿里云 OSS 保存简历、作品、报告和项目附件。 + +## 3. 已确认的工程规则 + +### 3.1 应用和访问路径 + +- Web 使用 Next.js + React + TypeScript; +- API 使用 NestJS + Fastify Adapter; +- Web 和 API 共用一个域名; +- API 路径统一从 `/api/v1` 开始; +- Web 负责页面和交互,API 负责业务规则; +- 入口代理按路径把请求转给 Web 或 API。 + +### 3.2 代码分层 + +数据库访问按下面的顺序组织: + +```text +Controller + -> Application Service + -> Repository + -> PostgreSQL +``` + +普通查询使用 Drizzle ORM。 +向量检索、全文搜索、推荐排序和复杂报表使用参数化原生 SQL。 +Controller 通过 Repository 访问数据库。 + +### 3.3 部署和基础设施 + +第一阶段的服务包括: + +```text +nginx +web +api +worker +postgres +redis +``` + +这些服务使用 Docker Compose 部署到自有 ECS。 +文件上传到 OSS。 +Uptime Kuma 检查首页、健康接口、端口和 HTTPS 证书。 + +## 4. 还需要拍板的事项 + +这些决定会直接影响产品和代码,建议按顺序确认: + +### 4.1 确定第一个用户场景 + +需要明确第一场重点竞赛或项目,并写出完整流程: + +- 用户从哪里进入; +- 需要填写哪些信息; +- 怎样看到机会; +- 怎样邀请队友; +- 怎样提交申请; +- 怎样记录项目结果。 + +### 4.2 确定个人画像的内容 + +需要确定自我认知助手的输入和输出: + +- 需要问哪些问题; +- 报告包含哪些部分; +- 哪些内容可以公开分享; +- 用户怎样修改或补充报告; +- 项目反馈怎样更新画像。 + +### 4.3 确定项目和申请规则 + +需要确定: + +- 项目有哪些状态; +- 项目角色怎样定义; +- 谁可以发布项目; +- 申请怎样审核; +- 成员怎样加入和退出; +- 项目完成后需要提交哪些结果。 + +### 4.4 确定 AI 助手方案 + +需要选择: + +- 第一阶段使用的模型供应商; +- 单轮问答还是多轮对话; +- 报告是否异步生成; +- 任务失败后的重试方式; +- 记录哪些提示词、版本和费用信息。 + +### 4.5 确定运行方式 + +需要确定: + +- PostgreSQL 和 Redis 自建还是托管; +- 备份保留多久; +- 生产环境的域名和证书管理; +- 日志、指标和告警使用哪些工具; +- 发布和回滚由谁负责。 + +## 5. 建议的开发顺序 + +### 第一步:写清第一个场景 + +先用一页文档写完「用户参加一场竞赛并找到队友」的过程。 +再把页面、接口、数据和成功条件列出来。 + +产出: + +- 用户流程图; +- 页面清单; +- API 清单; +- 数据表草图; +- 第一阶段成功指标。 + +### 第二步:初始化单仓库 + +创建下面的基础目录: + +```text +apps/web +apps/api +apps/worker +packages/contracts +packages/db +packages/validation +packages/ui +packages/config +infra/docker +docs/decisions +``` + +同时配置 TypeScript、Lint、测试命令、环境变量示例和数据库迁移流程。 + +### 第三步:先做最小 API + +建议先完成: + +1. 登录和会话; +2. 用户资料; +3. 机会和项目; +4. 项目成员和申请; +5. 邀请和共享许可; +6. 积分流水; +7. 健康检查接口。 + +这些接口先用固定测试数据跑通,再接入真实页面。 + +### 第四步:接入自我认知助手 + +先定义统一的输入、输出和任务状态: + +- 输入:用户回答、资料和项目上下文; +- 输出:结构化个人画像、推荐理由和待确认建议; +- 状态:待处理、处理中、完成、失败; +- 记录:模型名称、版本、提示词版本、耗时和费用。 + +模型供应商确定后,只替换具体实现,不改变业务接口。 + +### 第五步:完成 Web 主流程 + +Web 先实现这些页面: + +- 公开机会页; +- 登录页; +- 个人资料页; +- 自我认知助手页; +- 首页工作台; +- 项目详情页; +- 邀请和共享确认页; +- 双人合作建议页; +- 项目申请页; +- 项目进展和复盘页。 + +每个页面都要能回到明确的下一步操作。 + +### 第六步:联调和试用 + +按真实用户顺序测试: + +```text +登录 +→ 填写资料 +→ 完成自我认知 +→ 浏览机会 +→ 邀请朋友 +→ 确认共享 +→ 申请项目 +→ 记录进展 +→ 完成复盘 +``` + +记录用户在哪一步停下、哪些字段看不懂、推荐理由是否有帮助,再调整页面和数据结构。 + +## 6. 第一阶段完成标准 + +第一阶段完成时,至少要满足: + +- 用户可以完成登录并保存资料; +- 用户可以完成一次自我认知并得到结构化报告; +- 用户可以浏览机会和项目,并看到推荐原因; +- 用户可以邀请朋友,双方可以明确选择共享内容; +- 用户可以生成双方合作建议; +- 用户可以申请加入项目并看到申请状态; +- 项目可以记录成员、进展、结果和队友反馈; +- 复盘结果可以形成新的个人画像版本; +- 积分流水可以追溯到具体行为; +- 关键接口有权限检查、错误格式和请求编号; +- 核心流程有自动化测试; +- 生产环境有健康检查、备份和恢复步骤。 + +## 7. 需要持续记录的知识 + +后续每次决定都记录在对应位置: + +- 跨模块技术决定:`docs/decisions/`; +- API 接口和模块实现:`apps/api/docs/`; +- 数据库结构和迁移:`packages/db/docs/`; +- 部署、备份和恢复:`infra/docs/`; +- 临时讨论:`docs-local/`; +- 商业、市场、运营和合作:飞书。 + +每条决定写清楚「问题、选择、原因、影响和后续复查条件」。 +这样新成员可以直接看懂,也方便以后修改。 + +## 8. 当前一句话结论 + +AIwelink 先做一个围绕真实竞赛和项目的成长平台。 +用户从了解自己开始,找到机会和队友,完成项目,再用结果更新自己的认识。 + +开发先把这条用户流程跑通,再扩展 AI 助手、推荐系统、商业服务和更复杂的基础设施。 diff --git a/docs/discussion-summary.md b/docs/discussion-summary.md new file mode 100644 index 0000000..83a1a5d --- /dev/null +++ b/docs/discussion-summary.md @@ -0,0 +1,291 @@ +# AIwelink 讨论结果说明 + +这份文档把项目从最初想法到当前方案的变化讲清楚。 +它帮助新成员理解每个决定是怎么来的。 + +当前状态:产品方向已经收敛到「自我认知 + 项目机会 + 真实合作 + 项目反馈」。 +技术方案也已经确定第一阶段的主要工具。 +代码目录、AI 助手和运营节奏还要继续安排。 + +## 1. 项目从哪里开始 + +最初的想法是做一个项目合作平台。 +用户可以上传简历和资料、发布项目、发起组队,并寻找队友或协作者。 +平台面向大学竞赛,也保留真实开发者项目的空间。 + +继续讨论后,团队发现单独提供资料、帖子和私聊,用户很难得到长期价值。 +于是产品重点逐渐转向「帮助用户找到合适的任务和合作方式,并把项目做完」。 + +## 2. 第一阶段先服务大学生竞赛 + +第一阶段选择大学生竞赛和技术项目,原因有三点: + +- 赛事有明确的报名和截止时间; +- 学校、社团和学生组织方便触达用户; +- 发布机会、申请组队和提交作品的过程容易观察。 + +初期重点关注 AI、软件、数据分析、创新创业等技术相关竞赛。 +后续可以扩展到科研、开源、企业命题和创业项目。 + +## 3. 产品定位逐步明确 + +AIwelink 的核心场景是带着任务一起做事: + +```text +明确的竞赛或项目 + -> 找到需要的角色和能力 + -> 发起申请并组队 + -> 共同完成作品 + -> 记录结果和合作反馈 +``` + +平台沉淀的结果包括有效申请、成功组队、持续合作、作品完成、竞赛提交和项目复盘。 +浏览、点赞和聊天只是辅助行为。 + +校园墙可以作为信息分发渠道。 +校园墙负责本地触达,AIwelink 承接结构化报名、组队、工具使用和成果记录。 + +## 4. 商业方向怎样形成 + +团队把商业路径安排为: + +```text +免费赛事与项目机会 + -> 用户组队并开始真实项目 + -> 用户出现 AI 工具和能力需求 + -> 使用 API、工具包、课程或导师服务 + -> 学校、赛事方和企业采购组织服务 +``` + +当前重点方向包括: + +1. 面向竞赛团队的模型 API 和场景工具包; +2. 赛事课程、训练营、作品评审和答辩辅导; +3. 学校、社团和赛事方的报名、组队与活动管理; +4. 企业命题赛、模型或算力赞助、品牌合作; +5. 基于真实项目经历的人才发现和项目推荐。 + +平台在用户进入项目、遇到具体困难或开始备赛后展示相关服务。 +这样服务内容和用户当前任务直接相关。 + +## 5. 首页要呈现什么 + +首页围绕机会和下一步行动安排内容: + +1. 适合用户的竞赛和项目; +2. 即将截止或正在招募的机会; +3. 用户正在参与的项目; +4. 自我认知和成长任务; +5. 已完成的作品和经验; +6. 与当前项目有关的 API、课程和导师服务。 + +登录可以分阶段要求: + +- 未登录用户浏览部分公开机会; +- 用户收藏、报名、申请组队或开始个性化自我认知时登录; +- 微信作为主登录入口; +- 邮箱用于绑定、验证、通知和账号恢复。 + +## 6. 自我认知功能怎样形成 + +用户真正关心的是自己适合什么任务、角色和协作方式。 +因此,个人画像需要随着行动持续更新: + +```text +自我评估 + -> 选择项目 + -> 真实行动 + -> 队友反馈 + -> 项目复盘 + -> 更新个人画像 +``` + +AI 自我认知助手先给出阶段性建议。 +真实项目行为、合作结果和队友反馈会成为后续更新的重要依据。 + +平台通过提问、项目记录和复盘帮助用户了解: + +- 自己擅长什么; +- 适合承担什么角色; +- 适合怎样的工作环境; +- 哪些环节容易遇到困难; +- 下一步该学习或尝试什么。 + +## 7. 邀请、合作报告和积分 + +自我认知助手也可以作为推广入口: + +```text +免费自我认知助手 + -> 生成个人报告 + -> 分享用户选择的安全摘要 + -> 邀请朋友 + -> 生成双方或团队的合作建议 + -> 推荐适合一起参加的项目 +``` + +双方取得明确许可后,合作报告可以包含: + +- 互补优势; +- 分工建议; +- 可能发生摩擦的地方; +- 推荐的沟通方式; +- 适合一起参加的项目; +- 合作前需要约定的规则。 + +积分奖励绑定真实行为。 +例如完成个人报告、完成共享许可、生成合作报告、参加项目和完成复盘。 +积分可以兑换深度报告、API 额度、课程优惠、导师问答或挑战资格。 + +第一阶段先服务已经认识的朋友、同学和队友。 +随着项目记录增加,再扩展到三至五人的团队合作建议。 + +## 8. 推荐系统的方向 + +推荐对象包括竞赛、项目、学科和学习内容。 +也包括项目角色、合作对象、课程、导师和 AI 工具。 + +推荐会综合这些信息: + +- 用户能力和目标; +- 可以投入的时间; +- 工作偏好; +- 完成或放弃过的项目; +- 项目中的真实行为; +- 队友反馈和复盘结果。 + +第一阶段先采用规则、标签、行为信号和必要的向量检索。 +每条推荐带理由,让用户知道选择依据。 + +## 9. 技术方案怎样确定 + +### 9.1 后端语言 + +团队比较了 Go、TypeScript 和 Python。 +第一阶段业务主要处理网络请求、数据库读写和第三方模型调用。 +全栈 TypeScript 已经能够覆盖这些工作。 + +Go 留作未来独立高性能服务的选择。 +Python 留作算法和数据分析任务的选择。 +当前先保持一个主要语言,减少工程维护量。 + +### 9.2 Web 框架 + +React 负责 UI 组件,Next.js 负责完整 Web 应用。 +平台需要公开机会页、分享页、搜索收录和登录后的工作台。 +因此确定使用: + +> Next.js + React + TypeScript + +页面质量由设计系统、信息层级、动效、响应式布局和性能共同决定。 + +### 9.3 Web 和 REST API + +Web 与业务 API 分开: + +```text +https://aiwelink.com/ -> Next.js +https://aiwelink.com/api/v1/* -> 独立 REST API +``` + +同域名入口减少跨域和子域名配置工作,也保留未来独立扩展 API 的空间。 + +### 9.4 API 框架 + +后端采用 NestJS + Fastify Adapter。 +NestJS 负责模块、依赖注入、权限 Guard、异常处理和 OpenAPI。 +Fastify 负责 HTTP 服务。 + +### 9.5 数据访问 + +普通增删改查和事务使用 Drizzle ORM。 +向量相似度、全文搜索、推荐排序和复杂报表通过 Repository 使用参数化原生 SQL。 + +### 9.6 数据和基础设施 + +- PostgreSQL 保存主要业务数据; +- `pgvector` 提供向量检索; +- Redis 负责缓存、限流和任务队列; +- 阿里云 OSS 保存简历、作品、报告和附件; +- Docker 运行 Web、API 和 Worker; +- 第一阶段部署在自有 ECS + Docker Compose; +- 后续根据规模迁移 Kubernetes; +- Uptime Kuma 负责基础可用性监控。 + +## 10. 单仓库和文档位置 + +项目使用单 Git 仓库(Monorepo),计划按以下目录组织: + +- `apps/web`:Next.js Web; +- `apps/api`:NestJS REST API; +- `apps/worker`:异步任务; +- `apps/admin`:后续运营后台; +- `packages/contracts`:OpenAPI、DTO 和共享接口; +- `packages/db`:Drizzle Schema、迁移和种子数据; +- `infra`:Docker、ECS、备份和后续 Kubernetes 配置。 + +文档位置按内容分工: + +| 文档内容 | 位置 | +| --- | --- | +| 总体架构、技术栈、工程规范 | 根目录 `docs/` | +| API 接口和模块实现 | `apps/api/docs/` | +| 数据库结构和迁移规范 | `packages/db/docs/` | +| 技术部署和备份 | `infra/docs/` | +| 临时需求和未确认讨论 | `docs-local/` | +| 商业、市场、运营和合作 | 飞书 | + +## 11. 当前已经确定的事情 + +- 第一阶段服务大学生竞赛和技术项目; +- 产品由自我认知、机会推荐、真实合作和项目反馈组成; +- 首页围绕机会和下一步行动; +- 双方取得许可后生成合作建议; +- 推荐结果说明原因; +- 使用 Next.js + React + TypeScript; +- 使用独立 REST API,路径为 `/api/v1`; +- Web 和 API 共用一个域名; +- 使用 NestJS + Fastify Adapter; +- 使用 Drizzle 和参数化原生 SQL; +- API 内部建立 `Identity` 模块; +- 使用 PostgreSQL、`pgvector`、Redis 和阿里云 OSS; +- 第一阶段使用 ECS + Docker Compose; +- 商业和运营资料放在飞书。 + +## 12. 还要决定的事情 + +- AI 助手使用哪家模型和怎样路由模型; +- AI 助手使用哪种对话编排框架; +- 长报告和复杂任务使用哪种队列; +- 推荐系统是否拆成独立服务; +- 测试工具和日志、指标方案; +- 生产环境的 PostgreSQL 和 Redis 使用自建还是托管; +- 第一场重点竞赛、运营节奏和具体价格。 + +## 13. 给新成员的阅读顺序 + +1. 先读本文,了解产品方向的变化; +2. 再读 `docs/project-handoff.md`,了解工程规则; +3. 阅读 `docs/architecture/technology-stack.md`,掌握整体技术方案; +4. 阅读 `docs/architecture/technology-stack-details.md`,了解接口、数据和部署细节; +5. 开始实现对应模块前,再阅读模块文档和决定记录; +6. 遇到待决定的事项,先保持接口清楚,把选项和依据记录下来。 + +## 14. 讨论结论 + +项目方向从「项目合作平台」逐步明确为: + +```text +项目合作平台 + -> 大学生竞赛组队 + -> 以任务为中心的协作 + -> 以自我认知为长期能力 + -> 推荐项目、学科和合作对象 + -> 双方取得许可后生成合作建议 + -> 通过真实项目积累成长和合作数据 + -> 用 API、课程、导师和机构服务提供收入 +``` + +技术安排遵循同一原则:先用清楚、稳定、可以持续修改的模块化架构验证用户价值。 +等用户数量、项目数据和实际故障模式变得清楚后,再决定后续技术投入。 +候选项包括 AI 助手编排、复杂推荐、Kubernetes 和专用基础设施。 diff --git a/docs/project-handoff.md b/docs/project-handoff.md new file mode 100644 index 0000000..410c14e --- /dev/null +++ b/docs/project-handoff.md @@ -0,0 +1,289 @@ +# AIwelink 项目交接说明 + +这份文档帮助新成员快速了解 AIwelink 要解决的问题。 +文档也说明第一阶段要做什么,以及当前已经确定的工程规则。 + +当前状态:产品方向和主要技术选型已经确定。 +代码目录处于初始化前阶段。 +商业、市场和运营安排仍以飞书中的文件为准。 + +## 1. AIwelink 是什么 + +AIwelink 帮助大学生认识自己的能力,找到合适的学习或项目机会。 +用户在真实合作中积累经验。 + +第一阶段从大学生竞赛和技术项目开始。平台长期要做的事情是: + +```text +了解自己 + -> 找到合适的机会 + -> 参加真实项目 + -> 和合适的人合作 + -> 得到项目结果和队友反馈 + -> 更新对自己的认识 +``` + +这里的「个人画像」指对用户能力、偏好、目标和合作方式的结构化描述。 +画像会随着项目反馈持续更新。 + +## 2. 产品要解决什么问题 + +### 2.1 把信息变成行动 + +校园墙擅长让信息被看见。 +AIwelink 进一步把信息整理成可执行的项目机会,帮助合适的人开始合作并完成项目。 + +项目或竞赛机会应尽量写清楚: + +- 要做什么,以及何时截止; +- 需要哪些角色和能力; +- 每个角色要投入多少时间; +- 用户下一步可以做什么; +- 最后能留下什么作品或结果。 + +平台重点关注有效申请、成功组队、持续合作和完成项目的队伍数量。 + +### 2.2 让画像随着实践更新 + +AI 自我认知助手(Agent)先给出阶段性判断。 +用户参加项目后的行为、队友反馈和项目复盘,会帮助平台持续更新这份判断。 + +平台要帮助用户回答: + +- 我擅长哪类任务? +- 我适合在项目中承担什么角色? +- 什么工作环境更适合我? +- 哪些环节可能让我的合作变困难? +- 下一步应该尝试什么,或补哪项能力? + +### 2.3 社交从一起做事开始 + +平台的社交功能围绕共同目标展开。 +第一阶段优先服务用户已经认识的朋友、同学和队友。 +恋爱交友放到后续产品规划中。 + +推荐的合作过程是: + +```text +查看个人画像 + -> 邀请认识的人 + -> 双方明确同意共享内容 + -> 生成双方的合作建议 + -> 一起参加项目或挑战 + -> 根据结果建立长期合作关系 +``` + +双方合作报告重点说明优势互补、分工建议和可能的冲突。 +报告还会给出沟通方式和适合一起尝试的项目。 + +### 2.4 推荐要让用户知道原因 + +平台可以推荐竞赛、项目、学习内容、项目角色、合作对象、课程、导师和 AI 工具。 +每条推荐都应说明原因,并同时提供三类选择: + +1. 当前能力可以完成的机会; +2. 能补足短板的机会; +3. 有一定挑战、适合探索的机会。 + +这样的推荐会帮助用户理解自己,并保留尝试不同方向的空间。 + +### 2.5 首页先告诉用户下一步做什么 + +首页把机会和下一步行动放在最前面,首先展示: + +1. 适合用户的机会和项目; +2. 用户正在参与的项目; +3. 自我认知和成长任务; +4. 已完成的作品和项目经验; +5. 用户遇到具体问题后再推荐课程、API 或导师服务。 + +首页要回答一个简单问题:「现在最值得做的下一件事是什么?」 + +## 3. 第一阶段要验证的完整流程 + +第一阶段先验证下面这条流程能否真正帮助用户完成项目: + +```text +自我认知助手 + -> 生成个人画像 + -> 推荐竞赛、项目和学习方向 + -> 邀请朋友并取得共享许可 + -> 生成双方合作建议 + -> 参加一次真实项目或挑战 + -> 记录项目行为和队友反馈 + -> 复盘并更新个人画像 +``` + +免费自我认知助手可以作为推广入口。 +用户完成报告后,可以分享由自己选择的安全摘要。 +邀请朋友并完成有效合作行为后,可以获得积分。 +积分可兑换深度报告、API 额度、课程优惠或挑战资格。 + +积分奖励绑定报告完成、授权共享、生成合作报告、参加项目和完成复盘等真实行为。 + +## 4. 商业方向 + +平台先提供免费的机会和自我认知服务。 +用户进入项目并遇到真实需求后,再提供付费服务: + +```text +赛事和项目机会 + -> 组队并开始合作 + -> 产生 AI 工具和能力需求 + -> 使用 API、课程、训练营或导师服务 + -> 为学校、赛事方和企业提供组织服务 +``` + +可能的收入来源包括: + +- 面向竞赛团队的模型 API 和工具包; +- 赛事课程、训练营、作品评审和答辩辅导; +- 导师、作品评审和项目启动服务; +- 学校、社团和赛事方的报名、组队与活动管理; +- 企业命题赛、品牌合作和人才发现。 + +API 和课程在用户进入项目或明确遇到问题后出现,与当前任务直接相关。 + +## 5. 已确定的技术方案 + +| 领域 | 当前选择 | +| --- | --- | +| Web | Next.js、React、TypeScript | +| 业务 API | NestJS + Fastify Adapter | +| API 形式 | REST API,路径统一以 `/api/v1` 开头 | +| 数据访问 | Drizzle ORM;复杂查询使用参数化原生 SQL | +| 主数据库 | PostgreSQL | +| 向量检索 | PostgreSQL 的 `pgvector` 扩展 | +| 缓存和任务队列 | Redis | +| 文件存储 | 阿里云 OSS | +| 第一阶段部署 | 自有 ECS + Docker Compose | +| 后续部署 | Kubernetes | +| 身份系统 | API 内部的 `Identity` 模块 | +| 初期可用性监控 | Uptime Kuma | + +AI 助手使用哪家模型、怎样编排对话、是否拆成独立服务,列为后续技术决定。 +当前实现先保留清晰的接口,模型和框架确定后再接入。 + +### 5.1 Web 和 API 如何访问 + +Web 和 API 是两个独立应用,但第一阶段共用一个公网域名: + +```text +https://aiwelink.com/ -> Next.js Web +https://aiwelink.com/api/v1/* -> NestJS REST API +``` + +入口代理(例如 Nginx)根据路径把请求转给不同容器。 +第一阶段沿用同一个域名,核心业务统一放在 NestJS API 中。 + +### 5.2 API 规则 + +- URL 使用小写短横线,JSON 字段使用 `camelCase`; +- 使用资源名词和复数路径,例如 `/projects`; +- 使用标准 HTTP 方法和状态码; +- 列表优先使用游标分页; +- 订单、积分发放等容易重复提交的写操作按需支持 `Idempotency-Key`; +- 错误返回统一格式,并带 `requestId`; +- 权限由服务端统一检查,前端按钮只负责展示状态; +- 长时间任务建成任务资源,客户端可以查询任务进度和结果。 + +### 5.3 数据访问规则 + +代码按下面的顺序访问数据库: + +```text +Controller + -> Application Service + -> Repository Interface + -> Drizzle Repository 或 SQL Repository + -> PostgreSQL +``` + +普通增删改查和事务使用 Drizzle。 +向量相似度、全文搜索、复杂推荐和报表使用参数化 SQL。 +Controller 通过 Repository 访问数据库。 + +### 5.4 数据和文件怎么放 + +用户身份、测评原始回答、AI 生成的画像和项目行为,按敏感程度分开保存。 +公开内容、授权记录也分别管理。 +大表先用索引、归档和 PostgreSQL 分区处理。 +跨数据库分片等数据规模明确后再安排。 + +简历、作品、报告和项目附件放在阿里云 OSS。 +浏览器直接上传,API 负责签发临时凭证、记录文件信息和检查权限。 +私有文件用短期签名 URL 访问,应用容器只负责传输和权限控制。 + +## 6. 代码仓库和文档放在哪里 + +项目使用一个 Git 仓库(Monorepo),计划采用下面的目录: + +```text +AIwelink/ +├─ apps/ +│ ├─ web/ # Next.js Web +│ ├─ api/ # NestJS REST API +│ ├─ worker/ # 异步任务,AI 助手方案待决定 +│ └─ admin/ # 后续运营后台 +├─ packages/ +│ ├─ contracts/ # OpenAPI、DTO、共享接口 +│ ├─ db/ # Drizzle Schema、迁移、种子数据 +│ ├─ validation/ # 共享数据校验 +│ ├─ ui/ # 跨应用 UI +│ ├─ config/ # 共享配置 +│ └─ tooling/ # 工程工具配置 +├─ infra/ # Docker、ECS、备份和后续 Kubernetes 配置 +├─ scripts/ # 根目录脚本 +├─ docs/ # 进入 Git 的工程文档 +├─ docs-local/ # 本地临时文档,Git 忽略 +└─ .github/ # 后续 CI/CD 配置 +``` + +文档放置规则: + +| 内容 | 位置 | +| --- | --- | +| 总体架构、技术栈、工程规范 | 根目录 `docs/`,提交到 Git | +| API 接口和模块实现 | `apps/api/docs/`,提交到 Git | +| 数据库结构和迁移规范 | `packages/db/docs/`,提交到 Git | +| Docker、ECS、备份等运维说明 | `infra/docs/`,提交到 Git | +| 临时需求、草稿和未确认讨论 | `docs-local/`,不提交到 Git | +| 商业、市场、运营和合作 | 飞书,不复制到 Git | + +如果商业或运营决定会影响代码,只在 `docs/decisions/` 记录脱敏后的技术结论。 + +## 7. 新成员开始开发前要做什么 + +1. 先阅读本文件和[当前知识与安排](./current-knowledge-and-plan.md)。 + 再阅读 `docs/architecture/` 下的技术文档。 +2. 新 API 遵循 `/api/v1` 和资源式 REST 设计。 +3. 新业务模块放在 `apps/api/src/modules/` 对应目录。 +4. 数据库访问统一经过 Repository。 +5. 新的跨模块技术决定写进 `docs/decisions/`。 +6. 商业和运营内容回到飞书维护。 +7. AI 助手方案列为待决定事项。先保留接口和任务范围,模型和框架确定后再接入。 + +## 8. 后续再安排的能力 + +下面这些能力等真实用户和数据出现后再安排: + +- 微服务拆分; +- Kubernetes 生产部署; +- 独立向量数据库; +- Elasticsearch 或 OpenSearch; +- ClickHouse; +- MongoDB; +- 复杂的机器学习推荐服务; +- 已经定型的 AI 助手编排框架; +- 跨数据库分片。 + +当前先验证用户能找到机会、组队并完成项目。 +基础设施的复杂度根据真实数据再增加。 + +## 9. 一句话总结 + +AIwelink 通过真实项目帮助年轻人认识自己、找到合适的机会,并和合适的人把事情做完。 + +技术上先使用模块清楚的单仓库、独立 Web 和 REST API。 +数据使用 PostgreSQL、Redis 和 OSS,第一阶段部署在 ECS + Docker Compose。 +待决定的部分先保留接口,等真实需求出现后再选择。 diff --git a/docs_old/architecture/technology-stack-details.md b/docs_old/architecture/technology-stack-details.md new file mode 100644 index 0000000..6329145 --- /dev/null +++ b/docs_old/architecture/technology-stack-details.md @@ -0,0 +1,424 @@ +# AIwelink 技术栈选型细节 + +> 本文是 [技术栈选型](./technology-stack.md) 的细节说明,记录当前边界、约束、实现规则和演进条件。 + +## 1. Web 与 API 的同域名反向代理 + +### 1.1 对外访问模型 + +第一阶段使用同一个公网域名: + +```text +https://aiwelink.com/ -> Next.js +https://aiwelink.com/api/v1/... -> REST API +``` + +入口反向代理负责路由: + +```text +Client + │ + ▼ +Nginx + ├── /api/v1/* -> api:3000 + └── /* -> web:3000 +``` + +NestJS 设置全局 API 前缀 `/api/v1`。反向代理必须统一是否保留路径前缀,避免产生 `/api/v1/api/v1/...` 的重复路径。 + +### 1.2 同域名的优点 + +- 浏览器不需要跨域访问 API。 +- HttpOnly Cookie 的会话处理更直接。 +- 分享页、公开赛事页和登录后工作台使用同一域名。 +- 本地开发、测试和生产环境的请求路径一致。 +- 将来即使迁移到 `api.aiwelink.com`,外部资源路径仍可以保持不变。 + +### 1.3 注意事项 + +- API 和 Web 要在入口层设置不同的超时、缓存和安全策略。 +- API 不应由 Next.js 页面逻辑重复实现。 +- Next.js 服务端调用 API 时优先使用 Docker 内部网络,而不是绕回公网域名。 +- 如果未来提供 App、第三方赛事系统或开放平台,再单独设计 CORS、Token 和 API 子域名策略。 +- 如果未来使用 SSE,反向代理要关闭响应缓冲并设置长连接超时。 + +## 2. NestJS + Fastify Adapter + +### 2.1 选择原因 + +NestJS 提供模块、依赖注入、Guard、拦截器、异常过滤器和 OpenAPI 集成;Fastify Adapter 提供轻量 HTTP 层。该组合适合授权、项目、邀请、积分、订单等规则较多的业务。 + +### 2.2 代码约束 + +- 统一使用 Fastify 兼容的 NestJS 插件。 +- 不在 Controller 中编写数据库查询和复杂业务规则。 +- 通过 Guard 和服务端资源归属检查完成权限控制。 +- 统一错误格式和 `requestId`。 +- 统一使用 DTO 校验输入,不直接把数据库实体作为 API 响应。 +- API 使用 `/api/v1` 版本前缀,JSON 字段使用 `camelCase`,URL 使用小写短横线。 + +### 2.3 推荐的模块布局 + +```text +src/ + modules/ + identity/ + users/ + profiles/ + consents/ + projects/ + opportunities/ + invitations/ + points/ + commerce/ + recommendations/ + operations/ + common/ + guards/ + filters/ + interceptors/ + decorators/ + infrastructure/ + database/ + storage/ + cache/ +``` + +## 3. RESTful API 约束 + +### 3.1 资源设计 + +使用名词和复数: + +```text +GET /api/v1/projects +GET /api/v1/projects/{projectId} +POST /api/v1/projects +PATCH /api/v1/projects/{projectId} +DELETE /api/v1/projects/{projectId} +``` + +嵌套资源表示明确的从属关系: + +```text +GET /api/v1/projects/{projectId}/members +POST /api/v1/projects/{projectId}/applications +``` + +不要使用 `getProjects`、`createProject`、`generateReport` 这类动词路径。生成报告等动作应建模为创建报告资源或创建任务资源。 + +### 3.2 状态码 + +- `200`:读取或更新成功。 +- `201`:创建资源成功。 +- `202`:异步任务已接受。 +- `204`:成功但无响应体。 +- `400`:请求格式错误。 +- `401`:未登录或会话无效。 +- `403`:无权限。 +- `404`:资源不存在。 +- `409`:资源状态冲突。 +- `422`:字段校验失败。 +- `429`:请求过于频繁。 +- `500`:服务端异常。 + +### 3.3 响应和错误 + +成功响应统一包含 `data`,列表响应在 `meta` 中返回游标信息。错误建议采用 `application/problem+json`,至少包含 `type`、`title`、`status`、`code`、`detail` 和 `requestId`。 + +### 3.4 幂等和安全 + +以下写操作需要支持 `Idempotency-Key`: + +- 订单创建。 +- 积分发放。 +- 邀请接受。 +- 付费权益创建。 +- 可能重复提交的报告任务。 + +权限检查必须在 API 服务端完成,不能依赖前端隐藏按钮。 + +## 4. Identity 模块细节 + +### 4.1 责任边界 + +Identity 模块只负责身份和会话,不负责个人能力画像、项目经历或心理测评结论。 + +建议的核心表: + +```text +users +user_identities +sessions +email_verifications +login_events +``` + +### 4.2 登录方式 + +- 微信扫码或授权登录作为主入口。 +- 邮箱用于绑定、验证、通知和账号恢复。 +- 登录方式与用户主体分离,允许同一用户绑定多个身份。 +- 会话使用 HttpOnly、Secure Cookie。 +- 服务端保存会话状态和撤销记录。 +- 长期 Token 不存储在 `localStorage`。 + +### 4.3 后续可扩展 + +未来可增加手机号、学校身份验证或第三方身份,但不改变 `users` 作为统一用户主体的模型。 + +## 5. Drizzle 与原生 SQL + +### 5.1 默认规则 + +| 场景 | 方式 | +| --- | --- | +| 普通增删改查 | Drizzle | +| 普通事务 | Drizzle transaction | +| JSONB 复杂筛选 | Drizzle + SQL | +| pgvector 相似度 | SQL Repository | +| 推荐排序 | SQL Repository | +| 全文搜索 | SQL Repository | +| 报表和聚合 | SQL Repository | + +原生 SQL 必须参数化,禁止字符串拼接用户输入。 + +### 5.2 访问层边界 + +```text +Controller + ↓ +Application Service + ↓ +Repository Interface + ↓ +Drizzle Repository / SQL Repository + ↓ +PostgreSQL +``` + +Controller 不直接访问数据库,也不直接依赖 Drizzle 实现。 + +### 5.3 迁移 + +- 数据库结构必须版本化迁移。 +- 普通表结构可由 Drizzle Schema 和迁移工具维护。 +- pgvector、特殊索引、函数、分区等能力可以使用手写迁移 SQL。 +- 生产环境禁止手工修改表结构而不留下迁移记录。 + +## 6. PostgreSQL、JSONB 和 pgvector + +### 6.1 PostgreSQL 作为主数据源 + +PostgreSQL 保存所有需要事务一致性的业务数据:用户、身份、授权、项目、成员、申请、积分、订单、报告元数据和推荐记录。 + +Redis 不保存这些数据的最终状态。 + +### 6.2 JSONB 使用边界 + +适合 JSONB: + +- 灵活的用户偏好。 +- Agent 输出的结构化报告内容。 +- 版本化的推荐特征快照。 +- 运营可配置字段。 + +不适合全部放入 JSONB: + +- 用户身份。 +- 权限和授权。 +- 订单金额和状态。 +- 积分流水。 +- 项目成员关系。 + +这些核心关系仍应使用结构化字段和约束。 + +### 6.3 pgvector 使用边界 + +pgvector 用于项目、课程、学科和公开内容的语义召回。向量记录至少保存: + +- 来源资源 ID。 +- Embedding 模型名称。 +- 模型版本。 +- 向量维度。 +- 生成时间。 +- 来源内容版本。 + +原始测评答案和敏感心理数据不应默认向量化,也不应直接作为不可解释的决策依据。 + +## 7. 分层存储与分表策略 + +### 7.1 逻辑分层 + +建议至少划分以下数据层: + +```text +身份层:users、user_identities、sessions +资料层:profile_basics、profile_preferences、public_profiles +认知层:assessment_sessions、assessment_answers、insight_snapshots +证据层:insight_evidence、project_reviews、behavior_events +授权层:consent_grants、consent_audits +项目层:opportunities、projects、project_members、applications +增长层:referral_events、point_ledger +审计层:audit_logs +``` + +### 7.2 分表原则 + +现在就按业务边界拆分表,便于权限、索引和生命周期管理。不要按“感觉可能很大”把一个简单实体过度拆成多个表。 + +大型追加型表应优先考虑: + +- 合理索引。 +- 时间范围查询。 +- 冷数据归档。 +- 单独的查询 Repository。 +- 后续按时间做 PostgreSQL 分区。 + +暂不做跨库分片和手工水平分片。 + +## 8. Redis 使用边界 + +Redis 用于: + +- 缓存热点数据。 +- 请求限流。 +- 短期验证码和临时状态。 +- 队列基础设施。 +- 幂等键状态。 +- 短期排行榜。 + +Redis 不用于保存: + +- 最终积分余额。 +- 订单状态。 +- 授权记录。 +- 用户画像原始数据。 +- 项目成员关系。 + +## 9. 阿里云 OSS 文件流转 + +推荐流程: + +```text +API 创建临时凭证 + ↓ +浏览器直传 OSS + ↓ +上传完成通知 API + ↓ +PostgreSQL 写入文件元数据 + ↓ +按需执行解析、审核或索引 +``` + +数据库只保存: + +```text +fileId +ownerId +objectKey +mimeType +size +hash +visibility +createdAt +``` + +私有文件只能通过短期签名 URL 访问。上传必须限制类型、大小和归属,不能仅依赖文件扩展名。 + +## 10. ECS + Docker Compose + +### 10.1 第一阶段服务 + +```text +nginx +web +api +worker(具体 Agent 方案待定) +postgres +redis +``` + +应用容器需要配置健康检查和自动重启。镜像推送到镜像仓库,生产使用固定版本标签,不直接使用 `latest`。 + +### 10.2 对 Kubernetes 的兼容性 + +现在就遵守: + +- 应用服务无状态。 +- 配置通过环境变量或 Secret 注入。 +- OSS 保存文件,不使用容器本地磁盘。 +- 数据库迁移独立执行。 +- Web、API、Worker 独立容器。 +- 服务之间通过内部 DNS 或配置发现。 + +这些约束可以降低未来迁移 K8S 的改造量。 + +### 10.3 数据服务部署建议 + +如果 PostgreSQL 和 Redis 也运行在 ECS 上,应与应用容器至少分开主机或独立数据盘,并配置: + +- 自动备份。 +- 备份保留周期。 +- 恢复演练。 +- 磁盘空间监控。 +- 数据库升级和回滚方案。 + +## 11. Uptime Kuma 与测试 + +### 11.1 Uptime Kuma 的职责 + +Uptime Kuma 负责基础可用性: + +- 首页 HTTP 监控。 +- API 存活和就绪监控。 +- TCP/端口监控。 +- HTTPS 证书到期提醒。 + +建议提供: + +```text +GET /api/v1/health/live +GET /api/v1/health/ready +``` + +`live` 只判断进程是否存活;`ready` 检查 PostgreSQL、Redis 和必要配置是否可用。 + +### 11.2 测试不由 Uptime Kuma 替代 + +Uptime Kuma 不执行单元测试、接口测试或浏览器流程测试。最低测试基线建议为: + +- TypeScript 类型检查。 +- Lint。 +- API 单元和集成测试。 +- 关键流程端到端测试。 +- 发布前数据库迁移检查。 + +具体测试框架可以在开始实现前再确认,但必须覆盖: + +```text +微信登录 +→ 邮箱绑定 +→ 创建个人资料 +→ 创建项目 +→ 发送邀请 +→ 授权共享 +→ 项目申请 +→ 积分流水 +``` + +## 12. 暂不定型事项 + +以下内容当前不做最终技术承诺: + +- Agent 使用的模型供应商和模型路由。 +- Agent 对话编排框架。 +- 长报告是否使用队列以及具体队列库。 +- 推荐系统是否拆成独立服务。 +- 是否引入专用搜索引擎。 +- Kubernetes 的具体发行版和部署方式。 +- 完整日志、指标和链路追踪方案。 + +这些选项应在业务流程、数据量和实际故障模式出现后再定型。 + diff --git a/docs_old/architecture/technology-stack.md b/docs_old/architecture/technology-stack.md new file mode 100644 index 0000000..ce62f2d --- /dev/null +++ b/docs_old/architecture/technology-stack.md @@ -0,0 +1,143 @@ +# AIwelink 技术栈选型 + +> 状态:第一阶段基线 +> +> 范围:Web 应用、REST API、数据存储、文件存储、部署和基础监控 +> +> 说明:Agent 的具体实现方案暂不定型,不在本文件中做最终技术承诺。 + +## 1. 总体原则 + +AIwelink 第一阶段采用模块化、容器化和可渐进扩展的架构: + +- 前端与业务 API 分离。 +- 对外 API 统一遵循 RESTful 资源设计。 +- Web 与 API 通过同一域名提供服务,API 使用 `/api/v1` 路径反向代理。 +- PostgreSQL 作为业务主数据库,使用 `JSONB`、全文搜索和 `pgvector` 扩展。 +- Redis 用于缓存、限流和异步任务基础设施,不作为最终业务数据源。 +- 文件统一存储在阿里云 OSS,数据库只保存文件元数据。 +- 应用和任务容器化,第一阶段部署在自有 ECS + Docker Compose,后续按规模迁移到 Kubernetes。 +- 用户身份、个人画像、授权和项目行为按数据敏感性分层存储。 +- 先采用 Uptime Kuma 做基础可用性监控,后续再升级完整可观测性体系。 + +## 2. 已确认技术选型 + +| 层 | 选型 | +| --- | --- | +| Web 前端 | Next.js + React + TypeScript | +| 业务 API | NestJS + Fastify Adapter | +| API 风格 | RESTful API,路径前缀 `/api/v1` | +| 数据访问 | Drizzle ORM 为默认访问工具,复杂查询补充原生 SQL | +| 主数据库 | PostgreSQL | +| 向量能力 | PostgreSQL `pgvector` 扩展 | +| 缓存与队列基础设施 | Redis | +| 文件存储 | 阿里云 OSS | +| 运行环境 | Docker | +| 第一阶段部署 | 自有 ECS + Docker Compose | +| 后续部署 | Kubernetes | +| 身份系统 | API 内部 Identity 模块 | +| 初期监控 | Uptime Kuma | + +## 3. 服务边界 + +```text +浏览器 + │ + ▼ +Nginx / 入口反向代理 + ├── / -> Next.js Web 容器 + └── /api/v1/* -> NestJS + Fastify API 容器 + │ + Drizzle / SQL Repository + │ + PostgreSQL + pgvector + │ + Redis + │ + 阿里云 OSS +``` + +Next.js 负责页面和交互,NestJS 负责业务规则和 REST API。浏览器使用同源的 `/api/v1/...` 路径访问 API,不需要第一阶段建立 API 子域名。 + +## 4. 业务模块边界 + +API 内部按业务模块组织,至少包括: + +- `Identity`:微信登录、邮箱绑定、会话和登录审计。 +- `Users`:基础用户资料、学校、专业和年级。 +- `Profiles`:个人画像、公开画像和画像版本。 +- `Consents`:画像共享授权、撤销和授权审计。 +- `Projects`:竞赛、项目、队伍、成员和申请。 +- `Invitations`:邀请链接、接受记录和邀请关系。 +- `Points`:积分流水、任务和兑换权益。 +- `Commerce`:课程、API 权益、订单和退款记录。 +- `Recommendations`:推荐候选、推荐原因和行为反馈。 +- `Operations`:内容审核、举报、活动和运营配置。 + +Agent 模块只保留未来可接入的边界,暂不确定模型供应商、编排方式、队列方案和报告生成流程。 + +## 5. 数据分层原则 + +数据按业务含义和敏感性拆分,不提前做多数据库分片: + +- 身份数据与联系方式。 +- 原始测评回答。 +- AI 推测或生成的画像。 +- 真实项目行为与合作证据。 +- 用户主动公开的画像。 +- 授权记录与审计记录。 + +大型追加型数据先使用独立表、索引和归档策略。只有实际数据量和查询模式证明需要时,再引入 PostgreSQL 分区表或其他专用存储。 + +## 6. 文件和媒体 + +简历、作品、报告和项目附件存储在阿里云 OSS: + +1. API 创建临时上传凭证。 +2. 浏览器直接上传 OSS。 +3. API 接收上传完成通知。 +4. PostgreSQL 保存文件元数据和权限关系。 +5. 私有文件通过临时签名 URL 访问。 + +应用服务器不作为大文件长期存储位置。 + +## 7. 部署和演进 + +第一阶段使用 Docker Compose 管理: + +- Web 容器。 +- API 容器。 +- Worker 容器(具体 Agent 方案未定型)。 +- PostgreSQL。 +- Redis。 + +生产环境建议将应用容器与 PostgreSQL、Redis 分离到不同主机或使用托管服务,并配置备份和恢复演练。 + +后续迁移 Kubernetes 时,应用服务应保持无状态,配置通过环境变量或 Secret 注入,文件不写入容器本地磁盘。 + +## 8. 监控和测试边界 + +第一阶段使用 Uptime Kuma 监控: + +- 首页可访问性。 +- `/api/v1/health/live` 存活状态。 +- `/api/v1/health/ready` 依赖就绪状态。 +- HTTPS 证书和端口状态。 + +Uptime Kuma 只负责可用性监控,不替代自动化测试。测试工具和覆盖范围另行确定;核心链路至少应覆盖登录、授权、邀请、项目申请和积分流水。 + +## 9. 暂不引入 + +第一阶段暂不引入: + +- 微服务拆分。 +- Kubernetes。 +- 独立向量数据库。 +- Elasticsearch / OpenSearch。 +- ClickHouse。 +- MongoDB。 +- 复杂机器学习推荐服务。 +- 已定型的 Agent 编排框架。 + +这些能力在真实规模和业务需求出现后再评估。 + diff --git a/docs_old/discussion-summary.md b/docs_old/discussion-summary.md new file mode 100644 index 0000000..daa7cc9 --- /dev/null +++ b/docs_old/discussion-summary.md @@ -0,0 +1,350 @@ +# AIwelink 项目讨论过程总结 + +> 用途:记录 AIwelink 从最初想法到当前产品和技术共识的形成过程,帮助新开发者理解决策背景。 +> +> 文档性质:这是讨论过程记录,不替代具体技术规范,也不替代飞书中的正式商业和运营文档。 +> +> 当前阶段:方向已完成初步收敛,代码目录和 Agent 具体实现尚未定型。 + +## 1. 最初设想 + +项目最初的设想是建设一个项目合作平台: + +- 用户可以上传简历和个人资料。 +- 用户可以发布自己的项目。 +- 用户可以发布召集令,寻找队友或协作者。 +- 平台面向大学竞赛,也面向真实开发者项目。 +- 平台未来保留运营和商业化空间。 + +最开始看起来像是“项目合作 + 人才资料 + 组队”的平台,但讨论很快发现,如果只是简历、帖子、私聊和找队友,产品会接近校园墙或垂直交友平台,缺乏长期差异化。 + +## 2. 第一次收窄:先服务大学生竞赛 + +为了降低冷启动难度,第一阶段选择大学生竞赛作为主要市场,而不是同时服务大学生和成熟开发者。 + +选择原因: + +- 需求集中在明确的赛事周期内。 +- 学校、社团、校园墙和学生组织是可触达的渠道。 +- 组队需求明确,容易观察“发布、申请、成队”的闭环。 +- 技术类竞赛可以自然连接 AI API、课程和工具包。 + +第一阶段优先关注 AI、软件、数据分析、创新创业等技术关联竞赛,后续再扩展到更多竞赛、科研、开源、企业命题和创业项目。 + +## 3. 从“交友平台”转向“任务型协作平台” + +讨论中确认:如果平台只是“上传简历、发布召集令、私聊”,就会像校园版交友平台。 + +因此产品目标从“让人认识更多人”调整为: + +> 以明确的项目或竞赛任务为中心,帮助用户找到合适的能力、角色和协作者,并把项目真正做完。 + +平台的成果不应只是浏览、点赞或聊天,而应包括: + +- 有效申请。 +- 成功组队。 +- 持续协作。 +- 完成作品。 +- 提交竞赛。 +- 赛后复盘。 + +## 4. 与校园墙的区分 + +校园墙负责让信息被看见,AIwelink 负责让项目推进和结果沉淀。 + +区分重点: + +| 校园墙 | AIwelink | +| --- | --- | +| 单校或本地信息 | 跨学校的机会和项目网络 | +| 非结构化临时帖子 | 绑定赛事、角色、时间和能力要求 | +| 发帖后转到微信 | 记录申请、授权、组队和项目过程 | +| 主要关注曝光 | 关注成队率、完赛率和作品数量 | +| 广告或推广为主 | API、课程、导师、赛事和机构服务 | + +校园墙不必完全视为敌人,也可以成为分发渠道:校园墙提供本地触达,AIwelink 承接标准化报名、组队、工具和成果记录。 + +## 5. 商业化方向的形成 + +讨论中明确,平台不应主要依靠向学生收取“找队友”会员费。更自然的商业闭环是: + +```text +免费赛事与项目机会 + -> 用户组队并开始真实项目 + -> 产生 AI 工具和能力需求 + -> 使用模型 API、工具包、课程或导师服务 + -> 后续对接学校、赛事方和企业 +``` + +主要商业化方向: + +1. 面向竞赛团队的模型 API 和场景化工具包。 +2. 面向具体赛事的课程、训练营、作品评审和答辩辅导。 +3. 学校、社团和赛事方的报名、组队和运营服务。 +4. 企业命题赛、模型或算力赞助、品牌合作。 +5. 基于真实项目经历的人才发现和项目推荐。 + +商业表达不应聚焦“帮助用户访问国外 AI”,而应聚焦国内稳定可用、人民币结算、适合竞赛场景的 AI 能力。 + +API 和课程不应在用户刚进入平台时硬推,而应在用户进入项目、遇到具体困难或进入备赛阶段后出现。 + +## 6. 首页心智的讨论结果 + +首页不以产品介绍、API 或课程商城为中心,也不以简历瀑布流或泛校园信息流为中心。 + +首页应该围绕“机会”和“下一步行动”: + +> 找到适合你的下一次挑战,并知道现在应该做什么。 + +首页的优先内容: + +1. 适合用户的竞赛和项目。 +2. 即将截止或正在招募的机会。 +3. 用户正在参与的项目。 +4. 自我认知和成长任务。 +5. 真实项目成果和经验。 +6. 与当前项目有关的 API、课程和导师服务。 + +登录策略初步确定为:未登录用户可浏览部分公开机会;收藏、报名、申请组队或开始个性化自我认知时再要求登录。微信作为主登录入口,邮箱作为绑定、验证和恢复方式。 + +## 7. 自我认知方向的形成 + +讨论进一步从“竞赛组队”转向“帮助用户了解自己”。用户真正想知道的不是简单人格标签,而是: + +- 自己擅长什么。 +- 适合做什么类型的任务。 +- 适合承担什么项目角色。 +- 更适合什么工作环境和协作方式。 +- 容易在哪些环节遇到困难。 +- 下一步应该学习或尝试什么。 + +因此,心理测评不能只是一次性结果。平台应形成: + +```text +自我评估 + -> 选择项目 + -> 真实行动 + -> 队友反馈 + -> 项目复盘 + -> 更新自我认知 +``` + +测评结果是当前阶段的假设,真实项目行为和合作反馈是更有价值的证据。 + +平台不做心理疾病诊断,不用单次测评淘汰用户,也不把用户固定成某种人格类型。 + +## 8. 自我认知 Agent 与推广机制 + +随后提出将自我认知 Agent 作为推广阶段的独立产品入口: + +```text +免费自我认知 Agent + -> 生成个人报告 + -> 分享安全摘要 + -> 邀请朋友 + -> 解锁双人或团队分析 + -> 推荐项目和竞赛 +``` + +积分可以作为增长工具,但奖励不应只绑定链接点击或注册,而应绑定有效行为: + +- 完成个人报告。 +- 被邀请者完成授权。 +- 双人报告生成。 +- 参与项目或挑战。 +- 完成项目复盘。 + +积分可以兑换深度报告、API 额度、课程优惠、导师问答或挑战资格。 + +## 9. 双人画像与社交属性 + +讨论确认,社交属性可以存在,而且可能是产品传播力的一部分,但应该围绕“共同做事”展开。 + +用户邀请朋友并获得双方授权后,可以生成: + +- 彼此互补的优势。 +- 适合的分工方式。 +- 可能发生冲突的地方。 +- 推荐的沟通方式。 +- 适合一起参加的项目。 +- 合作前应该约定的规则。 + +社交产品结构可以逐步演进为: + +```text +个人画像 + -> 双人协作画像 + -> 三到五人的团队画像 + -> 项目复盘 + -> 长期成长和合作关系 +``` + +共享必须是双向、明确、可撤销的授权。默认私密,用户可以选择共享优势、偏好、协作建议或成长方向,不应默认共享原始回答和敏感结论。 + +第一阶段优先面向已经认识的朋友、同学和队友,暂不把陌生人交友或恋爱社交作为主场景。 + +## 10. 个性化推荐方向 + +推荐系统被定义为平台的长期核心能力,推荐对象包括: + +- 竞赛。 +- 项目。 +- 学科。 +- 学习内容。 +- 项目角色。 +- 合作对象。 +- 课程、导师和 AI 工具。 + +推荐依据不只包括兴趣,还包括: + +- 用户能力和目标。 +- 可投入时间。 +- 工作偏好。 +- 已完成或放弃过的项目。 +- 项目中的真实行为。 +- 队友反馈和复盘结果。 + +第一阶段采用可解释的规则、标签、行为信号和必要的向量召回,不直接引入复杂黑箱模型。 + +## 11. 技术选型过程 + +### 11.1 后端语言 + +讨论过 Go、TypeScript 和 Python 的适用性。 + +结论是:全栈 TypeScript 足以支撑第一阶段,因为业务主要是网络 I/O、数据库读写和第三方模型调用。Go 可以作为未来独立高性能服务的选择,Python 更适合未来算法和数据科学任务,但当前不需要为了 AI 提前拆成多语言微服务。 + +### 11.2 React 与 Next.js + +确认 React 是 UI 库,Next.js 是基于 React 的应用框架。由于平台同时需要公开机会页、分享页、搜索收录和登录后的个性化工作台,最终选择: + +> Next.js + React + TypeScript + +Next.js 负责 Web 应用,视觉质量由设计系统、信息层级、动效、响应式布局和性能实现决定,而不是由框架本身决定。 + +### 11.3 Web 与 REST API + +确认采用 Next.js 与独立 REST API,而不是把核心业务全部放入 Next.js Route Handler。 + +第一阶段使用同域名反向代理: + +```text +https://aiwelink.com/ -> Next.js +https://aiwelink.com/api/v1/* -> 独立 REST API +``` + +这样可以保留独立 API 边界,同时避免第一阶段的跨域和子域名复杂度。 + +### 11.4 API 框架 + +确认使用: + +> NestJS + Fastify Adapter + +NestJS 负责模块、依赖注入、权限 Guard、异常处理和 OpenAPI;Fastify 作为底层 HTTP 适配器。 + +### 11.5 数据访问 + +对比 Prisma、Drizzle 和原生 SQL 后,确认: + +> Drizzle ORM 作为默认数据访问工具,原生 SQL 作为复杂查询补充。 + +普通 CRUD 和事务使用 Drizzle;pgvector、全文搜索、推荐排序和复杂报表通过 Repository 使用参数化原生 SQL。 + +### 11.6 身份系统 + +确认在 API 内部建立 Identity 模块,统一管理微信登录、邮箱绑定、会话、验证和登录审计。第一阶段不把身份体系绑定在 Next.js 上。 + +### 11.7 数据与基础设施 + +确认使用: + +- PostgreSQL 作为业务主数据库。 +- `pgvector` 作为 PostgreSQL 扩展。 +- Redis 用于缓存、限流和队列基础设施。 +- 阿里云 OSS 存储简历、作品、报告和附件。 +- Docker 容器化 Web、API 和 Worker。 +- 自有 ECS + Docker Compose 作为第一阶段部署方式。 +- 后续业务规模增长后再迁移 Kubernetes。 +- Uptime Kuma 作为第一阶段基础可用性监控。 + +数据按身份、资料、原始测评、推测画像、行为证据、公开画像和授权审计分层存储。提前按业务边界分表,但不提前做跨库分片。 + +## 12. Monorepo 与文档管理决定 + +确认使用单 Git 仓库和 Monorepo,代码按以下概念划分: + +- `apps/web`:Next.js Web。 +- `apps/api`:NestJS REST API。 +- `apps/worker`:异步任务,Agent 方案暂不定型。 +- `apps/admin`:后续运营后台。 +- `packages/contracts`:OpenAPI、DTO 和共享接口。 +- `packages/db`:Drizzle Schema、迁移和种子。 +- `infra`:Docker、ECS 和未来 Kubernetes。 + +文档边界确定为: + +| 文档内容 | 位置 | +| --- | --- | +| 总体架构、技术栈、工程规范 | 根目录 `docs/`,进入 Git | +| API 具体接口和模块实现 | `apps/api/docs/`,进入 Git | +| 数据库规范 | `packages/db/docs/`,进入 Git | +| 技术部署和备份 | `infra/docs/`,进入 Git | +| 临时需求和未确认讨论 | `docs-local/`,Git 忽略 | +| 商业、市场、运营和合作 | 飞书,不进入 Git | + +## 13. 当前已确认与未确认 + +### 已确认 + +- 第一阶段面向大学生竞赛和技术项目。 +- 平台核心是自我认知、项目机会、真实协作和成长反馈。 +- 社交围绕双人或团队协作画像展开。 +- 推荐系统要可解释并帮助用户理解自己。 +- 使用 Next.js + React + TypeScript。 +- 使用独立 REST API,路径为 `/api/v1`,与 Web 同域名反向代理。 +- 使用 NestJS + Fastify Adapter。 +- 使用 Drizzle + 原生 SQL。 +- 使用 API 内部 Identity 模块。 +- 使用 PostgreSQL、pgvector、Redis 和阿里云 OSS。 +- 使用 ECS + Docker Compose,后续迁移 Kubernetes。 +- 商业和运营文档使用飞书。 + +### 暂未定型 + +- Agent 使用的具体模型供应商和模型路由。 +- Agent 的对话编排框架。 +- 长报告和复杂任务的具体队列实现。 +- 推荐系统是否拆为独立服务。 +- 测试工具和完整可观测性方案。 +- 生产数据库和 Redis 的最终托管或自建形态。 +- 具体的第一场竞赛、运营节奏和商业价格。 + +## 14. 新开发者阅读顺序 + +建议按以下顺序了解项目: + +1. 阅读本文,理解产品为什么不是校园墙或普通交友平台。 +2. 阅读 `docs/project-handoff.md`,了解当前工程共识和接手规则。 +3. 阅读 `docs/architecture/technology-stack.md`,了解技术基线。 +4. 阅读 `docs/architecture/technology-stack-details.md`,了解 API、数据和部署细节。 +5. 阅读对应模块下的文档和决策记录。 +6. 对未定型事项先保持接口边界,不要擅自提前固化实现。 + +## 15. 总结 + +本次讨论的核心收敛过程是: + +```text +项目合作平台 + -> 大学生竞赛组队 + -> 区别于校园墙的任务型协作 + -> 以自我认知为长期核心 + -> 个性化推荐项目、学科和合作对象 + -> 双方授权后生成协作画像 + -> 通过真实项目形成成长和关系数据 + -> 用 API、课程、导师和机构服务商业化 +``` + +技术选择遵循同一个原则:先用清晰、稳定、可迭代的模块化架构验证真实用户价值;在规模和业务证据出现后,再增加 Agent 编排、复杂推荐、Kubernetes 或专用基础设施。 + diff --git a/docs_old/project-handoff.md b/docs_old/project-handoff.md new file mode 100644 index 0000000..1c71ab7 --- /dev/null +++ b/docs_old/project-handoff.md @@ -0,0 +1,314 @@ +# AIwelink 项目交接说明 + +> 用途:帮助新加入的开发者快速理解 AIwelink 的产品方向、设计理念、技术基线和文档协作边界。 +> +> 当前状态:产品和技术方向已完成初步确认,尚未进入实际代码目录初始化阶段。 +> +> 重要范围:本文记录的是产品设计与工程共识,不等同于完整的商业运营方案。商业和运营细节以飞书为准。 + +## 1. 项目一句话定义 + +AIwelink 是一个帮助大学生认识自己、找到适合的学习或项目机会,并在真实协作中建立高质量关系的项目成长平台。 + +第一阶段从大学生竞赛和技术项目切入,但长期方向不局限于竞赛信息或组队,而是逐步形成: + +```text +认识自己 + -> 发现适合的机会 + -> 参与真实项目 + -> 与合适的人协作 + -> 获得项目反馈 + -> 更新个人认知和成长路径 +``` + +## 2. 产品设计理念 + +### 2.1 不做校园墙 + +校园墙解决的是“让信息被看见”;AIwelink 要解决的是“让合适的人真正开始并完成一件事”。 + +因此平台内容应尽量绑定: + +- 明确的竞赛、项目或挑战。 +- 具体的角色和能力缺口。 +- 时间投入和截止时间。 +- 用户能够采取的下一步行动。 +- 最终的作品、结果或复盘。 + +核心指标不应是发帖数和浏览量,而应逐步关注有效申请率、成队率、持续协作率和完成项目的队伍数量。 + +### 2.2 不做一次性人格测试 + +自我认知 Agent 不是为了给用户贴上固定人格标签,也不是心理疾病诊断工具。 + +测评或对话产生的结果应被视为当前阶段的“待验证假设”,后续通过真实项目行为、队友反馈和项目复盘逐渐修正。 + +平台要帮助用户回答: + +- 我擅长什么类型的任务? +- 我适合承担什么项目角色? +- 我在什么工作环境中更容易发挥? +- 我可能在哪些环节遇到困难? +- 下一步应该尝试什么或补足什么能力? + +### 2.3 社交来自共同目标 + +社交可以是平台的重要属性,但不应从泛聊天或陌生人浏览开始。 + +推荐路径是: + +```text +个人画像 + -> 邀请已认识的人 + -> 双方明确授权共享 + -> 生成双人合作报告 + -> 共同参加项目或挑战 + -> 通过结果建立长期关系 +``` + +社交关系的核心不是“匹配指数”,而是: + +- 彼此有哪些互补优势。 +- 适合怎样分工。 +- 可能在哪些地方产生协作摩擦。 +- 应该采用什么沟通方式。 +- 适合一起尝试什么项目。 + +第一阶段优先面向已经认识的朋友、同学和队友,降低信任和隐私风险。暂不以恋爱社交为主场景。 + +### 2.4 推荐应帮助用户理解自己 + +推荐系统不只是提高点击率的工具,而是帮助用户做选择和形成自我认知的导航系统。 + +推荐对象包括: + +- 竞赛和项目。 +- 学科和学习内容。 +- 项目角色。 +- 合作对象。 +- 课程、导师和 AI 工具。 + +每条推荐应尽量解释“为什么推荐”,并同时提供适合当前能力的机会、补足短板的机会和带有挑战性的探索机会,避免把用户锁死在单一标签中。 + +### 2.5 首页以机会和下一步为中心 + +首页不以介绍产品、API 或课程为主,也不做简历瀑布流或泛校园信息流。 + +首页的核心问题应是: + +> 用户现在最值得做的下一件事是什么? + +推荐内容优先级: + +1. 适合用户的机会和项目。 +2. 用户正在参与的项目。 +3. 自我认知和成长任务。 +4. 真实项目成果和经验。 +5. 在具体需求出现后推荐课程、API 或导师服务。 + +## 3. 第一阶段业务闭环 + +第一阶段优先验证以下闭环: + +```text +自我认知 Agent + -> 生成个人画像 + -> 推荐竞赛、项目和学习方向 + -> 邀请朋友并授权共享画像 + -> 生成双人合作报告 + -> 参与一次真实项目或挑战 + -> 记录项目行为和队友反馈 + -> 复盘并更新画像 +``` + +平台的推广入口可以是免费的自我认知 Agent: + +- 用户完成个人认知报告。 +- 用户分享安全、可控的摘要。 +- 邀请朋友后解锁双人或团队分析。 +- 完成有效邀请或项目行为后获得积分。 +- 积分可兑换深度报告、API 额度、课程优惠或挑战资格。 + +邀请机制应围绕双方共同获得的价值设计,不应只奖励链接点击或虚假注册。 + +## 4. 商业化方向 + +平台本身先提供免费价值,再在真实需求出现时转化: + +```text +赛事和项目机会 + -> 组队和真实协作 + -> AI 工具与 API 使用 + -> 竞赛课程、训练营和导师服务 + -> 学校、赛事方和企业服务 +``` + +主要商业化方向包括: + +- 面向竞赛团队的模型 API 和工具包。 +- 面向具体赛事的课程、训练营和作品辅导。 +- 导师、作品评审和项目启动服务。 +- 学校、社团和赛事方的组织管理服务。 +- 企业命题赛、品牌赞助和人才发现。 + +API 和课程不应成为首页硬广告,而应在用户已进入项目或明确遇到问题时出现。 + +## 5. 技术总体基线 + +### 5.1 已确认选型 + +| 层 | 选型 | +| --- | --- | +| Web | Next.js + React + TypeScript | +| 业务 API | NestJS + Fastify Adapter | +| API 规范 | RESTful API,路径前缀 `/api/v1` | +| 数据访问 | Drizzle ORM 为默认工具,复杂查询补充原生 SQL | +| 主数据库 | PostgreSQL | +| 向量能力 | PostgreSQL `pgvector` 扩展 | +| 缓存和队列基础设施 | Redis | +| 文件存储 | 阿里云 OSS | +| 部署 | 自有 ECS + Docker Compose | +| 后续部署 | Kubernetes | +| 身份系统 | API 内部 Identity 模块 | +| 初期可用性监控 | Uptime Kuma | + +Agent 的具体模型供应商、编排框架、异步任务实现和独立服务边界暂不定型。 + +### 5.2 Web 与 API 的关系 + +Web 和 API 是两个独立应用,但第一阶段使用同一个公网域名: + +```text +https://aiwelink.com/ -> Next.js Web +https://aiwelink.com/api/v1/* -> NestJS REST API +``` + +通过 Nginx 或同类入口反向代理分流。第一阶段不要求 API 子域名,也不把核心业务逻辑写进 Next.js 页面接口。 + +### 5.3 API 设计原则 + +- 使用资源名词和复数路径。 +- 使用标准 HTTP 方法和状态码。 +- 使用 `/api/v1` 版本前缀。 +- JSON 字段使用 `camelCase`,URL 使用小写短横线。 +- 列表优先使用游标分页。 +- 写操作按需支持 `Idempotency-Key`。 +- 错误响应统一格式,并带 `requestId`。 +- 权限必须在服务端校验,不能只依赖前端控制。 +- 长任务建模为资源或任务,不能把所有功能写成动词接口。 + +### 5.4 数据访问原则 + +```text +Controller + -> Application Service + -> Repository Interface + -> Drizzle Repository / SQL Repository + -> PostgreSQL +``` + +- 普通 CRUD 使用 Drizzle。 +- 普通事务使用 Drizzle transaction。 +- pgvector、全文搜索、复杂推荐和报表使用参数化原生 SQL。 +- Controller 不直接访问数据库。 +- 数据库结构必须通过版本化迁移维护。 + +### 5.5 数据分层原则 + +数据按业务和敏感性拆分,不提前进行跨数据库分片: + +- 身份数据和登录方式。 +- 基础资料和公开画像。 +- 原始测评回答。 +- AI 推测画像和画像版本。 +- 项目行为和队友反馈。 +- 公开共享结果。 +- 授权记录和审计记录。 + +大型追加型表先通过索引、归档和后续 PostgreSQL 分区解决,实际需要出现前不引入多数据库分片。 + +### 5.6 文件存储原则 + +简历、作品、报告和项目附件使用阿里云 OSS。推荐浏览器直传 OSS,API 只负责签发临时凭证、记录元数据和校验权限。私有文件通过短期签名 URL 访问,应用容器不作为长期文件存储位置。 + +## 6. 代码仓库和文档协作约定 + +使用单 Git 仓库和 Monorepo。当前只确定结构,不立即创建全部目录。 + +```text +AIwelink/ +├─ apps/ +│ ├─ web/ # Next.js Web +│ ├─ api/ # NestJS REST API +│ ├─ worker/ # 异步任务,Agent 方案未定型 +│ └─ admin/ # 后续运营后台 +├─ packages/ +│ ├─ contracts/ # OpenAPI、DTO、共享接口 +│ ├─ db/ # Drizzle Schema、迁移、种子 +│ ├─ validation/ # 共享数据校验 +│ ├─ ui/ # 跨应用 UI +│ ├─ config/ # 共享配置 +│ └─ tooling/ # 工程工具配置 +├─ infra/ +│ ├─ docker/ # Compose、Nginx、脚本 +│ ├─ ecs/ # ECS 部署配置 +│ ├─ k8s/ # 后续 Kubernetes 配置 +│ └─ docs/ # 技术运维文档 +├─ scripts/ # 根级脚本 +├─ docs/ # 全局工程文档,进入 Git +├─ docs-local/ # 临时文档,本地存在但 Git 忽略 +└─ .github/ # 后续 CI/CD +``` + +### 6.1 文档放置规则 + +| 内容 | 归属 | +| --- | --- | +| 总体架构、技术栈、工程规范 | 根目录 `docs/`,进入 Git | +| API 具体接口和模块实现 | `apps/api/docs/`,进入 Git | +| 数据库结构和迁移规范 | `packages/db/docs/`,进入 Git | +| Docker、ECS、备份等技术运维 | `infra/docs/`,进入 Git | +| 临时需求、草稿和未确认讨论 | `docs-local/`,Git 忽略 | +| 商业、市场、运营和合作 | 飞书,不进入 Git | + +如果商业或运营决策最终影响代码,只把脱敏后的技术结论记录到 `docs/decisions/`,不复制完整商业背景。 + +## 7. 开发者接手时的工作方式 + +新开发者开始实现前,应先确认: + +1. 先阅读本文和根目录工程文档。 +2. 不擅自改变已确认的 API、数据库和部署边界。 +3. 新增 API 必须遵循 `/api/v1` 和 RESTful 资源设计。 +4. 新增业务模块应放在 `apps/api/src/modules/` 对应目录。 +5. 数据库访问必须经过 Repository,不在 Controller 直接写查询。 +6. 新的跨模块技术决策记录到 `docs/decisions/`。 +7. 商业或运营内容不要提交到 Git,回到飞书维护。 +8. Agent 方案属于未定型事项,先保持接口边界,不要提前绑定具体供应商或框架。 + +## 8. 当前明确不做的事情 + +第一阶段暂不提前引入: + +- 微服务拆分。 +- Kubernetes 生产部署。 +- 独立向量数据库。 +- Elasticsearch / OpenSearch。 +- ClickHouse。 +- MongoDB。 +- 复杂机器学习推荐服务。 +- 已定型的 Agent 编排框架。 +- 过早的跨库分片。 + +选择这些边界的原因是:当前首先验证产品闭环和用户价值,而不是提前解决尚未出现的规模问题。 + +## 9. 交接结论 + +AIwelink 的核心不是“校园信息流”或“陌生人交友”,而是: + +> 通过真实项目帮助年轻人认识自己、找到适合的机会,并与合适的人建立高质量协作关系。 + +技术上采用清晰的模块化 Monorepo,Web 和 REST API 分离但同域名提供,业务数据以 PostgreSQL 为中心,敏感数据分层存储,文件使用 OSS,第一阶段使用 ECS + Docker Compose。 + +工程实现应优先保持边界清楚、可解释、可迭代;商业和运营决策则统一在飞书中维护。 +