Java / Kotlin / TypeScript / MetaObjects
288 hand-maintained database migrations collapsed into one generated baseline, ~1,900 lines of hand-built LLM prompts became typed contracts, and the model made removing dead schema mechanical — 29 tables and 49 columns gone in nine days, each proven safe by a clean recompile.
Party Lore is a large AI Game Master platform across Java, Kotlin, and TypeScript. Its schema drifted across hundreds of hand-written migrations, its LLM prompts were roughly 1,900 lines of string-building, and dead code was invisible — a manual audit once flagged 13 live files as dead. Moving to one metadata model collapsed 288 migrations into a single generated baseline, turned the prompts into typed contracts, and made removing dead schema mechanical: 29 tables and 49 columns deleted in nine days, each proven safe by a clean regenerate-and-recompile.
Party Lore drives a Discord experience, a web console, a React UI, and an LTI education mode across three languages, with 655 typed shapes in play. Three problems compounded. The database schema had accreted 288 hand-written migrations, with the JVM and TypeScript sides kept in agreement by hand. The 100+ LLM prompts were assembled by hand — an internal audit counted roughly 1,900 lines of prose append() calls across ten Java builders — untyped enough that one prompt shipped a routing bug (it logged one model's name while silently running on another), and one live prompt path had no test at all.
Worst of all, dead code was undeletable in practice: an early-2026 manual audit mis-flagged 13 live files as dead, so no one trusted deletions and the cruft just stayed. You can't safely remove what you can't prove is unused.
The domain is now declared once as 655 typed declarations across 50 YAML files, and every consumer is generated from it. The MetaObjects Maven plugin generates the JVM domain (Kotlin / Exposed); meta gen generates the TypeScript surfaces (a Drizzle console, a React UI); and both draw from the same model. The 288 migrations collapsed into a single generated baseline — 116 tables, 183 foreign keys, 196 checks, 524 indexes — guarded by a boot-time drift validator. The prompts became 45 typed prompt templates plus 23 output contracts, migrated in 107 byte-identical steps and gated three ways: the Maven build verifies them, a CI workflow checks codegen drift, and a test bans raw hand-written prompt files.
Guess from a manual audit that once flagged 13 live files as dead — so nobody deletes, and the cruft stays forever.
Remove its YAML, regenerate, recompile. If it compiles, nothing live pointed at it — proof, not hope.
288 hand-written migrations collapsed into one generated baseline — and then the model started finding the bodies: 29 dead tables and 49 dead columns, deleted in nine days because a clean recompile proved nothing needed them.
— verified in-repo: baseline generated June 2026, dead-shape sweep over nine days
Party Lore's source is private — for a clone-and-read version of the same pattern, see Wizards of Odd, or Draagon AI for the sibling story.
Since 2026-09-09 it has run the stable release on both toolchains it coordinates — npm 1.0.0 and Maven Central 8.0.0, the JVM line running a higher major by design on the same minor and patch. The two-toolchain cost named above is what paying for that looks like.
Doug works directly with teams evaluating MetaObjects. Tell us what you're building and we'll tell you, honestly, whether MetaObjects fits.
Email doug@dougmealing.com