跳转到内容

消息中心开发

message/ 是 cikio 的统一消息基础设施:承载「用户收到的消息」。 它是跨项目服务(与 authserver 同级),不服务单一站点,因此接口从第一天就按多项目接入设计。

项 值
包名 cikio-message
线上地址 https://message.cikio.cn
后端 Hono 4 + Cloudflare Workers + Drizzle(D1)
前端 React 19 + Vite 7 + Tailwind 4(SPA,构建产物由 Worker 作为静态资源托管)

一个 Worker 同时提供接口与界面:/api/* 由 Worker 处理,其余路径是 SPA 静态资源。

message/
├─ src/worker/ # 后端:index.ts(Hono 入口)+ lib/(env、http、用户上下文)+ routes/(inbox、ingest、preferences)
├─ src/web/ # 前端 SPA:pages/、components/、hooks/、lib/、styles/、mocks/
├─ src/db/schema.ts # 表定义(messages、preferences)
├─ src/shared/ # 前后端共用常量
├─ db/seed.sql # 本地种子数据
├─ migrations/ # drizzle-kit 产出的 SQL + meta/
├─ index.html # Vite 入口
├─ vite.config.ts # 插件、/api 代理、构建输出 dist/
├─ tsconfig.worker.json / tsconfig.web.json # 前后端分别检查
└─ wrangler.toml

前后端分两个 tsconfig,类型检查也会跑两遍(tsc -p tsconfig.worker.json && tsc -p tsconfig.web.json)。 改动时注意别让一端的类型泄漏到另一端。

终端窗口
pnpm --filter cikio-message dev # 同时起 wrangler dev(8787) + vite(5173),访问 http://localhost:5173
pnpm --filter cikio-message dev:api # 只起后端(8787)
pnpm --filter cikio-message dev:web # 只起前端(/api 不可达时回退浏览器端 mock)
pnpm --filter cikio-message typecheck
  • 界面开发访问 5173;Vite 把 /api 代理到 8787 上的 Worker,因此浏览器里是同源请求。
  • 只做样式/交互时用 dev:web + mock 数据即可,不必起 Worker。
  • db:migrate:local 建表、db:seed:local 灌种子数据。

所有接口以 /api 为前缀,输入输出经 zod 校验,错误响应结构统一为 { error: <机器可读码>, message?: string }:

分组 路径 用途
健康检查 /api/health 探活
收件箱 /api/inbox/* 列表、会话、详情、已读/未读、归档、全部已读、未读数
投递 /api/ingest/messages 其他服务投递消息(不是给浏览器调的)
偏好 /api/preferences 用户的消息偏好(GET / PUT / DELETE;未配置的组合默认开启)
  • 表:messages(消息本体,type 预留 dm、category 区分通知与互动,时间存 unixepoch 秒)、 preferences(复合主键 userId × project × type × channel)。

  • schema 在 src/db/schema.ts,配置在 drizzle.config.ts(sqlite、输出 migrations/)。

  • 流程:

    终端窗口
    pnpm --filter cikio-message db:generate # schema → migrations/*.sql
    pnpm --filter cikio-message db:migrate:local
    pnpm --filter cikio-message db:migrate # --remote,必须早于部署
    pnpm --filter cikio-message db:seed:local
  • 跨项目共用的消息类型定义在共享包 @cikio/types 里,不要在 message/ 内另立一套(见共享包开发)。

项 说明
DB D1 cikio-messages(migrations_dir = "migrations")
[assets] directory = "./dist"、not_found_handling = "single-page-application"、run_worker_first = ["/api/*"]

三处行为要理解清楚:not_found_handling 为 SPA 时未命中路径回落到 index.html(前端路由接管); run_worker_first = ["/api/*"] 保证接口先经过 Worker,不会被静态资源短路。

终端窗口
pnpm --filter cikio-message run deploy

wrangler.toml 里没有 routes:自定义域 message.cikio.cn 在 Cloudflare Dashboard 手动绑定, 声明 routes 会在部署时改写既有绑定。

首版刻意不做:私信(仅预留 type 字段)、实时推送、邮件投递。 另外日志不输出用户 ID 与消息内容,排查问题只看计数与错误码。

相关:消息中心(产品视角)、认证服务开发、共享包开发。