xmeta 联机数据

测试台

未连接 · uid — · —

所有请求都带这枚令牌。没连接时发出去会 401 —— 这也是要验的一条。

快捷填充 —— 点一下填进下面的表单,再按「发送」

读

写

删

管理员专属

调试

这几条动的是「别人的」数据(公共板、改动记录、换昵称),默认拿 466 当那个人 —— 点一次上面的「初始化测试数据」会换成真实存在的 uid。 想亲眼看到「改别人没开放的字段 → 403」,得换个不是管理员的身份;测试台上做不到(你自己就是管理员), 这条在 e2e 测试里用三个令牌验过了。

测试数据

造一批能跑通所有接口的样本:每人一条私有背包 + 一条公开角色池、别人一条开放的公共板、 我自己的世界 boss,外加几条改动日志。全部走上面这些公开接口,不碰数据库。 重复点会覆盖,不会越堆越多。


  
返回 —

  
返回结构速查 —— 每个接口回什么

接口 → 返回

http
GET     /api/kv/:scope           → { "data": Row | null }
PUT     /api/kv/:scope           → { "data": Row, "created": true, "modified": true, "changed": ["tagInt1"] }
PATCH   /api/kv/:scope           → { "data": Row, "modified": true, "changed": ["tagInt1"] }
DELETE  /api/kv/:scope/:uid      → { "deleted": 1,  "data": Row }
DELETE  /api/kv/:scope?all=1     → { "deleted": 12, "scope": "package" }
GET     /api/kv/:scope/list      → { "items": [Row], "page": 1, "size": 20, "total": 3, "hasNext": false }
GET     /api/kv/:scope/:uid/log  → { "items": [Log], "page": 1, "size": 20, "total": 2, "hasNext": false }
POST    /api/user/profiles       → { "profiles": [ { "uid": 42, "nickname": "…", "avatar": "…" } ] }
  • GET 没建过回 data: null,不是报错 —— 别当成失败处理。
  • PUT 是整行覆盖,没写的字段会被清空;日常改数据用 PATCH。
  • PATCH 的 inc 也一样,新值直接就在 data 里,不用再查一次。
  • 一个字段都没变时 modified 是 false、changed 是空数组,日志也不会记 —— 那不是出错,是「你提交的内容和原来一模一样」。
  • DELETE /:uid 回带被删掉的那一行,客户端可以据此撤销。
  • ?all=1 删的是整个 scope(所有人的数据),必须显式带上。
  • list / log 都带 hasNext,分页不用自己算 page * size < total。

Row —— 一条数据

json
{
  "uid": 42,
  "scope": "package",
  "isPublic": false,
  "openEdit": ["tagInt1"],
  "tagTinyint": 1,
  "tagInt1": 100,
  "tagInt2": 0,
  "tagBigint": 0,
  "text1": "我的背包",
  "text2": null,
  "textLong": null,
  "extra": { "items": ["sword"], "gold": 1000 },
  "expiresAt": "2026-10-17T12:00:00.000Z",
  "createdAt": "2026-10-10T12:00:00.000Z",
  "updatedAt": "2026-10-10T12:00:00.000Z"
}
  • uid / scope —— 这条数据归谁、属于哪个业务。
  • isPublic —— false 时只有属主和管理员看得见。
  • openEdit —— 别人能改哪些字段的白名单,空数组 = 只读。只收这 7 个:tagTinyint / tagInt1 / tagInt2 / tagBigint / text1 / text2 / textLong。写 extra、isPublic 之类会 400。
  • tagTinyint / tagInt1 / tagInt2 / tagBigint —— 数字标签,给筛选用;也可以是「剩余血量」那种状态。
  • text1 / text2 / textLong —— 上限 128 / 512 / 1024 字符。
  • extra —— 任意 JSON,序列化后不超过 2048 字节;永远不在 openEdit 里,别人改不了。
  • expiresAt —— 过期时刻。写的时候带 ttl(秒,最多 30 天)就从当前时刻重算;不带就不动。

Log —— 改一次留一条

json
{
  "id": 901,
  "dataId": 77,
  "actorUid": 42,
  "action": "update",
  "changed": ["tagInt1", "text1"],
  "before": { "tagInt1": 100, "text1": "旧值" },
  "after":  { "tagInt1": 90,  "text1": "新值" },
  "createdAt": "2026-10-10T12:00:00.000Z"
}
  • actorUid —— 真正动手的人(管理员替玩家改时就是管理员)。
  • action —— "create" 或 "update"。
  • changed —— 这次动了哪几个字段,用的也是字段名。
  • before / after —— 只含被改字段的前后值,不是整行快照。

出错

json
{ "error": { "code": "invalid_param", "message": "text1 超过 128 字" } }
  • 所有失败都是这个形状,按 code 判断,别按 message 匹配。
  • quota_exceeded(409)—— 行数用满了:普通用户每个 toy 128 条,管理员 512 条。

字段名一律是驼峰(tagInt1、text1),请求和响应都一样。 写错名字不会被静默放过 —— 会 400,而且报错里会点出是哪个字段。

xmeta 联机数据测试台