docs(gateway): gateway 剩余文件注释改中文(逐行 1:1,代码零字节改动)
主人 2026-10-03 拍板「注释一律中文」;gateway 至此整包注释中文化完成(本会话共 3 批: 已推库 16 个文件 + 本批剩余文件)。 校验:机械校验(非注释改动行)= 空;剥注释后代码文本逐行比对全等(不一致文件数 0); 全树 go test ./... 58 包 ok / 0 FAIL;交叉编译绿。
This commit is contained in:
1 parent
91e8d7a029
commit
074ffc4ebf
73 files changed
+2529
-2529
No files matched your search
@@ -16,25 +16,25 @@ import (
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/config/runtimeconfig"
|
||||
)
|
||||
|
||||
// This file covers the admin half of the channel-level role binding (design/22 §2
|
||||
// 方案 b / §4.4): PUT /admin/channels/{platform}/config accepts personaId through the
|
||||
// existing read-modify-write + bridge.Reload path, an unknown role is refused
|
||||
// instead of binding a role that cannot answer, and the list endpoint reports the
|
||||
// binding back.
|
||||
// 本文件覆盖渠道级角色绑定的管理侧一半(design/22 §2
|
||||
// 方案 b / §4.4):PUT /admin/channels/{platform}/config 通过
|
||||
// 既有的 read-modify-write + bridge.Reload 路径接受 personaId,
|
||||
// 未知角色会被拒绝,而不是绑定一个无法应答的角色;
|
||||
// 列表端点会回报该绑定。
|
||||
//
|
||||
// personaId is three-state on the wire, because the panel sends the key only when
|
||||
// the owner actually touched the role select:
|
||||
// personaId 在线上是三态的,因为面板仅在主人
|
||||
// 真正触碰过角色选择时才发送该键:
|
||||
//
|
||||
// key absent → keep the stored binding
|
||||
// explicit "" → clear the binding
|
||||
// non-empty id → bind that role (unknown id → 400)
|
||||
// 键缺失 → 保留已存绑定
|
||||
// 显式 "" → 清除绑定
|
||||
// 非空 id → 绑定该角色(未知 id → 400)
|
||||
//
|
||||
// The absent-key case is the one that silently dropped bindings, so it is asserted
|
||||
// with a literal JSON body: a map[string]any would still make the assertion pass if
|
||||
// the DTO had picked up a value from somewhere else.
|
||||
// 「键缺失」这一情形正是静默丢弃绑定的那个,因此用字面量
|
||||
// JSON 请求体断言:若 DTO 从别处取到了值,map[string]any
|
||||
// 仍会让断言通过。
|
||||
|
||||
// putChannelConfigRaw posts a literal JSON body so a test can pin the exact wire
|
||||
// shape (notably: no personaId key at all).
|
||||
// putChannelConfigRaw 发送字面量 JSON 请求体,使测试能钉死确切的
|
||||
// 线上结构(尤其是:完全没有 personaId 键)。
|
||||
func putChannelConfigRaw(t *testing.T, ts *httptest.Server, platform, raw, token string) (*http.Response, []byte) {
|
||||
t.Helper()
|
||||
req, err := http.NewRequest(http.MethodPut,
|
||||
@@ -59,7 +59,7 @@ func putChannelConfigRaw(t *testing.T, ts *httptest.Server, platform, raw, token
|
||||
return resp, b
|
||||
}
|
||||
|
||||
// storedPersonaID reads the binding channels.json holds for one account.
|
||||
// storedPersonaID 读取 channels.json 为某个账号保存的绑定。
|
||||
func storedPersonaID(t *testing.T, path, platform, accountID string) string {
|
||||
t.Helper()
|
||||
accounts, warn := runtimeconfig.LoadChannels(path, nil)
|
||||
@@ -75,8 +75,8 @@ func storedPersonaID(t *testing.T, path, platform, accountID string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// listedPersonaID is the personaId GET /admin/channels reports for one account, i.e.
|
||||
// what the panel reads back to render the role select.
|
||||
// listedPersonaID 是 GET /admin/channels 为某个账号报告的 personaId,
|
||||
// 即面板读回用于渲染角色选择的值。
|
||||
func listedPersonaID(t *testing.T, ts *httptest.Server, token, platform, accountID string) (string, []byte) {
|
||||
t.Helper()
|
||||
resp, body := doReq(t, http.MethodGet, ts.URL+"/api/v1/admin/channels", nil, token)
|
||||
@@ -107,9 +107,9 @@ func listedPersonaID(t *testing.T, ts *httptest.Server, token, platform, account
|
||||
return "", body
|
||||
}
|
||||
|
||||
// TestAdminSaveChannelConfigPersonaIDBindsAndEchoes binds a channel role and
|
||||
// asserts it reached channels.json, that the list endpoint echoes it back for the
|
||||
// panel to render, and that the hot-reload path ran.
|
||||
// TestAdminSaveChannelConfigPersonaIDBindsAndEchoes 绑定一个渠道角色,
|
||||
// 断言它到达了 channels.json、列表端点回显它供面板渲染,
|
||||
// 并且热重载路径被执行。
|
||||
func TestAdminSaveChannelConfigPersonaIDBindsAndEchoes(t *testing.T) {
|
||||
t.Parallel()
|
||||
path := filepath.Join(t.TempDir(), "channels.json")
|
||||
@@ -136,9 +136,9 @@ func TestAdminSaveChannelConfigPersonaIDBindsAndEchoes(t *testing.T) {
|
||||
t.Logf("GET /api/v1/admin/channels echoes the binding: %s", listBody)
|
||||
}
|
||||
|
||||
// TestAdminSaveChannelConfigPersonaIDKeptWhenOmitted is the regression for the
|
||||
// silent data loss: the panel omits personaId unless the owner touched the role
|
||||
// select, so saving another field must leave the stored binding alone.
|
||||
// TestAdminSaveChannelConfigPersonaIDKeptWhenOmitted 是静默数据
|
||||
// 丢失的回归:除非主人触碰过角色选择,面板会省略 personaId,
|
||||
// 因此保存另一个字段必须不碰已存绑定。
|
||||
func TestAdminSaveChannelConfigPersonaIDKeptWhenOmitted(t *testing.T) {
|
||||
t.Parallel()
|
||||
path := filepath.Join(t.TempDir(), "channels.json")
|
||||
@@ -148,8 +148,8 @@ func TestAdminSaveChannelConfigPersonaIDKeptWhenOmitted(t *testing.T) {
|
||||
_, ts, jwt := buildEnv(t, cfgDefault(), Deps{Channels: store, Personas: personaTestRegistry(t)})
|
||||
tok := signAny(t, jwt, "acct", auth.RoleOwner)
|
||||
|
||||
// The wire body carries the new token and no personaId key at all — exactly
|
||||
// what an untouched role select produces.
|
||||
// 线上请求体携带新 token,且完全没有 personaId 键 ——
|
||||
// 正是一个未被触碰的角色选择所产生的形态。
|
||||
_, body := putChannelConfigRaw(t, ts,
|
||||
"telegram", `{"id":"conf0","token":"new-tok","groupMsgPerMin":5}`, tok)
|
||||
|
||||
@@ -164,16 +164,16 @@ func TestAdminSaveChannelConfigPersonaIDKeptWhenOmitted(t *testing.T) {
|
||||
t.Fatalf("GET /admin/channels personaId = %q, want yuki (body=%s)", echoed, listBody)
|
||||
}
|
||||
|
||||
// An explicit JSON null is the same as an absent key: the DTO cannot tell them
|
||||
// apart, and neither means "clear".
|
||||
// 显式的 JSON null 与键缺失相同:DTO 无法区分二者,
|
||||
// 二者都不表示「清除」。
|
||||
putChannelConfigRaw(t, ts, "telegram", `{"id":"conf0","token":"newer-tok","personaId":null}`, tok)
|
||||
if got := storedPersonaID(t, path, "telegram", "conf0"); got != "yuki" {
|
||||
t.Fatalf("null personaId cleared the binding: personaId = %q, want yuki", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdminSaveChannelConfigPersonaIDClearedOnExplicitEmpty asserts that clearing
|
||||
// the binding still works, but only when the panel says so with an explicit "".
|
||||
// TestAdminSaveChannelConfigPersonaIDClearedOnExplicitEmpty 断言清除
|
||||
// 绑定仍然可行,但仅在面板以显式 "" 表示时才如此。
|
||||
func TestAdminSaveChannelConfigPersonaIDClearedOnExplicitEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
path := filepath.Join(t.TempDir(), "channels.json")
|
||||
@@ -193,9 +193,9 @@ func TestAdminSaveChannelConfigPersonaIDClearedOnExplicitEmpty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdminSaveChannelConfigPersonaIDKeptPerAccount pins the read-modify-write to
|
||||
// the account being saved: an omitted personaId on one account must inherit that
|
||||
// account's binding, not a sibling's.
|
||||
// TestAdminSaveChannelConfigPersonaIDKeptPerAccount 把 read-modify-write
|
||||
// 钉在正在保存的账号上:某账号省略 personaId 时必须继承该
|
||||
// 账号自己的绑定,而不是兄弟账号的。
|
||||
func TestAdminSaveChannelConfigPersonaIDKeptPerAccount(t *testing.T) {
|
||||
t.Parallel()
|
||||
path := filepath.Join(t.TempDir(), "channels.json")
|
||||
@@ -218,9 +218,9 @@ func TestAdminSaveChannelConfigPersonaIDKeptPerAccount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdminSaveChannelConfigRejectsUnknownPersonaID keeps the save fail-closed: a
|
||||
// channel bound to a role the library does not know would silently answer as the
|
||||
// default role, so it is refused and nothing is written or reloaded.
|
||||
// TestAdminSaveChannelConfigRejectsUnknownPersonaID 保持保存 fail-closed:
|
||||
// 绑定到一个库不认识的角色时,渠道会静默地以默认角色应答,
|
||||
// 因此该绑定被拒绝,不写入也不重载。
|
||||
func TestAdminSaveChannelConfigRejectsUnknownPersonaID(t *testing.T) {
|
||||
t.Parallel()
|
||||
path := filepath.Join(t.TempDir(), "channels.json")
|
||||
|
||||
Reference in new issue
Block a user