docs: initialize AIwelink project

This commit is contained in:
2026-08-23 00:16:15 +08:00
commit 28f4efd675
10 changed files with 2680 additions and 0 deletions
@@ -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 的具体发行版和部署方式。
- 完整日志、指标和链路追踪方案。
这些选项应在业务流程、数据量和实际故障模式出现后再定型。
+143
View File
@@ -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 编排框架。
这些能力在真实规模和业务需求出现后再评估。
+350
View File
@@ -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 或专用基础设施。
+314
View File
@@ -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。
工程实现应优先保持边界清楚、可解释、可迭代;商业和运营决策则统一在飞书中维护。