轻湖文本快递柜

轻湖文本快递柜 API 文档

轻湖文本快递柜(LiteTextShare)取件码模式 API 参考。本页面供人阅读;AI Agent 请直接抓取下方 Markdown 原文。

🤖 AI Agent / 爬虫:请直接抓取 Markdown 原文:/docs/api.md(英文)/docs/api.zhs.md(中文)

TextShare API(轻湖文本快递柜后端)

文本快递柜(TextShare)后端 API——前端(BFF)与 AI Agent 对接的单一事实源。本文档的任何变更必须与对应的接口变更同版本发布。

  • REST 基址(经 BFF 代理):https://textshare.litelake.com/api/**
  • 协同编辑(WebSocket,浏览器直连,不经 BFF): wss://ws.textshare.{env}/collab/{noteId}?token={editToken}——wsUrl 基址由创建/verify 响应下发,调用方不自行拼接。

通用约定

  • /docs/* 与 WebSocket 端点为 GET 外,全部 REST 接口为 POST + application/json
  • 统一响应信封:{ "code": number, "message": string, "data": T };成功 code = 200
  • 业务错误 HTTP 恒 200,靠 body.code 区分(4101/4103/4104);限流用真实 HTTP 429 + Retry-After;存储故障(fail-closed)用真实 HTTP 503。
  • 全部请求应携带 X-Device-Id 头(localStorage 生成的 UUID)。非法/缺失按「无设备号」处理,防爆破自动退化为仅 IP 维度(不报错)。

POST /api/public/notes —— 创建文档并生成取件码

携带本地已书写内容创建文档(先写后生成码),创建即 active

请求体:

{
  "mode": "md",
  "initState": "<base64(本地 Y.Doc 的 V1 update)>"
}
  • modetxt | md(白名单,其余 → 4103)
  • initState:本地 Y.Doc Y.encodeStateAsUpdate() 的 base64(V1)。空串表示空文档。服务端将 update 应用到空 doc,fold 后实测纯文本字节数。

响应 data

{
  "noteId": "cz9fkq2wm4xv...",
  "pickupCode": "K7M2XQ",
  "mode": "md",
  "expiresAt": "2026-09-16T08:00:00Z",
  "wsUrl": "wss://ws.textshare.{env}/collab",
  "editToken": "9f2c8e...64 位 hex"
}

错误:4103 mode 非法 / initState 无法应用(HTTP 200);4104 文本超过 128KB(HTTP 200);429 创建限流(每 IP 12 次/小时 + 30 次/天,真实 HTTP 429 + Retry-After);503 存储不可用(fail-closed)。

POST /api/public/pickup/verify —— 凭码换取协同入口

请求体:

{ "pickupCode": "K7M2XQ" }

服务端归一化:去空格与连字符、转大写、O→0I/L→1。响应 data 与创建响应字段一致(pickupCode 回显归一化后的值)。

错误:4101 取件码无效或已过期——统一文案防枚举(HTTP 200;每次失败对 IP 与设备号双维度计数 +1)。防爆破:任一维度 5 次/10 分钟即封禁,返回真实 HTTP 429 + Retry-After;成功不清零。Redis 故障 → 真实 HTTP 503(fail-closed)。

GET /collab/{noteId}?token={editToken} —— 协同 WebSocket

Yjs 协同端点,兼容 Hocuspocus 消息协议(@hocuspocus/provider 可直连;每帧带 VarString(docName) 前缀)。浏览器直连(不经 BFF;网关按域名转发)。

握手鉴权(在 WebSocket 升级之前执行):

  1. noteId 存在、status = active 且未过期(Redis 缓存 60s + MySQL 兜底;过期/不存在 → 401 拒绝,业务码 4102)
  2. editToken 有效且绑定该 noteId(Redis;miss 或 Redis 故障 → 拒绝,fail-closed,业务码 4105)
  3. 单 IP 连接数 < 10、单房间人数 < 16、单 update ≤ 768KB、单帧 ≤ 1MB

升级完成后服务端执行 y-protocols 同步握手(SyncStep1/2)、广播 awareness(光标/在线状态),并把每次 commit 以增量 V1 update 持久化(append-then-compact 写 MySQL:notes.snapshot + note_updates 流水)。文档创建后 48 小时过期;过期时强制关房(客户端收到 close 事件)。

没有只读连接:持 token 即得编辑权(v1 产品定义)。

GET /docs/api.md、/docs/api.en.md、/docs/api.zhs.md

本文档(内嵌于二进制;en 为默认/兜底,zhs 为简体中文)。以 text/markdown 输出,Cache-Control: no-cache

GET /api/health、/api/ready

框架内置存活/就绪探针(网关 healthcheck 指向 /api/health)。

错误码表

body.code语义HTTP 状态码
200成功200
400参数/绑定错误200
4101PICKUP_NOT_VALID(统一文案,防枚举)200
4102NOTE_NOT_FOUND / 已过期(WS Authorize 用,REST 一般不触达)200
4103INVALID_ARGUMENT(mode / initState)200
4104NOTE_TOO_LARGE(fold 后纯文本 > 128KB)200
4105EDIT_TOKEN_INVALID(WS 握手被拒)200
429RATE_LIMITED429 + Retry-After
503STORAGE_UNAVAILABLE(Redis 故障 fail-closed)503
500内部错误500

注:/api/public 写方法的基线限流中间件(30 次/min/IP)触发时响应体为中间件自拼格式;调用方对 429 一律按 HTTP 状态码处理,不依赖 body 形状。