Repository navigation
Commit 7053333
refactor(service-analytics): set the drill sidecars on the declared AnalyticsResult (#20762)
Fixes #20727
Clause-②: no
`AnalyticsResult` (`@objectstack/spec/contracts`) has declared
`dimensionFields`, `drillRawRows`, `drillRawTotals` and `drillRanges`
since #20700 (PR #20720). This retires the service's module-private
`AnalyticsResultWithDrill` augmentation and sets the four members on the
declared type, with no cast. No answer changes, and nothing published
changes.
## What changed
- `packages/services/service-analytics/src/analytics-service.ts`:
deleted `type AnalyticsResultWithDrill` (at `:100` on the base) and its
doc comments. The four sets in `answerDataset` now write
`result.dimensionFields`, `result.drillRawRows`, `result.drillRawTotals`
and `result.drillRanges` on `result: AnalyticsResult`. Each was `(result
as AnalyticsResultWithDrill).…` (`:1970`, `:1973`, `:1985`, `:2034` on
the base). No new local type, no other cast, no contract change.
- Two of the deleted doc comments disagreed with the emission: the
`drillRanges` bounds and omission rule, and `dimensionFields` values,
which can be relationship paths. The contract's descriptions follow the
emission and are now the only text.
- New pin: `src/__tests__/drill-sidecars-emission.test.ts` (1 test).
- Not touched: the `previewDrafts` early return (triage ruled it out of
this card), and `packages/spec`.
## Premises measured (dispatch D1 to D4)
- **D1: the sets type-check on the declared type.** `pnpm --filter
@objectstack/service-analytics run typecheck` exits 0 with the casts
gone. `tsc --listFiles` holds 138 of 138 `src/__tests__` files, the new
pin included. Two reverse checks ran through
`scripts/ablation-replace.mjs`, each with the restore proven (blob
equals HEAD, `git diff HEAD` empty):
- A wrong value shape at the `dimensionFields` set gives `TS2322` at
`(1923,7)`: the type `{ [k: string]: number; }` is not assignable to the
declared `Record` of string to string. (The message's angle-bracket
spelling is written out here in words.)
- An undeclared member name at the `drillRanges` set gives `TS2551:
Property 'drillRangez' does not exist on type 'AnalyticsResult'. Did you
mean 'drillRanges'?` at `(1987,14)`.
- So each set is checked against the member `AnalyticsResult` declares.
The emission and the contract agree.
- **D2: every reference.** `git grep AnalyticsResultWithDrill` over the
whole tracked tree at the base finds 5 hits, all in
`analytics-service.ts`: the type and the four casts. After the edit it
finds 0 (exit 1). After a full build, none of the 68 `packages/**/dist`
directories names it, against a positive control (`drillRawTotals` hits
the spec and service-analytics dists).
- **D3: what publishes. Nothing, so `skip-changeset`.**
`@objectstack/service-analytics` was built at the base and after the
edit. A determinism control (the base rebuilt unchanged) gave the same
six hashes.
- `index.js`, `index.cjs`, `index.d.ts`, `index.d.cts`: byte-identical
(`cmp` exit 0 for each).
- `index.js.map`, `index.cjs.map`: differ in position data only.
Decoded, `version`, `sources` and `names` are identical, and neither map
embeds source text. Every segment matches once the original lines of
`analytics-service.ts` after the deleted block move up by 47, except on
the four set lines, whose columns moved with the removed cast. A
comment-only edit makes the same kind of delta.
- The retired name has 0 hits in the built `dist`, before and after. The
positive control `drillRawTotals` hits `index.js` and `index.cjs`.
- **D4: the byte-identity proof.** No existing fixture emits all four
sidecars at once: the two `totals` fixtures in `query-dataset.test.ts`
group by no date dimension. So the pin's fixture joins two existing
ones: the matrix "X by time" dataset (`stage` beside a month-bucketed
`close_date`), and the per-grouping driver of the subtotal test, with
`totals: { groupings: [['stage'], []] }`.
- Its full answer (8 keys, 744 bytes) was serialised at the base and
after the edit. The sha256 was `06130c86…3ec980` both times, and `cmp`
exits 0. The same bytes came back on the final head.
- The pin reads the answer as `AnalyticsResult` with no cast, and holds
the four keys, their order and their serialised bytes.
## Pin and ablation
- The pin was committed first (`285a39f6e`) and was green on the
unedited source. The retirement follows in `725819485`.
- Ablation on the committed state, in WRAP mode inside an outer restore
trap: `result.drillRawTotals = …` becomes `void …` (anchor 1 to 0, blob
`d22f648e` to `9be86803`).
- The pin goes red: `expected [ 'dimensionFields', …(2) ] to deeply
equal [ 'dimensionFields', …(3) ]`.
- Restore: the blob equals HEAD (`d22f648e`) and `git diff HEAD` is
empty.
- The subject is imported relatively, so it resolves to `src/` and no
`dist` leg applies.
## Verification, at `39d49081b`
This is the head after merging `origin/main` at `a6866da0c`, which
touched two other `service-analytics` files.
- `pnpm --filter @objectstack/service-analytics run typecheck`: exit 0.
- `pnpm --filter @objectstack/service-analytics test`: 141 files and
3267 tests passed.
- The contract pins from #20700, `packages/spec`
`src/api/analytics.test.ts` and
`src/contracts/analytics-service.test.ts`: 2 files and 40 tests passed.
- **Gates.**
- `dispatch-gates --commands` derived 55. All 55 ran with exit 0, and
`--ran` reads "55 derived, 55 run, 0 NOT-MEASURED, 0 UNRUN", a derived
zero with every line carrying its exit code.
- Also run, all exit 0: the dispatch's 7 changeset-keyed families, and
the four roster families outside the list (`check-changeset-fixed`,
`check:authz-resolver`, `check:error-code-casing`,
`check:filter-alias-parity`).
- `check:dual-build-cjs-loads` and `check:type-check-debt` first
answered exit 3 (unbuilt packages). Both were green after a full build.
- **Lint, a declared narrowing.** The repo-wide `pnpm lint` is CI's to
run.
- Population: eslint's config puts both changed `.ts` files in scope
(`isPathIgnored` is false).
- Count: `eslint --no-inline-config --format json` reads 2 files, 0
errors, 0 warnings.
- Invariance: the config enables no type-aware linting
(`eslint.config.mjs:327-328`, and `calculateConfigForFile` shows no
`parserOptions.project` or `projectService` for either file). It reads
only baseline JSONs this diff does not touch, so no untouched file's
verdict can move.
## Acceptance notes
- No out-of-scope finding to file.
- carrier: none · noted, not filed. The `previewDrafts` question the
card carried is answered by triage for this card: a preview answer
carries no sidecars, and the early return and the contract sentence
stay. A consumer that needs preview drill is a card of its own.
- The D3 reading, for the seat: the published `.map` files move by
position only (above). By the package's policy that is the same class as
a comment edit, so this PR carries `skip-changeset` and no changeset. If
the seat reads a position-only map delta as published, a `patch`
changeset on `@objectstack/service-analytics` is the whole remedy.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 0d9349f commit 7053333
2 files changed
Lines changed: 105 additions & 51 deletions
File tree
- packages/services/service-analytics/src
- __tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | 91 | | |
139 | 92 | | |
140 | 93 | | |
| |||
1967 | 1920 | | |
1968 | 1921 | | |
1969 | 1922 | | |
1970 | | - | |
| 1923 | + | |
1971 | 1924 | | |
1972 | 1925 | | |
1973 | | - | |
| 1926 | + | |
1974 | 1927 | | |
1975 | 1928 | | |
1976 | 1929 | | |
| |||
1982 | 1935 | | |
1983 | 1936 | | |
1984 | 1937 | | |
1985 | | - | |
| 1938 | + | |
1986 | 1939 | | |
1987 | 1940 | | |
1988 | 1941 | | |
| |||
2031 | 1984 | | |
2032 | 1985 | | |
2033 | 1986 | | |
2034 | | - | |
| 1987 | + | |
2035 | 1988 | | |
2036 | 1989 | | |
2037 | 1990 | | |
| |||
0 commit comments