From f027e28f8344592447e8b7b69ed5ae4778b9225f Mon Sep 17 00:00:00 2001 From: Wael <38723677+WaelAbuSeada@users.noreply.github.com> Date: Wed, 2 Sep 2026 03:16:30 -0600 Subject: [PATCH] knowledge: improve review precision from BCApps PR 10080 feedback (#128) * knowledge: improve review precision from BCApps PR 10080 feedback * Update microsoft/knowledge/appsource/object-affixes-prevent-collisions.md Co-authored-by: Natalie Karolak, MVP <34504100+NKarolak@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Jesper Schulz-Wedde Co-authored-by: Natalie Karolak, MVP <34504100+NKarolak@users.noreply.github.com> --- .../knowledge/appsource/object-affixes-prevent-collisions.md | 4 +++- microsoft/knowledge/error-handling/fielderror-vs-testfield.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/microsoft/knowledge/appsource/object-affixes-prevent-collisions.md b/microsoft/knowledge/appsource/object-affixes-prevent-collisions.md index a46c0d1..a3542a1 100644 --- a/microsoft/knowledge/appsource/object-affixes-prevent-collisions.md +++ b/microsoft/knowledge/appsource/object-affixes-prevent-collisions.md @@ -1,7 +1,7 @@ --- bc-version: [all] domain: appsource -keywords: [object-affix, prefix, suffix, as0011, appsourcecop, collision, tableextension] +keywords: [object-affix, prefix, suffix, as0011, appsourcecop, collision, tableextension, first-party, isv] technologies: [al] countries: [w1] application-area: [all] @@ -15,6 +15,8 @@ An AppSource extension must prevent name collisions through its registered affix AppSourceCop enforces this. The primary rule is AS0011 ("An affix is required"); the affixes are configured through `mandatoryAffixes` (and `mandatoryPrefix`) in `AppSourceCop.json`. Two placements matter and are easy to get half-right: an object you define carries the affix at **object-name** level, while a member you add to a **standard** object carries the affix on that **member's** name. Adding an affixed object is not enough — an unaffixed field bolted onto `Customer` still collides and still fails validation. +This rule scopes to Marketplace ISV extensions, which is what AppSourceCop validates. A first-party Microsoft in-box module (publisher `Microsoft`, an object range reserved for first-party use, and no `AppSourceCop.json`/`mandatoryAffixes` in the app) is not built or shipped as an Marketplace extension and is not subject to AS0011, so an unaffixed action or field it adds to a base-application page is not a collision risk to flag. Renaming an existing shipped first-party member to add an affix is itself a breaking change to that module's own history and is not required by this rule. + ## Best Practice Own objects use the registered affix (for example `ABC Loyalty Tier`) or, when targeting BC23 or later, a qualifying namespace. Every field or action added to a standard object remains individually affixed (for example `Loyalty Points ABC` on a `Customer` tableextension). diff --git a/microsoft/knowledge/error-handling/fielderror-vs-testfield.md b/microsoft/knowledge/error-handling/fielderror-vs-testfield.md index 1353c03..9b58b32 100644 --- a/microsoft/knowledge/error-handling/fielderror-vs-testfield.md +++ b/microsoft/knowledge/error-handling/fielderror-vs-testfield.md @@ -1,7 +1,7 @@ --- bc-version: [all] domain: error-handling -keywords: [fielderror, testfield, field-validation, onvalidate, error-message, mandatory-field, record-context] +keywords: [fielderror, testfield, field-validation, onvalidate, error-message, mandatory-field, record-context, onaction, enabled-property] technologies: [al] countries: [w1] application-area: [all] @@ -14,6 +14,8 @@ application-area: [all] ## Best Practice Use `TestField` when the condition is a simple presence-or-equality check on a single field — mandatory-field gates and prerequisite checks at the top of a procedure read clearly and self-document intent. Use `FieldError` inside an `OnValidate` trigger or a validation procedure where surrounding business logic has already determined the value is invalid and you want a specific, custom message. Rely on the built-in field-and-record context both methods add rather than re-stating the field name in the text. +A page action's `OnAction` trigger is a different case: a page action is only invocable through its own UI control, so when the action's `Enabled` property is already bound to the same condition the trigger would otherwise `TestField`, the control cannot be clicked while the field is blank and the field can never reach the trigger empty. Adding a `TestField` there is redundant defensive code, not a missing check — flag it only when the trigger can run through a path `Enabled` does not cover (a shared procedure, an API, or a condition broader than what gates the action). + See sample: `fielderror-vs-testfield.good.al`. ## Anti Pattern