mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-07 09:56:52 +01:00
Add BCApps citations to Tier 1+2 knowledge files; add 2 new rules
- All 7 existing Tier 1/2 knowledge files now include a BCApps Reference section with concrete source links and observed patterns - New: bcpt-scenarios-must-be-app-specific — PerformanceTest apps must include app-domain BCPT scenarios, not only Microsoft generic samples - New: permission-sets-must-follow-least-privilege — View/Edit/Admin hierarchy with IncludedPermissionSets, mirroring BCApps BusFound pattern - api-page-key-fields-must-be-editable-on-insert clarified: SystemId as ODataKeyField + Editable=false is valid (auto-generated); rule applies to consumer-provided key fields only Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e11c1fd16c
commit
288f64df16
9 changed files with 365 additions and 355 deletions
|
|
@ -1,20 +1,19 @@
|
|||
# CURABIS MCP: FlowFields on API Pages Must Be CalcFields'd
|
||||
# CURABIS MCP: FlowFields on API Pages Rule Summary
|
||||
|
||||
## Core Principle
|
||||
## The Rule
|
||||
**FlowFields on API pages must be explicitly calculated** via `CalcFields()` in the `OnAfterGetRecord` trigger, or they return empty values in OData responses.
|
||||
|
||||
FlowFields on API pages return empty or zero unless explicitly calculated. Every FlowField exposed on a `PageType = API` page must be called via `CalcFields` in the `OnAfterGetRecord` trigger — otherwise the OData response will contain empty values regardless of what the underlying data contains.
|
||||
## Key Points
|
||||
|
||||
## Why This Happens
|
||||
**Why it matters:** "FlowFields are not stored in the database. Business Central only calculates them on demand." Regular pages auto-calculate during rendering, but API pages don't—external consumers receive raw empty values otherwise.
|
||||
|
||||
FlowFields are not stored in the database. Business Central only calculates them on demand. Regular pages trigger calculation automatically as part of the page rendering pipeline. API pages do not — the agent or external consumer receives the raw stored (empty) value.
|
||||
**What to do:** Every FlowField exposed in an API page's layout section requires inclusion in a `CalcFields()` call within `OnAfterGetRecord`. Multiple fields can be combined in one call.
|
||||
|
||||
## Requirements
|
||||
**What doesn't need it:** Stored (non-FlowField) fields require no CalcFields processing.
|
||||
|
||||
- All FlowFields exposed in the `layout` section of an API page must be listed in a `CalcFields()` call in `OnAfterGetRecord`
|
||||
- If multiple FlowFields are needed, they can be combined in a single call: `Rec.CalcFields(Field1, Field2)`
|
||||
- Stored fields (non-FlowField) do not need CalcFields
|
||||
## Implementation Pattern
|
||||
|
||||
## Example
|
||||
The provided example demonstrates proper implementation:
|
||||
|
||||
```al
|
||||
trigger OnAfterGetRecord()
|
||||
|
|
@ -23,10 +22,19 @@ begin
|
|||
end;
|
||||
```
|
||||
|
||||
## Verification
|
||||
## Verification Approach
|
||||
|
||||
When reviewing an API page, identify every field bound to a FlowField source expression. Confirm each appears in the `OnAfterGetRecord` CalcFields call. Any FlowField missing from CalcFields is a defect — it will silently return empty to the MCP consumer.
|
||||
Audit API pages by:
|
||||
1. Identifying every field bound to FlowField sources in the layout
|
||||
2. Confirming each appears in the `OnAfterGetRecord` CalcFields statement
|
||||
3. Flagging any missing FlowField as a defect (silent empty return to consumers)
|
||||
|
||||
## Related Rule
|
||||
This rule prevents data gaps in API integrations caused by overlooked calculation requirements.
|
||||
|
||||
CURABIS-MCP-002 — Stored derived fields must be recalculated in OnAfterGetRecord, not exposed directly.
|
||||
## BCApps Reference
|
||||
|
||||
BCApps API pages implement `CalcFields()` in `OnAfterGetRecord` for all FlowField-sourced fields. The BCPT Suite API page demonstrates the correct pattern for API pages with computed data.
|
||||
|
||||
- **Source:** https://github.com/microsoft/BCApps/blob/main/src/Tools/Performance%20Toolkit/App/src/BCPTSuiteAPI.Page.al
|
||||
- **Additional API pages:** https://github.com/microsoft/BCApps/tree/main/src/Tools/Performance%20Toolkit/App/src
|
||||
- **Pattern:** Any FlowField appearing in an API page layout is explicitly calculated before the record is returned. Microsoft does not rely on implicit calculation in API contexts.
|
||||
|
|
|
|||
|
|
@ -1,40 +1,43 @@
|
|||
# CURABIS MCP: ODataKeyFields Must Be Editable for Create Operations
|
||||
# CURABIS MCP: ODataKeyFields Editability Rule
|
||||
|
||||
## Core Principle
|
||||
## The Rule
|
||||
|
||||
Fields declared in `ODataKeyFields` that identify the record must not have `Editable = false` when the API page allows insert. If they are read-only, the OData API rejects them as unknown properties on POST — the create operation fails and the caller receives a `BadRequest` error.
|
||||
Key fields declared in `ODataKeyFields` cannot have `Editable = false` when the API page permits inserts and **the field is consumer-provided**. This restriction causes the OData layer to reject the field as an unknown property during POST operations.
|
||||
|
||||
## Why This Happens
|
||||
## Why It Matters
|
||||
|
||||
`Editable = false` on a page field removes the field from the OData write schema entirely. When a consumer POSTs a new record and includes the key field in the body, BC cannot match it to any writable property and rejects the request.
|
||||
When a field is marked read-only, Business Central removes it from the OData write schema. If a consumer attempts to POST a new record with that key field in the request body, the system cannot match it to any writable property and returns a `BadRequest` error.
|
||||
|
||||
## Pattern to Avoid
|
||||
## Problematic vs. Correct Approach
|
||||
|
||||
**Incorrect:**
|
||||
```al
|
||||
// WRONG: Key field marked Editable = false — cannot be set on create
|
||||
field(projectNo; Rec."Project No.")
|
||||
{
|
||||
Caption = 'projectNo';
|
||||
Editable = false; // blocks insert via API
|
||||
Editable = false; // prevents API inserts when consumer must supply the value
|
||||
}
|
||||
```
|
||||
|
||||
## Correct Pattern
|
||||
|
||||
**Correct:**
|
||||
```al
|
||||
// CORRECT: No Editable = false — BC controls mutability after insert via ODataKeyFields
|
||||
field(projectNo; Rec."Project No.")
|
||||
{
|
||||
Caption = 'projectNo';
|
||||
// No Editable = false — consumer supplies this on POST
|
||||
}
|
||||
```
|
||||
|
||||
## Requirements
|
||||
## Key Takeaways
|
||||
|
||||
- Fields listed in `ODataKeyFields` must not carry `Editable = false` on pages where `InsertAllowed = true`
|
||||
- Fields that should be read-only after creation but writable on insert need no special property — OData key semantics handle immutability after the record exists
|
||||
- Non-key fields that are genuinely read-only may still use `Editable = false`
|
||||
- Every **consumer-provided** field referenced in `ODataKeyFields` on pages where `InsertAllowed = true` must remain editable
|
||||
- The OData specification itself enforces immutability of key fields post-creation — no additional markup required
|
||||
- Non-key fields can still use `Editable = false` without triggering this issue
|
||||
- Test create operations via your OData endpoint to verify compliance
|
||||
|
||||
## Verification
|
||||
## BCApps Reference
|
||||
|
||||
On any API page with `InsertAllowed = true`, confirm that every field referenced in `ODataKeyFields` does not have `Editable = false` in its field definition. A create test via the OData endpoint is the definitive check.
|
||||
BCApps `BCPTSuiteAPI.Page.al` uses `ODataKeyFields = SystemId` with `SystemId` marked `Editable = false`. This is a **valid exception** — `SystemId` is a system-generated GUID that BC assigns automatically on insert. The consumer never provides it in a POST body, so marking it non-editable does not break API inserts.
|
||||
|
||||
- **Source:** https://github.com/microsoft/BCApps/blob/main/src/Tools/Performance%20Toolkit/App/src/BCPTSuiteAPI.Page.al
|
||||
- **Clarification from BCApps:** The rule distinguishes two key field types:
|
||||
- **Auto-generated keys** (`SystemId`, auto-numbered codes): May be `Editable = false` — BC supplies the value, not the consumer.
|
||||
- **Consumer-provided keys** (`"Project No."`, `"Code"`, `"Entry No."`): Must remain editable — the POST request must include this value and BC must accept it.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue