<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yahya Touil</title>
    <description>The latest articles on DEV Community by Yahya Touil (@yahyatouil).</description>
    <link>https://dev.to/yahyatouil</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3808581%2F1133b606-9bd7-45da-ab42-db01de995132.jpg</url>
      <title>DEV Community: Yahya Touil</title>
      <link>https://dev.to/yahyatouil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yahyatouil"/>
    <language>en</language>
    <item>
      <title>How I turned 200+ BCQuality knowledge files into 26 AL rules (and rejected most of the rest)</title>
      <dc:creator>Yahya Touil</dc:creator>
      <pubDate>Mon, 24 Aug 2026 10:41:50 +0000</pubDate>
      <link>https://dev.to/yahyatouil/how-i-turned-200-bcquality-knowledge-files-into-26-al-rules-and-rejected-most-of-the-rest-1cnm</link>
      <guid>https://dev.to/yahyatouil/how-i-turned-200-bcquality-knowledge-files-into-26-al-rules-and-rejected-most-of-the-rest-1cnm</guid>
      <description>&lt;p&gt;I just shipped &lt;a href="https://marketplace.visualstudio.com/items?itemName=yahyatouil.al-griller-analyzer" rel="noopener noreferrer"&gt;AL Griller&lt;/a&gt;, a static analyzer for Dynamics 365 Business Central AL code that roasts you when it finds a real problem. Before I talk about the jokes, I want to talk about the boring part, because the boring part is the reason the jokes are trustworthy: how the 26 rules actually got chosen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclosure up front:&lt;/strong&gt; AL Griller's rule research was built by working through Microsoft's &lt;a href="https://github.com/microsoft/BCQuality" rel="noopener noreferrer"&gt;BCQuality&lt;/a&gt; repository - a curated knowledge base and skills library for Business Central quality. Full credit to the BCQuality team and community for that research. AL Griller is an independent, community-run open-source project. It is not a Microsoft product and there's no official partnership.&lt;/p&gt;

&lt;h2&gt;
  
  
  The starting point
&lt;/h2&gt;

&lt;p&gt;BCQuality is big - north of 200 knowledge files across 14 domains (performance, query, data modeling, error handling, events, security, and more). Not every one of those files can become a static analysis rule. A lot of them describe judgment calls: "reorder this switch by frequency, but only if profiling shows it's hot," or "pick the right key based on read/write ratio." Real advice, completely useless as a line-matching rule, because it needs information a single-file text scanner will never have.&lt;/p&gt;

&lt;p&gt;So the research pass wasn't "convert every file to a rule." It was a filter, applied file by file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is this a meaningful practice?&lt;/li&gt;
&lt;li&gt;Is it deterministic?&lt;/li&gt;
&lt;li&gt;Is it detectable from AL source without AI?&lt;/li&gt;
&lt;li&gt;Are false positives controllable?&lt;/li&gt;
&lt;li&gt;Is it explainable?&lt;/li&gt;
&lt;li&gt;Is it testable?&lt;/li&gt;
&lt;li&gt;Is it already covered by a Microsoft analyzer (CodeCop / AppSourceCop / PerTenantExtensionCop / UICop)?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Full reads went into Performance (54 files), Query, Data Modeling, Error Handling, the community layer, and the Events files specific to loop/database behavior. Security got a representative sample (8 of ~20 files, chosen for deterministic detectability). Domains like Privacy, Telemetry, Testing, and Interfaces got only a file-listing pass - flagged as future research, not "nothing there."&lt;/p&gt;

&lt;h2&gt;
  
  
  What survived
&lt;/h2&gt;

&lt;p&gt;Everything that passed the filter got classified STRONG / GOOD / EXPERIMENTAL, and every rule that actually shipped got a priority: P0 or P1.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;P0 (12 rules)&lt;/strong&gt; - purely syntactic or local to a single procedure/trigger, with short, reliable false-positive carve-outs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;P1 (14 rules)&lt;/strong&gt; - still deterministic, but needs cross-statement ordering within a procedure, a light heuristic, or one extra piece of context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the entire shipped set: 26 rules, &lt;code&gt;ALGRILL001&lt;/code&gt;–&lt;code&gt;ALGRILL026&lt;/code&gt;. No P2 or P3 rules made it into &lt;code&gt;rules.json&lt;/code&gt;. That was a deliberate call - the project's own research doc calls it "trust over rule count." A rule that's right 80% of the time and annoying the other 20% erodes trust in every other rule it ships next to.&lt;/p&gt;

&lt;h2&gt;
  
  
  What got rejected outright
&lt;/h2&gt;

&lt;p&gt;A handful of well-documented BCQuality patterns were investigated and explicitly rejected - not deferred, rejected - because they fail on a fundamental axis rather than just confidence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Error message tone (internal vs. client-facing)&lt;/strong&gt; - requires judging the &lt;em&gt;tone&lt;/em&gt; of English prose. Not a syntactic pattern.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hand-rolled validation error accumulation&lt;/strong&gt; - the anti-pattern has too many unrelated shapes (a List, a TextBuilder, a temp table, plain concatenation) to match reliably.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Case-branch reordering by frequency&lt;/strong&gt; - the source article itself says this is only justified when profiling shows a hot path. Not statically detectable, and explicitly called out as "not a default review finding."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SetCurrentKey&lt;/code&gt; alignment with filters&lt;/strong&gt; - picking the "right" key requires understanding business-relevant filter/sort intent that isn't recoverable from source. The original task brief flagged this one specifically as a trap: don't manufacture "SetCurrentKey after FindSet = bad" out of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's deferred, not rejected
&lt;/h2&gt;

&lt;p&gt;A separate bucket - real, well-evidenced findings that didn't clear the bar &lt;em&gt;this pass&lt;/em&gt;, usually because reliable detection needs cross-object context a single-file scanner can't resolve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;N+1 &lt;code&gt;Get()&lt;/code&gt;/&lt;code&gt;FindFirst()&lt;/code&gt; in a loop, refined by "and a query/dictionary would have collapsed it" - needs join-feasibility awareness across tables.&lt;/li&gt;
&lt;li&gt;Missing &lt;code&gt;SetLoadFields()&lt;/code&gt; - the source article lists four separate suppression conditions (field count, field-read percentage, loop iteration bound, temp/singleton exemption). Shipping without all four would produce exactly the false-positive fatigue the project was trying to avoid.&lt;/li&gt;
&lt;li&gt;Setup-table singleton detection - currently only a naming heuristic (&lt;code&gt;*Setup&lt;/code&gt;, blank &lt;code&gt;Code[10]&lt;/code&gt; key), with real false-positive risk on legitimately multi-row tables that happen to end in "Setup."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are recorded in the research doc specifically so a future contributor doesn't have to re-derive them from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for the roasts
&lt;/h2&gt;

&lt;p&gt;Every AL Griller finding carries a joke, but the joke only exists because the pattern underneath it survived that filter. &lt;code&gt;ALGRILL003&lt;/code&gt; doesn't say "consider CalcSums." It says &lt;code&gt;CalcFields()&lt;/code&gt; "got summoned once per row like a tiny genie who can only grant one wish before vanishing back into the lamp, forever, on repeat" - and then, one click away under "Technical details," the actual mechanism: one SQL round trip per row vs. one aggregate query. The joke is decoration. The finding underneath has to survive the same bar CodeCop's own rules would.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this goes next
&lt;/h2&gt;

&lt;p&gt;BCQuality is an active, growing project, and AL Griller's rule set is meant to track it over time rather than freeze at v1.0.0. If you work in AL and know a pattern that should be a rule - or have a better roast for an existing one - PRs are genuinely welcome. New rules need the same false-positive discipline described above; new roasts just need to be specific to the pattern, not generic.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/yahyatouil-dev/al-griller" rel="noopener noreferrer"&gt;https://github.com/yahyatouil-dev/al-griller&lt;/a&gt;&lt;br&gt;
BCQuality (the research this is built on): &lt;a href="https://github.com/microsoft/BCQuality" rel="noopener noreferrer"&gt;https://github.com/microsoft/BCQuality&lt;/a&gt;&lt;br&gt;
Read More: &lt;a href="https://yahyatouil.com/posts/bcquality-for-business-central-how-to-use-it-with-ai-and-vs-code/" rel="noopener noreferrer"&gt;https://yahyatouil.com/posts/bcquality-for-business-central-how-to-use-it-with-ai-and-vs-code/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>opensource</category>
      <category>software</category>
      <category>vscode</category>
    </item>
    <item>
      <title>I built 7 VS Code tools for Business Central developers because the workflow pain was real</title>
      <dc:creator>Yahya Touil</dc:creator>
      <pubDate>Thu, 05 Mar 2026 20:26:32 +0000</pubDate>
      <link>https://dev.to/yahyatouil/i-built-7-vs-code-tools-for-business-central-developers-because-the-workflow-pain-was-real-4cgn</link>
      <guid>https://dev.to/yahyatouil/i-built-7-vs-code-tools-for-business-central-developers-because-the-workflow-pain-was-real-4cgn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Field 19 of 43. Typed by hand. From a JSON response.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That was the moment I stopped accepting the workflow and started building something better.&lt;/p&gt;

&lt;p&gt;Business Central development carries a lot of invisible overhead, and none of it is the hard part. It's the boilerplate, the folder setup, the JSON-to-AL mapping, the constant Postman context switching. Mechanical work that consumes focus without earning it.&lt;/p&gt;

&lt;p&gt;I spent six months building BC HERO: a free VS Code extension with seven tools that eliminate the most painful parts of the AL development workflow.&lt;/p&gt;

&lt;p&gt;What's inside:&lt;/p&gt;

&lt;p&gt;🗂️ Quick Project Setup - select your AL component folders, preview the structure, generate in one click. No more five-minute directory rituals.&lt;/p&gt;

&lt;p&gt;🧱 AL Object Creator - is a focused, single-screen workflow for creating a table and related objects. Configure the table, fields, and objects, then generate and review everything in one place.&lt;/p&gt;

&lt;p&gt;⚡ JSON → AL Generator - drop a JSON file (plain objects, arrays, OData { "value": [...] } all work). BC HERO infers AL types, lets you customize, outputs syntax-highlighted AL. 30 fields in about 3 minutes instead of 25.&lt;/p&gt;

&lt;p&gt;🔌 API Explorer - full HTTP client inside VS Code. Scans your workspace for API pages and queries. Basic Auth and OAuth 2.0. I haven't opened Postman for a BC project since I built this.&lt;/p&gt;

&lt;p&gt;🌍 Translation Assistant - visual XLIFF editor with progress bars, inline editing, validation, and batch updates. A 200-unit review cycle went from over an hour to under 20 minutes.&lt;/p&gt;

&lt;p&gt;📊 Schema Viewer - interactive force-directed graph of your table relationships with field metadata sidebar. First thing I open in an unfamiliar codebase.&lt;/p&gt;

&lt;p&gt;🔗 Dependency Graph - visualization of every object in your workspace, color-coded by type, with directed dependency edges.&lt;br&gt;
It's free and always will be.&lt;/p&gt;

&lt;p&gt;Full story and design rationale on my blog 👉 &lt;a href="https://yahyatouil.com/alhero" rel="noopener noreferrer"&gt;blog link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;VS Code Marketplace 👉 &lt;a href="https://marketplace.visualstudio.com/items?itemName=yahyatouil.bc-hero" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=yahyatouil.bc-hero&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub (issues, roadmap) 👉 &lt;a href="https://github.com/yahyatouil-dev/bc-hero-info" rel="noopener noreferrer"&gt;https://github.com/yahyatouil-dev/bc-hero-info&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vscode</category>
      <category>productivity</category>
      <category>businesscentral</category>
    </item>
  </channel>
</rss>
