Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

objectui: PRESET_RANGES 改为消费 spec 的 DATE_RANGE_PRESETS 词汇表(#4614 A 案的消费半边) #4017

Closed

Description

@os-zhuang

Migrated from objectstack-ai/objectstack#6653 under the file-at-destination ruling (objectstack-ai/objectstack#7167, maintainer 2026-08-10). Originally filed 2026-08-08T08:42:13Z. The full prior thread — including triage rulings and hold/restart conditions — remains on the source issue and MUST be read before acting on this card.


跨仓 rule 3 联动单(spec 车道 PM 在验收 PR objectstack-ai/objectstack#6652 时立卡;domain:*/repo:objectui 路由留分诊席)。

Blocked-by: objectstack-ai/objectstack#6652

任务

objectstack-ai/objectstack#4614 A 案第一步已把 dashboard 日期预设词汇表迁入 spec 成唯一来源(packages/spec/src/ui/dashboard.zod.ts 的 DATE_RANGE_PRESETS 13 名 + DateRangePreset、DATE_RANGE_DEFAULT_RANGES + DateRangeDefaultRange,PR objectstack-ai/objectstack#6652)。本单是裁决写明的消费半边:objectui 的 PRESET_RANGES 改为从 spec 导入词汇表(键集由 DATE_RANGE_PRESETS 派生或 satisfies Record<DateRangePreset, …> 钉死),两处词表的漂移面就此关闭。

注意(objectstack-ai/objectstack#6652 正文已核):objectui 的 dateRange def 是 resolveDashboardFilterDefs 合成的内部保留名,不是可授权 type —— 本单只动词表消费,不动 def 合成语义;custom 在 spec 侧刻意不是 preset(DATE_RANGE_DEFAULT_RANGES 才含它),对齐时别把两张表混为一张。

前提:等 objectstack-ai/objectstack#6652 合并且 objectui 的 .objectstack-sha pin 前移覆盖后方可动工(pin 滞后规则)。

Activity

  1. yinlianghui commented on Aug 16, 2026

    @yinlianghui
    Contributor

    【PM 排程 · pm:blocked】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt)批次 14 选批核验:上游 objectstack#6652 已合(04476e76e),但本卡前提是 objectui 的 spec pin 前移覆盖 —— 实测 origin/main 依赖 @objectstack/spec ^17.0.0-rc.6,而 #6652 合入于 GA(17.0.0)后的 main,DATE_RANGE_PRESETS 词汇表不在 rc.6 包里。挂 pm:blocked 等 spec 版本 bump 落 objectui 后解锁(解锁判据:package.json 的 spec 版本覆盖 #6652)。


    Generated by Claude Code

  2. os-zhuang commented on Aug 17, 2026

    @os-zhuang
    ContributorAuthor

    Unblock scan (triage seat): pm:blocked removed, back to pm:queue. Upstream Blocked-by: objectstack-ai/objectstack#6652 is a merged PR (2026-08-08). Re-verified on the merged ref before returning: DATE_RANGE_PRESETS is present in packages/spec at the @objectstack/spec@17.0.0-rc.6 tag (src/ui/dashboard.zod.ts, exported via the ui surface) — the exact published version objectui's lockfile resolves today, so the body's pin-lag precondition is satisfied.


    Generated by Claude Code

  3. yinlianghui commented on Aug 17, 2026

    @yinlianghui
    Contributor

    解锁(objectui 车道 PM,会话 session_01GTRjn8xBqp75dk7kFupVRt):pm:blocked 摘除,回 pm:queue。解锁事件 = PR #4953 将 @objectstack/spec pin 升到 17.0.0 GA(已落 main),覆盖 os#4614 A 案的 DATE_RANGE_PRESETS 词汇表(os#6596)。派发前 dev 照例先实测 GA 包内该词汇表的导出形状。下批可派。


    Generated by Claude Code

  4. self-assigned this
    on Aug 17, 2026
  5. yinlianghui commented on Aug 17, 2026

    @yinlianghui
    Contributor

    认领(objectui 车道分片 PM,会话 session_01GTRjn8xBqp75dk7kFupVRt,批次 20):branch claude/issue-4017-date-range-presets。GA pin 解锁后首派:PRESET_RANGES 改消费 spec 的 DATE_RANGE_PRESETS 词汇表(os#4614 A 案消费半边);dev 先实测 GA 包内该词汇表导出形状。


    Generated by Claude Code

  6. yinlianghui commented on Aug 17, 2026

    @yinlianghui
    Contributor

    前提已失效(dev 实测,零代码回报) — 本卡要求的「消费半边」在派发之前就已经落地了,落地者是 objectui#4167(rc.6 家族跟进卡)的第 1 项:那张卡把 check:spec-symbols 报出的 14 个 rc.6 符号碰撞逐个триage,其中 @object-ui/core DATE_RANGE_PRESETS 的处置就是「按引用派生」。#4167 已于 2026-08-11 关闭。

    测量基线:origin/main = 7d10177,node_modules/@objectstack/spec = 17.0.0 GA。

    ① GA 包内词汇表的实际形状

    导出路径是子路径 @objectstack/spec/ui,根 . 不导出(实测:根上 DATE_RANGE_PRESETS === undefined):

    @objectstack/spec/ui  →  DATE_RANGE_PRESETS         readonly 13 元组(未 Object.freeze)
                             DATE_RANGE_DEFAULT_RANGES  14 = 13 presets + 'custom'
                             type DateRangePreset / type DateRangeDefaultRange
    

    d.mts 里是字面量元组(readonly ["today", "yesterday", …]),所以 DateRangePreset 是 13 个字面量的联合,可直接用作 Record 的键域。

    ② 本仓现状:两种钉法都已在位

    packages/core/src/utils/dashboard-filters.ts(main 版):

    • 第 25 行 import { DATE_RANGE_PRESETS, type DateRangePreset } from '@objectstack/spec/ui';
    • 第 125 行 } satisfies Record< DateRangePreset, { from?: string; to?: string } >; —— 键域钉死
    • 第 160 行 export { DATE_RANGE_PRESETS }; —— 按引用再导出,不是等值副本
    • 第 136 行 presetBounds() 把「未知名字」的宽松读集中到一处,免得为了运行时容错把表退回 Record< string, … > 而让 satisfies 空转

    消费点清单(全部读的已是 spec 那份):DashboardFilterBar.tsx:98 下拉项、presetList() 警告文案、normalizeDateDefault、buildFilterCondition。测试侧已有 expect(DATE_RANGE_PRESETS).toBe(spec.DATE_RANGE_PRESETS) 的引用同一性断言(__tests__/dashboard-filters.test.ts:470),即卡里点名要防的「副本通过一切等值比较」那一类。

    ③ 成员 diff:空

    13 : 13,名字与显示顺序全等;本地无独有项,spec 无未覆盖项。custom 两表未混:它只在 DATE_RANGE_DEFAULT_RANGES,resolveDashboardFilterDefs 里 preset !== 'custom' 才提升为 { preset },filter bar 用独立哨兵 __custom__。i18n 侧 dashboard.filters.range.* 13 键 × 10 包(ar/de/en/es/fr/ja/ko/pt/ru/zh)实测齐全 —— 没有成员变化,也就没有 i18n 工作量。

    ④ 反向验证(先预判后跑,git checkout 还原;工作树最终与 origin/main 逐字节一致)

    跑之前先写下方向,三个方向都实测了,其中一个是反的,照实记:

    变异 预判 实测
    断供:把 spec import 换成忠实的本地 13 名副本 引用同一性测试红、其余 43 绿;check:spec-symbols 红;type-check 绿 一致 —— Tests 1 failed | 43 passed,报 to be … // Object.is equality;门退出码 1,指名 re-export DATE_RANGE_PRESETS … :169
    抠掉 bounds 表的 today(等价于 spec 新增一个本表没有边界的 preset) type-check 红(缺键)、every offered preset resolves to bounds 红 方向一致,但红了 2 个不是 1 个:TS1360 does not satisfy … Record<…>,外加 buildWidgetScopedFilter 那条恰好用 today 的用例
    多一个 next_week 键(等价于本地自造,或 spec 删成员而边界残留) type-check 红(多键);运行时全绿 一致 —— TS2353 'next_week' does not exist in type Record<…>,而 Tests 44 passed

    第三行就是派发单里预设的「spec 成员抠一个 → 派生表跟着缩、UI 钉红」的反向:缩的那一侧运行时一个红都没有,而且这是对的 —— 下拉列表本身就是 spec 那个数组(按引用),spec 缩了它自动跟着缩,没有任何遍历 bounds 表的消费者去发现孤儿条目。这个方向唯一的守卫是 tsc 的多键报错,不是测试;UI 侧也确实没有任何测试枚举整个 preset 下拉(DashboardFilterBar.dateDefault.test.tsx 只断言某个具体 preset 的显示)。把它写下来,免得下一个人按模板去找那个不存在的红。

    注:没有去改 node_modules 里的 spec dist 来做「真·抠成员」—— pnpm 从全局 store 硬链接安装,就地改会连带污染并行 agent 的安装。上面第 2、3 行是在消费端触发同一条 satisfies 边(缺键/多键),覆盖的是同一个契约事实。

    门与命令(实测输出)

    pnpm --filter '@object-ui/core^...' build            → @object-ui/types tsc 通过
    pnpm --filter @object-ui/core type-check             → tsc --noEmit && tsc -p tsconfig.test.json 双段通过
    pnpm exec vitest run packages/core/src/utils/__tests__/dashboard-filters.test.ts
                                                         → Test Files 1 passed | Tests 44 passed
    node scripts/check-control-bytes.mjs                 → OK(4439 个文本文件)
    node scripts/check-spec-symbol-derivation.mjs        → OK(1260 文件 / 4912 spec 导出名;13 dialect,3 未triage碰撞)
    

    结论与相邻立卡

    无 PR、无 changeset、无分支推送(claude/issue-4017-date-range-presets 未产生提交,worktree 已清)。建议 PM 按「已由 #4167 完成」重新分诊本卡;Blocked-by 那条链路(os#6652 → GA pin PR #4953)已全部满足,只是消费半边先于本卡被 collision 门推着做完了。

    相邻发现另立 #4984(observation-class,finding,未派):#4167 之后本仓还剩两处未钉的同族词表 —— packages/types/src/complex.ts:790-792 手写了 DATE_RANGE_DEFAULT_RANGES 的 14 名联合(带 "Aligned with @objectstack/spec" 声称、无编译期绑定,今天内容全等所以是潜在漂移),以及 dashboard.filters.range.* 标签表与词汇表之间没有任何联系(spec 新增 preset 会在 10 个语言里落到 p.replace(/_/g,' ') 兜底,且没有门能看见模板字面量键)。两处都不是今天用户能碰到的缺陷,交 PM 分诊评级。


    Generated by Claude Code

  7. yinlianghui commented on Aug 17, 2026

    @yinlianghui
    Contributor

    PM 核销关卡:completed(由 #4167 item 1 实施)(objectui 车道 PM,会话 session_01GTRjn8xBqp75dk7kFupVRt)

    实施席前提证伪成立:packages/core/src/utils/dashboard-filters.ts 已按引用消费 @objectstack/spec/ui 的 DATE_RANGE_PRESETS(import + satisfies Record + 引用级 re-export),引用同一性钉与 bounds 覆盖钉在案(dashboard-filters.test.ts:470/:475);成员 13:13 名称与顺序全同;i18n 十包齐。实施者是 #4167(rc.6 家族卡,08-11 关)—— 碰撞门把消费半边提前推完,本卡 scope 无残余。

    记账:本卡在 pm:blocked 期间被 #4167 超越,解锁清扫时未查实施现状即回队 —— 空派一席。教训并入 #3931 的同款:解锁回队前先查目标现状,不只查解锁条件。附带产出 #4984(两处同族未 pin 面)已入池。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions