Base Account / Integration

账号系统接入文档

按能力模块拆分的接入规范,供产品工程和 AI Agent 按需获取。

Issuerhttps://user.stringzhao.lifeAudiencebase-account-clientJWKShttps://user.stringzhao.life/.well-known/jwks.jsonDocv2026-03-06.3

反馈系统 API Contract

仅复制反馈系统文档

用户侧反馈提交复用 base-account 登录态(跨子域 cookie 自动携带),按 serviceKey 标识来源项目;管理员处理在 Admin Console 反馈看板。

POST/api/feedback

提交反馈(Bug/建议/咨询),可选附带已上传的截图 url。

Auth: access_token

展开查看请求/响应示例

Request

{ "serviceKey": "little-bee", "type": "BUG", "description": "登录按钮无反应", "attachments": ["https://.../a.png"] }

Response

{ "feedback": { "id": "fb-1", "status": "PENDING" } }

Errors

  • invalid_input(400): 描述为空 / 类型非枚举 / 附件 url 非 https
  • too_many_attachments(400): 附件数 > 4
  • invalid_service_key(400): serviceKey 未注册
  • unauthorized(401): 未登录
  • rate_limited(429): 单用户 60s 内提交 > 3 条
GET/api/feedback/mine

查看我的反馈列表(含对外消息 messages,仅 PUBLIC;不含内部备注)。

Auth: access_token

展开查看请求/响应示例

Response

{ "feedbacks": [{ "id": "fb-1", "status": "PENDING", "messages": [{ "authorRole": "ADMIN", "content": "已收到" }] }] }

Errors

  • unauthorized(401): 未登录
POST/api/feedback/attachments

上传单张截图(multipart file),返回 blob url。校验 image/* + ≤2MB。

Auth: access_token

展开查看请求/响应示例

Request

multipart/form-data: file=<image/png>

Response

{ "url": "https://.../a.png", "size": 102400 }

Errors

  • invalid_file_type(400): 非 image/*
  • file_too_large(413): > 2MB
  • unauthorized(401)
POST/api/feedback/:id/messages

用户在反馈下追加消息(双向对话,通知管理员邮箱)。

Auth: access_token

展开查看请求/响应示例

Request

{ "content": "补充:重启后恢复" }

Response

{ "message": { "id": "cm-1", "content": "补充:重启后恢复", "createdAt": "..." } }

Errors

  • invalid_input(400): 内容为空
  • forbidden(403): 反馈不属于该用户(横向越权)
  • feedback_not_found(404)
GET/api/admin/feedback

管理员看板列表:按 serviceKey/type/status 筛选 + 描述搜索 + 游标分页。

Auth: admin

展开查看请求/响应示例

Request

?serviceKey=little-bee&status=PENDING&q=登录&limit=50

Response

{ "feedbacks": [{ "id": "fb-1", "userEmail": "a@x.com", "status": "PENDING" }], "total": 1 }

Errors

  • forbidden(403): 非管理员
GET/api/admin/feedback/:id

管理员详情:反馈全文 + 附件 + 全部 comments(含 INTERNAL 备注 + PUBLIC 消息 + authorRole/visibility)。

Auth: admin

展开查看请求/响应示例

Response

{ "feedback": {...}, "attachments": [...], "comments": [{ "authorRole": "ADMIN", "visibility": "PUBLIC", "content": "..." }] }

Errors

  • feedback_not_found(404)
  • forbidden(403): 非管理员
PATCH/api/admin/feedback/:id/status

状态流转(PENDING/IN_PROGRESS/RESOLVED/IGNORED)。状态变更不再自动发邮件。

Auth: admin

展开查看请求/响应示例

Request

{ "status": "RESOLVED" }

Response

{ "feedback": { "id": "fb-1", "status": "RESOLVED" } }

Errors

  • invalid_status(400): 非法状态值
  • feedback_not_found(404)
  • forbidden(403)
POST/api/admin/feedback/:id/comments

添加内部备注(visibility=INTERNAL,仅管理员可见,用户看不到)。

Auth: admin

展开查看请求/响应示例

Request

{ "content": "已复现,排期本周修" }

Response

{ "comment": { "id": "cm-1", "content": "已复现,排期本周修", "createdAt": "..." } }

Errors

  • invalid_input(400): 内容为空
  • feedback_not_found(404)
  • forbidden(403)
POST/api/admin/feedback/:id/reply

回复用户(visibility=PUBLIC,用户可见 + 触发回访邮件,正文含回复内容)。

Auth: admin

展开查看请求/响应示例

Request

{ "content": "已修复,请升级到最新版" }

Response

{ "message": { "id": "cm-2", "content": "已修复,请升级到最新版", "createdAt": "..." } }

Errors

  • invalid_input(400): 内容为空
  • feedback_not_found(404)
  • forbidden(403)

类型 / 状态 / 可见性

  • 类型 type: BUG / SUGGESTION / INQUIRY
  • 状态 status: PENDING / IN_PROGRESS / RESOLVED / IGNORED(用户视角 IGNORED → CLOSED)
  • 消息可见性 visibility: INTERNAL / PUBLIC(INTERNAL=内部备注仅管理员,PUBLIC=对外消息双向对话)
  • 消息作者 authorRole: ADMIN / USER
  • 附件: ≤4 张 / ≤2097152 字节 / image/*
  • 频率限制: 单用户 3 条 / 60s

邮件通知规则

  • 新反馈到达 → 邮件通知管理员(ADMIN_EMAILS)
  • 用户发消息(POST /messages)→ 通知管理员
  • 管理员回复用户(POST /reply)→ 发邮件给提交者(正文含回复内容)
  • 状态变更(RESOLVED/IGNORED)→ 不再自动发邮件,改由 reply 显式触发

Integration Template

提交反馈 + 查看我的反馈(浏览器 fetch)

browser
展开查看模板代码
// 复用 base-account 登录态(跨子域 cookie 自动携带)
const submit = await fetch("/api/feedback", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    serviceKey: "little-bee",
    type: "BUG",
    description: "播放音频时偶尔没声音"
  })
});
const { feedback } = await submit.json();

// 查看我的反馈 + 管理员回复
const mine = await fetch("/api/feedback/mine").then(r => r.json());
for (const f of mine.feedbacks) {
  console.log(f.status, f.messages); // messages 仅含 PUBLIC 对外消息
}