Reshape shared/commonMain domain model

Replace the 11 hand-rolled model files with 7 grouped by concern. Typed
ID value classes kill bare-string FKs. Canonical 3-value MeasurementUnit
enum kills the runtime unitMismatch class — Polish vocabulary lives in
Quantity.displayHint as render-only metadata. MealExtras (5 maps) collapses
into IngredientCustomization + PlanCustomization. IngredientCategory and
MealSlot become household-scoped entities with LocalizedString names so
they're customizable without an app release. Display names land as
LocalizedString from day one; no Polish strings in identifiers or wire
codes. Recipe drops allowedSlots — slot affinity is a UI-layer match on
Recipe.tags vs MealSlot.name. Skip is absence, not a sealed sibling.

Plan: ~/.claude/plans/i-have-generated-some-inherited-conway.md.

Covered by SerializationRoundTripTest: 12 assertions across typed-ID
inlining, MeasurementUnit wire format, LocalizedString JSON shape, full
PlanEntry round-trip with every customization kind, SyncMeta tombstone
omission, and Catalog defaults handling. All targets compile and pass:
JVM, Android (debug + release), iOS Simulator Arm64.
This commit is contained in:
2026-05-19 23:11:05 +02:00
parent 815c4f4efc
commit 2d2556fd26
9 changed files with 720 additions and 4 deletions

View File

@@ -23,11 +23,15 @@ kotlin {
sourceSets {
commonMain.dependencies {
// Phase 2: DTOs land here (MeResponse/User per D-27). kotlinx.serialization
// is the only allowed runtime dependency in shared/commonMain — D-19 / INFRA-06
// forbids Ktor, Compose, SQLDelight, Koin, Kermit. `api(...)` so consumers
// (composeApp, server) inherit the @Serializable runtime without each
// re-declaring it.
// and kotlinx.datetime are the only allowed runtime dependencies in
// shared/commonMain — D-19 / INFRA-06 forbids Ktor, Compose, SQLDelight,
// Koin, Kermit. `api(...)` so consumers (composeApp, server) inherit the
// @Serializable runtime + datetime types without each re-declaring them.
api(libs.kotlinx.serializationJson)
// Domain types need Instant (SyncMeta.updatedAt/createdAt/deletedAt) and
// LocalDate (PlanEntry.date). kotlinx.datetime is the project's locked
// datetime lib per CLAUDE.md; pure types, no platform deps.
api(libs.kotlinx.datetime)
}
commonTest.dependencies {