Each DA row corresponds to one detection rule or analytical capability. Priority follows MoSCoW: Must (launch-blocking), Should (high value, planned), Could (nice-to-have), Won't (out of scope).
| ID | Title | Description | Priority | Phase | Status |
|----|-------|-------------|----------|-------|--------|
| DA-001 | XAF Ingestion | Parse XAF-format auditfile XML into internal GL transaction model. | Must | 1 | Shipped |
| DA-002 | CSV GL Ingestion | Import general-ledger CSV exports (configurable column mapping). | Must | 1 | Shipped |
| DA-003 | Population Analysis Dashboard | Overview screen showing flagged-transaction counts per category with drill-down. | Must | 1 | Shipped |
| DA-004 | ROUND_AMOUNTS Detection | Flag transactions whose debit or credit amount is divisible by a configurable divisor (default 1 000). NV COS anchor (datadump 2026-09-03): NV COS 240 §A44(e) names entries "die ronde getallen bevatten of op telkens dezelfde eindcijfers eindigen" (round numbers or consistently repeated ending digits) as a characteristic of fraudulent journal entries — direct standard-text basis for this check. | Must | 1 | Shipped |
| DA-005 | GL-to-Trial-Balance Reconciliation | Cross-check sum of GL postings per account against uploaded trial balance; surface variances. NV COS anchor (datadump 2026-09-03): NV COS 330 §20(a) requires in every audit ("dient in ieder geval") that the auditor agrees or reconciles the financial statements with the underlying accounting records — this check automates a mandatory substantive procedure, not an optional CAAT. | Must | 1 | Shipped |
| DA-006 | WEEKEND_ENTRIES Detection | Flag journal entries posted on Saturday or Sunday. NV COS note (datadump 2026-09-03): weekend posting is not itself named among the fraudulent-JE characteristics of NV COS 240 §A44; the anchor is §33(a)(iii) — the auditor must consider testing journal entries made throughout the period — for which full-population timing screens per NBA Handreiking 1141 are a recognized selection approach. | Must | 1 | Shipped |
| DA-007 | UNUSUAL_USERS Detection | Flag entries posted by user accounts that appear in fewer than a configurable % of total postings. NV COS anchor (datadump 2026-09-03): NV COS 240 §A44(b) names entries "verricht door personen die gewoonlijk geen journaalboekingen verrichten" as a fraudulent-JE characteristic — direct standard-text basis for this check. | Must | 1 | Shipped |
| DA-008 | POTENTIAL_DUPLICATES Detection | Flag entries with identical account, date, amount, and description. | Must | 1 | Shipped |
| DA-009 | LARGE_ENTRIES Detection | Flag entries whose absolute amount exceeds a configurable materiality threshold. | Must | 1 | Shipped |
| DA-010 | CUTOFF_EXCEPTIONS Detection | Flag entries dated within a configurable window of business days before or after the period-end date. | Must | 1 | Shipped |
| DA-019 | ADMIN_ENTRIES Detection | Flag entries created by recognized administrator/superuser accounts (distinct from UNUSUAL_USERS). | Should | 2 | Shipped |
| DA-020 | LOW_ACTIVITY_ACCOUNTS Detection | Flag entries posted to GL accounts with posting frequency below the population average. NV COS anchor (datadump 2026-09-03): NV COS 240 §A44(a) names entries posted to accounts that are "ongebruikelijk ... of zelden worden gebruikt" (unusual or seldom-used accounts) as a fraudulent-JE characteristic — direct standard-text basis for this check. | Should | 2 | Shipped |
| DA-025 | BLOCKED (Invoice Sequence) | Sequence-gap analysis on invoice numbers. Blocked: no invoice-number field in current XAF DTOs; requires schema extension. | Won't | — | Blocked |
| DA-026 | DUPLICATE_AMOUNT_DATE Detection | Flag entries sharing the same account, date, and amounts regardless of description text. | Should | 2 | Shipped |
| DA-027 | FUZZY_DUPLICATES Detection | Flag near-identical entries using Levenshtein description similarity ≥ 0.75 and amount within 1% tolerance. | Should | 2 | Shipped |
| DA-029 | Configurable Round-Amount Divisor | Expose round-amount divisor via GET/PUT /api/analysis/settings; backed by AnalysisSettingsService. | Should | 2 | Shipped |
| DA-030 | Credit-Side Population Filter | ?creditOnly=true query parameter on category drill-down and export endpoints; toggle in frontend. | Should | 2 | Shipped |
| DA-031 | Revenue-Account Filter | Exclude revenue-account postings from population; requires revenue-account mapping input. Implemented as a per-session mapping (PUT /api/analysis/{id}/account-type-mapping, revenueAccountIds) plus an excludeRevenue=true query parameter on the summary, category drill-down and export endpoints; the analysis is re-run on the reduced population. Frontend: mapping form on the dashboard and an "Exclude revenue accounts" toggle next to the period filter. | Could | 3 | Shipped |
| DA-032 | Expense-Account Filter | Exclude expense-account postings from population; requires account-type mapping input. Shares the DA-031 account-type mapping (expenseAccountIds) and adds an excludeExpense=true query parameter on the same endpoints; both filters combine with each other and with the from/to period window. | Could | 3 | Shipped |
| DA-033 | Materiality Threshold Engine | Weighted risk score per entry combining flag count, amount, and account type; configurable weight matrix. Implementation: weightedRiskScore = (flagCountWeight × triggered flags + amountWeight × min(amount ÷ materiality, 1)) × accountTypeMultiplier[BALANCE \| PROFIT_LOSS \| UNKNOWN], with the account class derived from the GL accountType (B/Balance/Activa/Passiva → BALANCE, P/P&L/W&V → PROFIT_LOSS). The materiality reference is the configured engagement materiality (materialityThreshold in /api/analysis/settings), falling back to the population's 95th-percentile amount when not set. highRisk is now derived from the weighted score (≥ highRiskScoreThreshold, default 2.0) instead of the fixed "≥ 2 flags" v0 rule; drill-down lists and the PDF top-list are ranked by weighted score. Weight matrix (flag weight, amount weight, per-class multipliers, high-risk threshold) is editable in the dashboard Analysis Settings panel. | Should | 3 | Shipped |
| DA-035 | Configurable Cut-off Window | Expose cut-off business-day window via settings endpoint (athena.analysis.cutoff-window-business-days). | Should | 2 | Shipped |
| DA-036 | Benford's Law Digit-Distribution Analysis | Compute the observed first-digit distribution of all debit/credit amounts and compare it against the Benford expected distribution (P(d) = log₁₀(1 + 1/d)). Flag the population when the chi-squared statistic or per-digit Z-score indicates a statistically significant deviation (p < 0.05). Surface per-digit observed vs. expected chart in the dashboard. Standard CAAT per ISA 240 / AICPA SAS 99 / ISACA GTAG 16. NV COS refinement (datadump 2026-09-03): digit-pattern screening operationalizes NV COS 240 §A44(e) (round numbers / repeated ending digits as fraudulent-JE characteristic). When Benford output is relied on as a substantive analytical procedure, NV COS 520 §5 applies: evaluate the reliability of the underlying data (§5(b)), establish that the expectation is precise enough to identify a material misstatement (§5(c)), and predefine the acceptable difference (§5(d)) — the chi-squared p < 0.05 cutoff is that §5(d) parameter and should be documented as such. Per §7, significant deviations require inquiry of management plus additional procedures: a Benford flag is a trigger for follow-up, not a conclusion. | Should | 2 | Shipped |
| DA-037 | Journal/Voucher Sequence Gap Detection | Sort GL transactions by journal ID (JrnId) or voucher number (VouNr) and detect non-consecutive steps (gaps) as well as duplicate sequence numbers. Each gap or duplicate is surfaced as a flagged finding. Gaps may indicate deleted or suppressed postings; duplicates may indicate double-posting. Standard completeness CAAT per ISACA and AICPA guidance. Feasible with current XAF data (JrnId present); distinct from DA-025 which requires invoice-number fields absent from source DTOs. | Should | 2 | Shipped |
| DA-082 | XLSX Category Export | GET /api/analysis/{id}/categories/{category}/export returns an Apache POI .xlsx file with all flagged transactions; frontend "Export XLSX" button triggers download. | Should | 2 | Shipped |
| DA-038 | XFC Compressed Auditfile Ingestion | Accept .xfc files (ZIP archives containing one or more .xaf files), transparently decompressing them before ingestion. If the archive is password-protected (e.g. exports from Multivers, AFAS Small Business), prompt the user for the password. Reject Belastingdienst-certificate-encrypted XFCs with a clear error message explaining they cannot be opened without the tax authority's private key. As observed on fiba.nl/auditfile: XFC is the standard export format of several Dutch accounting packages and is commonly encountered in practice. | Should | 3 | Shipped |
| DA-039 | Kolommenbalans Report | Present a cross-reference trial balance per GL account for a user-selected period range. Columns: GL code, account description, account type (Activa/Passiva/W&V), opening balance, total debit mutations, total credit mutations, closing balance. The user can filter by period (from–to), toggle inclusion of the opening balance, and switch to RGS-grouped view when RGS codes are present (XAF 4.0). The report is exportable as CSV/Excel and printable. As observed on fiba.nl viewer at /kolommenbalans. | Should | 3 | Shipped |
| DA-040 | Periodebalans Report | Present a period-by-period balance evolution table: one row per GL account (same columns as Kolommenbalans) with one additional column per accounting period (month, quarter, or year — user-selectable granularity via a Weergave dropdown). The user selects a from–to period range; the table scrolls horizontally when many periods are present. Opening balance toggle and RGS view toggle included. Exportable as CSV/Excel, printable. As observed on fiba.nl viewer at /periodebalans. | Should | 3 | Shipped |
| DA-041 | Balans per Dagboek Report | Present the GL balance broken down by journal (dagboek): one row per GL account, one column per journal type present in the auditfile (e.g. Bank, Inkoop, Memoriaal, Verkoop) identified by their journal code and description, plus opening balance and totaal columns. Individual journals can be toggled on/off via filter chips. Period filter (from–to) and opening balance toggle included. Exportable as CSV/Excel, printable. As observed on fiba.nl viewer at /journaalbalans. | Should | 3 | Shipped |
| DA-042 | Balans per BTW-code Report | Present GL account balances broken down by VAT code (BTW-code): one row per GL account that has VAT-coded postings, one column per BTW code present in the auditfile (e.g. BTW Hoog 21%, BTW Verlegd EU), plus a Totaal column. Period filter (from–to) included. Exportable as CSV/Excel, printable. As observed on fiba.nl viewer at /btwbalans. Belastingdienst note (2026-09-03, ODB scrape): the Belastingdienst's own ODB auditfile page designates the open-source Analytics Library check "H004 aansluiting aangifte btw" as the standard XAF-based BTW analysis and notes it works optimally when both XAF 3.2 and RGS 3.0 are present — the per-BTW-code balances this report produces are exactly the input needed to reconcile GL VAT against the filed btw-aangifte, so the report should present per-code totals in a form comparable to the aangifte (source: odb.belastingdienst.nl/auditfiles/oproep-tot-implementeren-van-auditfile-financieel-xaf3-2-met-rgs/; github.com/AnalyticsLibrary/Analytics/wiki/H004-aansluiting-aangifte-btw). The official tariff structure defines the expected BTW-code groups: 21% (algemeen), 9% (verlaagd), 0% (export/douane-entrepot and grensoverschrijdend vervoer), vrijgesteld, and verlegd (source: belastingdienst.nl "Tarieven en vrijstellingen"). A discrepancy between GL VAT and the filed return must legally be corrected via the Suppletie btw form, so suppletie postings in the GL signal prior-period VAT corrections worth auditor attention (source: belastingdienst.nl "Btw-aangifte corrigeren" / "Toelichting bij de suppletie btw"). SBR-XAF koppeling — leadCode/RGS bridge (ODB platform meeting minutes 2014, datadump 2026-09-04): The 2014 ODB platform meeting on SBR linkage in XAF (source: 2014_02_19_n.a.v._de_bijenkomst_SBR_koppeling_in_Auditfile_Financieel.pdf, odb.belastingdienst.nl/auditfiles/verslagen-en-presentaties-auditfiles/) confirmed that the XAF generalLedger header elements leadCode (SBR rapportage-groepcode) and leadDescription are the formal SBR bridge for BTW-aangifte group mapping at the account level. RGS (Referentie Grootboekschema) was established as the canonical intermediary: ERP account codes are RGS-classified at the rubriek and transaction level, enabling automated aggregation to SBR aangifte groups. The meeting noted that in 2014, Dutch ERP vendors implemented the SBR-XAF bridge inconsistently — some via the leadCode header path, others via per-transaction BTW code fields — which is the root reason why the H004 check (cited above) requires BOTH XAF 3.2 AND RGS 3.0 to work optimally: the RGS codes provide the structured classification that resolves the ambiguity in the leadCode path. For XAF files without RGS codes (pre-3.2 or 3.2 exports without RGS enabled), the BTW reconciliation report should fall back to per-transaction BTW code aggregation alone, with a disclosed caveat that the mapping to aangifte-groups is unverified. | Could | 3 | Shipped |
| DA-043 | Grootboekkaart — GL Account Drill-down | Provide a searchable list of all GL accounts in the left panel; selecting an account shows all individual journal postings for that account in a sortable, filterable table (columns: date, journal, voucher number, description, debit amount, credit amount, running balance). Filters: period from–to, journal type. Exportable as CSV/Excel. As observed on fiba.nl viewer at /grootboek. | Should | 3 | Shipped |
| DA-044 | Relatiekaart — Counterparty Drill-down | Provide a searchable list of all relations (klanten, leveranciers, overige) extracted from the auditfile; selecting a relation shows all journal postings attributed to that counterparty (date, GL account, description, debit, credit). Period filter included. Exportable as CSV/Excel. As observed on fiba.nl viewer: Relatiekaarten section in sidebar. | Should | 3 | Shipped |
| DA-045 | Stamgegevens Master Data Browser | Surface the master data embedded in the XAF file as searchable, browseable tables accessible via a Stamgegevens section: (a) Bedrijfsgegevens — company name, fiscal number, KvK number, address, software package name, XAF version, boekjaar, start date, end date; (b) Rekeningen — full chart of accounts with code, description, account type, RGS code if present; (c) Relaties — counterparty list with name, type, address, VAT number; (d) BTW — VAT codes with description and rate; (e) Perioden — accounting periods with start/end dates. Each table is searchable and exportable. As observed on fiba.nl viewer: Stamgegevens section in sidebar and company info screen. | Should | 3 | Shipped |
| DA-046 | Financial KPI Dashboard Tiles | Add a Financial Summary section to the main Athena dashboard, derived directly from the ingested GL data: (a) Balansstatus — indicates whether the loaded auditfile balances (total debit mutations = total credit mutations); (b) account count, booking count, relation count; (c) nettoresultaat — net result for the period (revenue accounts sum minus cost accounts sum); (d) Activa / Passiva totals with opening-balance and mutation sub-totals; (e) Resultaatrekeningen — cost (D) vs revenue (C) totals. As observed on fiba.nl viewer /dashboard KPI tile row and "Verdeling rekeningen" panel. | Should | 3 | Shipped |
| DA-047 | Top Customers and Suppliers by Volume | Show, in the dashboard or a dedicated analysis screen, the top-N relations by revenue (credit-side postings on revenue/sales accounts) and the top-N suppliers by cost (debit-side postings on expense accounts), with booking count and total amount per relation. N is configurable (default 10). Clicking a relation navigates to its Relatiekaart drill-down (DA-044). As observed on fiba.nl viewer /dashboard "Top 10 klanten op omzet" and "Top 10 leveranciers op kosten" panels. | Could | 3 | Shipped |
| DA-048 | Revenue / Cost / Result Trend Chart | Show a bar + line combination chart of revenue (omzet), costs (kosten), and net result (resultaat) per accounting period for the loaded auditfile. The user selects the period range (from–to). Useful for spotting seasonal patterns or sudden anomalies before drilling into JET detection. As observed on fiba.nl viewer /dashboard "Trend omzet & kosten per periode" chart. | Could | 3 | Shipped |
| DA-049 | Financial Ratio Analysis (Kengetallen) | Compute and display standard financial ratios from the loaded GL data, including but not limited to: current ratio, solvency ratio, gross margin, and debtor/creditor days. Ratios are computed from Activa, Passiva, and W&V accounts using RGS classification when available (XAF 4.0) or user-configured account-type mapping otherwise. A period filter and RGS tab selector are provided. A note is shown that ratios are indicative and require a full opening balance for accuracy. As observed on fiba.nl viewer /dashboard "Kengetallen" section with RGS and period tabs. | Could | 4 | Shipped |
| DA-050 | RGS Category Dashboard (XAF 4.0) | When the loaded auditfile contains RGS codes (present in XAF 4.0 exports), detect them and display a categorized RGS summary dashboard grouping balance sheet accounts by main RGS category (Activa, Passiva, Eigen Vermogen) and P&L accounts by RGS category (Omzet, Kosten). Each category shows a subtotal with drill-down to constituent accounts. A RGS-weergave toggle on the Kolommenbalans and Periodebalans reports switches between raw account order and RGS-grouped order. As observed on fiba.nl viewer: RGS-weergave button on /kolommenbalans and /periodebalans, and RGS tab on /dashboard Kengetallen. RGS publication status and XAF 4.0 development timeline (ODB Plenaire Auditfileplatform 2018, datadump 2026-09-04): The 2018 Plenaire Auditfileplatform meeting (source: Concept-Verslag-Plenaire-Auditfileplatform-vergadering-2018-06-14.pdf, odb.belastingdienst.nl/auditfiles/verslagen-en-presentaties-auditfiles/) confirmed that RGS 3.x was published on GitHub by the SBR/RGS organisation, making it publicly downloadable and verifiable. At that point XAF 4.0 — which makes RGS codes a structured first-class element rather than an optional string — was in active development and had not yet reached its final Publicatie phase in the Auditfileplatform roadmap. This confirms why the when the loaded auditfile contains RGS codes guard in this check's implementation is correct: XAF 3.2 introduced RGS as optional, and XAF 4.0 mandatory-RGS files are not yet the population norm. The check must remain gracefully optional rather than treating absent RGS codes as a data error. | Should | 3 | Shipped |
| DA-051 | Memorial / Journal Entries Viewer | Present all postings from the memoriaaldagboek (memorial journal) in a dedicated, searchable table with columns: date, voucher number, description, GL account, debit, credit, posting user. Filterable by period and searchable by description or account; exportable as CSV/Excel. As observed on fiba.nl viewer: "Memoriaal" section under AANVULLINGEN in the sidebar, and "Memoriaalboeking" screenshot on fiba.nl/auditfile. | Should | 3 | Shipped |
| DA-052 | Manual Adjusting Journal Entries | Allow auditors to record their own adjusting entries on top of the ingested auditfile data (balanced debit/credit pairs with date, description, and account assignment). Adjusting entries are stored separately from the original XAF data and are never written back to the source file. Their effect on balance reports (DA-039 through DA-041) can be toggled on/off via an "include adjustments" switch. Enables what-if analysis during the audit without altering the evidential record. As observed on fiba.nl desktop viewer: users can add memoriaalboeking entries that are saved in the viewer's project file alongside the original auditfile. | Could | 4 | Shipped |
| DA-083 | Statistical Amount Outlier Detection (Z-Score / IQR) | Complement the Benford first-digit test (DA-036) with per-entry amount outlier detection using two industry-standard statistical methods: (1) Z-score — compute the mean and standard deviation of absolute transaction amounts per GL account; flag entries whose Z-score exceeds a configurable threshold (default: 3.0σ). (2) IQR — compute Q1 and Q3 of absolute amounts per GL account; flag entries outside the fence Q1 − 1.5×IQR / Q3 + 1.5×IQR. Both methods run per account and across the full population; results are surfaced as a flagged category with per-entry drill-down. The configurable grouping dimension (per account vs. population-wide) allows auditors to tune sensitivity. Acceptance criteria: (a) given a population with a known outlier injected, the outlier is flagged; (b) a population of normally distributed amounts with no injected outlier produces zero flags at the 3σ threshold; (c) Z-score and IQR thresholds are independently configurable via the analysis settings endpoint (DA-029). Standard CAAT per AICPA audit data analytics guide and IDEA/ACL default test set. NV COS refinement (datadump 2026-09-03): NV COS 315 (automated tools and techniques guidance) recognizes analyzing "grote aantallen gegevens (van het grootboek, subgrootboeken of andere operationele gegevens)" as a risk-assessment procedure; per NBA Handreiking 1141, observations from such analyses must themselves be validated and followed up — outlier flags are risk-assessment input, not audit evidence of misstatement. Data model: uses debitAmount, creditAmount, accountId from TransactionDto. Fully supported — no data gaps. | Should | 3 | Shipped |
| DA-084 | Dutch Public Holiday Posting Detection | Extend the weekend-entry test (DA-006) to cover the full set of Dutch statutory public holidays: Nieuwjaarsdag (Jan 1), Goede Vrijdag (computed — Friday before Easter), Eerste and Tweede Paasdag (computed — Easter Sunday/Monday), Koningsdag (Apr 27, or Apr 26 when Apr 27 is Sunday), Bevrijdingsdag (May 5), Hemelvaartsdag (computed — 39 days after Easter), Eerste and Tweede Pinksterdag (computed — 49/50 days after Easter), Eerste and Tweede Kerstdag (Dec 25–26). Holiday dates are computed algorithmically for the fiscal year in the auditfile header; no external calendar dependency. Entries on a statutory holiday are surfaced as a distinct flagged category (separate from WEEKEND_ENTRIES) with configurable suppression of individual holidays. Acceptance criteria: (a) a transaction dated Apr 27 in a non-Sunday year is flagged; (b) a transaction dated Apr 26 in a year where Apr 27 falls on Sunday is flagged; (c) a transaction dated a normal weekday is not flagged; (d) the holiday set is derived from HeaderDto.fiscalYear, requiring no user input. Standard CAAT per AICPA SAS 99. Citation correction (NV COS 240 full text, datadump 2026-09-03): in the current NV COS 240 the journal-entry-testing requirement is §33(a), not §32: §33(a)(ii) mandates selecting entries made at period-end and §33(a)(iii) requires considering entries made throughout the period — holiday screening is a §33(a)(iii) selection filter. The §A44 characteristics list targets period-end/post-closing timing; posting on an unusual calendar date per se is firm methodology, not literal standard text. Data model: transactionDate (LocalDate) and HeaderDto.fiscalYear are sufficient. Fully supported — no data gaps. | Should | 3 | Shipped |
| DA-085 | Manual Entry Dominance and Concentration Analysis | Analyze the proportion and concentration of manual journal entries (TransactionDto.manualEntry = true) in the loaded population. Compute: (a) manual entry rate for the full population (count and % of total); (b) manual entry rate per GL account — flag accounts where manual entries exceed a configurable threshold (default: 20% of that account's total postings); (c) manual entry rate per calendar period — flag periods where manual entries spike relative to the population average (e.g., last month of the fiscal year). Surface results as a dedicated dashboard tile showing the population-level rate and a drillable list of flagged accounts and periods. Distinct from DA-019 (ADMIN_ENTRIES), which identifies who posts; this check identifies how many entries are manual vs. system-generated and where they concentrate. Citation correction (NV COS 240 full text, datadump 2026-09-03): the "§32(b)" reference is inaccurate — in the current NV COS 240, §33(b) covers the review of estimates for management bias, not manual entries. The manual-entry scoping anchor is the §33(a) journal-entry-testing requirement plus §A44, which notes that journal-entry processing can involve "zowel handmatige als geautomatiseerde werkzaamheden" and that non-standard journal entries may be subject to less control than recurring system entries; understanding the manual entry volume is a prerequisite for scoping that test. Standard CAAT per AICPA analytics guidance and ISACA GTAG 16. Data model: manualEntry (boolean) is present in TransactionDto. Fully supported — no data gaps. | Should | 3 | Shipped |
| DA-086 | Abnormal Posting Direction Detection (Account-Type Violations) | Flag journal entries where the posting direction (debit vs. credit) is inconsistent with the account's normal balance side as defined by its accountType. Asset and expense accounts (accountType = "Activa" or expense classification) normally carry debit balances — flag significant standalone credit postings to those accounts. Liability, equity, and revenue accounts (accountType = "Passiva" or W&V) normally carry credit balances — flag significant standalone debit postings to those accounts. An amount threshold (configurable, default: materiality threshold from DA-033 if set, otherwise 0) suppresses noise from small contra-balance entries (e.g., accumulated depreciation corrections). Acceptance criteria: (a) a credit entry to an asset account above the threshold is flagged; (b) a debit entry to a revenue account above the threshold is flagged; (c) entries below the threshold are not flagged; (d) accounts with unknown accountType are excluded from this check with a data-quality warning. Standard CAAT per IDEA/ACL "posting to inappropriate account" test and ISACA GTAG 16. Data model: accountType from GeneralLedgerAccountDto joined to accountId in TransactionDto. Fully supported — no data gaps. | Should | 3 | Shipped |
| DA-087 | Same-Day Reversal Entry Detection | Flag pairs of journal entries that are potential same-day reversals: same accountId, same transactionDate, where one entry has a debit amount and the other has a credit amount within a configurable tolerance of the same absolute value (default: exact match; optional 1% tolerance). Same-day reversals may indicate error correction or management override via the create-reverse-repost pattern. Citation correction (NV COS 240 full text, datadump 2026-09-03): the current NV COS 240 does not name reversing entries anywhere — its §A43 concerns override of automated journal-entry processing. Anchor this check on the §33(a) journal-entry-testing requirement and the §A44 characteristics instead, and drop the "§A43 reversing entries" reference. Each flagged pair is presented with both entries side by side. The check does not suppress reversals that share the same transactionId (those are expected balanced journal entry lines); it targets cross-transactionId reversals on the same day. Acceptance criteria: (a) two entries with the same account, same date, one debit 1000 and one credit 1000, different transactionIds, are flagged as a pair; (b) two entries that are lines of the same journal entry (same transactionId) are not flagged; (c) a debit of 1000 and a credit of 1005 are flagged only when tolerance ≥ 0.5%; (d) entries on different dates are not flagged. Standard CAAT per AICPA analytics guidance and ACFE fraud examiner guide. Data model: transactionDate, accountId, debitAmount, creditAmount, transactionId from TransactionDto. Fully supported — no data gaps. | Should | 3 | Shipped |
| DA-088 | Threshold-Avoidance Transaction Splitting Detection | Flag multiple entries to the same GL account within a configurable time window (default: same calendar day) whose individual amounts each fall below a configurable authorization threshold but whose aggregate amount on that account that day exceeds the threshold. This pattern — known as structuring or smurfing in fraud literature — is used to circumvent per-transaction approval limits. Parameters: authorization threshold (default: value from DA-009 LARGE_ENTRIES threshold), time window in days (default: 1), minimum number of entries required to trigger the flag (default: 3). Each flagged group is presented with all constituent entries and the aggregate total. Acceptance criteria: (a) five entries of 900 on the same account on the same day, with threshold 1000, are flagged as a group with aggregate 4500; (b) two entries of 900 on the same account on the same day (below the minimum count of 3) are not flagged; (c) five entries of 900 spread across five different accounts on the same day are not flagged; (d) the threshold and window are independently configurable via the analysis settings endpoint (DA-029). Standard CAAT per ACFE fraud examiner guide chapter on asset misappropriation and AICPA SAS 99 §83. Data model: transactionDate, accountId, debitAmount, creditAmount from TransactionDto. Fully supported — no data gaps. | Should | 3 | Shipped |
| DA-089 | End-of-Period Transaction Volume Concentration | Analyze the temporal distribution of journal entries across the fiscal year and flag populations where an abnormally high proportion of entries or monetary value is concentrated in the final N business days of the period. Compute: (a) percentage of total entry count and total debit+credit value posted in the last N business days of the fiscal year (N configurable, default 5); (b) compare that percentage against the population average for an equivalent N-day window earlier in the year; (c) flag when the final-window percentage of total value exceeds a configurable threshold (default: 2.5× the average N-day window value from earlier in the period). Surface as a timeline bar chart (entries per week across the fiscal year) with the final-window bar highlighted, plus the computed concentration ratio. Distinct from DA-010 (CUTOFF_EXCEPTIONS), which flags individual entries dated near period-end based on a fixed calendar window; this check measures the aggregate concentration of the full population as an indicator of period-end earnings manipulation or premature revenue recognition. Citation refinement (NV COS 240 full text, datadump 2026-09-03): NV COS 240 §33(a)(ii) makes selecting period-end journal entries mandatory in every audit ("dient ... een selectie te maken van journaalboekingen en andere aanpassingen die aan het einde van een verslagperiode zijn aangebracht"), and §A45 notes fraudulent entries are often posted at period-end — this check scopes that mandatory selection; replace the "§32" citation with §33(a)(ii)/§A45. AICPA SAS 99 §66 identifies unusual timing concentrations as fraud indicators. Data model: transactionDate (LocalDate), HeaderDto.startDate, HeaderDto.endDate, debitAmount, creditAmount from TransactionDto and HeaderDto. Fully supported — no data gaps. | Should | 3 | Shipped |
| DA-090 | Zero-Amount and Null-Value Entry Detection | Flag journal entries where both debitAmount and creditAmount are zero, null, or below the currency's minimum unit (< 0.01 for EUR). Zero-amount entries have no effect on account balances but indicate data quality issues: test or placeholder entries left in the production GL, incomplete imports, or system errors during migration. Surface as a data quality category in the dashboard tile row alongside other flag categories; provide a drillable list of all zero-amount entries with their accountId, date, transactionId, and description. Acceptance criteria: (a) an entry with debitAmount = 0 and creditAmount = 0 is flagged; (b) an entry with debitAmount = null and creditAmount = null is flagged; (c) an entry with debitAmount = 0 and creditAmount = 100 is not flagged (one side is non-zero); (d) an entry with debitAmount = 0.005 (below EUR minimum unit) and creditAmount = 0 is flagged. Standard data quality CAAT per ISACA GTAG 16 §3.2 and IDEA default test "Zero-amount transactions". Data model: debitAmount, creditAmount from TransactionDto. Fully supported — no data gaps. | Could | 3 | Shipped |
| DA-091 | Net-Flow Circular Account Pair Detection | Detect account pairs (A, B) where, within the fiscal period, there are flows from A to B in one direction AND approximately equal flows from B to A in the other direction — a pattern consistent with round-trip or fictitious transactions. Flows between accounts are inferred from the flat XAF model by grouping transaction lines by transactionId: a journal entry (same transactionId) containing a debit on account A and a credit on account B represents a flow from B to A (conventional double-entry direction). For each ordered account pair, compute the net debit and net credit flows across all journal entries in the period. Flag pairs where both directions have aggregate flows exceeding a configurable threshold (default: 10× the average single-entry amount) and the net round-trip amount (min of the two direction totals) exceeds materiality. Surface flagged pairs with constituent journal entries listed. Acceptance criteria: (a) a set of journal entries where account 1000 consistently debits account 2000 and a separate set where account 2000 consistently debits account 1000, both above threshold, are flagged as a circular pair; (b) a normal payable cycle (AP credits, bank debits) where flows are all in one direction is not flagged; (c) the threshold is configurable via the analysis settings endpoint. Assumption: lines of the same journal entry share the same transactionId in the flat XAF model. Standard CAAT per ACFE fraud examiner guide on fictitious/related-party transactions. NV COS anchor (datadump 2026-09-03): NV COS 315 (automated tools and techniques examples) explicitly describes using automated techniques to identify "een rekening met een nul-saldo aan het einde van de verslagperiode [die] bestond uit talrijke compenserende transacties en journaalboekingen" — precisely the offsetting-flow pattern this check detects. Data model: transactionId, accountId, debitAmount, creditAmount from TransactionDto. Feasible with current flat model — no data gaps, provided transactionId groups double-entry lines of the same posting. | Could | 4 | Shipped |
| DA-092 | After-Hours Posting Time Detection | Flag journal entries posted outside normal business hours (configurable window, e.g., before 07:00 or after 19:00 local time). After-hours posting is one of the first checks run by tools such as CaseWare IDEA and MindBridge. Citation correction (NV COS 240 full text, datadump 2026-09-03): time-of-day posting is not mentioned anywhere in the current NV COS 240 (§A44 covers period-end timing, not clock time); the correct anchor is the general §33(a) journal-entry-testing requirement. The data-gap conclusion below is unchanged. Data gap — not implementable with current model. TransactionDto.transactionDate is a LocalDate (date only). The XAF 3.2 standard's <trDt> element is typed as xs:date (no time component); there is no posting-time field in the XAF standard. Implementing this check would require an alternative data source (e.g., ERP system transaction logs from SAP, Exact, or AFAS that include a separate creation timestamp). This item is recorded to document the gap. No implementation is possible until a source with time-of-day data is available. Status: Candidate — blocked by fundamental XAF standard data gap (not an Athena model limitation — the source standard does not carry posting time). | Should | — | Candidate |
| DA-093 | Segregation-of-Duties — Same-User Post-and-Approve Detection | Flag instances where the same user identity appears to have both initiated and approved a transaction — a classic SoD violation per ISACA GTAG 14 and COSO internal control framework. A full SoD check requires an approver or authorizedBy field in addition to the creator field. Partial data support. TransactionDto has createdBy (the posting user) but no approvedBy, authorizedBy, or supervisorId field. The XAF 3.2 standard does not include an approver element; only the userID (creator) is standardized. A proxy check is feasible with current data: flag journal entries (grouped by transactionId) where the same createdBy user posts to both an accounts-payable or expense account AND a cash/bank account within the same journal entry, which may indicate the same person initiating and settling a payment without independent approval. This proxy has limited precision; it produces false positives where one person legitimately handles both sides (e.g., sole traders). NV COS refinement (datadump 2026-09-03): NV COS 315 itself notes that functiescheiding may be impracticable in less complex entities, where the eigenaar-bestuurder can compensate through direct oversight — confirming this caveat from the standard text; consider down-weighting or suppressing the proxy flag when the population profile indicates an owner-managed entity (e.g., a single posting user). Controls over journal entries are identified per NV COS 315 §26(a)(ii) (cross-referenced from NV COS 240). Acceptance criteria for the proxy check: (a) a journal entry with the same createdBy posting a debit to an expense account and a credit to a bank account is flagged; (b) journal entries by different users on both sides are not flagged. A full SoD check (creator ≠ approver) is recorded here as a long-term goal requiring an XAF schema extension or an alternate ERP data source with approval metadata. Status: Candidate — proxy check feasible now; full check blocked by XAF standard data gap (no approver field). | Should | 4 | Shipped |
| DA-094 | Restricted-Account Detection (G-rekening / Escrow / Waarborgrekeningen / Derdengelden) | From Document1.docx Stap 8 — Liquide Middelen audit workflow authored by the owner. Per ISA 500 §§8–9 and Dutch NV COS 500, the auditor must determine whether cash and bank balances are freely available (vrij beschikbaar) or restricted, and ensure restricted balances are separately presented on the balance sheet and excluded from available liquidity. Restricted account types in Dutch practice: G-rekeningen (tax-authority-blocked accounts under the Wet Keten- en Inlenersaansprakelijkheid, used by subcontracting chains); escrow accounts; waarborgrekeningen (deposit / guarantee accounts); geblokkeerde rekeningen (blocked by court order, bank covenant, or regulatory authority); derdengelden accounts (third-party client funds held by notaries, lawyers, etc. under Wwft). For each identified restricted account: determine the nature of the restriction, assess whether the balance is freely available, and flag it for separate balance-sheet presentation. Acceptance criteria: (a) when the user uploads a list of restricted GL account codes (or marks accounts as restricted during auditfile configuration), those accounts appear in a dedicated "Restricted Accounts" section of the Liquide Middelen analytical view showing the account code, restriction type (user-selected from the list above), closing balance, and a "vrij beschikbaar: Ja/Nee" indicator; (b) the system computes a "restricted liquidity total" and a "freely available liquidity total" and surfaces both in the Liquide Middelen summary; (c) an account whose description contains a keyword from a configurable list (default: "g-rekening", "escrow", "waarborg", "derdengeld", "geblokkeerd") is automatically suggested as a restricted account, pending user confirmation; (d) when no restricted accounts are identified or configured, the check produces an explicit "geen beperkte rekeningen vastgesteld" conclusion rather than zero output. Data model assessment — partial data gap. GeneralLedgerAccountDto.accountDescription is available for keyword heuristics, but there is no structured restrictionType or isRestricted field in the XAF 3.2 standard or the current Athena data model. A reliable implementation requires either (a) a user-provided list of restricted account codes uploaded alongside the auditfile, or (b) a new restrictionType field added to GeneralLedgerAccountDto, populated from user input during auditfile configuration. Keyword heuristics on accountDescription are feasible as a first-pass suggestion only. This requirement was previously identified as out-of-scope; it is elevated here to a documented Must-have based on the owner's Liquide Middelen workflow. Statutory anchor + citation correction (BW2 Titel 9 / NV COS 500 full text, datadump 2026-09-03): art. 2:372 lid 1 BW defines liquide middelen (kasmiddelen, tegoeden op bank- en girorekeningen, wissels en cheques) and lid 2 requires disclosure of the extent to which tegoeden "niet ter vrije beschikking van de rechtspersoon staan" — this, not ISA 500 §§8–9, is the presentation/disclosure requirement the "vrij beschikbaar: Ja/Nee" indicator serves (in the current NV COS 500, §8 concerns management's experts and §9 the reliability of entity-produced information). Cite BW2 art. 2:372 lid 2 in the Restricted Accounts UI note. Belastingdienst G-rekening operational rules (2026-09-03, primary-source scrape of belastingdienst.nl/wps/wcm/connect/nl/betalenenontvangen/content/g-rekening): (1) a G-rekening is linked at application time to one or more loonheffingen- and/or omzetbelastingsubnummers and may only be used to pay the loonheffingen/btw for those subnumbers (including naheffingsaanslagen) to the Belastingdienst — once an account is confirmed as a G-rekening, outgoing postings to any counterparty other than the Belastingdienst (or another G-rekening) can be flagged as usage-pattern violations, extending this check beyond balance presentation; (2) payments lacking a betalingskenmerk/aangiftenummer are refunded by the Belastingdienst, so terugstortingen from the Belastingdienst on a G-rekening indicate misreferenced payments rather than income; (3) a ZZP'er without personnel is refused a G-rekening (not inhoudingsplichtig for loonheffingen), so a keyword-suggested "g-rekening" account in an administration with no payroll activity is likely mislabeled — a useful validation on the keyword heuristic in criterion (c); (4) an entity normally holds at most one G-rekening (a second requires demonstrated necessity) and a change of rechtsvorm requires a new G-rekening rather than a mutation, so more than one active G-rekening GL account in a fiscal year warrants review; (5) surplus balances are only released after a granted deblokkering request, and opheffing first settles outstanding taxes (verrekening, 6–8 weeks), so the full balance remains restricted at the balance-sheet date unless a granted deblokkering is documented. Standard: BW2 art. 2:372, ISA 320, Dutch NV COS 500; NVKS Beroepsregels for derdengelden. | Must | 3 | Shipped |
| DA-095 | Foreign-Currency Handling (ECB Rate Conversion / Koersverschillen) | From Document1.docx Stap 9 — Liquide Middelen audit workflow. When the audited entity holds bank accounts denominated in a currency other than the reporting currency (typically EUR), the auditor must verify: (a) that each foreign-currency closing balance has been converted to EUR using the ECB reference spot rate at the balance-sheet date (per RJ 290 and IAS 21); (b) that realized and unrealized exchange differences (koersverschillen) have been correctly computed and posted to the appropriate W&V account; (c) that the sum of all converted foreign-currency bank balances agrees with the Liquide Middelen balance per the trial balance. Acceptance criteria: (a) when the auditfile contains transactions with a foreign-currency code and amount, they are identified and the implied exchange rate (debitAmount_EUR / foreignCurrencyAmount) is computed per transaction; (b) the computed rate is compared against the ECB reference rate for that transaction date (or balance-sheet date for year-end valuations); deviations beyond a configurable tolerance (default: 1%) are flagged as "koersverschil buiten tolerantie"; (c) the aggregate net exchange difference computed by the tool (sum of conversion deltas across all foreign-currency positions) is compared against the amount posted to the koersverschillen W&V GL account — discrepancies beyond materiality are flagged; (d) accounts with transactions where currencyCode is absent or unrecognised are flagged as data-quality issues; (e) the ECB rate source (static lookup table or API endpoint) is configurable and the date of the rate used is disclosed in the output. Data model assessment — schema extension implemented. currencyCode (String) and foreignCurrencyAmount (BigDecimal) have been added to both TransactionDto (XmlElement) and TrLineDto (mapped from XAF <curCode> / <curAmnt>); the XafParser maps these fields in the real-XAF normalisation path. ECB rates are auditor-supplied per request (CODE:rate format) — no live API dependency. Standard: IAS 21 / RJ 290, ISA 500 §§8–9. | Should | 4 | Shipped |
| DA-096 | Cash Control / Kascontrole (Kasopnames / Kasboek / Kasverschillen) | From Document1.docx Stap 7 — Liquide Middelen audit workflow. When the audited entity maintains a physical cash register (kas), the auditor must verify: (a) that the opening and closing cash balances per the kasboek (cash book) agree with the GL cash account (rekeningtype "Kas"); (b) that no unexpected cash withdrawals (onverwachte kasopnames) are present — large, round, or frequent withdrawals relative to normal cash-handling patterns; (c) that the kas running balance never goes negative at any point during the period (physically impossible with a real cash box — a negative running balance indicates an error, omission, or unrecorded receipt); (d) that cash differences (kasverschillen) between the physical count and the book balance are identified, quantified, and explained. Acceptance criteria: (a) the user configures which GL account code(s) represent the kas, or the system suggests accounts whose accountDescription contains "kas" and whose accountType indicates an asset — the check runs only when at least one kas account is identified and confirmed; (b) the system reconstructs the running balance of each kas account in chronological transaction order; any point where the running balance goes negative is flagged as a kascontrole violation with the date, transaction, and resulting negative amount; (c) individual cash credit entries (kasopnames / withdrawals) exceeding a configurable threshold (default: EUR 500 for entities with average daily movement < EUR 2 000, EUR 2 000 otherwise) relative to the average daily cash movement are flagged as "onverwachte kasopname"; (d) opening balance (first period cumulative position) and closing balance (last period cumulative position) of each kas account are surfaced in the Kascontrole section for the auditor to reconcile against the physical kasboek; (e) if no kas accounts are identified, the check produces an explicit "geen kasadministratie vastgesteld — kascontrole niet van toepassing" result. Data model assessment — partial data gap. TransactionDto provides transactionDate, accountId, debitAmount, creditAmount — sufficient to reconstruct a per-account running balance and flag negative positions. GeneralLedgerAccountDto.accountDescription and .accountType enable heuristic kas account identification, but there is no structured accountSubType field distinguishing kas from bank in the XAF model. User-configured kas account mapping is required for reliable operation. The running-balance reconstruction is accurate only when the auditfile contains the full fiscal-year population (standard for XAF exports). No opening-balance field exists in TransactionDto; the cumulative position must be derived from mutations alone (assumes balance-forward = 0 unless the user supplies an opening balance). Feasible with the current data model once kas accounts are configured. NV COS anchor (datadump 2026-09-03): NV COS 240 bijlage 2 lists, among example fraud-response procedures for oneigenlijke toe-eigening van activa, "het tellen van contant geld ... op of tegen de einddatum van het boekjaar" and "het uitvoeren van kasopnames op een onverwacht moment" (unannounced cash counts) — Athena's kas running-balance reconstruction and kasopname flags scope and prepare exactly these procedures. Belastingdienst afrekensystemen note (2026-09-03, ODB scrape): the Belastingdienst treats the data in an afrekensysteem (kassa) as an integral part of the legally required administratie (open norm; 7-year fiscale bewaarplicht), and the Dutch auditfile family includes XAA (XML Auditfile Afrekensystemen) as the open standard for exporting cash-register data — for entities with an electronic afrekensysteem, an XAA export is a candidate structured source for the kasboek side of the reconciliation in criterion (d), analogous to the XAS ingestion path noted under DA-098 (sources: odb.belastingdienst.nl/afrekensystemen-kassa/informatie-afrekensystemen-kassa/; odb.belastingdienst.nl/auditfiles/achtergrondinformatie-auditfiles/; belastingdienst.nl "Houd een goede administratie bij"). XAA category differentiation (ODB Domain Group meeting 2018, datadump 2026-09-04): The 2018 XAA Domain Group meeting (source: Verslag-Auditfile-Platform-Domeingroep-XAA-13-februari-2018.pdf, odb.belastingdienst.nl/auditfiles/verslagen-en-presentaties-auditfiles/) was actively working on improving transaction category differentiation within XAA exports — specifically distinguishing cash sales, card payments, and other payment method categories within POS register data. This means a future XAA ingestion feature implementing criterion (d) must not treat all XAA transaction lines as physical cash: the XAA category field must be mapped to identify cash-specific lines (contante betalingen) separately from card or voucher lines — only the cash-categorised lines feed the kascontrole running-balance. Standard: ISA 501 §§A14–A20 (kas and other liquid assets), Dutch NV COS 501, NV COS 240 bijlage 2. | Should | 3 | Shipped |
| DA-097 | Bank-Balance Analytical Review (Banksaldo Trend / Gemiddelde Saldi / Kasstroomontwikkeling / Omzet-Saldo Ratio) | From Document1.docx Stap 6 — Liquide Middelen audit workflow. Distinct from DA-048 (Revenue/Cost/Result Trend Chart), which covers P&L line items period-over-period. This requirement covers the Liquide Middelen balance itself as the subject of analytical review per ISA 520. Compute and visualize, per bank/cash GL account (and in aggregate): (a) the monthly balance evolution (saldoverloop) as a line chart showing the closing balance at the end of each accounting period; (b) the average balance across the fiscal year (arithmetic mean of period-end closing balances); (c) the cash-flow development (kasstroomontwikkeling) — net cash movement per period, computed as period debit mutations minus period credit mutations on bank/cash accounts; (d) the revenue/balance ratio (omzet/banksaldo) — monthly revenue (sum of credit postings on revenue GL accounts for that period) divided by the average bank balance for that period; (e) identification of unusual fluctuations (uitzonderlijke fluctuaties) — periods where the closing bank balance deviates more than a configurable threshold (default: 2 standard deviations) from the fiscal-year average. Visualizations: maandgrafiek (monthly bar chart of net cash flow), saldoverloop (line chart of closing balance per period), pieken (highlighted peaks/troughs). Acceptance criteria: (a) for a loaded auditfile with 12 accounting periods, the saldoverloop chart shows 12 data points per bank account; (b) the average balance computed by the tool equals the arithmetic mean of the 12 period-end closing balances within rounding tolerance; (c) periods where the closing balance deviation exceeds the configured σ threshold are highlighted on the chart and listed as analytical review findings; (d) the omzet/banksaldo ratio panel displays "omzetrekeningen niet geconfigureerd" when revenue accounts have not been mapped (dependency on DA-031 revenue-account filter configuration); (e) the user can view individual bank accounts separately or view a consolidated aggregate; (f) all charts and the underlying data table are exportable as XLSX (per DA-082). Data model assessment — partial data gap (same account-classification gap as DA-096). Computing period-end balances from TransactionDto is fully feasible: group by accountId + accounting period (derived from transactionDate + HeaderDto.startDate / HeaderDto.endDate), accumulate debitAmount − creditAmount. Identifying which GL accounts are bank accounts vs. other asset accounts requires user configuration or accountDescription heuristics — no structured accountSubType field distinguishes bank from other assets in the XAF model. Revenue account identification has the same dependency as DA-031/DA-032. For auditfiles with RGS codes (XAF 4.0), bank and revenue accounts can be classified from rgsCode patterns (e.g., BIi = bank, OVo = omzet) without user input. The arithmetic, aggregation, and charting are fully supported by the current data model once account classification is resolved. NV COS 520 refinement (datadump 2026-09-03): as a substantive analytical procedure this check falls under NV COS 520 §5 — evaluate the reliability of the underlying data (§5(b)), form an expectation precise enough to identify a material misstatement (§5(c)), and predefine the acceptable deviation (§5(d)): the 2σ default is that §5(d) parameter and must remain configurable and documented. Per §7, deviations beyond it require inquiry of management plus additional procedures — surface flagged periods as open findings requiring auditor follow-up, never as auto-cleared. Standard: ISA 520 (Analytical Procedures), ISA 315 §§A130–A135 on liquidity risk. | Should | 3 | Shipped |
| DA-098 | Fictitious-Bank-Account and Salary-Fraud Detection (Frauderisico Liquide Middelen) | From Document1.docx Stap 2 (Frauderisico's) — Liquide Middelen audit workflow. Three distinct fraud patterns identified in the owner's workflow: (1) Fictitious bank accounts — payments directed to bank account numbers (IBANs) that do not correspond to known counterparties in the entity's debtor/creditor master data, which may indicate fictitious supplier fraud or embezzlement; (2) Management override via salary manipulation (bestuurder / directeur) — a director whose personal bank account number appears in the Liquide Middelen mutations receives total bank payments exceeding their registered gross salary for the period, which may indicate unauthorized self-payment or bonus fraud; (3) Surname concentration — multiple payees sharing the same surname as a director or management-team member receive payments, which may indicate related-party transactions with concealed beneficial ownership or fictitious-payee fraud. Acceptance criteria for (1): (a) when the user uploads a counterparty master list (name + IBAN) — or the system extracts IBANs from transaction descriptions using NL IBAN regex (NL\d{2}[A-Z]{4}\d{10}) — IBANs present in Liquide Middelen transactions that do not appear in the counterparty master are flagged as "onbekende begunstigde"; (b) IBANs appearing for the first time in the current fiscal year (not present in prior-period data when available) receive elevated risk weight and are flagged separately as "nieuwe begunstigde". Acceptance criteria for (2): (a) the user provides a director registry (name, personal IBAN, registered annual gross salary); the system sums all bank-account payments to each director's IBAN from Liquide Middelen GL accounts and compares the total against the registered salary; payments exceeding the registered salary by more than a configurable tolerance (default: 0%) are flagged as "overschrijding salarisgrens"; (b) the flag includes the total payments found, the registered salary, the excess amount, and a drillable list of constituent transactions. Acceptance criteria for (3): (a) the system extracts payee name tokens from transaction descriptions (free text) and matches against a configurable surname list (populated from the director registry); transactions where the payee description contains a matching surname are flagged for review with the matched surname highlighted. Data model assessment — genuine data gap; not implementable with current model without significant user-provided supplementary data. TransactionDto contains description (free text, unstructured) and no counterpartyName, counterpartyIban, or payeeId fields. IBAN extraction from description via regex is feasible as a best-effort heuristic but is fragile — Dutch accounting packages often abbreviate or omit the IBAN in the description field. Director salary comparison requires a director registry not present in the XAF file. Surname matching depends on structured payee names absent from TransactionDto. Full implementation requires: (a) adding counterpartyIban (String) and counterpartyName (String) to TransactionDto, mapped from XAF bank-statement import fields (<effDate> companion fields) or a supplementary bank-statement import; (b) a user-uploadable director-salary reference CSV. A V1 partial implementation (IBAN regex from description + user-supplied director registry) is feasible but carries known precision limitations that must be disclosed to the auditor in the UI. XAS reconciliation note (2026-09-02): The Belastingdienst's XAS (AuditfileSalaris v2027.1.0) standard defines, in structured form, exactly the director salary and bank account data that the DA-098 salary-comparison check needs: SrtInkCd (income type codes 13 = directeur NV/BV, 17 = directeur-grootaandeelhouder / DGA) distinguishes directors from regular employees; JrlnTbBzBel carries the annual salary basis per income relationship; IbanRknr within LnPrLncmp carries the exact IBAN receiving each salary payment. A XAS file submitted to the Belastingdienst is more reliable than a user-supplied CSV (it is independently filed and cannot be altered post-submission). Near-term (V1): retain the manual director-registry CSV upload as the practical path — XAS files are not universally available in audit engagements and building a XAS parser is a distinct, larger work item. Future: a "XAS Ingestion" feature (separate pipeline, separate DTOs, separate ingestion endpoint) would parse the employer's XAS file and populate director/IBAN data automatically, eliminating manual CSV entry and improving check precision. See docs/xas2027-srs-reconciliation.md for the full XAS schema analysis. Citation refinement + workflow positioning (NV COS 240 / NBA Handreikingen, datadump 2026-09-03): in the current NV COS 240 the evaluation of significant unusual transactions cited as "§32(c)" is §33(c) ("Voor significante transacties die buiten het kader van de normale bedrijfsvoering ... vallen ... dient de accountant te beoordelen of de zakelijke beweegredenen ... doen vermoeden dat ze mogelijk zijn aangegaan met het oog op frauduleuze financiële verslaggeving of het verhullen van een oneigenlijke toe-eigening van activa"). Flags from this check feed the client-specific frauderisicoanalyse per NBA Handreiking 1153 (2025), and — where they lead to specific audit attention — the "Controleaanpak frauderisico's" section of the controleverklaring per NBA Handreiking 1150 / NV COS 700. Standard: NV COS 240 §33(c) (management override of controls), ISA 550 (Related Parties), ACFE Fraud Examiners Manual §3.300 (payroll fraud). | Should | 4 | Shipped |
| DA-099 | ISA-Assertion Conclusion Table for Liquide Middelen (Bestaan / Volledigheid / Waardering / Rechten & Verplichtingen / Presentatie) | From Document1.docx Eindconclusie — Liquide Middelen audit workflow. The final step of the Liquide Middelen module produces an assertion-level summary table per ISA 315 / ISA 330 / ISA 500, mapping each audit procedure to the relevant financial-statement assertion it addresses and capturing the auditor's conclusion. The five ISA assertions relevant to Liquide Middelen: Bestaan (Existence — cash and bank balances physically or legally exist at the balance-sheet date, supported by bank confirmations and GL-to-trial-balance reconciliation); Volledigheid (Completeness — all cash and bank accounts are included; no accounts have been omitted; bank confirmation covers all accounts); Waardering (Valuation — balances are stated at correct amounts in the reporting currency; foreign-currency accounts converted at ECB rate; exchange differences correctly posted); Rechten & Verplichtingen (Rights & Obligations — the entity has legal right to the balances; restricted accounts are excluded from freely available liquidity); Presentatie (Presentation — balances are correctly classified as Liquide Middelen on the balance sheet; restricted amounts separately presented; disclosures adequate). Acceptance criteria: (a) after running the Liquide Middelen audit module, the system generates a conclusion table with one row per assertion and columns: assertion name (NL/EN), audit procedures performed (linked DA-XXX checks and manual steps), automatic result (✅ geen bevindingen / ⚠️ aandachtspunten aanwezig / ❌ afwijkingen vastgesteld), and an auditor comment field (free text, editable inline); (b) the automatic result is derived from findings raised by the relevant DA checks — e.g., if DA-094 raises restricted-account flags, the Rechten & Verplichtingen row is marked ⚠️; if DA-095 raises an ECB rate deviation, the Waardering row is marked ⚠️; (c) the auditor can override the automatic result with a manual status selection and a mandatory explanation; the override is logged with the auditor's user identity and timestamp (audit trail); (d) the conclusion table is exportable as PDF and included in the Athena audit documentation package alongside the individual detection-category exports; (e) each assertion row includes a reference to the applicable standard (ISA 500, ISA 520, ISA 240 §32, etc.); (f) when an upstream DA check that feeds an assertion has not been run (e.g., DA-095 for Waardering when no foreign-currency accounts are configured), the row shows "controle niet uitgevoerd — niet van toepassing verklaard door auditor" pending manual confirmation. Data model assessment — no fundamental XAF data gap. This is a reporting and workflow layer that aggregates results from existing and planned DA checks; it does not require new XAF source-data fields. It does require a new AuditConclusion persistence entity in the backend (one record per analysis session per assertion, storing the automatic result, auditor override status, comment, and override timestamp) — this is an Athena application data model extension, not an XAF schema dependency. The table's analytical value is proportional to the number of upstream Liquide Middelen checks implemented (DA-094 through DA-098); until those are complete, rows depending on unimplemented checks show the "niet uitgevoerd" status. Standard: ISA 315, ISA 330, ISA 500, ISA 520; Dutch NV COS equivalents; ISQM 1 documentation requirements. | Could | 4 | Planned |
Reacties