Skip to content

refactor(core): dashboard date presets read their bounds from the spec window table - #29320

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-e8bmpz
Nov 2, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-e8bmpz

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steedos · project thread

Fixes #29116

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:仪表盘日期筛选不再自带一份预设日期区间表,13 个预设(本月、上季度、近 30 天等)一律读 spec 里那张唯一的表。
  • 为什么改:两张表写的是同一组区间,只是本期写法不同({current_month_start} 对 {month_start}),迟早会漂移;你已定为低优先级卡。
  • 风险与回滚:本期区间的写法从 {current_*} 换成同义的 {month_start} 这类别名,解析出的日期逐一相同;回滚就是 revert 本 PR。
  • 先看:ui/packages/core/src/utils/dashboard-filters.ts 里的 presetBounds,然后是新测试 dashboard-filters.presetWindows-29116.test.ts。
  • 两分钟验证:在 ui/ 下运行 pnpm exec vitest run packages/core/src/utils/__tests__/dashboard-filters.presetWindows-29116.test.ts,应看到 44 个测试全部通过。
  • 需要你做的:无,席位落地。

What changes

  • ui/packages/core/src/utils/dashboard-filters.ts: the local PRESET_RANGES table is gone. presetBounds(preset) now returns the spec's window from DATE_RANGE_PRESET_MACRO_WINDOWS (@objectstack/spec/data), and membership is decided by the spec's exact isDateRangePresetName, both in presetBounds and in normalizeDateDefault (which used defaultValue in PRESET_RANGES). The docblocks that explained the table's satisfies pin now say where that guarantee lives: the spec declaration is typed Record<DateRangePreset, …>, so a preset added without a window fails to compile in the spec, and there is no local table to invent a name in.
  • The emitted condition for the four current-period presets changes spelling only: this_week, this_month, this_quarter and this_year emit the bare aliases ({month_start} / {month_end} and so on) instead of {current_month_start} / {current_month_end}. The other nine presets emit byte-identical tokens.
  • No new key, option, schema or export. No spec change. DATE_RANGE_PRESETS is still re-exported from @object-ui/core as before.
  • Patch changeset .changeset/29116-dashboard-preset-windows-from-spec.md for @object-ui/core.

Why

The card: the same 13 presets had two tables, the spec's and this module's, in two spellings of the same days. Both resolve today through DATE_MACRO_ALIAS_TOKENS, so nothing was wrong on screen; the risk was the tables drifting.

Tests

New ui/packages/core/src/utils/__tests__/dashboard-filters.presetWindows-29116.test.ts (44 tests):

  • every preset in DATE_RANGE_PRESETS emits exactly the spec's window (13 cases), and the preset set equals the retired table's 13 keys;
  • every preset resolves (resolveDateMacros) to the same two calendar dates under the new spelling and under the retired {current_*} table, copied verbatim into the test, on six reference dates that cross week, month, quarter and year boundaries plus a leap day (13 cases);
  • for a compare-to widget fed the same condition, shiftFilterByCompareTo gives the same window for previousPeriod and previousYear, and compareToTrendLabelKey gives the same label under both spellings (13 cases);
  • a stored dashboard written in the {current_*} spelling still filters: a custom range { from: '{current_month_start}', to: '{current_month_end}' } passes through and selects the same days as the this_month preset, and a date global filter defaulting to '{current_quarter_start}' is kept as a token, passed through and resolved;
  • an unknown preset still misses with the usual warning, including names that are Object.prototype members (constructor, toString, __proto__), and such a name is not lifted to { preset } as a date default.

Changed pin: ui/packages/core/src/utils/__tests__/dashboard-filters.test.ts asserted the literal {current_month_start} / {current_month_end} emitted for this_month (two places). They now assert {month_start} / {month_end}. This is behaviour-neutral: the pin is on the emitted token string, and the parity cases above prove the two tokens resolve to the same day on every preset and reference date.

Pins named by the card stay green without edits: ui/packages/types/src/__tests__/report-chart-query-spec-parity.test.ts, the plugin-dashboard DashboardFilterBar* and DashboardRenderer.filters tests (none of them pins an emitted current-period token).

Acceptance notes

Verification

Local runs (ui/, locked; b8bd448, core suite again on 97d4d50)
  • Prerequisite closure turbo run build --filter='@object-ui/core^...' plus formula, sdui-parser, lint, client: 38/38 tasks, exit 0.
  • pnpm exec vitest run packages/core/: Test Files 231 passed (231), Tests 4280 passed, 27 skipped.
  • Consumer pins (16 files: plugin-dashboard DashboardFilterBar*, DashboardRenderer.filters, DashboardPhoneTouchTargets-29078; types report-chart-query-spec-parity; plugin-designer DashboardDesignPage.presetAlias; i18n dashboard-range-preset-labels-4984; app-shell DashboardWidgetInspector): Test Files 16 passed, Tests 142 passed, 6 skipped.
  • turbo run type-check --filter=@object-ui/core: exit 0 (it compiles the test files; the first run caught a typing slip in the new test, fixed in the second commit).
Ablations (scripts/ablation-replace.mjs, restored to the HEAD blob each time)
  • presetBounds guard swapped to preset in DATE_RANGE_PRESET_MACRO_WINDOWS: "an unknown preset name still misses, prototype member names included" goes red; restored, blob equals HEAD.
  • normalizeDateDefault guard swapped to defaultValue in DATE_RANGE_PRESET_MACRO_WINDOWS: "a non-preset date default is not lifted to a preset" goes red; restored, blob equals HEAD.
Derived gates

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at b8bd448 (34 families) and run there; --ran reconciliation: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. Every family exit 0:

  • node scripts/check-adr-0087-registration.mjs --base origin/main exit 0
  • node scripts/check-adr-0087-registration.mjs --self-test exit 0
  • node scripts/check-changeset-no-major.mjs --base origin/main exit 0
  • node scripts/check-closing-keyword-parity.mjs exit 0
  • node scripts/check-closing-keyword-parity.mjs --self-test exit 0
  • node scripts/check-comment-mask-corpus.mjs exit 0
  • node scripts/check-empty-changeset.mjs --base origin/main exit 0
  • node scripts/check-empty-changeset.mjs --self-test exit 0
  • node scripts/check-sdui-manifest.mjs exit 0
  • node scripts/check-sdui-manifest.mjs --self-test exit 0
  • node scripts/pm/release-rehearsal-clone.mjs --self-test exit 0
  • node scripts/release-pending-publish.mjs --self-test exit 0
  • pnpm --filter @objectstack/spec run check:duration-unit-keys exit 0
  • pnpm check:changeset-gate-self-tests exit 0
  • pnpm check:closed-ceremony-text exit 0
  • pnpm check:cross-package-test-inputs exit 0
  • pnpm check:dispatcher-error-vocabulary exit 0
  • pnpm check:driver-memory-census exit 0
  • pnpm check:engine-double-contract exit 0
  • pnpm check:gitlink-declared exit 0
  • pnpm check:nul-bytes exit 0
  • pnpm check:pm-changeset-deadline-census exit 0
  • pnpm check:published-files exit 0
  • pnpm check:query-options-erasure exit 0
  • pnpm check:refd-timer-probe exit 0
  • pnpm check:skill-identifier-liveness exit 0
  • pnpm check:test-source-alias exit 0
  • pnpm check:tier-file-adoption exit 0
  • pnpm check:type-check-coverage exit 0
  • pnpm check:type-check-debt exit 0
  • pnpm check:undeclared-dep-imports exit 0
  • pnpm check:watch-hint-literal exit 0
  • pnpm check:where-matcher exit 0
  • pnpm --dir ui exec vitest run scripts/ exit 0

pnpm --dir ui exec vitest run scripts/: Test Files 169 passed, 2 skipped (171). After merging main (head 97d4d50, no change to the touched files or the spec date tables): vitest run packages/core/ again 231/231 files, check:nul-bytes and check-sdui-manifest.mjs exit 0.


Generated by Claude Code

…c window table

dashboard-filters drops its local PRESET_RANGES copy and lowers every
preset through @objectstack/spec's DATE_RANGE_PRESET_MACRO_WINDOWS, with
membership decided by isDateRangePresetName. The emitted current-period
tokens move to the spec's bare aliases, which resolve to the same days.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jSgqmN55SMKRe9YTif
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Nov 2, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#5 · zhuangjianguo · session_01QsR2jQjvWkZ7is6GXbC6DB

席位核对 — ACCEPT · domain:ui#5 · head 97d4d508 · 2026-11-02T12:12Z

  • 形态: draft PR on main. The body has Fixes #29116 on its own line and no other card number next to a closing keyword. 4 files, +255/−61, Tier S: check-governed-merges --pr 29320 finds no governed path and 316 lines, under the 3000 limit. The body carries 维护者速读 and both declaration lines (Clause-②: no, Metadata-protocol: none), copied from claim 6575679437.
  • 前提实测: at origin/main 39951d2a, dashboard-filters.ts:165 held PRESET_RANGES. It repeated the spec's DATE_RANGE_PRESET_MACRO_WINDOWS (packages/spec/src/data/date-range-presets.ts:120-136), spelling the four current-period presets in {current_*} (seat read, claim on Dashboard date presets: read the spec macro window table instead of a second table with different spellings #29116). The dev ran two ablations, and both go red.
  • diff read: the local table is gone. presetBounds returns the spec's window, gated by the spec's isDateRangePresetName, and normalizeDateDefault uses the same predicate instead of in PRESET_RANGES. So an unknown name still misses with the usual warning, and an Object.prototype name (constructor, toString) now misses too, where it used to reach a bare index. The spec's own declaration, typed Record<DateRangePreset, …>, now carries the old satisfies guarantee: a preset without a window fails to compile. No export changes, and DATE_RANGE_PRESETS is still re-exported. Only the four current-period presets change spelling ({month_start} for {current_month_start}, and so on). The new file pins resolved-date parity for all 13 presets on six reference dates, including period boundaries and a leap day, plus compare-to window and label parity, and confirms that a stored {current_*} custom range and token default still filter.
  • 门禁 check-runs (pinned to head 97d4d508c6b995064b66d7d329686bcb41907b80): 44 success, 11 skipped, 0 failed, 0 pending. mergeable_state clean. Dev local gates: 34 derived, all exit 0; --ran 0 NOT-MEASURED. Core suite 231/231; 16 consumer pin files green.
  • 接受的偏差: (1) two this_month pins in dashboard-filters.test.ts now assert {month_*} instead of {current_month_*}. The pin is on the token string, and the parity cases prove both resolve to the same day, so this is behaviour-neutral. (2) A prototype-only preset name is now dropped with the usual warning instead of silently. Both are declared in the body.
  • 范围外去向: none reported.
  • 落地条款: no contract review owed (Clause-②: no, no export changed). Land by pr_ready + automerge_enable.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 2, 2026 12:13
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 2, 2026 12:13
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 57cde8c Nov 2, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-e8bmpz branch November 2, 2026 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard date presets: read the spec macro window table instead of a second table with different spellings

1 participant