Repository navigation
feat(spec): a report declares its period (dateRange) and the export of its table (exportOptions) - #26628
Conversation
Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
…geset Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
…ess counts; drill the two report containers Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
…ection Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
…cate census Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
…e empty state Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 3 package(s): 11 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 7 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 147 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin dd34d9461ef9c38e21e66497c4aa106ba72d2023 && git checkout dd34d9461ef9c38e21e66497c4aa106ba72d2023
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 8222fa805d0e288fec470e47e374e408b4925745 be4a0204cdad1918fcf4a6571c7e87d8faabf2b5 && git checkout -B drift-repro 8222fa805d0e288fec470e47e374e408b4925745 && git merge --no-ff be4a0204cdad1918fcf4a6571c7e87d8faabf2b5
node scripts/docs-audit/affected-docs.mjs --json 8222fa805d0e288fec470e47e374e408b4925745
|
Contract reviewServed-tier: Inputs read: card #26548 (body and all three comments: triage 6436657773, claim 6437381453, os-dev report 6440254029), PR #26628 (body, 29-file list, net diff against Gate state at the time of this review. Complete and green: ① Derived judgments
② Semver levelThe changeset is Clause-②: yes (widening) ③ Boundary flagsThe dev's os-dev report (6440254029) raises one open question and seven deviations. Each is answered here. Open question: should a joined report refuse Deviations, in the dev's order:
Skills-docs follow-up owed. The PR's Governed surface. The diff touches ④ Design judgmentpackages/spec/src/ui/report.zod.ts. The design holds against its first consumer and its execution plan. The first consumer is #25873's Console report page; its contract is written in the TSDoc (the packages/spec/src/ui/list-view-export-options.ts. packages/spec/src/ui/report.form.ts. One collapsed section, section-level skills/objectstack-ui/rules/dashboards.md. The hunk adds one
Implemented-by: VERDICT: PASS |
… the served-schema census; skills: name the report dimension rule and the order default Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: This is the delta review of Inputs read: card #26548 (body and its three comments; nothing was added after the full review), PR #26628 (body, 30-file list, Delta shape. One commit, Gate state at the time of this review. The new head has no check-runs: Test Core on the old head, for the record. ① Derived judgments
② Semver levelUnchanged by the delta. No published package moves: a test file and a skills file. The changeset and the PR body's declaration lines still read Clause-②: yes (widening) ③ Boundary flagsThe head cannot land as it stands, and this record covers no later head. The PR is in conflict with Governed surface. The diff still touches Skills-docs follow-up named in the full review (an eval prompt in ④ Design judgmentskills/objectstack-ui/rules/dashboards.md. The two changed lines are the two should-fixes of the full review, in the form that review asked for, and each sentence was checked against the code it describes (items 4 to 6 above). The dashboard example at line 166 of the same file still writes
packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts (cited, not a hits file). The count moves by exactly what the served schema gained, and the comment records why. No finding on the delta; the conflict with Implemented-by: VERDICT: PASS |
Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com> # Conflicts: # packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts
Claude-Session: https://claude.ai/code/session_01WGufzhMJrMdCkQS33DYtmu Co-authored-by: Claude <noreply@anthropic.com>
席位核对 · ACCEPT ·
|
Requested by Yibo Wang · project thread
Fixes #26548
Clause-②: yes (widening)
Metadata-protocol: added
Skills-docs: follow-up owed — skills/objectstack-ui/evals/analytics-inline-vs-dataset.json
维护者速读
dateRange是报表覆盖的时间段,预设表、默认值和改名提示与仪表盘逐字相同,作用于数据集里一个type: 'date'的维度;exportOptions是报表表格的下载(csv / xlsx,默认开启,formats: []关闭)。另加一条 lint 规则(判定维度是否存在、是否日期、省略时是否唯一)、表单「时间段与导出」分区、文档和三种语言的翻译。packages/spec/src/ui/report.zod.ts(两个新键和 joined 报表的拒绝),packages/lint/src/validate-report-date-range.ts(四种判定,也接在报表发布门上),packages/spec/src/ui/list-view-export-options.ts(ReportExportOptionsSchema,只留 csv / xlsx)。pnpm --filter @objectstack/spec exec vitest run src/ui/report-date-range-export.test.ts,预期 48 个用例全部通过,其中一条断言报表的defaultRange/allowCustomRange与仪表盘的声明逐字相等。skills/**,属受管面:席位合同评审通过后由你合并。What changes
ReportSchemagains two optional top-level keys (packages/spec/src/ui/report.zod.ts). A report that declares neither parses exactly as before, with neither key in its output.dateRange: { dimension?, defaultRange, allowCustomRange }, a closed block.defaultRangeandallowCustomRangeare the dashboard's declaration: the sameDATE_RANGE_DEFAULT_RANGESimport (no second preset table), the same defaults (this_month,true), the same describes and the same rename hints (preset/range/default,allowCustom/custom).report-date-range-export.test.tsholds the two declarations equal throughstrictObjectDeclarations()and their JSON Schema, sodashboard.zod.tsis untouched.dimensionnames a dataset dimension that declarestype: 'date'(ADR-0021: a report selects by dimension name), with the dashboardcompareTohintsfield/dateField/fieldName/timeDimensionrenamed onto it. The TSDoc states the renderer contract: the window ridesselection.timeDimensions: [{ dimension, dateRange }]with nogranularity, a filter window the analytics service already accepts. Top-level aliasesdateFilter/timeRange→dateRange(the dashboard's).exportOptions: { formats?, includeHeaders?, fileNamePrefix? }, declared asReportExportOptionsSchemabeside its list sibling inlist-view-export-options.ts.includeHeadersandfileNamePrefixare the list block's members by identity;formatsisListViewExportFormatSchema.exclude(['json']), socsv/xlsx.maxRecords/streamingare answered as list-only. No permission key: the TSDoc and describe nameObjectPermission.allowExporton the dataset base object, the predicate the list toolbar uses. Default on (both formats),formats: []off.joinedreport refuses both keys, in the superRefine arm that already refuses the containerchart, with the same no-pointer style.JoinedReportBlockSchemagetsguidancefor both keys.ReportSchemaforallowExport(points at the permission-set axis andexportOptions: { formats: [] }),subscriptionandschedule(no scheduled delivery of a report).validateReportDateRange(packages/lint/src/validate-report-date-range.ts), in the reference-integrity suite besidevalidateChartBindings, so it runs onos validate/os lint/os buildand at thereportpublish door (runtimeTypes: ['flow', 'report']). Fourerrorverdicts, each with anos explainentry:report-date-range-dimension-unknown,-not-date,-ambiguous(omitted, two or more date dimensions) and-none(omitted, none). The omitted-dimension rule is the dashboard executor'scompareTorule: exactly one candidate is used.liveness/report.jsonrows for both keys,planned,authorWarnwith an author hint, notes naming the renderer read point inDatasetReportRenderer.tsxand [Decision] The report page offers only "Edit": should a shipped report get a time-range filter, export and subscription, and in which order #25873 as carrier. Both containers are drilled (children, six child rows) so the gate's undeclared-inheritance check is satisfied.lint-liveness-propertiesnow walksreports, so the warning reaches authors.report.form.tsgets a collapsed "Period & export" section,visibleWhen: "data.type != 'joined'", with both composites. Translated in@objectstack/platform-objectsfor zh-CN, ja-JP and es-ES.content/docs/ui/reports.mdx§ "Period and export" (anos:checkexample, the dimension rule, the window lowering, the export permission axis, a "declared, not drawn yet" callout, what is not offered) and a paragraph under "Permissions and protection".skills/objectstack-ui/rules/dashboards.md§ Report Configuration gets thedateRangeexample.content/docs/references/ui/report.mdx,authorable-surface/ui.json, the strictness-ledger counts and the liveness state counts.@objectstack/specminor,@objectstack/lintminor,@objectstack/platform-objectspatch, with both declaration lines.Skills readings (
skills/**touched):skills/objectstack-ui/rules/dashboards.mdlinesskills/objectstack-ui/rules/dashboards.mdtokens (ratchet, ceiling 6239)skills/objectstack-ui/**linesSKILL.mdlinesThe three-line
ordercomment becomes a trailing comment onorder, and the freed lines carry a one-line period comment plus thedateRangeexample, so the file still shrinks by one line and 3 tokens. Before isorigin/mainat the round-3 merge. The eval is the owed half (filed as #26633): bothskills/objectstack-ui/evals/*.jsonfiles sit at their token ceiling (headroom 0), so a report-period prompt cannot be added here without deleting another prompt.Tests
packages/spec/src/ui/report-date-range-export.test.ts(new, 48 cases): untouched reports,dateRange: {}defaults, every preset accepted,last_6_monthsrefused, every rename hint, unknown member,dateFilter/timeRange, joined refusal on container and block, declaration parity with the dashboard,exportOptionsaccepts and refusals (json,pdf,docx,maxRecords,streaming, bare array, joined, block),allowExport/subscription/scheduleguidance,defineReportandgetMetadataTypeSchema('report').packages/lint/src/validate-report-date-range.test.ts(new): all four verdicts on theapp-todotask-dataset shape, nearest-name suggestion among date dimensions only, silence on unbound / joined / malformed input, suite integration, verdict length andos explainper id.runtime-gate.inert-type-writes.test.ts: a new block proving thereportpublish door judges a date range against the dataset it binds (four cases and a control); the door's member pin is now two members.lint-liveness-properties.test.ts: both keys warn with the authored hint; a report without them is silent.report-form-echo-decisions.test.ts(population 44 → 50), the catalog-wide positive control inobject-lifecycle-panel-echo-decisions.test.ts(683 → 686),validate-predicate-path-refs.test.tspredicate census (88 → 89, literal comparisons 63 → 64). Each carries a dated comment.packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts: the served/meta/typescensus pinsreportat 23 top-level properties (was 21), with a JSDoc line saying why. The round-3 merge ofmainkept main's lowered counts for the other types (feat(spec)!: retirement kits whose conversion retired at or below 16.x age out; the strict unknown-key refusal names the protocol upgrade guide #26599).Acceptance notes
Read against the card's Acceptance list. Deviations, each a choice made here:
exportOptionsis also refused on ajoinedcontainer. The card decides the joined case fordateRangeonly. A joined report draws one table per block, so "the table the report draws" has no single answer. Widening later is non-breaking. Raised as an open question in the report.jsonandpdfget report-side messages. The card sayspdfkeeps the list's retirement prescription, but that text sends the author to list behaviour that is false for a report. The report message forpdfpoints at a page withprint.subscription/scheduleguidance cites no ruling. Runtime strings carry no tracker numbers in this repo, so the text says what is true (no scheduled delivery) without the ruling reference.reportpublish door as well asflow(the chart-bindings precedent), so publishing a report with a baddimensionis refused, as the docs say.this_year, notthis_quarter. The example's matrix bucketsclose_dateby quarter, so a quarter window would draw one column.@objectstack/platform-objectsbundles metadata forms, so the six new leaves landed there (three locales, authored, not filled);pnpm check:i18nreports all ten packages in sync.ReportExportOptionsSchemalives inlist-view-export-options.ts, which, like its list sibling, is outside theuibarrel;check:api-surfaceis unchanged.Out of scope, untouched:
ui/(the renderer is #25873), any server export route,dashboard.zod.ts.Verification
All readings local, final head
be4a0204cdad. It mergesorigin/mainat86ae47e13(no rebase);mainmoved 6 commits during the test run, none touching a file this PR changes, andgit merge-treeagainst8222fa805is clean. CI check-runs are not cited here: they report after this push.0c548c59a8ca):@objectstack/spec729 files / 22095 tests passed (1 skipped, 1 todo);@objectstack/lint167 files / 7411 passed;@objectstack/platform-objects96 files / 1361 passed. Typecheck of all three: exit 0.eslinton the 15 changed source files: exit 0.node scripts/pm/dispatch-gates.mjs --commandsnamed 113 families at4dca57f78; all were run on a full workspace build (118 turbo tasks) with each exit code recorded before any pipe. One was red:check:empty-state(exit 1), because thedateRangeTSDoc says an absent window shows every period and nothing classified it. Fixed in8c03abecb: the sentence now sits beside the key anddateRangeis registered as ascopeempty state (it widens the period, never the access). That commit derived one more family (check:pnpm-flag-spellings). Re-run after it:check:empty-state,check:pnpm-flag-spellings,check:spec-docblock-symbol-anchors,check:liveness,check:docs,check:api-surface,check:nul-bytes, all exit 0.dispatch-gates --ran: 114 derived, 114 run, 0 NOT-MEASURED, 0 UNRUN.be4a0204cdad): the merge conflicted only inCARD_PROPERTY_COUNTS(protocol.meta-types-degenerate-derivation.test.ts), resolved to main's lowered counts withreport: 23and both comment blocks.pnpm install, thencheck:generated --fixregeneratedauthorable-surface/ui.json(main's file plusui/Report:dateRangeandui/Report:exportOptions), then 0 stale.check:empty-stateandcheck:livenessexit 0. Suites, each exit 0:@objectstack/spec732 files / 21956 passed (1 todo);@objectstack/lint167 / 7411;@objectstack/platform-objects96 / 1361;@objectstack/metadata-protocol269 files (3 skipped) / 21580 passed (19 skipped), census file 18 / 18;@objectstack/plugin-security230 / 4991 passed (45 skipped).check:dev-prereqsexit 0,check:skill-frame-freshnessexit 0.check:liveness (report rows)
check:i18n and the translation ledgers
Skills token ratchet
Focused tests
Generated by Claude Code