Skip to content

Commit 78f1869

Browse files
committed
no-mistakes(document): Docs updated for MySQL report lane and Cube live check
1 parent b9d67b6 commit 78f1869

3 files changed

Lines changed: 14 additions & 6 deletions

File tree

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ PyPI has had no product change since `0.25.0` — nothing is broken.
7373
**Cross-port conformance corpora** (every port runs the shared corpus):
7474
- Metamodel: `fixtures/conformance/` (374 fixtures; 29 shared corpora in total — per-corpus counts + the corpus x port matrix live in `docs/CONFORMANCE.md`). TS / C# / Java / Python all green.
7575
- Render: `fixtures/render-conformance/`. TS / C# / Java / Kotlin / Python byte-identical.
76-
- Persistence: `fixtures/persistence-conformance/`. **Query** scenarios run on every port (TS / C# / Java / Kotlin / Python), each provisioning its test DB by executing the committed, TS-produced `canonical/schema.postgres.sql` (Postgres only — Derby dropped for the cross-port query corpus, ADR-0015). The **migration** scenarios are exercised by **TS only** (TS owns schema migrations). **The corpus now gates WRITES, not just reads (SP-H):** an `op: roundtrip` scenario type INSERTs through each port's runtime/ORM write codec (NOT raw SQL), reads the row back, and asserts the wire-normalized value. The `AllTypes` entity (`roundtrip-all-types.yaml`) carries one field of **every** persistable `field.*` subtype — string/int/long/double/float/decimal/boolean/date/time/timestamp(+tz)/currency/enum/uuid/object — plus an **array-of-VO** `field.object @isArray @storage:jsonb` column (`labels`, written as 2-element / empty-`[]` / single-element arrays across the three rows) — so every subtype write+read (incl. the array-of-value-object jsonb codec) round-trips through every port against Testcontainers PG. (`field.byte`/`field.short`/`field.class` were cut as non-functional registration-only stubs — the matrix tracks only genuinely-supported subtypes; see `fixtures/registry-conformance/README.md` → "Per-subtype write-round-trip matrix".)
76+
- Persistence: `fixtures/persistence-conformance/`. **Query** scenarios run on every port (TS / C# / Java / Kotlin / Python), each provisioning its test DB by executing the committed, TS-produced `canonical/schema.postgres.sql` (Postgres only — Derby dropped for the cross-port query corpus, ADR-0015; the FR-044 `report-*` scenarios also run on SQLite, MySQL and D1 where a port has the engine, see [docs/CONFORMANCE.md](docs/CONFORMANCE.md)). The **migration** scenarios are exercised by **TS only** (TS owns schema migrations). **The corpus now gates WRITES, not just reads (SP-H):** an `op: roundtrip` scenario type INSERTs through each port's runtime/ORM write codec (NOT raw SQL), reads the row back, and asserts the wire-normalized value. The `AllTypes` entity (`roundtrip-all-types.yaml`) carries one field of **every** persistable `field.*` subtype — string/int/long/double/float/decimal/boolean/date/time/timestamp(+tz)/currency/enum/uuid/object — plus an **array-of-VO** `field.object @isArray @storage:jsonb` column (`labels`, written as 2-element / empty-`[]` / single-element arrays across the three rows) — so every subtype write+read (incl. the array-of-value-object jsonb codec) round-trips through every port against Testcontainers PG. (`field.byte`/`field.short`/`field.class` were cut as non-functional registration-only stubs — the matrix tracks only genuinely-supported subtypes; see `fixtures/registry-conformance/README.md` → "Per-subtype write-round-trip matrix".)
7777
- API-contract: `fixtures/api-contract-conformance/`. TS / C# / Java / Kotlin / Python all green — each port runs **two lanes**: a hand-rolled reference server AND its **generated** API artifact booted over HTTP (the deployed controller/routes; TS+C# full-stack vs Testcontainers PG, Java/Kotlin/Python generated controller + in-memory repo behind the consumer seam). The generated fan-out found 10 real deployment bugs golden snapshots missed. Three sub-corpora run the **generated lane only, on all five ports** — `write-through/`, `projection/` (F22: a view-only `object.projection` serves GET list + GET by id and answers every write verb with `405 {"error": "method_not_allowed"}`) and `report/` (FR-044: a view-backed `object.report` serves GET list, answers `POST` with that same `405`, and mounts no `/{id}` route). That is deliberate, not a gap: what is under test is whether a port's GENERATOR emits those routes, and a hand-rolled reference server would answer every scenario by construction. The `m2m/` sub-corpus also gates **TPH x M:N together** (base-declared, subtype-declared, abstract-mid-declared, a non-subtype source onto a subtype TARGET, and the cross-subtype source id answering `200 []`) — the two corpora were originally built disjoint (`tph/` had no relationships, `m2m/` no discriminators), which is precisely how that defect class survived.
7878
- YAML / verify corpora green across the ports that ship those layers.
7979
- **Codegen-compile gate** (all five ports; a GATE, not a corpus — it has no fixtures of its own and no row in the matrix). Every corpus above gates BEHAVIOUR; none asks whether the emitted code BUILDS, which is how four "generated code does not compile" defects shipped in 1.0.4 with the whole matrix green — `gen` exits 0 in all four cases and the adopter's build is the first thing that disagrees. Each port generates from `fixtures/persistence-conformance/canonical/meta.fitness.json` (reused deliberately: a second kitchen sink would drift from the one the other corpora already maintain) and compiles the emitted tree with its real compiler — `ts.createProgram` / Roslyn / `javac` / `KotlinCompilation` / (Python, having no static compiler) importing the generated package plus `ruff` F821. **Every port excludes its framework-bound route tier** (TS `routesFile`, C# `RoutesGenerator`, Java `SpringControllerGenerator`, Kotlin `KotlinSpringControllerGenerator`): those imports are not on an in-memory compile's classpath and stubbing them drowns the signal, so that tier is proven by the api-contract integration lane instead. One cross-port rule, not four local concessions. Found 5 further real defects on first run. Boundary detail: `docs/CONFORMANCE.md` → "Split coverage".

‎docs/features/cube-export.md‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ development mode, with its embedded Cube Store, against a private `postgres:16-a
580580
holds the persistence-conformance schema and a seed
581581
(`fixtures/cube-model/canonical/seed.sql`). Each run owns a private Docker network and binds
582582
one ephemeral port on `127.0.0.1`; it never uses the shared Postgres sidecar, and every
583-
container and the network are removed on every exit path. It checks six things:
583+
container and the network are removed on every exit path. It checks six things on Postgres:
584584

585585
1. The generated canonical model is the reviewed golden.
586586
2. Cube compiles it and lists every cube and member the files declare.
@@ -605,6 +605,12 @@ container and the network are removed on every exit path. It checks six things:
605605
`@default` divides that numerator's `COALESCE(sum(…), 0)`, with and without the ratio's own
606606
default, as the view does.
607607

608+
The MySQL path is a second file in the same lane (`cube-model-mysql.live.ts`). It runs the same
609+
Cube over a private MySQL 8.4 holding the report views `buildReportViews` lowers
610+
(`fixtures/cube-model/canonical/seed.mysql.sql`), and for each served report it checks item 3:
611+
the Cube query returns the rows of `SELECT * FROM <view>`, from the rollup when the model has one.
612+
Checks 4, 5 and 6 are Postgres only.
613+
608614
Run it with `scripts/ci-local.sh --only cube`. The full `scripts/ci-local.sh` runs it after the
609615
integration suite, and `--quick` and `--no-integration` drop it. The first run pulls the Cube
610616
image, which is about 1 GB. With Docker down, the lane records a SKIP behind a banner, never a
@@ -627,9 +633,10 @@ the table names above are the development-mode form.
627633
refuses the model with `ERR_CUBE_AMBIGUOUS_PATH`, naming both. The lossless form needs a
628634
nested alias for each path. That is more machinery than a rare model is worth yet, so the
629635
exporter errors rather than guess.
630-
- **The lane never executes MySQL SQL.** The corpus pins it byte for byte and the lane compiles
631-
it in Cube, but no MySQL database runs it there. The one MySQL form chosen for its meaning, the
632-
tuple distinct count, was compared with the view's on mysql:8.4 by hand when it was built.
636+
- **The two MySQL mapping cases are compiled, never executed.** The corpus pins their SQL byte
637+
for byte and Cube compiles them, but no MySQL database runs them. The MySQL path runs only the
638+
served reports. The tuple distinct count's MySQL form was compared with the view's on mysql:8.4
639+
by hand when it was built.
633640
- **Some shapes are compile-checked, not query-checked.** Cube accepts the alias cubes, the TPH
634641
subtype's `sql`, one-to-one joins, the int-backed enum's `CASE` and a two-hop `@spine` chain
635642
(the corpus pass), but no live query of the lane crosses them. The two-hop chain's rows were

‎docs/recipes/mysql.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ These tests exercise the whole list against a real MySQL 8.4 server:
2929
The FR-044 report views are read on MySQL by C# (EF Core with Pomelo), Kotlin (Exposed) and
3030
Java (OMDB) as well, through the persistence `report-*` scenarios; C# also serves its generated
3131
report routes over MySQL. Python ships a Postgres driver only (pg8000), so it is not run there.
32-
The Cube exporter's MySQL output is executed against a real MySQL 8.4 by the `cube` lane.
32+
The Cube queries for the served reports are executed against a real MySQL 8.4 by the `cube` lane
33+
(see [features/cube-export.md](../features/cube-export.md)).
3334

3435
## TypeScript setup
3536

0 commit comments

Comments
 (0)