Files
NewPlatform/docs/architecture/technology-stack-details.md
T
2026-08-23 00:16:15 +08:00

10 KiB
Raw Blame History

AIwelink 技术实现规则

本文补充 AIwelink 技术方案。 文档说明请求怎样进入系统、代码怎样分层、数据怎样保存。 文档也列出第一阶段的部署和测试要求。

1. Web 和 API 使用一个域名

1.1 请求路径

第一阶段对外使用一个公网域名:

https://aiwelink.com/            -> Next.js Web
https://aiwelink.com/api/v1/... -> REST API

入口代理(例如 Nginx)按路径转发:

客户端
  |
  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 使用小写短横线。

推荐的目录如下:

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 用资源设计路径

资源名使用名词和复数形式:

GET    /api/v1/projects
GET    /api/v1/projects/{projectId}
POST   /api/v1/projects
PATCH  /api/v1/projects/{projectId}
DELETE /api/v1/projects/{projectId}

明确的从属关系使用嵌套资源:

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 负责用户身份和会话。 个人资料、能力画像、项目经历和测评结果由其他模块管理。

建议的核心表:

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 数据访问顺序

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 业务分层

建议按下面的业务层组织表:

身份层: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 文件流程

API 创建临时凭证
  ↓
浏览器直接上传 OSS
  ↓
上传完成后通知 API
  ↓
PostgreSQL 写入文件信息
  ↓
按需解析、审核或建立索引

数据库保存的文件信息包括:

fileId
ownerId
objectKey
mimeType
size
hash
visibility
createdAt

私有文件通过短期签名 URL 访问。上传流程检查文件类型、大小、哈希和归属关系。

10. ECS 和 Docker Compose

10.1 第一阶段服务

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 可用性检查

建议提供两个健康检查接口:

GET /api/v1/health/live
GET /api/v1/health/ready

live 只检查进程是否存活。ready 检查 PostgreSQL、Redis 和必要配置是否可用。

Uptime Kuma 监控首页、两个健康接口、TCP 端口和 HTTPS 证书到期时间。

11.2 测试范围

第一阶段至少安排:

  • TypeScript 类型检查;
  • Lint;
  • API 单元测试和集成测试;
  • 关键流程端到端测试;
  • 发布前数据库迁移检查。

核心流程按下面的顺序覆盖:

微信登录
→ 绑定邮箱
→ 创建个人资料
→ 创建项目
→ 发送邀请
→ 授权共享
→ 提交项目申请
→ 记录积分流水

12. 仍需决定的技术事项

以下内容等产品流程和数据量更清楚后再决定:

  • AI 助手使用的模型供应商和模型路由;
  • AI 助手的对话编排框架;
  • 长报告和复杂任务使用哪种队列;
  • 推荐系统是否拆成独立服务;
  • 是否引入专用搜索引擎;
  • Kubernetes 的发行版和部署方式;
  • 完整的日志、指标和链路追踪方案。