feat(pivot): pivot / group-by explorer and the field-access resolver seam #6

Merged
KofTwentyTwo merged 6 commits from feature/pivot into develop 2026-10-14 12:09:22 +00:00
KofTwentyTwo commented 2026-10-13 23:56:52 +00:00 (Migrated from github.com)

Summary

Phase (c) of docs/DATA-ANALYSIS.md (§5), plus the §2.4 field-access seam. Stacked on #5 (it targets develop and includes #5's commits). It stays a draft until #5 merges after RC.6.

  • POST /qqq/v1/qbit/data-analysis/tables/{table}/pivot (extension 1.1.0):
    • 1–3 row and 0–2 column dimensions, with date buckets (year … hour, day of week, hour of day) or nice numeric bins;
    • fields from related tables through exposed joins;
    • measures: count, sum, avg, min, max, distinct, percentile;
    • totals, with "Other (k groups)" for groups beyond limitGroups (top N per dimension, drill = NOT IN the kept values).
    • Pushed down through core aggregates, as the user.
  • Drills per cell and total: request filter AND row conditions AND column conditions.
    • To-one joined fields use joinTable.field criteria, which core's JoinsContext turns into joins automatically.
    • To-many joins count joined rows, so they get no drill and a warning.
    • Multi-hop joins also get no drill for now: core's memory backend doesn't reproduce multi-hop implicit-join counts, which I'm reporting to core.
  • Privacy guard: cells and groups below min_group_size are merged or suppressed, with no drill.
  • Field-access seam (secured-data program, qqq#1146 §2.4):
    • FieldAnalysisAccessResolver maps each field to FULL, EXACT_MATCH_ONLY or NONE.
    • It uses core FieldAccessHelper.getTier / getAccessFingerprint reflectively when present (REVEALABLE → exact-match only; MASKED, HIDDEN → none), and FieldSecurityLockHelper otherwise.
    • Only FULL fields are analyzable; others get 400 as unknown and never appear in drills.
    • Exact-run cache keys include the field-access fingerprint.

Test plan

  • ./mvnw verify with Docker: green on memory, H2 and Postgres. JaCoCo ~98% instructions / 100% classes.
  • Pivot shapes 1x1, 2x1, 1x2, date x category; totals; Other and its drill; to-one join; percentile; privacy guard; drill equivalence for every count cell and total; validation errors; HTTP 200, 400 and 403
  • Field access: NONE fields are refused and absent from capabilities; fingerprint cache miss; the reflective core-tier path

🤖 Generated with Claude Code

## Summary Phase (c) of `docs/DATA-ANALYSIS.md` (§5), plus the §2.4 field-access seam. **Stacked on #5** (it targets `develop` and includes #5's commits). It stays a draft until #5 merges after RC.6. - **`POST /qqq/v1/qbit/data-analysis/tables/{table}/pivot`** (extension 1.1.0): - 1–3 row and 0–2 column dimensions, with date buckets (year … hour, day of week, hour of day) or nice numeric bins; - fields from related tables through exposed joins; - measures: count, sum, avg, min, max, distinct, percentile; - totals, with "Other (k groups)" for groups beyond `limitGroups` (top N per dimension, drill = NOT IN the kept values). - Pushed down through core aggregates, as the user. - **Drills per cell and total:** request filter AND row conditions AND column conditions. - To-one joined fields use `joinTable.field` criteria, which core's `JoinsContext` turns into joins automatically. - To-many joins count joined rows, so they get no drill and a warning. - Multi-hop joins also get no drill for now: core's memory backend doesn't reproduce multi-hop implicit-join counts, which I'm reporting to core. - **Privacy guard:** cells and groups below `min_group_size` are merged or suppressed, with no drill. - **Field-access seam** (secured-data program, qqq#1146 §2.4): - `FieldAnalysisAccessResolver` maps each field to FULL, EXACT_MATCH_ONLY or NONE. - It uses core `FieldAccessHelper.getTier` / `getAccessFingerprint` reflectively when present (REVEALABLE → exact-match only; MASKED, HIDDEN → none), and `FieldSecurityLockHelper` otherwise. - Only FULL fields are analyzable; others get 400 as unknown and never appear in drills. - Exact-run cache keys include the field-access fingerprint. ## Test plan - [x] `./mvnw verify` with Docker: green on memory, H2 and Postgres. JaCoCo ~98% instructions / 100% classes. - [x] Pivot shapes 1x1, 2x1, 1x2, date x category; totals; Other and its drill; to-one join; percentile; privacy guard; drill equivalence for every count cell and total; validation errors; HTTP 200, 400 and 403 - [x] Field access: NONE fields are refused and absent from capabilities; fingerprint cache miss; the reflective core-tier path 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.