Vibe Coding for AL coding rules

- Added new rules files for Vibe Coding, including guidelines on AL code style, naming conventions, performance optimization, error handling, event-driven development, and testing.
- Updated existing links
This commit is contained in:
Dmitry Katson 2025-06-26 14:58:03 +07:00
parent 5e76983b77
commit 6b3f522a16
10 changed files with 1272 additions and 5 deletions

View file

@ -0,0 +1,167 @@
---
title: "AL Code Style & Formatting Rules"
description: >
AL Code structure, formatting, and folder organization guidelines for AL development
globs: ["*.al"]
alwaysApply: true
---
# AL Code Style & Formatting Rules
These rules ensure consistent code structure and organization across AL projects, making code more maintainable and AI-assistant friendly.
## Style guidelines for AL code
- Always use camelCase for variable and function names.
- Use PascalCase for object names (e.g., tables, pages, reports).
- Maintain a consistent indentation style (2 spaces preferred).
## Commonly used methods and patterns
- Temporary tables for performance optimization
- Use of events for extensibility
## Rule 1: Consistent Indentation and Formatting
### Intent
Maintain consistent code formatting to improve readability and enable better AI understanding of code structure. Use 2-space indentation consistently throughout your project and maintain consistent formatting within functions and procedures.
### Examples
```al
// Good example
procedure CalculateDiscount(Amount: Decimal; DiscountPct: Decimal): Decimal
begin
if DiscountPct > 0 then
exit(Amount * DiscountPct / 100);
exit(0);
end;
```
## Rule 2: Feature-Based Folder Organization
### Intent
Organize code by business features rather than object types to improve maintainability and logical grouping. Use feature-based organization with `src/feature/subfeature/` structure and place shared components in `Common` or `Shared` folders.
### Examples
```
// Good example - Feature-based organization
src/
├── NoSeries/
│ ├── NoSeries.Table.al
│ ├── NoSeries.Page.al
│ └── NoSeriesSetup.Codeunit.al
├── Sales/
│ ├── Invoice/
│ │ ├── SalesInvoice.Page.al
│ │ └── SalesInvoicePosting.Codeunit.al
│ └── Order/
│ └── SalesOrder.Page.al
└── Common/
├── Helpers/
│ └── DateHelper.Codeunit.al
└── Interfaces/
└── IPostable.Interface.al
```
```
// Bad example (avoid object-type segregation)
src/
├── Tables/
│ ├── NoSeries.Table.al
│ └── SalesHeader.Table.al
├── Pages/
│ ├── NoSeries.Page.al
│ └── SalesInvoice.Page.al
└── Codeunits/
├── NoSeriesSetup.Codeunit.al
└── SalesInvoicePosting.Codeunit.al
```
## Rule 3: Code Documentation and Comments
### Intent
Provide clear documentation for global functions using XML documentation comments. Code should be self-documenting through clear naming, but global functions in codeunits require proper documentation for API clarity.
### Examples
```al
// Good example - XML documentation for global functions
codeunit 50100 "Base64 Convert"
{
/// <summary>
/// Converts the value of the input string to its equivalent string representation that is encoded with base-64 digits.
/// </summary>
/// <param name="String">The string to convert.</param>
/// <returns>The string representation, in base-64, of the input string.</returns>
procedure ToBase64(String: Text): Text
begin
exit(Base64ConvertImpl.ToBase64(String));
end;
/// <summary>
/// Validates discount percentage against business rules.
/// </summary>
/// <param name="DiscountPct">The discount percentage to validate.</param>
procedure ValidateDiscountPercentage(DiscountPct: Decimal)
begin
if DiscountPct > 50 then
Error('Discount cannot exceed 50% due to company policy');
if DiscountPct < 0 then
Error('Discount percentage cannot be negative');
end;
}
```
```al
// Bad example (avoid inline comments for obvious operations)
procedure ValidateDiscountPercentage(DiscountPct: Decimal)
begin
// Check if discount is greater than 50
if DiscountPct > 50 then
Error('Discount cannot exceed 50%');
// Check if discount is less than 0
if DiscountPct < 0 then
Error('Discount percentage cannot be negative');
end;
```
## Rule 4: Modular and Reusable Code Structure
### Intent
Keep code modular and reusable to enhance maintainability and reduce duplication. Write small, focused procedures that do one thing well and use interfaces and patterns where appropriate.
### Examples
```al
// Good example - Modular approach
procedure PostDocument(var DocumentHeader: Record "Sales Header")
begin
ValidateDocument(DocumentHeader);
CalculateTotals(DocumentHeader);
CreateLedgerEntries(DocumentHeader);
UpdateStatus(DocumentHeader);
end;
local procedure ValidateDocument(var DocumentHeader: Record "Sales Header")
begin
if DocumentHeader."No." = '' then
Error('Document number cannot be empty');
end;
local procedure CalculateTotals(var DocumentHeader: Record "Sales Header")
begin
DocumentHeader.CalcFields(Amount);
end;
```
```al
// Bad example (avoid monolithic procedures)
procedure PostDocument(var DocumentHeader: Record "Sales Header")
begin
// All validation, calculation, and posting logic in one procedure
// ... 200+ lines of mixed concerns
end;
```