mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 14:46:55 +01:00
* knowledge(events): database trigger setup flags may only be set to true Add an events article with compiled good/bad samples: GetDatabaseTableTriggerSetup (Global Triggers) and OnAfterGetDatabaseTableTriggerSetup (GlobalTriggerManagement) share four var Booleans across all subscribers, which run in no particular order. Assigning false, or a lookup result without or-ing in the current value, clears flags other features set (Dataverse sync, API webhooks, data archive, and, for direct Global Triggers subscribers, the change log). Recommends the codeunit 49 integration events per Learn's guidance on system codeunits 2000000001..2000000010 and handler-side table filtering. Wired into al-events-review tokens and an event-design check, with carve-outs for conditional := true, Flag := Flag or ..., and the no-op "if not Flag then Flag := false" found in BCApps. Registered in the events review-fixtures override. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * knowledge(events): address review of database trigger setup flags article - Name the BCApps code that clears flags (demo data tool W1/CZ/IN, Backup Management test library) as the mechanism in demo/test-only sessions; carve such code out of the al-events-review check. - Label "events are raised only when the flag is true" as inferred and cite the supporting sources (Learn integration-record refactoring on disabled bulk SQL operations, ChangeLog test cache comment, No Transactions Subscriber); fold the bulk-SQL cost into Best Practice. - Drop the "handler without opt-in" signal from article and check. - Qualify change log protection as normal execution context only. - Drop the unverifiable codeunit ID; describe Global Triggers by its 2000000001..2000000010 range and mark the transition page as v14-era. - Order-dependent wording for flag overwrites; add GP and No Transactions as further direct subscribers; link the references. Samples rechecked with alc 30.0 against Base Application 28.4 symbols. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
196 lines
7.8 KiB
JSON
196 lines
7.8 KiB
JSON
{
|
|
"version": 2,
|
|
"selection": "first-paired-al-article",
|
|
"minimumExpectedRecall": 1.0,
|
|
"minimumCleanRate": 1.0,
|
|
"coverageWaivers": [],
|
|
"overrides": {
|
|
"agents": {
|
|
"article": "wire-all-three-agent-interfaces"
|
|
},
|
|
"breaking-changes": {
|
|
"article": "do-not-expose-sensitive-data-through-public-api"
|
|
},
|
|
"data-modeling": {
|
|
"articles": [
|
|
"activate-new-price-calculation-handler-via-onfindsupportedsetup",
|
|
"check-blocked-in-referencing-code-not-in-master",
|
|
"code-must-not-change-workdate",
|
|
"custom-document-dispatch-must-not-bypass-report-selections",
|
|
"delete-master-data-with-trigger",
|
|
"document-line-prices-follow-prices-including-vat",
|
|
"document-print-and-email-actions-call-report-selections-directly",
|
|
"extend-find-entries-navigate-for-new-document-types",
|
|
"extend-price-source-type-must-sync-document-subset-enum",
|
|
"extend-report-selection-usage-for-new-document-types",
|
|
"master-data-must-be-inserted-with-trigger",
|
|
"new-price-source-must-add-candidate-and-trigger-recalculation",
|
|
"pictures-must-use-media-not-blob",
|
|
"report-barcodes-must-use-barcode-module-and-production-font-name",
|
|
"table-design-must-match-bc-table-type-conventions",
|
|
"transferfields-mirrored-fields-must-match-type-and-length"
|
|
]
|
|
},
|
|
"error-handling": {
|
|
"articles": [
|
|
"collect-validation-errors-with-errorbehavior",
|
|
"declined-confirm-must-abort-not-partially-apply",
|
|
"defensive-vs-offensive-code-must-match-blast-radius",
|
|
"log-writes-must-survive-rollback"
|
|
]
|
|
},
|
|
"events": {
|
|
"articles": [
|
|
"reset-ishandled-only-when-the-value-can-carry-over",
|
|
"changecompany-runs-triggers-in-the-calling-company",
|
|
"database-trigger-setup-flags-may-only-be-set-to-true"
|
|
]
|
|
},
|
|
"finance": {
|
|
"articles": [
|
|
"apply-ledger-entries-through-application-codeunits",
|
|
"change-ledger-due-dates-through-entry-edit",
|
|
"do-not-edit-shared-dimension-sets",
|
|
"do-not-modify-or-delete-posted-ledger-entries",
|
|
"normal-vat-journal-amount-includes-vat",
|
|
"post-ledger-entries-through-posting-codeunits",
|
|
"preserve-journal-batch-document-balance",
|
|
"reverse-transactions-by-transaction-number",
|
|
"write-dimensions-as-dimension-set-entries"
|
|
],
|
|
"context": "Target Business Central 28, worldwide standard application (w1). Review each file as an independent source input."
|
|
},
|
|
"interfaces": {
|
|
"article": "set-defaultimplementation-on-enum"
|
|
},
|
|
"performance": {
|
|
"articles": [
|
|
"use-isempty-for-existence-check",
|
|
"use-get-instead-of-findfirst-on-full-primary-key",
|
|
"job-queue-category-code-serializes-conflicting-jobs",
|
|
"job-queue-external-effects-must-be-idempotent",
|
|
"job-queue-handlers-must-not-require-ui",
|
|
"job-queue-handlers-must-propagate-failures",
|
|
"job-queue-on-hold-does-not-stop-running-work",
|
|
"store-scheduled-task-id-to-avoid-duplicate-tasks",
|
|
"design-covering-keys-from-read-pattern",
|
|
"review-overlapping-keys-before-adding-an-index",
|
|
"setcurrentkey-sets-sort-order-not-index-hint",
|
|
"preserve-buffered-inserts-by-separating-target-reads",
|
|
"aggregate-before-persisting-intermediate-results",
|
|
"cache-repeated-filtered-results-with-explicit-scope",
|
|
"avoid-repeating-unchanged-validation",
|
|
"avoid-get-inside-loop-on-large-table",
|
|
"isempty-before-findset-is-extra-round-trip",
|
|
"query-results-bypass-primary-key-cache",
|
|
"calcsums-instead-of-calcfields-in-loop",
|
|
"use-setautocalcfields-for-per-row-flowfields",
|
|
"temporary-tables-have-no-database-cost",
|
|
"use-setloadfields-for-partial-records",
|
|
"prefer-modifyall-over-per-row-modify",
|
|
"al-methods-limited-during-write-transactions",
|
|
"avoid-user-prompts-inside-transactions",
|
|
"use-grouped-query-for-distinct-values-and-duplicates"
|
|
]
|
|
},
|
|
"privacy": {
|
|
"article": "no-pii-in-telemetry-message-string"
|
|
},
|
|
"query": {
|
|
"articles": [
|
|
"dataitemtablefilter-cannot-be-overwritten-at-runtime",
|
|
"reopening-query-resets-cursor-but-keeps-filters",
|
|
"set-query-filters-before-open",
|
|
"setfilter-overwrites-query-columnfilter"
|
|
]
|
|
},
|
|
"reporting": {
|
|
"articles": [
|
|
"clear-report-variable-before-independent-runmodal",
|
|
"currreport-break-ends-the-current-trigger",
|
|
"currreport-quit-rolls-back-and-skips-onpostreport",
|
|
"currreport-skip-does-not-stop-trigger-code",
|
|
"report-output-in-a-loop-needs-one-client-download",
|
|
"reportextension-dataitem-trigger-order-is-explicit",
|
|
"reportextension-report-triggers-run-after-base-triggers",
|
|
"settableview-cannot-broaden-dataitemtableview",
|
|
"stop-when-runrequestpage-returns-empty-parameters"
|
|
]
|
|
},
|
|
"scm": {
|
|
"articles": [
|
|
"post-item-ledger-changes-through-item-journals",
|
|
"post-revaluation-through-the-item-journal-batch",
|
|
"change-item-applications-through-posting-routines",
|
|
"cancel-reservations-through-reservation-management",
|
|
"transfer-item-tracking-through-source-reservation-codeunits",
|
|
"reconcile-warehouse-adjustments-with-the-item-ledger",
|
|
"post-transfers-through-shipment-and-receipt-codeunits",
|
|
"use-date-aware-availability-for-promising",
|
|
"carry-out-requisition-actions-through-the-standard-workflow",
|
|
"derive-base-quantities-through-the-line-unit-of-measure"
|
|
]
|
|
},
|
|
"security": {
|
|
"articles": [
|
|
"al-has-no-built-in-htmlencode",
|
|
"do-not-concatenate-external-text-into-setfilter",
|
|
"exposed-objects-must-be-in-a-permission-set"
|
|
]
|
|
},
|
|
"style": {
|
|
"articles": [
|
|
"label-comment-explains-placeholders",
|
|
"dateformula-evaluate-needs-language-independent-literals",
|
|
"al-comments-must-not-restate-what-code-already-shows",
|
|
"pages-must-not-contain-business-logic",
|
|
"mutating-procedure-for-a-page-caller-takes-var-record"
|
|
]
|
|
},
|
|
"telemetry": {
|
|
"article": "telemetry-event-id-stable-unique"
|
|
},
|
|
"testing": {
|
|
"articles": [
|
|
"ui-handlers-in-tests",
|
|
"reset-per-test-state-before-the-isinitialized-guard",
|
|
"asserterror-needs-expectederror-and-code",
|
|
"bcpt-scenarios-must-be-app-specific",
|
|
"commit-shared-test-fixture-inside-lazy-initialize",
|
|
"given-blocks-must-cover-full-precondition-chain",
|
|
"table-relation-test-exclude-known-invalid-relations-via-event",
|
|
"test-feature-scenario-tags",
|
|
"test-one-when-per-test",
|
|
"transactionmodel-attribute-governs-test-transactions",
|
|
"ui-test-codeunit-naming",
|
|
"use-assert-isfalse-not-asserterror-for-boolean-checks"
|
|
]
|
|
},
|
|
"ui": {
|
|
"articles": [
|
|
"default-descending-sort-on-historical-pages",
|
|
"page-design-must-match-bc-page-type-conventions",
|
|
"page-client-expression-must-not-use-in-list",
|
|
"rolecenter-permission-gating-must-use-accessbypermission"
|
|
]
|
|
},
|
|
"upgrade": {
|
|
"articles": [
|
|
"initvalue-does-not-update-existing-rows",
|
|
"upgrade-tag-logic-must-not-nest-deeply",
|
|
"no-changecompany-in-upgrade"
|
|
],
|
|
"context": "The extended table existed in the previous app version and already contains rows."
|
|
},
|
|
"web-services": {
|
|
"articles": [
|
|
"expose-systemid-as-the-api-key",
|
|
"handle-httpclient-platform-failure-before-response-access",
|
|
"check-http-status-before-consuming-response-body",
|
|
"check-json-null-before-converting-values",
|
|
"format-exchanged-values-with-standard-format-9",
|
|
"api-page-least-privilege-write-access"
|
|
]
|
|
}
|
|
}
|
|
}
|