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
@@ -14,54 +14,54 @@ import (
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/services/backthink"
|
||||
)
|
||||
|
||||
// Notification feed limits (design/10 §3 #16). Compile-time constants so no bare
|
||||
// magic number appears in the run path (project rule §10).
|
||||
// 通知 feed 的限制(design/10 §3 #16)。编译期常量,因此运行路径中
|
||||
// 不出现裸魔法数字(项目规范 §10)。
|
||||
const (
|
||||
defaultNotificationLimit = 50
|
||||
maxNotificationLimit = 200
|
||||
// notificationFetchFactor widens the per-source read. The merged page must be
|
||||
// the newest N of the union, which the per-source newest-N always contains,
|
||||
// but with a `before` cursor one source can dominate the newest window and
|
||||
// starve the other — the factor pays for that.
|
||||
// notificationFetchFactor 加宽每来源的读取。合并页必须是并集的
|
||||
// 最新 N 条,而每来源的最新 N 条总是包含它,
|
||||
// 但在带 `before` 游标时某一来源可能占据最新窗口并
|
||||
// 饿死另一来源 —— 该系数就是为此付出的代价。
|
||||
notificationFetchFactor = 4
|
||||
// notificationBodyRunes caps a backthink summary in the feed; the full text
|
||||
// stays available on GET /api/v1/admin/backthink.
|
||||
// notificationBodyRunes 限定 feed 中后台思考摘要的长度;全文
|
||||
// 仍可在 GET /api/v1/admin/backthink 获取。
|
||||
notificationBodyRunes = 200
|
||||
)
|
||||
|
||||
// The unified feed's families, used both as the item `type` and as the `?type=`
|
||||
// filter. They are derived from the sources the composition root already has
|
||||
// (design/10 §3 #16: 先聚合现有源为统一 feed,避免新建重模型).
|
||||
// 统一 feed 的族,既用作条目的 `type`,也用作 `?type=`
|
||||
// 过滤器。它们派生自组合根已有的来源
|
||||
// (design/10 §3 #16:先聚合现有源为统一 feed,避免新建重模型)。
|
||||
const (
|
||||
// NotificationTypeSystem is a system/security operation: backup & restore,
|
||||
// JWT rotation, API-key revocation, plugin install/uninstall, tool policy.
|
||||
// NotificationTypeSystem 是系统/安全操作:备份与恢复、
|
||||
// JWT 轮换、API key 吊销、插件安装/卸载、工具策略。
|
||||
NotificationTypeSystem = "system"
|
||||
// NotificationTypeChannel is a channel lifecycle or connection event
|
||||
// (channel.open / close / save / reject / login).
|
||||
// NotificationTypeChannel 是渠道生命周期或连接事件
|
||||
// (channel.open / close / save / reject / login)。
|
||||
NotificationTypeChannel = "channel"
|
||||
// NotificationTypeBackthink is one proactive push the background thinker
|
||||
// decided to send.
|
||||
// NotificationTypeBackthink 是后台思考器决定发送的一次
|
||||
// 主动推送。
|
||||
NotificationTypeBackthink = "backthink"
|
||||
// NotificationTypeAudit is the remaining admin audit trail: personas, memory,
|
||||
// users, RAG, sessions, uploads, audio.
|
||||
// NotificationTypeAudit 是剩余的管理审计链:人格、记忆、
|
||||
// 用户、RAG、会话、上传、音频。
|
||||
NotificationTypeAudit = "audit"
|
||||
)
|
||||
|
||||
// Provenance labels carried on an item's `source` field.
|
||||
// 条目 `source` 字段上携带的来源标签。
|
||||
const (
|
||||
notificationSourceAudit = "audit"
|
||||
notificationSourceBackthink = "backthink"
|
||||
// notificationIDPrefixAudit / ...Backthink namespace the source's own record id
|
||||
// so the merged feed has stable, collision-free, client-dedupable ids.
|
||||
// notificationIDPrefixAudit / ...Backthink 为来源自身的记录 id 加命名空间,
|
||||
// 使合并 feed 的 id 稳定、无冲突、客户端可去重。
|
||||
notificationIDPrefixAudit = "audit:"
|
||||
notificationIDPrefixBackthink = "backthink:"
|
||||
)
|
||||
|
||||
// AdminNotification is one item of the unified notification feed (design/10 §3
|
||||
// #16). It is a read-only projection of an existing record — audit rows and
|
||||
// backthink records — never a new persisted model: `id` is "<source>:<原生 id>",
|
||||
// `title`/`body` are derived from the source record, and `createdAt` is epoch
|
||||
// milliseconds.
|
||||
// AdminNotification 是统一通知 feed 的一个条目(design/10 §3
|
||||
// #16)。它是既有记录 —— 审计行与后台思考记录 —— 的只读
|
||||
// 投影,绝不是新的持久化模型:`id` 是 "<source>:<原生 id>",
|
||||
// `title`/`body` 派生自来源记录,`createdAt` 是 epoch
|
||||
// 毫秒。
|
||||
type AdminNotification struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
@@ -71,13 +71,13 @@ type AdminNotification struct {
|
||||
CreatedAt int64 `json:"createdAt"`
|
||||
}
|
||||
|
||||
// adminListNotifications returns the unified notification feed (owner/admin
|
||||
// read): the admin audit trail and the background thinker's proactive pushes,
|
||||
// merged newest-first and filterable by family and by a `before` cursor.
|
||||
// adminListNotifications 返回统一通知 feed(owner/admin
|
||||
// 读):管理审计链与后台思考器的主动推送,
|
||||
// 最新优先合并,可按族与 `before` 游标过滤。
|
||||
//
|
||||
// A source that is not injected contributes no items — the feed reports what
|
||||
// actually exists instead of fabricating a family — so a deployment without the
|
||||
// backthink service simply has no `backthink` items.
|
||||
// 未注入的来源不贡献任何条目 —— feed 报告确实存在的
|
||||
// 内容,而不是编造一个族 —— 因此没有后台思考服务的
|
||||
// 部署就是没有 `backthink` 条目。
|
||||
func (s *Server) adminListNotifications(w http.ResponseWriter, r *http.Request) {
|
||||
limit := parseNotificationLimit(r)
|
||||
typ := strings.TrimSpace(r.URL.Query().Get("type"))
|
||||
@@ -112,9 +112,9 @@ func (s *Server) adminListNotifications(w http.ResponseWriter, r *http.Request)
|
||||
writeJSON(w, http.StatusOK, out)
|
||||
}
|
||||
|
||||
// notificationItems reads both sources and returns their merge, newest first. A
|
||||
// source failure is returned (never swallowed into a silently shorter feed), so
|
||||
// the endpoint answers a clear error instead of pretending there was no event.
|
||||
// notificationItems 读取两个来源并返回它们的合并结果,最新优先。
|
||||
// 来源失败会被返回(绝不被吞进静默变短的 feed),因此
|
||||
// 端点返回明确的错误,而不是假装没有事件。
|
||||
func (s *Server) notificationItems(ctx context.Context, fetch int) ([]AdminNotification, error) {
|
||||
auditItems, err := s.notificationsFromAudit(ctx, fetch)
|
||||
if err != nil {
|
||||
@@ -129,17 +129,17 @@ func (s *Server) notificationItems(ctx context.Context, fetch int) ([]AdminNotif
|
||||
if items[i].CreatedAt != items[j].CreatedAt {
|
||||
return items[i].CreatedAt > items[j].CreatedAt
|
||||
}
|
||||
// Descending id keeps the order deterministic for items sharing a
|
||||
// millisecond (the cursor can split one millisecond across pages).
|
||||
// id 降序为共享同一毫秒的条目保持确定性顺序
|
||||
// (游标可能把一毫秒拆到两页)。
|
||||
return items[i].ID > items[j].ID
|
||||
})
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// notificationsFromAudit projects the admin audit trail (audit_logs, persisted
|
||||
// by NewSQLiteAuditStore) into feed items. The fallback in-memory store holds
|
||||
// only records really appended in this process, so an unwired store yields an
|
||||
// empty family rather than fabricated entries.
|
||||
// notificationsFromAudit 把管理审计链(audit_logs,由
|
||||
// NewSQLiteAuditStore 持久化)投影为 feed 条目。回退的内存存储
|
||||
// 只保留本进程真正追加过的记录,因此未接线的存储得到
|
||||
// 空族,而不是编造条目。
|
||||
func (s *Server) notificationsFromAudit(ctx context.Context, fetch int) ([]AdminNotification, error) {
|
||||
if s.obs == nil || s.obs.audit == nil {
|
||||
return nil, nil
|
||||
@@ -162,10 +162,10 @@ func (s *Server) notificationsFromAudit(ctx context.Context, fetch int) ([]Admin
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// notificationsFromBackthink projects the background thinker's records into feed
|
||||
// items. Only records that decided to push are notifications (a plain thinking
|
||||
// record is not an event the owner needs to be told about); each carries the
|
||||
// delivery state so the feed never claims an undelivered push was sent.
|
||||
// notificationsFromBackthink 把后台思考器的记录投影为 feed
|
||||
// 条目。只有决定推送的记录才是通知(普通思考
|
||||
// 记录不是需要告知主人的事件);每条都携带
|
||||
// 投递状态,因此 feed 绝不声称未投递的推送已发出。
|
||||
func (s *Server) notificationsFromBackthink(ctx context.Context, fetch int) ([]AdminNotification, error) {
|
||||
if s.backthink == nil {
|
||||
return nil, nil
|
||||
@@ -191,9 +191,9 @@ func (s *Server) notificationsFromBackthink(ctx context.Context, fetch int) ([]A
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// notificationTypeOfAudit classifies an audit operation into a feed family: the
|
||||
// channel lifecycle is `channel`, and the system/plugin/policy operations are
|
||||
// `system`; everything else stays `audit`.
|
||||
// notificationTypeOfAudit 把审计操作归类到 feed 族:
|
||||
// 渠道生命周期是 `channel`,系统/插件/策略操作是
|
||||
// `system`;其余保持 `audit`。
|
||||
func notificationTypeOfAudit(what string) string {
|
||||
switch {
|
||||
case strings.HasPrefix(what, "channel."):
|
||||
@@ -207,8 +207,8 @@ func notificationTypeOfAudit(what string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// notificationAuditBody derives an audit item's body from its who/what/result
|
||||
// trail, e.g. "owner:owner · ok".
|
||||
// notificationAuditBody 从审计条目的 who/what/result
|
||||
// 链推导其 body,例如 "owner:owner · ok"。
|
||||
func notificationAuditBody(rec AuditRecord) string {
|
||||
parts := make([]string, 0, 2)
|
||||
if who := strings.TrimSpace(rec.Who); who != "" {
|
||||
@@ -220,9 +220,9 @@ func notificationAuditBody(rec AuditRecord) string {
|
||||
return strings.Join(parts, " · ")
|
||||
}
|
||||
|
||||
// notificationAuditAt parses an audit record's RFC3339 timestamp into epoch
|
||||
// milliseconds. An unparseable timestamp yields 0: the item still appears (oldest
|
||||
// first) instead of being dropped or stamped with a made-up time.
|
||||
// notificationAuditAt 把审计记录的 RFC3339 时间戳解析为 epoch
|
||||
// 毫秒。无法解析的时间戳得到 0:条目仍然出现(最旧
|
||||
// 优先),而不是被丢弃或被盖上一个编造的时间。
|
||||
func notificationAuditAt(when string) int64 {
|
||||
ts, err := time.Parse(time.RFC3339Nano, strings.TrimSpace(when))
|
||||
if err != nil {
|
||||
@@ -231,9 +231,9 @@ func notificationAuditAt(when string) int64 {
|
||||
return ts.UnixMilli()
|
||||
}
|
||||
|
||||
// backthinkNotificationTitle labels one proactive push with its trigger and
|
||||
// delivery state, so the feed distinguishes "sent" from "decided but not
|
||||
// delivered" (route none / no online client / push failure).
|
||||
// backthinkNotificationTitle 用触发原因与投递状态标注一条主动
|
||||
// 推送,使 feed 区分「已发送」与「已决定但未
|
||||
// 投递」(route none / 无在线客户端 / 推送失败)。
|
||||
func backthinkNotificationTitle(rec backthink.Record) string {
|
||||
state := "未送达"
|
||||
if rec.PushResult.Pushed {
|
||||
@@ -245,8 +245,8 @@ func backthinkNotificationTitle(rec backthink.Record) string {
|
||||
return "主动推送(" + state + ")"
|
||||
}
|
||||
|
||||
// clipRunes truncates s to at most max runes, appending an ellipsis when it was
|
||||
// cut. It never splits a multi-byte rune.
|
||||
// clipRunes 把 s 截断到至多 max 个 rune,被截断时追加省略号。
|
||||
// 它绝不切开多字节 rune。
|
||||
func clipRunes(s string, max int) string {
|
||||
if max <= 0 || utf8.RuneCountInString(s) <= max {
|
||||
return s
|
||||
@@ -255,9 +255,9 @@ func clipRunes(s string, max int) string {
|
||||
return string(runes[:max]) + "…"
|
||||
}
|
||||
|
||||
// parseNotificationLimit parses the ?limit= query param, clamping to
|
||||
// [1, maxNotificationLimit] and selecting defaultNotificationLimit when absent or
|
||||
// invalid.
|
||||
// parseNotificationLimit 解析 ?limit= 查询参数,夹取到
|
||||
// [1, maxNotificationLimit],缺失或非法时选用
|
||||
// defaultNotificationLimit 作为默认值。
|
||||
func parseNotificationLimit(r *http.Request) int {
|
||||
n, err := strconv.Atoi(r.URL.Query().Get("limit"))
|
||||
if err != nil || n <= 0 {
|
||||
@@ -269,11 +269,11 @@ func parseNotificationLimit(r *http.Request) int {
|
||||
return n
|
||||
}
|
||||
|
||||
// parseNotificationBefore parses the ?before= epoch-millisecond cursor. The
|
||||
// cursor is inclusive (items with createdAt <= before are returned): the sources
|
||||
// resolve to milliseconds, so a page boundary can fall inside one millisecond,
|
||||
// and the client deduplicates by id. An absent or malformed cursor means "from
|
||||
// the newest item".
|
||||
// parseNotificationBefore 解析 ?before= epoch 毫秒游标。该
|
||||
// 游标是包含式的(返回 createdAt <= before 的条目):来源
|
||||
// 解析到毫秒,因此页边界可能落在一毫秒之内,
|
||||
// 而客户端按 id 去重。游标缺失或畸形意味着「从
|
||||
// 最新条目开始」。
|
||||
func parseNotificationBefore(r *http.Request) (int64, bool) {
|
||||
raw := strings.TrimSpace(r.URL.Query().Get("before"))
|
||||
if raw == "" {
|
||||
@@ -286,8 +286,8 @@ func parseNotificationBefore(r *http.Request) (int64, bool) {
|
||||
return ms, true
|
||||
}
|
||||
|
||||
// notificationFetchLimit widens a page request into the per-source read window,
|
||||
// capped at maxObsLimit (the audit store's own ceiling) and never below the page.
|
||||
// notificationFetchLimit 把页请求加宽为每来源读取窗口,
|
||||
// 上限为 maxObsLimit(审计存储自身的上限),且绝不低于该页。
|
||||
func notificationFetchLimit(limit int) int {
|
||||
fetch := limit * notificationFetchFactor
|
||||
if fetch > maxObsLimit {
|
||||
@@ -299,8 +299,8 @@ func notificationFetchLimit(limit int) int {
|
||||
return fetch
|
||||
}
|
||||
|
||||
// validNotificationType reports whether t names a feed family. An unknown family
|
||||
// is rejected with 400 rather than answered with a silently empty feed.
|
||||
// validNotificationType 报告 t 是否是一个 feed 族名。未知族
|
||||
// 以 400 拒绝,而不是以静默为空的 feed 作答。
|
||||
func validNotificationType(t string) bool {
|
||||
switch t {
|
||||
case NotificationTypeSystem, NotificationTypeChannel, NotificationTypeBackthink, NotificationTypeAudit:
|
||||
|
||||
Reference in new issue
Block a user