mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-07 18:06:53 +01:00
- Introduced `al-test-writer` to generate AL test codeunits for production objects based on TDD principles. - Added `al-userguide-test-writer` to create test codeunits from user guide steps, mapping actions and assertions. - Implemented `bc-extension-test-guide` to generate a comprehensive TEST_GUIDE.md for Business Central extensions, covering various categories. - Created `bc-webclient-runner` to automate UI testing of the Business Central web client, capturing screenshots and asserting UI states. - Developed `page-scripting-e2e` to produce a recording plan for Page Scripting, ensuring a structured approach to browser-level testing.
33 lines
1.7 KiB
AL
33 lines
1.7 KiB
AL
// Anti-pattern: insert on every call with no idempotency check, keyed on a brand-new GUID.
|
|
// A retried or re-fetched delivery is processed again as a fresh message, so a duplicating
|
|
// source produces duplicate documents and double-applied side effects.
|
|
|
|
codeunit 50142 "Inbound Dedup Bad"
|
|
{
|
|
procedure Stage(ExternalRef: Text[100]; MsgType: Code[40]; Payload: Text): Guid
|
|
var
|
|
IntegrationMessage: Record "Integration Message";
|
|
begin
|
|
// BAD: no SetRange on External Reference + Type, no Get, no lookup of any kind.
|
|
// The source system's stable id is captured on the row but never used to detect a repeat.
|
|
IntegrationMessage.Init();
|
|
|
|
// BAD: the only "identity" is a fresh GUID. If anyone later "dedups" on Message ID,
|
|
// it can never match, because every insert mints a new one. This is the illusion of a
|
|
// dedup key that can never actually fire.
|
|
IntegrationMessage."Message ID" := CreateGuid();
|
|
|
|
IntegrationMessage.Direction := IntegrationMessage.Direction::Inbound;
|
|
IntegrationMessage."External Reference" := ExternalRef;
|
|
IntegrationMessage.Type := MsgType;
|
|
IntegrationMessage.Status := IntegrationMessage.Status::New;
|
|
IntegrationMessage.SetRequest(Payload);
|
|
|
|
// When the source RETRIES (a webhook that did not see our ack, a restart re-send, an
|
|
// overlapping poll window): this runs again with the same ExternalRef and stages a
|
|
// second message. Downstream it becomes a second sales order and a second posting.
|
|
// The duplicate volume scales with how aggressively the source retries.
|
|
IntegrationMessage.Insert(true);
|
|
exit(IntegrationMessage."Message ID");
|
|
end;
|
|
}
|