Skip to content

Commit edcc775

Browse files
dmealingclaude
andcommitted
docs: second-pass accuracy sweep (README, CLAUDE.md, features)
Hunt across the remaining public surfaces found more of the same class of issues the port audits did — all verified against source: README.md: Python codegen "@DataClass" → Pydantic + FastAPI; Java pillar "POJO + OMDB" → Spring REST + DTO + repository; Kotlin "9 generators" → 14 and "12/12" → "24/24"; removed the false "not yet wired" + broken `mvn -pl integration-tests-kotlin test` (→ `scripts/integration-test.sh kotlin`); C# `meta verify` → `dotnet meta verify`; `Renderer.verify` → `Verify.check`. docs/features/api-contract.md: "Kotlin Ktor" → "Kotlin Spring" (the last of the review's "self-contradicts 4×"); stale "20/20" scenario count → "full suite"; a backwards cross-reference. Recurring Python-SQLAlchemy overclaim removed: own-your-codegen.md, relationships.md, docs/ports/python.md (Python codegen is Pydantic + FastAPI; the runtime is a shipped DB-API-2 ObjectManager, not an in-progress SQLAlchemy ORM). CLAUDE.md "20/20" → "green". entities.md MetaDataGenerator → MetaDataGeneratorMojo; extending-with- providers.md stale version stamp removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeGSV3StPCcJGZNNJ4ZfAb
1 parent aa08dfe commit edcc775

8 files changed

Lines changed: 21 additions & 20 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ _Last refreshed 2026-07-25._
3333
- Metamodel: `fixtures/conformance/` (~90 fixtures). TS / C# / Java / Python all green.
3434
- Render: `fixtures/render-conformance/`. TS / C# / Java / Kotlin / Python byte-identical.
3535
- 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".)
36-
- API-contract: `fixtures/api-contract-conformance/`. TS / C# / Java / Kotlin / Python all 20/20 — 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.
36+
- 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.
3737
- YAML / verify corpora green across the ports that ship those layers.
3838

3939
**Key cross-language features shipped:** FR5 family (a/b/c/d/e + WARN envelope-shape — actionable loader errors per ADR-0009); FR-003 (Java RDB runtime persistence + projections; schema migrations are TS-only — the Java migration engine was removed); FR-006 (template.output parser-on-receipt codegen per ADR-0010 in all 5 ports); FR-008 + FR-009 (cross-port REST API contract + 10 filter operators); FR-018 (M:N relationship codegen in all 5 ports — entity navigation + idiomatic ORM wiring [Drizzle m2m / EF Core `UsingEntity` / Spring repo+JPA / Exposed / Pydantic+route as the SQLAlchemy-secondary equivalent] + REST traversal `GET /<source-plural>/{id}/<relation>` + Tier-2 docs, gated by the shared api-contract m2m corpus in both lanes + persistence-conformance; the TanStack M:N client hook is a deferred client-ergonomics follow-up); SP-H (field-subtype end-to-end hardening: every concrete `field.*` subtype write+read round-trips cross-port via the persistence `op: roundtrip` gate; cut `field.byte`/`field.short`/`field.class` non-functional stubs; cross-port filter-op reconciliation for uuid/currency); source v2 paradigm (ADR-0007); metadata-ktx Kotlin facade; per-target output directories (TS codegen).

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ first-week wedge plan — and `meta init` picks up from there.
8888
|---|---|---|---|
8989
| TypeScript | Published to npm at `0.20.0` (the `@metaobjectsdev/*` packages) | [`docs/ports/typescript.md`](docs/ports/typescript.md) | [`server/typescript/`](server/typescript/) · [`client/web/`](client/web/) |
9090
| Java | Loader + OMDB + render + Maven plugin all shipped; full conformance green | [`docs/ports/java.md`](docs/ports/java.md) | [`server/java/`](server/java/) |
91-
| Kotlin | Codegen tier on top of Java — 9 generators (entity, Exposed table, relations, payload, output-parser, validator, Spring config, storedProc, Spring controller); 12 / 12 persistence-conformance | [`docs/ports/kotlin.md`](docs/ports/kotlin.md) | [`server/java/codegen-kotlin/`](server/java/codegen-kotlin/) · [`server/java/metadata-ktx/`](server/java/metadata-ktx/) |
91+
| Kotlin | Codegen tier on top of Java — 14 generators (entity, Exposed table, relations, repository, payload, output-parser, output-prompt, render-helper, extractor, filter-allowlist, validator, Spring config, storedProc, Spring controller); 24 / 24 persistence-conformance | [`docs/ports/kotlin.md`](docs/ports/kotlin.md) | [`server/java/codegen-kotlin/`](server/java/codegen-kotlin/) · [`server/java/metadata-ktx/`](server/java/metadata-ktx/) |
9292
| C# | Loader + conformance + EF Core codegen + render engine + `dotnet meta` CLI all shipped | [`docs/ports/csharp.md`](docs/ports/csharp.md) | [`server/csharp/`](server/csharp/) |
9393
| Python | Loader + conformance + render + entity-model codegen + ObjectManager runtime shipped; schema migrations are TS-owned (ADR-0015) | [`docs/ports/python.md`](docs/ports/python.md) | [`server/python/`](server/python/) |
9494

@@ -105,8 +105,8 @@ first-week wedge plan — and `meta init` picks up from there.
105105
| Templates + render (FR-004) | Yes | Yes | Yes (wraps Java) | Yes | Yes |
106106
| Payload-VO codegen | Yes (via projection) | Yes (`SpringPayloadGenerator`) | Yes (`@Serializable`) | Yes | Yes (`payload_vo_generator`) |
107107
| Migration emission | `meta migrate` (Postgres / SQLite / D1) | Via TS toolchain (`@metaobjectsdev/cli migrate`) | Via TS toolchain (`@metaobjectsdev/cli migrate`) | Via TS toolchain (ADR-0015) | Via TS toolchain (ADR-0015) |
108-
| DB-drift verify | `meta verify --db` | Template-drift: `Renderer.verify`; schema-drift is TS-owned (ADR-0015) | Template-drift: `Renderer.verify`; startup: `MetadataStartupValidator` | `dotnet meta verify` (codegen-drift) | Schema-drift is TS-owned (ADR-0015) |
109-
| Template-drift verify | Yes | Yes (`Renderer.verify`) | Yes (via Java) | Yes (`meta verify`) | Yes (`metaobjects.render.verify`) |
108+
| DB-drift verify | `meta verify --db` | Template-drift: `Verify.check`; schema-drift is TS-owned (ADR-0015) | Template-drift: `Verify.check`; startup: `MetadataStartupValidator` | `dotnet meta verify` (codegen-drift) | Schema-drift is TS-owned (ADR-0015) |
109+
| Template-drift verify | Yes | Yes (`Verify.check`) | Yes (via Java) | Yes (`dotnet meta verify`) | Yes (`metaobjects.render.verify`) |
110110
| YAML authoring (sigil-free → JSON) | Yes | Yes | Yes (via Java) | Yes | Yes |
111111
| Runtime metadata (ObjectManager-style) | Yes (`runtime-ts`) | Yes (OMDB) | Yes (via Java OMDB + Exposed) | Roadmap | Yes (ObjectManager) |
112112
| React / Angular UI client (browser) | Yes — React (`@metaobjectsdev/react` + `@metaobjectsdev/tanstack`) and Angular 18 (`@metaobjectsdev/angular`, published at `0.6.0`); both codegen + runtime | Consumes TS client via REST | Consumes TS client via REST | Consumes TS client via REST | Consumes TS client via REST |
@@ -135,8 +135,8 @@ complete in all five ports; MCP exposure of declared prompts/tools is the one
135135
remaining roadmap item:
136136

137137
1. **Codegen** — emit idiomatic per-language code (Drizzle/Zod + Fastify for TS,
138-
POJO + OMDB for Java, `data class` + Exposed for Kotlin, EF Core
139-
record + ASP.NET routes for C#, `@dataclass` for Python). Hand-edit-preserving
138+
Spring REST + DTO + repository for Java, `data class` + Exposed for Kotlin, EF Core
139+
record + ASP.NET routes for C#, Pydantic + FastAPI for Python). Hand-edit-preserving
140140
regen via three-way merge.
141141
2. **Runtime metadata** — load metadata at runtime, drive behavior dynamically
142142
(CRUD, validation, relationships, dynamic admin UIs; typed tool payloads are
@@ -200,13 +200,12 @@ ephemeral Postgres containers and exercises every shipped port's persistence
200200
layer against the shared scenario corpus:
201201

202202
```bash
203-
scripts/integration-test.sh # all runners (ts + csharp + java + python)
203+
scripts/integration-test.sh # all runners (ts + csharp + java + python + kotlin)
204204
scripts/integration-test.sh ts # just TypeScript
205205
scripts/integration-test.sh csharp # just C#
206206
scripts/integration-test.sh java # just Java
207207
scripts/integration-test.sh python # just Python
208-
# Kotlin runs via Maven directly (not yet wired into the script):
209-
cd server/java && mvn -pl integration-tests-kotlin test
208+
scripts/integration-test.sh kotlin # just Kotlin
210209
```
211210

212211
The persistence corpus + the cross-port test harness are the contract: identical

docs/features/api-contract.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The browser-side TypeScript client (`@metaobjectsdev/runtime-web` +
44
`@metaobjectsdev/react` + `@metaobjectsdev/tanstack`) is **universal**: it
55
ships with the React + TanStack runtime and the generated query hooks +
66
column defs, but it makes **no assumption about which language wrote the
7-
backend**. Any HTTP server — TypeScript Fastify, Java Spring, Kotlin Ktor,
7+
backend**. Any HTTP server — TypeScript Fastify, Java Spring, Kotlin Spring,
88
C# ASP.NET, Python FastAPI — that speaks the URL grammar and JSON wire
99
format on this page can serve the same React app, with the same generated
1010
hooks and grids.
@@ -309,7 +309,7 @@ into your framework's idiomatic query-builder, gated by the generated
309309
Cross-port route + filter codegen (Java, Kotlin, Python), the shared
310310
route-shape oracle (`fixtures/api-contract-conformance/`), and a
311311
browser-side Angular client have all shipped — see "Per-port route
312-
codegen status" and "Verified by" above, and
312+
codegen status" above and "Verified by" below, and
313313
[`docs/ports/typescript-client.md#angular-18`](../ports/typescript-client.md#angular-18).
314314

315315
What's still genuinely open:
@@ -349,8 +349,9 @@ each spin up their generated routes and pass every scenario. See
349349
[`docs/CONFORMANCE.md`](../CONFORMANCE.md) for per-port pass status.
350350

351351
Filter operator coverage (`eq` / `ne` / `gt` / `gte` / `lt` / `lte` / `in` /
352-
`like` / `isNull`) is part of the corpus: 10 filter scenarios run on top of
353-
the 10 base CRUD scenarios, and all five ports satisfy all 20 today (see
352+
`like` / `isNull`) is part of the corpus: filter scenarios run on top of
353+
the base CRUD scenarios, and all five ports satisfy the full
354+
api-contract-conformance suite today (see
354355
[`docs/CONFORMANCE.md`](../CONFORMANCE.md)).
355356

356357
## See also

docs/features/entities.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export type Author = z.infer<typeof AuthorSchema>;
145145

146146
### Java
147147

148-
`metaobjects-maven-plugin` with `MetaDataGenerator` writes a POJO + an OMDB-backed
148+
`metaobjects-maven-plugin` with `MetaDataGeneratorMojo` writes a POJO + an OMDB-backed
149149
descriptor. The OMDB ObjectManager reads the same metadata at runtime to drive
150150
CRUD.
151151

docs/features/extending-with-providers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ goes up sharply at each step: **attr (cheap) < abstract (free) < subtype
315315
adding power; defaulting to attrs keeps the vocabulary narrow and the
316316
configuration rich.
317317

318-
## Cross-port parity status (as of 0.15.19 · 7.7.9)
318+
## Cross-port parity status
319319

320320
| Port | API | Status |
321321
|---|---|---|

docs/features/own-your-codegen.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ three-way-merges against a committed merge base, so your edits are preserved.
2727
| **TypeScript** | `meta init``meta gen` (Bun/Node CLI) | **Scaffold-and-own**`meta init` copies `entityFile`/`queriesFile`/`routesFile`/`barrel` into `codegen/generators/*.ts`; `metaobjects.config.ts` imports those local copies. Edit them freely. |
2828
| **C#** | `dotnet meta gen` / `dotnet meta verify` (.NET tool) | Build-config: the generator set (EF Core entities + `AppDbContext` + CRUD routes) is selected via config; customize via template-spec. |
2929
| **Java / Kotlin** | `mvn metaobjects:generate` / `mvn metaobjects:verify` (`metaobjects-maven-plugin`) | Build-config: generators selected in `pom.xml`, by **stable name** (`entity`/`routes`/…) through the `GeneratorRegistryProvider` ServiceLoader SPI. Kotlin generators run through the same goal. |
30-
| **Python** | `metaobjects gen` / `metaobjects verify` (console-script) | Build-config: the generator set (Pydantic + FastAPI + SQLAlchemy) selected via config; customize via template-spec. |
30+
| **Python** | `metaobjects gen` / `metaobjects verify` (console-script) | Build-config: the generator set (Pydantic + FastAPI) selected via config; customize via template-spec. |
3131

3232
*(Full command/flag matrix and rationale: [`docs/features/cli.md`](cli.md), locked per
3333
ADR-0015. Schema migrations are TypeScript-owned across all ports.)*

docs/features/relationships.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ metadata:
106106
| `@onUpdate` | both | same as `@onDelete` | RDB referential action |
107107

108108
The kebab-case metamodel values map to the SCREAMING_SNAKE forms in Exposed / EF
109-
Core / SQLAlchemy at codegen time.
109+
Core / the target ORM or DDL at codegen time.
110110

111111
## Navigating a relationship or reference in a projection (`@via`)
112112

@@ -222,8 +222,9 @@ ALTER TABLE "posts"
222222
### Python
223223

224224
The Python loader recognizes `relationship.composition` and `identity.reference`
225-
and exposes them on the navigation API. SQLAlchemy `relationship()` codegen and
226-
the runtime ORM tier are in progress.
225+
and exposes them on the navigation API. Relationship-navigation codegen (emitting
226+
the FK-derived accessors into the generated Pydantic + FastAPI code) is still
227+
pending; the runtime is the shipped DB-API-2 `ObjectManager`.
227228

228229
```python
229230
# generated/acme/blog/post.py — current state

docs/ports/python.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ import lines are stable.
341341
| Feature | Status |
342342
|---|---|
343343
| Entities + fields | Yes |
344-
| Relationships + FK | Loader-level yes; SQLAlchemy `relationship()` codegen is on the roadmap |
344+
| Relationships + FK | Loader-level yes; relationship-navigation codegen is on the roadmap |
345345
| Source kinds (table / view / storedProc) | Loader-level yes; codegen for non-`table` kinds is in progress |
346346
| `field.currency` / `field.enum` / `field.object` + `@storage` | Loader-level yes; codegen for `field.object` `flattened` storage is in progress |
347347
| Templates + render (FR-004) | Yes (`metaobjects.render`) |

0 commit comments

Comments
 (0)