mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-08 18:31:36 +01:00
Add mcp knowledge category with 5 rules
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>
This commit is contained in:
parent
c2aaf92748
commit
935d756f05
5 changed files with 190 additions and 0 deletions
|
|
@ -0,0 +1,44 @@
|
|||
# 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
|
||||
|
||||
```al
|
||||
// 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:
|
||||
|
||||
```al
|
||||
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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue