Make the GL account-code check report instead of refusing to start

The check shipped in f753cae threw on a missing code, which core-dumped
erpcore.service on deploy: 11 of the 12 configured Gl*Code values turned
out never to have existed in GL's chart of accounts, so a long-standing
mismatch became an immediate outage.

Detection was the point; refusing to serve the rest of the app was not.
GL already rejects a posting to an unknown account, so the per-flow error
stays the real enforcement — this now logs the whole set at Error once at
boot instead of surfacing one flow at a time.

Hard-fail is still available behind
GeneralLedgerService:FailOnMissingAccountCodes, for once the chart of
accounts is known-good and drift should stop a deploy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 11:40:46 +05:30
parent b236b2b126
commit 9eab6372b3
2 changed files with 46 additions and 8 deletions
@@ -26,8 +26,12 @@ public class GlAccountCodeValidatorTests
await validator.StartAsync(CancellationToken.None);
}
/// <summary>
/// The default must not block startup. Throwing here cost an outage on 2026-10-07 — a config
/// mismatch that had existed all along became a core-dump the moment the check shipped.
/// </summary>
[Fact]
public async Task StartAsync_Throws_AndNamesEveryMissingCode()
public async Task StartAsync_DoesNotThrow_WhenCodesAreMissing_ByDefault()
{
var validator = CreateValidator(
new()
@@ -36,6 +40,22 @@ public class GlAccountCodeValidatorTests
["SalesDayEnd:GlCashAccountCode"] = "1000-01",
["Adjustment:GlLossAccountCode"] = "5100"
},
new StubGl(["1000-01"]));
await validator.StartAsync(CancellationToken.None);
}
[Fact]
public async Task StartAsync_Throws_AndNamesEveryMissingCode_WhenConfiguredToFail()
{
var validator = CreateValidator(
new()
{
["GeneralLedgerService:FailOnMissingAccountCodes"] = "true",
["Grn:GlInventoryAccountCode"] = "1100",
["SalesDayEnd:GlCashAccountCode"] = "1000-01",
["Adjustment:GlLossAccountCode"] = "5100"
},
new StubGl(["1100"]));
var ex = await Assert.ThrowsAsync<InvalidOperationException>(
@@ -43,6 +63,7 @@ public class GlAccountCodeValidatorTests
Assert.Contains("1000-01", ex.Message);
Assert.Contains("5100", ex.Message);
Assert.Contains("2 of 3", ex.Message);
Assert.DoesNotContain("1100,", ex.Message);
}