Conversation
- repository:新增 WarMapKey/NewsnowKey/SituationMonitor{Monitors,Layout,Settings}Key
编译期常量;FindWarMap/FindNewsnow 复用既有单 key 参数化查询;
FindSituationMonitor 一次聚合查询三个固定 key(对齐 NestJS findMany,
WHERE orgId+userId+key IN 三个编译期常量——无任意 key API)
- situationmonitor.go:三段聚合响应(updatedAt 各段 omitempty、无记录 null)
+ monitors(trim/截断/keywords 先截 30 再去重/color/location/最多 20)
+ layout(五断点/legacy lg 回退/取整与最小值/visibility 64 项有序上限)
+ settings(windowHours 6/24/72、scope、三个布尔回退)
- warmap.go:完整移植 packages/utils war-map-contract.ts——46 layer 固定
struct 序列化、legacy key 映射、viewState clamp、bearing/pitch 归零、
枚举回退、根对象 vs 嵌套 layerVisibility 差异
- newsnow.go:source id pattern/trim/去重/上限(200/32/300)、
hideCrossSourceDuplicates 的 JS Boolean 真值、smart→personalized、
clamp+round;columnOrders/sourceAffinity 用 orderedEntries 流式有序解码
(Object.entries 顺序 + 前N项语义,map 随机遍历不可用)+ 自定义
MarshalJSON 保持对象形态与字段顺序
- internal/usersettingsread:六个 GET 共享一个 handler——同一 authhttp.Authenticator 鉴权链装配(Bearer→JWT 验签→Redis blacklist→ MySQL membership/RBAC)、同一 usersettings.Repository、同一连接池; 端点差异收敛为编译期绑定表(query+build 闭包对),不复制六份 handler - 请求链固定:items.read 判定 → 固定 UserSetting 查询 → normalization → 契约响应(Cache-Control: no-store、authhttp 错误契约、不追加换行) - 旧 internal/onboarding 已被完全替代,删除(任务书:不得新旧并存); onboarding 端点改由统一 handler 的绑定表承载
- config:新变量 API_GO_USER_SETTINGS_READ_MODE=shadow|go(非法值启动
失败);空=兼容旧行为(API_GO_ONBOARDING_MODE 继续控制 onboarding,
rss/spacetime shadow,war-map/newsnow/situation-monitor legacy);
go 模式要求 JWT_SECRET/DATABASE_URL/REDIS_HOST 齐备(与批3A 变量
取或触发同一校验)
- legacyproxy.DefaultRules(onboardingMode, readMode):六个 user-settings
GET 的模式由 readMode 统一决定(设置时优先级高于 onboardingMode);
全部 exact path + GET method 白名单
- main.go:go 接管时装配 usersettingsread.NewHandler 并注册六个 path;
shadow 单元表扩展到六端点(war-map/newsnow 单 key + situation-monitor
三 key 聚合 executant);go 接管端点按路由表 ModeGo 集合从 shadow
单元表过滤;healthz 自省改报 userSettingsRead.{mode,database}
- 新增唯一测试文件 batch3b_test.go(4 个顶层函数,未超过 5 个上限): Situation Monitor(三段聚合/部分记录/代表性规整)、War Map(默认/ legacy key/clamp/嵌套差异)、NewsNow(有序对象/真值/clamp/去重/ smart 归一 + 序列化形态)、situation visibility 64 项有序上限 - main_test.go:shadow identity gate 表格扩展六端点(新三端点 GET 执行 一次/PUT 零执行);countingRepo 扩展六方法 + 聚合计数;新增 TestUserSettingsReadModeRouting(readMode 三态路由表矩阵 + go 模式 下 PUT/POST/HEAD/相似路径回落 legacy 的 exact-method 边界) - config_test.go:read mode 三值语义 + go 模式依赖前置(合并表格) - mysql_integration_test.go:扩展到 8 个固定 key——war-map/newsnow 真实 读取与 normalization 抽查;situation-monitor 部分记录聚合(只有 monitors)与全三 key 聚合、租户隔离
…立性证明 - Phase A:六个 PUT(含 situation-monitor 三段一次写入)经 api-go 由 NestJS 单写;MySQL 直查 8 个固定 key 均存在;PUT 前后 shadow executed 不变;相似路径 404 不误命中 - Phase B:API_GO_USER_SETTINGS_READ_MODE=shadow 启动——六个 GET 全部 NestJS 响应 + Go 真实旁路差分(executed 精确 +7 含 healthz/live、 diffs/dropped 六类零增量、inflight 归零;不扩大 ignore 集) - Phase C:重启为 readMode=go——六端点与 NestJS 直连逐字段契约对比 (status/Cache-Control/content-type/JSON/trace header、各端点读自己 key、situation-monitor 三段 updatedAt 对应);Go 请求零 shadow 执行 - Phase D:停止 NestJS 并确认 4000 关闭——六个 GET 仍 200(Phase A 持久化数据);代表性 PUT(war-map)502 证明写路径未迁入 Go;未迁移 GET(/api/items)502 证明不伪装成功;容器 healthcheck 保持健康 - 共享鉴权链负向用例只保留代表性端点(onboarding)——批3A 已验证的 JWT/RBAC 行为不重复铺矩阵
- compose api-go pilot:API_GO_USER_SETTINGS_READ_MODE=go(优先级高于 批3A 变量,后者保留 go 兼容);.env.example/.env.sample 登记新变量 与兼容优先级 - apps/api-go/README:统一接管章节(替换批3A 单端点叙述——不并存)、 配置表新变量、四态路由表、四阶段 smoke 描述、回滚(shadow 或删除 变量回兼容行为) - 根 README:pilot 章节、流量去向、验证状态(四阶段 + 明确生产/预发 流量未切换、不代表 NestJS 迁移完成) - ADR §4.4:统一接管决策记录(绑定表非注册框架、8 key 封闭集合、 有序对象语义、四阶段验收、边界如实登记) - four-mode/contract-inventory/roadmap:六 GET=ModeGo、六 PUT=Legacy、 API_GO_USER_SETTINGS_READ_MODE 优先级与兼容语义
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
CI 根因(run 34112159439,verify lint / user-settings-integration 同源): NormalizeSituationMonitors 的循环变量是 any(asJSONObjectArray 返回 []any),直接下标索引编译失败(cannot index record)。修复:循环内先 断言为 map[string]any(非对象跳过——与 NestJS !entry || typeof !== object || Array.isArray 跳过语义一致)。 同时修正 smoke fixture 的 fallback 断言:Bad location 监控项缺失 id/createdAt 时 NestJS 回填 randomUUID()/Date.now()(非确定值)—— 改用 @exists: 哨兵断言存在性与形态(id 以 sm- 开头、createdAt 为毫秒 时间戳),不是把随机字段加入 ignore 集。Phase A 与 Phase D 同步。
CI 根因(run 34112587502)三处独立: 1. warmap.go:warMapLayerCount 常量误写 46(WAR_MAP_LAYER_IDS 实际 45 项)——[46]T 数组声明 + 45 个初始化器会零值填充第 46 个空 layer id,defaultWarMapVisibility 遍历 46 个下标时 fields[45] 越界 panic。修正常量并同步文档口径。 2. batch3b_test.go:monitors 数量断言错——fixture 4 条中 #2(name 空) 与 #3(无 keywords)整条丢弃,保留 2 条(不是 3);Bad location 的索引也相应是 [1] 不是 [2]。 3. mysql_integration_test.go:步骤 4 的「其他 key 不串读」占位插入用了 ui:war-map:settings:v1——批3B 步骤 7 的真实 WarMapKey 插入撞 orgId+userId+key 唯一键(1062)。占位改用非业务 key。
CI 根因(run 34115328067 verify Go tests)三处均为 fixture/断言错误: 1. cables 断言方向反了——if Cables 触发的是 want-true 场景(新 key true 应被采用),应为 !Cables 才报错。 2. situation settings autoRefresh:输入 0 是数字非布尔——NestJS normalizeBoolean 回退默认 true(不是 false)。 3. visibility 64 项上限:NestJS 对 key 只要求 trim 后非空(无 pattern 检查)——'bad-key!' 也占位。fixture 67 个非空 key 前 64 个存活 = v001…v063 + bad-key!;v064 起丢弃(此前误以为非法 key 不占位)。 同步修正误导性注释(fixture 无 not-a-bool 项)。
smoke run 34117253953 根因:Phase A 的 PUT 回显断言用 "settings" in doc
判别响应形态——situation-monitor 的响应顶层三段(monitors/layout/
settings)同样含顶层 settings 键,被误判为单 key 端点的 {settings:{…}}
包裹形态,monitors 断言拿到 None。改以 monitors 段判别(仅
situation-monitor 有)。
smoke run 34118687382 根因:Phase D 的 _partial 断言直接读响应顶层字段,
而 war-map 的 viewState/activePreset 等在 settings 段内(单 key 端点的
{settings:{…}} 包裹形态)——顶层取到 None。改为先断言 settings 非 null
(war-map 数据确实存在),再从 settings 段读 partial 字段。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Go-批3B:user-settings 六个只读 GET 统一 Go 接管
核心变更
六个只读 GET 在 pilot Go 模式(
API_GO_USER_SETTINGS_READ_MODE=go)下全部由 Go 独立完成——不请求 NestJS、不读 JWT permissions claim、NestJS 停止后仍可用:GET /api/user-settings/ui/onboardingGET /api/user-settings/ui/rss-readerGET /api/user-settings/ui/spacetime-timelineGET /api/user-settings/ui/war-mapGET /api/user-settings/ui/newsnowGET /api/user-settings/ui/situation-monitor六个 PUT 仍全部由 NestJS 单写(exact path + GET method 白名单)。
实现要点
war-map-contract.ts(46 layer + legacy key 映射 + viewState clamp + bearing/pitch 归零);Situation Monitor 三段聚合;NewsNow 有序对象(Object.entries顺序 + 200/32/300 上限 + JS Boolean 真值,流式有序解码而非 map 随机遍历)internal/usersettingsread):六端点共享同一鉴权链装配与连接池,编译期绑定表;旧internal/onboarding删除(不并存)API_GO_USER_SETTINGS_READ_MODE=shadow|go,空=兼容旧行为(批3A 变量继续控制 onboarding);非法值启动失败边界(不变)
登录/refresh/logout/MFA/OIDC/机器令牌仍全部 NestJS;canary 未激活;默认生产入口未切换;本轮是远端真实栈验证,不是生产/预发流量验收。
无新增 Go 依赖(go.mod/go.sum 零变化);NestJS 契约零修改(OpenAPI/Auth Matrix/GraphQL 基线应零漂移)。