Skip to content

fix(print): scaffold emits only keys the feeder puts; back-references label by their number (#6503) - #6504

Merged
delchev merged 2 commits into
masterfrom
feat/print-scaffold-feeder-contract
Aug 4, 2026
Merged

fix(print): scaffold emits only keys the feeder puts; back-references label by their number (#6503)#6504
delchev merged 2 commits into
masterfrom
feat/print-scaffold-feeder-contract

Conversation

@delchev

@delchev delchev commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Closes #6503. Stacked on #6502 (line-item relation feeding) - the diff includes it until #6502 merges; review the last commit only.

What

The .print scaffold generator and the print-feeder generator derive from the same model but disagreed about one contract, producing dead placeholders on freshly scaffolded templates:

  • Footer {{document.Id}} on a master without a DocumentTitle field - the feeder deliberately excludes the primary key. The footer now shows the number when one exists and nothing otherwise.
  • Bare back-reference maps with no __label ({{document.GoodsIssue}}) - the feeder labeled a relation target only by a literal name field, and a document's identity is its number.

Both sides now converge on one shared label resolution (IntentEntities.labelFieldOf): authored name field → the stored Name a label: expression generates → the function: DocumentTitle field. A document back-reference therefore prints its number ("GI0000042") - exactly what a follow-up document wants - instead of rendering empty; and the scaffold omits a same-model relation only when its target resolves no label at all (a cross-model target keeps the owner-model convention).

Test

PrintScaffoldFeederContractTest (4 new cases, 13/13 print tests green): a back-reference is labeled by its number on both sides; a label-less relation is omitted from the scaffold; the footer never references the PK; and the sweep - every {{...}} placeholder the scaffold emits resolves against the feeder's contract (root scalars + header nodes, item scalars + item nodes) over a fixture with number/status/back-refs.

🤖 Generated with Claude Code

delchev and others added 2 commits August 4, 2026 18:06
…} / {{Unit.Name}} render in items columns (#6501)

The generated PrintFeeder's items map carried only the line's scalar
fields, so an invoice line could not print its unit or product - while
header relations DID get resolved maps + __label. Each line-item to-one
relation is now fed the same way: PrintFeederSupport contributes
itemNodes (the composition back-reference to the document excluded -
that is the header itself), and the template loads the target per row
through its generated repository (validations + the multilingual
translation overlay apply), caches lookups per DISTINCT key rather than
per row, and hangs a map carrying __label + the target's fields under
the relation's own key - so {{Unit}} renders the label and {{Unit.Name}}
descends. Same-model targets name their fields one by one (the audit);
a cross-model target is copied reflectively per the #6422 rule, so this
project's committed gen/ survives the owner retiring a field.

Covered by PrintFeederSupportTest (item nodes: back-ref exclusion,
Settings perspective, prefixed variables, cross-model no-named-fields)
and IntentEmissionCoverageIT (BillLine gains a Unit relation; the
generated BillPrintFeeder's lookup/cache/__label emission is asserted
and the whole app compiles and publishes end-to-end - green locally).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nces label by their number (#6503)

The scaffold and the feeder generator disagreed about one contract, so a
freshly scaffolded standard.print carried dead placeholders that render
as empty values: {{document.Id}} in the footer of a master without a
DocumentTitle field (the feeder deliberately excludes the primary key),
and bare relation maps with no __label (a document back-reference's
target has a number, not a `name` field).

Both generators now converge on one label resolution, the shared
IntentEntities.labelFieldOf: an authored name field, the stored Name a
label: expression generates, or the DocumentTitle field - so a document
back-reference prints its number ("GI0000042") instead of an empty
value. The scaffold emits a same-model relation field only when its
target resolves a label, and the footer never falls back to the primary
key.

PrintScaffoldFeederContractTest locks the contract: every {{...}}
placeholder the scaffold emits is a key the feeder puts, over a fixture
with a DocumentTitle number, an EntityStatus, a document back-reference
and a label-less target.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@delchev
delchev force-pushed the feat/print-scaffold-feeder-contract branch from a9e0974 to d698a0d Compare August 4, 2026 15:07
@delchev
delchev merged commit 380475a into master Aug 4, 2026
9 checks passed
@delchev
delchev deleted the feat/print-scaffold-feeder-contract branch August 4, 2026 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generated .print scaffold references keys its own feeder never puts (dead placeholders)

1 participant