From 17f18636c71929d0a3490718e64a045e33cf279e Mon Sep 17 00:00:00 2001 From: Nikola Kukrika Date: Wed, 8 Oct 2025 12:52:09 +0200 Subject: [PATCH] Adding lattest instructions --- ...e-claude-instructions.md => al-upgrade.md} | 72 +++++++++++++------ 1 file changed, 49 insertions(+), 23 deletions(-) rename content/docs/vibe-coding/{al-upgrade-claude-instructions.md => al-upgrade.md} (85%) diff --git a/content/docs/vibe-coding/al-upgrade-claude-instructions.md b/content/docs/vibe-coding/al-upgrade.md similarity index 85% rename from content/docs/vibe-coding/al-upgrade-claude-instructions.md rename to content/docs/vibe-coding/al-upgrade.md index 456d1b95..3113ca8b 100644 --- a/content/docs/vibe-coding/al-upgrade-claude-instructions.md +++ b/content/docs/vibe-coding/al-upgrade.md @@ -103,7 +103,22 @@ codeunit 4123 UpgradeMyFeature ### Rule: Minimize Upgrade Blocking - **Throw errors ONLY** when absolutely necessary to abort upgrade -- Handle unexpected scenarios gracefully without blocking. All read operations (GET, FIND, FINDSET, FINDLAST) should have IF THEN +- Handle unexpected scenarios gracefully without blocking. All read operations (Get, Find, FindSet, FindFirst, FindLast) should have if [OPERATION] then to make it safe. +**BAD EXAMPLE** +```al +Item.Get(); +Customer.FindSet(); +Vendor.FindLast(); +``` +**GOOD EXAMPLE** +```al +if Item.Get() then + // CustomCode; +if Customer.FindSet() then; +if not Vendor.FindLast() then + exit; +``` + - Use telemetry for logging issues instead of throwing errors - Customers should not be blocked from upgrading due to data inconsistencies @@ -127,22 +142,22 @@ Every GET, FIND, FINDSET, FINDLAST operation MUST be within IF-THEN structure: **CORRECT Examples:** ```al -if Customer.Get(CustomerNo) then - Customer.Modify(); +if MyTable.Get(CustomerNo) then + MyTable.Modify(); -if ItemLedgerEntry.FindSet() then +if MyTable.FindSet() then repeat // Process records - until ItemLedgerEntry.Next() = 0; + until MyTable.Next() = 0; -if SalesHeader.FindLast() then +if MyTable.FindLast() then // Process record ``` **INCORRECT Examples:** ```al -Customer.Get(CustomerNo); // WRONG - not protected -SalesHeader.FindLast(); // WRONG - not protected +MyTable.Get(CustomerNo); // WRONG - not protected +MyTable.FindLast(); // WRONG - not protected ``` ## 5. Execution Control - Use Upgrade Tags (Not Version Checks) @@ -221,9 +236,10 @@ end; ### Upgrade Tag Rules - Maximum 2 levels of nesting in upgrade tag logic - No complex if-then structures -- Reuse existing event subscribers when possible - only add new lines +- **IMPORTANT** When adding new lines to the register upgrade tags subscribers you must check from where the upgrade method is called. If it is called from OnUpgradePerCompany then it must be registered from OnGetPerCompanyUpgradeTags method. If it is called from OnUpgradePerDatabase it must be registered under OnGetPerDatabaseUpgradeTags. It **MUST** not be called from both, we need to use a different tags in this case. +- Reuse existing event subscribers when possible - only add new lines. - Use upgrade tags ONLY in upgrade code - +- Every new upgrade tag added **MUST** be referenced within an OnGetPerDatabaseUpgradeTags or OnGetPerCompanyUpgradeTags event subscriber ## 6. No Outside Calls During Upgrade ### Rule: No Outside Calls During Upgrade @@ -262,7 +278,9 @@ if GetExecutionContext() = ExecutionContext::Upgrade then - New fields and tables added in the same PR - Initializing newly added data structures -If there is no new fields and tables, comment should be added that the validation triggers and event subscribers will not be raised, potentially breaking the business logic. +**IMPORTANT** +- If there is no new fields and tables, comment should be added that the validation triggers and event subscribers will not be raised, potentially breaking the business logic. +- If a new field is added, especially with InitValue, datatransfer is strongly recommended to be used to have a fast upgrade. ### DataTransfer vs Loop/Modify Comparison @@ -373,35 +391,43 @@ end; When a field is added with InitValue: - InitValue applies ONLY to new records - Existing records get datatype default (0 for numbers, false for Boolean) -- Code reviewer MUST ask if upgrade code is needed +- Code reviewer MUST ask if upgrade code is needed for each of the fields. **Example Field Addition:** ```al -field(100; "Override Allowed"; Boolean) +field(100; "New Field"; Boolean) { DataClassification = CustomerContent; - Caption = 'Override Manual'; + Caption = 'New Field'; InitValue = true; } + +field(101; "New Field 2"; Integer) +{ + DataClassification = CustomerContent; + Caption = 'New Field 2'; + InitValue = 5; +} ``` **Required Upgrade Code:** ```al -local procedure UpgradeAllocationAccounts() +local procedure UpgradeMyTables() var - BlankAllocationAccount: Record "Allocation Account"; + BlankMyTable: Record "My Table"; UpgradeTag: Codeunit "Upgrade Tag"; UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; - AllocationAccountDataTransfer: DataTransfer; + MyTableDataTransfer: DataTransfer; begin - if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetUpgradeAllocationAccountsTag()) then + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetUpgradeMyTablesTag()) then exit; - AllocationAccountDataTransfer.SetTables(Database::"Allocation Account", Database::"Allocation Account"); - AllocationAccountDataTransfer.AddConstantValue(true, BlankAllocationAccount.FieldNo("Override Allowed")); - AllocationAccountDataTransfer.CopyFields(); + MyTableDataTransfer.SetTables(Database::"My Table", Database::"My Table"); + MyTableDataTransfer.AddConstantValue(true, BlankMyTable.FieldNo("New Field")); + MyTableDataTransfer.AddConstantValue(5, BlankMyTable.FieldNo("New Field 2")); + MyTableDataTransfer.CopyFields(); - UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetUpgradeAllocationAccountsTag()); + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetUpgradeMyTablesTag()); end; ``` @@ -416,7 +442,7 @@ When reviewing upgrade code, verify: 5. ✅ No external calls (HTTP, DotNet interop) 6. ✅ DataTransfer used for tables > 300k records 7. ✅ DataTransfer only used for new fields/tables -8. ✅ InitValue fields have corresponding upgrade code +8. ✅ InitValue fields have corresponding upgrade code. Each new file **MUST** be verified. 9. ✅ Proper error handling (minimal blocking) 10. ✅ Upgrade tags properly registered with event subscribers