Add data-modeling and appsource knowledge articles (MICROSOFT layer)

Author 7 remedial BCQuality knowledge articles plus good/bad AL samples
(21 files) covering AL master-table and data-model design:

- data-modeling: master No. from number series in OnInsert; use codeunit
  "No. Series" not obsolete NoSeriesManagement; setup table is a singleton;
  set Last Date Modified in OnModify and OnRename; enforce Blocked in
  referencing code not in the master.
- style: ApplicationArea required on page controls (AS0062).
- appsource: object affixes prevent collisions (AS0011).

Clean-room authored from own BC knowledge; specifics verified against public
sources only (learn.microsoft.com, microsoft/BCApps). Introduces two new
domains (data-modeling, appsource).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Jesper Schulz-Wedde 2026-07-01 11:00:05 +02:00
parent 24e62f5ec8
commit 18cb503540
21 changed files with 885 additions and 0 deletions

View file

@ -0,0 +1,28 @@
---
bc-version: [all]
domain: data-modeling
keywords: [setup-table, insertallowed, deleteallowed, getrecordonce, primary-key, card-page]
technologies: [al]
countries: [w1]
application-area: [all]
---
# A setup table is a singleton: one blank-keyed row, no insert or delete
## Description
An application-area setup table (`Sales & Receivables Setup`, `Inventory Setup`, and any custom `* Setup`) holds exactly one record per company. Its primary key is a single `Code[10]` field named `Primary Key`, and the row's value is left blank. Nothing else identifies the row — there is only ever one.
The setup **card** page enforces the singleton: `InsertAllowed = false` and `DeleteAllowed = false` stop a second row or an empty table, and the page guarantees the row exists on first open — typically `OnOpenPage` with `if not Rec.Get() then begin Rec.Init(); Rec.Insert(); end;`, or a `GetRecordOnce` helper on the table. Consuming code then reads it with a plain `Get()`. The read side needs no access optimization — see `singleton-setup-tables-need-no-access-optimization.md`.
## Best Practice
`Primary Key` `Code[10]` is the sole key; the setup is surfaced through a Card page with `InsertAllowed = false`, `DeleteAllowed = false`, and an open-time guard that inserts the blank row if it is missing.
See sample: `setup-table-is-a-singleton.good.al`.
## Anti Pattern
An `Integer` / `AutoIncrement` key, a page that allows insert or delete, or a List page over the setup table. Any of these lets the table hold zero or many rows, so "the setup" becomes ambiguous and `Get()` may fail or read the wrong record.
See sample: `setup-table-is-a-singleton.bad.al`.