From 6a013a3ffba2c1fd05bd78c21488b663cf904365 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 10:53:42 +0000 Subject: [PATCH] docs(ogar-emitter): record Pattern-C (Anamnese) boundary on the projection arm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Harvest of medcare-rs queries/anamnese.rs (2026-07-19) found the furnace's next entity is NOT Pattern A: it is a tuple-fold read (query_as::<(T,..)>, positional destructure, no named row struct). Records the exact distinct arm it needs (positional-tuple destructure, SQL-side CAST templating, clamp-and-cast) + the three hand-keep slag outliers (Gyn/Sexual/Alkohol), and corrects the worklist's "purest metal / id·patient_id·date·text ×14" label — those are query filters, not domain fields. Do-not-speculatively- pre-build: the arm lands when the loop reaches Anamnese. Doc-only; no code change (38 tests still green). Generated by Claude Code. --- crates/ogar-emitter/src/projection_adapter.rs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/ogar-emitter/src/projection_adapter.rs b/crates/ogar-emitter/src/projection_adapter.rs index 6c8fce9..304a239 100644 --- a/crates/ogar-emitter/src/projection_adapter.rs +++ b/crates/ogar-emitter/src/projection_adapter.rs @@ -24,6 +24,32 @@ //! set of transforms the Pattern-A projections actually use. A field whose //! transform is not yet in this set is a Core gap: extend the enum //! deliberately (Core-First), never hand-patch the generated output. +//! +//! # Scope boundary — this arm is Pattern A only (row→domain `From`) +//! +//! This emitter covers the **Pattern A** shape: a named row struct +//! (`#[derive(sqlx::FromRow)] struct XRow`) with a hand `From for +//! Domain`. It does NOT cover **Pattern C** — the tuple-fold read +//! (`sqlx::query_as::<(T1, T2, …)>` mapped by positional destructure, no +//! named row struct). The furnace's next entity (Anamnese, worklist row 2) +//! is Pattern C, and a 2026-07-19 harvest of medcare-rs `queries/anamnese.rs` +//! found it needs a *distinct* arm, not an extension of this one: +//! +//! - **positional-tuple destructure** — map columns to tuple *position* +//! (`|(a, b, c)| Domain { … }`), not to a named row field. +//! - **SQL-side coercion templating** — several fields are `CAST(col AS +//! CHAR) AS alias` in the query text (numeric FK → String); that lives in +//! the emitted SQL, not in a post-fetch Rust transform. +//! - **clamp-and-cast** — `col.unwrap_or(0).clamp(0, u8::MAX as i32) as u8` +//! (a new `FieldSource` variant when that arm is built). +//! +//! And it names three genuine slag outliers to hand-keep, never codegen: +//! `GynAnamnese` (17 cols → sqlx's 16-field tuple cap forces name-keyed +//! `try_get`), `Sexualanamnese` (code→enum matching), and `Alkohol` / +//! `GynAnamnese` array assembly (`[bool; 7]`). This corrects the worklist's +//! "purest metal / id·patient_id·date·text ×14" label: those are query +//! filters, not domain fields. Build the Pattern-C arm when the loop reaches +//! Anamnese (A records the C# fixture first) — do not speculatively pre-build. use ogar_vocab::canonical_concept_id;