Rules derived from BC MCP API page development experience: - api-page-flowfields-must-be-calcfields: FlowFields return empty on API pages unless explicitly CalcFields'd in OnAfterGetRecord - stored-derived-fields-must-not-be-exposed-directly: Stored fields updated only via OnValidate triggers can be stale; recalculate live in OnAfterGetRecord - api-page-key-fields-must-be-editable-on-insert: ODataKeyFields with Editable=false are rejected as unknown properties on POST - api-page-least-privilege-write-access: Create dedicated minimal pages per write concern rather than widening general-purpose pages - agent-must-not-write-business-process-status: Agents must only write developer-tracking fields; business status fields affect invoicing/time registration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.7 KiB
CURABIS MCP: Stored Derived Fields Must Be Recalculated in OnAfterGetRecord
Core Principle
A stored field whose value is derived from other fields via OnValidate triggers can be stale. When the source data changes (e.g., new time entries posted), the stored derived field is not updated automatically — it only recalculates when a specific trigger fires. Exposing such a field directly via an API page returns a value that may be hours, days, or weeks out of date.
Pattern to Avoid
// WRONG: Exposes the stored snapshot — may be stale
field(timeLeft; Rec."Time left") { }
"Time left" is recalculated only when "Estimated time" is validated. If new time entries are posted, the stored value does not update.
Correct Pattern
Recalculate in OnAfterGetRecord using a page variable:
trigger OnAfterGetRecord()
begin
Rec.CalcFields("Elapsed time (Chargeable)");
TimeLeftCalc := Rec."Estimated time" - Rec."Elapsed time (Chargeable)";
end;
var
TimeLeftCalc: Decimal;
// In layout:
field(timeLeft; TimeLeftCalc) { } // live value
field(elapsedTime; Rec."Elapsed time (Chargeable)") { } // source FlowField
Requirements
- Identify stored fields whose value is computed from other fields via triggers
- Do not expose them directly in API pages
- Recalculate from the authoritative source (FlowField or live query) in
OnAfterGetRecord - Expose both the recalculated result and the source FlowField so the consumer can verify
Verification
Inspect the source table for any field with FieldClass = Normal whose value is set inside an OnValidate trigger on another field. If that field is exposed on an API page, verify it is recalculated in OnAfterGetRecord rather than read from Rec directly.