mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-07 01:46:53 +01:00
Add CMFRT best practices and anti-patterns documentation for various coding standards
This commit is contained in:
parent
cfcf16a00e
commit
906ddcfd72
21 changed files with 427 additions and 5 deletions
|
|
@ -0,0 +1,15 @@
|
|||
page 55035 "CMFRT AQ FS JJL API"
|
||||
{
|
||||
PageType = API;
|
||||
SourceTable = "Job Journal Line"; // real table exposed directly to the API
|
||||
|
||||
trigger OnInsertRecord(BelowxRec: Boolean): Boolean
|
||||
begin
|
||||
// Manual insert/exit boilerplate duplicates the framework insert
|
||||
// and couples the HTTP request to the real-table insert: no retry,
|
||||
// no error queue, one validation error fails the whole request.
|
||||
Rec.Insert(true);
|
||||
Rec.CMFRTAQFSLogIncomingRequest();
|
||||
exit(false);
|
||||
end;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
page 55035 "CMFRT AQ FS JJL API"
|
||||
{
|
||||
PageType = API;
|
||||
SourceTable = "CMFRT AQ FS JJL Buffer"; // buffer table, not Job Journal Line
|
||||
|
||||
trigger OnInsertRecord(BelowxRec: Boolean): Boolean
|
||||
begin
|
||||
// Side effects only; framework performs the default insert.
|
||||
Rec.CMFRTAQFSLogIncomingRequest();
|
||||
end;
|
||||
}
|
||||
|
||||
codeunit 55038 "CMFRT AQ FS JJL Proc"
|
||||
{
|
||||
procedure CMFRTAQProcessPendingEntries()
|
||||
var
|
||||
JJLBuffer: Record "CMFRT AQ FS JJL Buffer";
|
||||
JJLCreator: Codeunit "CMFRT AQ FS JJL Creator";
|
||||
begin
|
||||
JJLBuffer.SetRange("CMFRT AQ Status", "CMFRT AQ Buffer Status"::"CMFRT AQ Pending");
|
||||
if JJLBuffer.FindSet(true) then
|
||||
repeat
|
||||
// Proc owns the error boundary: one bad row does not abort the batch.
|
||||
if Codeunit.Run(Codeunit::"CMFRT AQ FS JJL Creator", JJLBuffer) then
|
||||
JJLBuffer."CMFRT AQ Status" := "CMFRT AQ Buffer Status"::"CMFRT AQ Processed"
|
||||
else begin
|
||||
JJLBuffer."CMFRT AQ Status" := "CMFRT AQ Buffer Status"::"CMFRT AQ Error";
|
||||
JJLBuffer."CMFRT AQ Error Message" := CopyStr(GetLastErrorText(), 1, MaxStrLen(JJLBuffer."CMFRT AQ Error Message"));
|
||||
end;
|
||||
JJLBuffer.Modify(true);
|
||||
until JJLBuffer.Next() = 0;
|
||||
end;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
bc-version: [all]
|
||||
domain: architecture
|
||||
keywords: [api, buffer, staging, oninsertrecord, api-page, inbound, creator, proc, codeunit-run]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [all]
|
||||
---
|
||||
|
||||
# CMFRT inbound API pages write to buffer tables
|
||||
|
||||
## Description
|
||||
|
||||
Inbound CMFRT API pages never source from real application tables. Each API page sources from a dedicated buffer (staging) table owned by the extension. The buffer row records the raw inbound payload plus a status field (Pending/Processing/Processed/Error) and an operation enum where applicable. A Proc codeunit picks up pending buffer rows and owns the `Codeunit.Run` error boundary; a Creator codeunit transfers buffer values into the real table via `Validate` calls. The API page's `OnInsertRecord` trigger contains no manual insert plumbing — the framework performs the default insert; the trigger only performs side effects such as request logging.
|
||||
|
||||
## Best Practice
|
||||
|
||||
For each inbound API: one buffer table (with status and error-message fields), one API page sourced from the buffer, one Proc codeunit that iterates pending rows and calls the Creator inside a `Codeunit.Run` boundary so one failing row does not abort the batch, and one Creator codeunit that fills and inserts the real record. `OnInsertRecord` bodies contain only logging or metadata capture and no `exit` statement, so the framework insert proceeds.
|
||||
|
||||
See sample: `cmfrt-buffer-table-api-pattern.good.al`.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
An API page sourced directly from a real table (Sales Header, Job, Ship-to Address), or an `OnInsertRecord` trigger that calls `Rec.Insert(true)` followed by `exit(false)` to suppress the framework insert. Direct-to-real-table APIs make inbound failures atomic with the HTTP request (no retry, no error queue), and the manual insert/exit boilerplate duplicates framework behaviour while hiding the insert from other trigger logic.
|
||||
|
||||
See sample: `cmfrt-buffer-table-api-pattern.bad.al`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue