Skip to content

checks: a check on a calculated field judges the value the write will store, not the payload's (#7544) - #7666

Open
NicoleNG18 wants to merge 2 commits into
eclipse-dirigible:masterfrom
NicoleNG18:issue-7544-checks-read-calculated
Open

NicoleNG18 wants to merge 2 commits into
eclipse-dirigible:masterfrom
NicoleNG18:issue-7544-checks-read-calculated

Conversation

@NicoleNG18

Copy link
Copy Markdown
Contributor

Cause

The generated controllers run validate() and repository.warnings() before save()/update(), but the calculatedOnCreate / calculatedOnUpdate assignments only happen inside those methods. A check on a calculated field, soft (severity: warn) or refusing, therefore compared whatever the caller sent: nothing on a create, a stale value on an edit. The issue's legally required "issued more than 5 days after the tax event" warning never fired for a REST write.

Change

This implements option (a) of the issue: evaluate the calculated expressions on the candidate row before the checks read it.

  • The generated repository gains calculatedForCreate / calculatedForUpdate. Each returns a field copy of the submitted record carrying what the write will compute for its calculated fields:
  • Only the neutral Calc expressions are evaluated. A calculatedAction* may mint or mutate state, so it still runs only on the write itself.
  • The submitted record is untouched. dropSystemOwnedOnCreate, save() and update() see exactly what they saw before, and what is persisted is still computed by the repository. An entity with nothing calculated gets the record itself back.
  • All three controllers use the candidate row. In the power, my and partner controllers, on create and on both update branches, validate(), validateReferences() and warnings() now run on that candidate row.
  • The assistant guide documents checks on calculated fields, using the issue's declaration as the example.

Verification

  • New IntentCalculatedFieldChecksIT (HTTP-only; generates, compiles and runs the issue's declaration, plus a refusing compare on the same calculated field):
    • a create within the deadline passes silently;
    • a create 9 days late is answered 428, and nothing is persisted until the code is confirmed, after which it stores 9;
    • an update with a stale payload delay, and one with the delay omitted, are both judged on the recomputed 19;
    • a negative delay is refused with 400.
    • Against the unfixed templates the IT fails: the late create answered 200 instead of 428.
  • These all pass on H2:
    • IntentSoftWarningsIT
    • IntentCheckMessageI18nIT
    • IntentEmissionCoverageIT (compiles and runs a broad generated model)
    • ModelGenerationIT
    • the two controller template ITs, whose validate(...) anchors now point at the candidate-row call
  • ide-template (216) and engine-intent (1479) unit suites pass.
  • mvn formatter:validate passes after wiping the formatter cache.

Not verified: the PostgreSQL leg.

Not in scope:

Fixes #7544

🤖 Generated with Claude Code

NicoleNG18 and others added 2 commits October 3, 2026 19:44
… store, not the payload's (eclipse-dirigible#7544)

Cause: the generated controllers run validate() and repository.warnings()
before save()/update(), while the calculatedOnCreate / calculatedOnUpdate
assignments happen inside them. A check on a calculated field - soft
(severity: warn) or refusing - compared whatever the caller sent: nothing
on a create, a stale value on an edit. The issue's "issued more than 5 days
after the tax event" warning never fired for a REST write.

Change (option (a) of the issue):
- The generated repository gains calculatedForCreate / calculatedForUpdate:
  a field copy of the submitted record carrying what the write computes for
  its calculated fields - on create after the authored defaults, on update
  after taking the system-owned fields from the stored row and recomputing
  the document totals, as update() does. Only the neutral Calc expressions
  are evaluated; a calculated action runs on the write alone. The submitted
  record is untouched (dropSystemOwnedOnCreate and save()/update() see what
  they always saw); an entity with nothing calculated gets itself back.
- All three controllers (power / my / partner, create and both update
  branches) run validate(), validateReferences() and warnings() on that
  candidate row.
- The assistant guide documents checks on calculated fields.

Verified: IntentCalculatedFieldChecksIT (new; the issue's declaration plus
a refusing compare on the same field: create, stale and omitted payloads
on update, a negative delay refused) - answered 200 instead of 428 against
the unfixed templates, green with the fix; IntentSoftWarningsIT,
IntentCheckMessageI18nIT, IntentEmissionCoverageIT, ModelGenerationIT and
the two controller template ITs (anchors updated to the candidate-row
call) green on H2; ide-template (216) and engine-intent (1479) unit suites;
formatter:validate with the cache wiped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…file-wide count (eclipse-dirigible#7544)

The checks' create-time candidate row (calculatedForCreate) applies the
authored defaults as save() does, so the default literal now appears twice
in the generated repository and the occurrence count failed the smoke gate.
Assert what the test means instead: save() and calculatedForCreate() apply
the default, update() and calculatedForUpdate() never do.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant