The Daily Cash Report aggregates CLA Group cash position across 13 legal entities into 11 normalized sections. The report is regenerated nightly by a chain of Vercel crons; the rendered UI at /cash-daily/ reads from cla_cash_daily_report_<YYYYMMDD> tool_keys.
| UTC time | Cron | What it does |
|---|---|---|
00:00 / 02:00 / … every 2h | /api/keez-sync?action=sync | Pull Keez Balanță XLS reports (treasury class 5, 411, 401, 461, 451) |
06:30 | /api/daily-brief | Front-load: 4 Keez pipes (balances · 411 receivables · 401 payables · transactions) + AR pull + cash-daily resolver + priority-recompute. Writes cla_cash_daily_report_<YYYYMMDD>. |
07:00 | /api/cash-daily-truth-check?send=true | Compare today's report vs yesterday vs Keez source. Emit cla_cd_truth_check + email to Ionut+Elena (NOT controlling@ — confidential). |
Four sources feed the report. Each cell of the rendered table is resolved by a fixed precedence rule. Higher row wins.
| # | Source | Tool key prefix | What it covers | Latency |
|---|---|---|---|---|
| 1 | Bank statement ingest LIVE 2026-06-01 | cla_cd_bank_statements_ | Per-IBAN closing balances posted by local scrapers / RezolvIT RPA / manual upload. Covers gaps not in Keez Open Banking. | ≤24h |
| 2 | Elena XLSX (legacy) | cla_cd_transactions_elena_ | Manual daily upload by Elena · until 2026-06-04. Includes refacturare assignments + descriptive context. | Same-day morning |
| 3 | Keez Open Banking | cla_cd_balances_ | 13 entities · aggregate per-entity sum of class 5121+5124. No per-IBAN split (escalation to Stelian Trandafir · deadline 2026-06-05). | ≤2h |
| 4 | Keez Balanță (books-side) | cla_cd_keez_balanta_ | Chart-of-accounts class 5 totals + 411 + 401 + 461 + 451 from accounting books. | ≤2h |
shared/cash-daily-resolver.js · function resolveCashBank(). When Elena XLSX is missing for a date, the resolver falls back to Keez aggregate per entity. Invariant cash-daily-keez-filter-matches-resolver-labels pins the renderer to the resolver's output labels.
PAF = Payment Authorization Form. Procedure live since 2025-12-01 (Elena's official PDF dated that day). Governs how client-payroll payments by CLA BPS are recorded, authorized, and reconciled.
Fisier suport denumiri.xlsx file in SharePoint at Shared Workspace / 02. PAYMENT RECORDS / 03. CLA BPS PAYROLL /. Hub mirror: tool_key cla_cd_bps_payroll_clients_v1.
Shared Workspace
/02. PAYMENT RECORDS
/01. GENERAL ← procedure docs
/02. CLA TAX COMPLIANCE & REPRESENTATION
/03. CLA BPS PAYROLL
/YYYY_MM/ ← one folder per month
<CLIENT>_OP_<CATEGORY> ← payment order
<CLIENT>_MACHETA_PLATI_<CATEGORY> ← template
/Fisier suport denumiri.xlsx ← auto-generates filenames
/04. CLA BPS ACCOUNTING
Example (2 December 2025 · BUCK ActivPayroll · taxes):
2025_12_2_BUCK_ACTIVPAYROLL_LTD_OP_TAXE
2025_12_2_BUCK_ACTIVPAYROLL_LTD_MACHETA_PLATI_TAXE
| Code | Meaning | Hits BUGETUL DE STAT? |
|---|---|---|
TAXE | Payroll taxes paid to ANAF for the client's employees | Yes · refacturated to client |
SALARII | Net salaries to client's employees | No · paid directly to employees |
BENEFICII | Benefits: meal vouchers, medical insurance, etc. | No · paid to provider |
POPRIRI | Garnishments / court-ordered withholdings | Sometimes · ANAF or third party |
| # | Short code | Full client name | Notes |
|---|---|---|---|
| 1 | BUCK | BUCK_ACTIVPAYROLL LTD | Funded via ActivPayroll Ltd intermediary |
| 2 | TTI | TTI_ACTIVPAYROLL LTD | Funded via ActivPayroll Ltd intermediary |
| 3 | PAN | PAN_ACTIVPAYROLL LTD | Funded via ActivPayroll Ltd intermediary |
| 4 | AIRBUS NO | AIRBUS DEFENCE AND SPACE AS | Norway entity |
| 5 | AIRBUS RO | AIRBUS DEFENCE AND SPACE SPD | |
| 6 | CHINT | CHINT SOLAR EUROPE GMBH | |
| 7 | CIDP | CIDP BIOTECHNOLOGY SRL | |
| 8 | ELEMENTAL | ELEMENTAL ENERGIES SRL | |
| 9 | EYEO | EYEO GMBH | |
| 10 | FRONTWELL | FRONT WELL SOLUTIONS GMBH | |
| 11 | KAVO | KAVO DENTAL POLAND | |
| 12 | OYSTER | OYSTER HR SRL | |
| 13 | PARTNERHERO | PARTNERHERO EASTERN EUROPE SRL | |
| 14 | SPM | SPM MANAGEMENT LIMITED | |
| 15 | WESEEDO | WESEEDO BV |
The refacturare engine (section 4) consults this list before doing frequency-based inference. When a Keez transaction at CLA BPS has a description containing any of these client codes (whole-token match) or the full name, the engine assigns the refacturare client with confidence: 1.00 and match_pattern: paf_code_in_description.
Endpoint: /api/cash-daily-refacturare-infer · Tool keys: cla_cd_refacturare_mapping (inferred) + cla_cd_bps_payroll_clients_v1 (PAF authoritative).
match: 'paf_authoritative'.match: 'inferred_exact' with the observed confidence.match: 'inferred_substring'.match: 'none'. Row falls to manual review by controlling@.| Tier | Threshold | Behavior |
|---|---|---|
| Authoritative | conf = 1.00 (PAF only) | Auto-apply · no flag |
| High confidence | conf ≥ 0.75 | Auto-apply · no flag |
| Review | 0.50 ≤ conf < 0.75 | Suggestion shown · needs controlling@ confirmation |
| Skip | conf < 0.50 | No suggestion (too noisy) |
GET /api/cash-daily-refacturare-infer?action=rebuild (partner-only or cron). Scans all cla_cd_transactions_elena_* keys. Should be re-run after any Elena XLSX import.controlling@cla.com.ro with subject ADJUSTMENTS + the change · Controlling updates the Fisier suport denumiri.xlsx · Hub re-syncs the cla_cd_bps_payroll_clients_v1 tool_key.Endpoint: /api/cash-daily-variance-thresholds · Tool key: cla_cd_variance_thresholds.
For every (section, entity) pair, compute the absolute day-over-day delta across the last 90 days of cla_cash_daily_report_* snapshots. Take the P95 of those deltas. That's the threshold.
Sections tracked: cash_bank · ico_loans · client_cash · money_status. Need ≥5 historical datapoints to compute (avoids junk thresholds on new entities/sections).
Today's report is auto-confirmed when:
(section, entity) pair has |today − yesterday| ≤ threshold, ANDIf any pair fails (1), the report is flagged NEEDS REVIEW for that day; controlling@ gets a single notification listing the above-threshold lines.
verdict : NEEDS REVIEW above : 2 within : 41 no_threshold: 0 ⚠ cash_bank|CLA BPS Δ=-406,753 / threshold 406,638 (just over) ⚠ money_status|CLA BPS Δ=-406,753 / cross-section confirmed ✓ cash_bank|CLA ROMANIA Δ=-5,331 / threshold 1,735,608 ✓ cash_bank|CLA TC&R Δ=+50,058 / threshold 739,265
Endpoint: /api/cash-daily-bank-statement-ingest · Tool key: cla_cd_bank_statements_<YYYYMMDD>.
Keez Open Banking covers 13 entities at the aggregated 5121+5124 level. It does NOT cover three accounts that need separate ingestion:
Three POST sources are supported (all hit the same endpoint):
| source | How it works | Status |
|---|---|---|
playwright-local | Headless browser on user's Mac · scripts/_scrape-bcr-daily.mjs | PoC ready · needs first-run validation |
rezolvit-rpa | RezolvIT RPA infra POSTs daily | Feasibility ask Resend 886927f6 · deadline 2026-06-05 |
manual | Paste-in via Hub admin UI (not built yet) | Endpoint accepts · UI pending |
Endpoint: /api/cash-daily-truth-check · Cron: 0 7 * * *. Compares today's report against Keez source values for the same date. Outputs:
When cells_compared = 0, the UI renders ⊘ Skipped on the Yesterday pill (no false-green).
GET /api/cash-daily-variance-thresholds?action=check&date=YYYY-MM-DD. See section 5.
GET /api/cash-daily-refacturare-infer?action=suggest&vendor=<name> · returns the inferred client + confidence. For BPS Payroll rows, the PAF decoder fires first (consults the description text against the 15-client list).
Hub == Keez 5121+5124 raw · 13/13 entities · Δ = 0.00. Tested via scripts/_verify-keez-parity.mjs. Gaps vs Elena XLSX are real-world coverage (BCI EUR · BRD client-money) — not parsing bugs.
| What changes | Where to update | Hub re-sync |
|---|---|---|
| Add / remove BPS Payroll client | Email controlling@cla.com.ro · subject: ADJUSTMENTS | Controlling updates Fisier suport denumiri.xlsx · Hub re-loads cla_cd_bps_payroll_clients_v1 via re-run of scripts/_load-paf-bps-clients-*.mjs |
| Add new vendor → client refacturare rule | Add to Elena XLSX with linked_client populated · OR email controlling@ with subject ADJUSTMENTS | Engine auto-picks up after next ?action=rebuild |
| Variance threshold drift | Re-run ?action=recompute (auto-pulls last 90 days · no manual config) | Immediate |
| New bank account (not in Keez) | Email controlling@ + Hub admin · add IBAN + entity mapping to scraper config | Manual: update scripts/_scrape-*-daily.mjs |
| Term | Meaning |
|---|---|
| PAF | Payment Authorization Form. Generated by BPS Payroll consultant per client per payment cycle. Visible at Internal Resources → Controlling Resources → Payment Authorization Forms. |
| OP | Ordin de Plată · Romanian payment order. |
| Macheta | Payment template/draft used as a basis for the OP. |
| Refacturare | Pass-through invoicing: CLA pays a vendor on behalf of the client, then invoices the client for the same amount. linked_client in Elena XLSX = the end client to invoice. |
| ICO | Intercompany. Account 451 in Romanian accounting. CLA Romania ↔ CLA Global ROMANIA SA, etc. |
| FF NNNN | Prefix found on ~42 % of Elena's row descriptions (e.g., FF 1036, FF 526/08.01.2026). Likely Factură Furnizor # but not confirmed. Round 3 Q17 open. |
| SUMA BLOCATA | "Blocked amount." Could be card pre-auth, garnishment, bank hold. Round 2 Q11 open. |
| IPS | Counterparty on 1.7M RON loan flows. Identity unconfirmed. Round 3 Q20 open. |
| 461 / 401 / 451 / 411 | Romanian chart-of-accounts: 461 = client cash escrow · 401 = suppliers · 451 = intercompany · 411 = clients (receivables). |
| 5121 / 5124 / 5125 | Bank accounts: 5121 = RON current · 5124 = EUR/foreign-currency current · 5125 = overnight deposits (only 4 entities use this). |
Sent to Elena via three handover emails. Combined deadline: Marți 2026-06-03 seara.
| # | Topic | Round | Status |
|---|---|---|---|
| 1–7 | Original structured handover (extras downloaders · refacturare · Q1 deadline · etc.) | 1 (272ff52c) | Awaiting reply |
| 8–16 | Numeric patterns (ICO statics · client-cash mapping · ACTIVPAYROLL inflows · SUMA BLOCATA · DOBANDA · overnight scope · fees · refacturare exceptions) | 2 (30cf8af1) | Awaiting reply |
| 17–26 | Deep semantic patterns (FF# · group allocations · IPS · auto-debits · TVA refunds · vendor dedup) | 3 (d06e88e6) | Awaiting reply · Q18 PARTIALLY ANSWERED by PAF PDF received 2026-06-01. |
Concrete curl commands to invoke each engine manually. Substitute $TOKEN with either a partner-level user session token OR the CRON_SECRET (from .env.local or Vercel env).
curl -sS -H "Authorization: Bearer $TOKEN" \
"https://app.cla.com.ro/api/cash-daily-refacturare-infer?action=rebuild" | jq .
# returns: { rows_scanned, vendors_after_dedup, vendors_above_confidence, mapping }
# run after: any Elena XLSX import · or when ADJUSTMENTS email arrives
curl -sS -H "Authorization: Bearer $TOKEN" \ "https://app.cla.com.ro/api/cash-daily-variance-thresholds?action=recompute" | jq . # Run weekly · or after a major one-off event (M&A · capital injection) # Output: per-(section,entity) p95_abs_delta thresholds
curl -sS -H "Authorization: Bearer $TOKEN" \
"https://app.cla.com.ro/api/cash-daily-variance-thresholds?action=check&date=2026-06-01" | jq .
# returns: { auto_confirm, summary: {above, within, no_threshold}, checks: [...] }
# auto_confirm=true → controlling@ can sign off without further review
curl -sS -H "Authorization: Bearer $TOKEN" \
"https://app.cla.com.ro/api/cash-daily-refacturare-infer?action=suggest&vendor=CENTRUL+MEDICAL+UNIREA" | jq .
# returns: { match: 'inferred_exact'|'paf_authoritative'|'inferred_fuzzy'|'inferred_substring'|'none',
# top_client, full_name, confidence, auto_apply, alternates }
# Scan one month (Dec 2025) curl -sS -H "Authorization: Bearer $TOKEN" \ "https://app.cla.com.ro/api/cash-daily-paf-folder-scan?action=scan&yyyy_mm=2025_12" | jq . # Scan all available months · writes cla_cd_paf_folder_index curl -sS -H "Authorization: Bearer $TOKEN" \ "https://app.cla.com.ro/api/cash-daily-paf-folder-scan?action=scan-all" | jq .
curl -sS -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"https://app.cla.com.ro/api/cash-daily-bank-statement-ingest" \
-d '{
"date": "2026-06-01",
"bank": "BCR",
"source": "manual",
"rows": [
{ "iban": "RO12BCRT...", "entity_code": "BCI", "currency": "EUR",
"closing_balance": 194000.00, "account_label": "EUR BCR current" }
]
}' | jq .
Trace a real Keez row through the engines to see how every number is decided.
Input row (from cla_cd_transactions_keez_20260520):
{
"entity_code" : "CLA BPS",
"iban" : "RO82BTRL...",
"counterparty" : "BUGETUL DE STAT",
"amount" : -42393.00,
"currency" : "RON",
"description" : "PAF - Taxe 12.2025 KAVO",
"date_posted" : "2026-05-20"
}
suggestVendor("BUGETUL DE STAT", { description: "PAF - Taxe 12.2025 KAVO", date: "2026-05-20", category: "TAXE" })
KAVO matched as whole token.{ match: 'paf_authoritative', top_client: 'KAVO', full_name: 'KAVO DENTAL POLAND', confidence: 1.00, auto_apply: true }−42,393 to cash_bank|CLA BPS and money_status|CLA BPS sections.cash_bank|CLA BPS total vs yesterday's vs threshold. If |Δ| > threshold, flag the row in the verdict output.KAVO assignment surfaces in the daily refacturare review table · controlling@ approves → BPS issues invoice to KAVO Dental Poland for 42,393 RON.Counter-example: same row but description = "impozit salariu 04.2026" (no client code):
cla_cd_paf_folder_index for entries with date=2026-05-20 + category=TAXE. If exactly one client filed under that bucket → match with conf=0.85, auto_apply.match: 'paf_folder_ambiguous' with the list · row gets flagged for controlling@ manual review.What fires when something goes wrong. Every alarm has a single recipient by design (no fan-out · per the Daily Hub Audit confidentiality rule).
| Symptom | Probable cause | Where to look | Who gets notified |
|---|---|---|---|
| Truth-check email lists Δ > tolerance | Keez source updated after report ran · OR Elena XLSX missed a row · OR ingest race | cla_cd_truth_check_<date> + Keez raw vs report blob | Ionut + Elena (until 2026-06-04) |
| Daily-brief silent (no CRON_DONE in audit log) | maxDuration exceeded · OR a downstream fetch hung | hub_audit_log WHERE event_type='CRON_START' AND no matching DONE within 720s | Daily Hub Audit (Ionut only) |
| UI shows "⊘ Skipped" on Yesterday pill | cells_compared = 0 · truth-check ran but had no overlap (e.g., first day · or section schema drift) | Browser DevTools network panel for the /api/cash-daily-truth-check response | UI-only badge · no email |
| Cash & Bank table shows entity at 0 RON | Resolver fallback failed · OR groupRon === 0 && keezRon > 0 orphan handled · OR keez tool_key empty for date | Look at cla_cash_daily_report_<date>.cash_bank[ENTITY] · then walk up to cla_cd_balances_<date> | UI-only · no email · check invariant cash-daily-keez-filter-matches-resolver-labels |
| Variance check flags 5+ above-threshold lines on same day | Real major event (M&A, capital injection, large refund) · OR known monthly cycle day (20/26-27 spike) · OR threshold recompute overdue | Cross-check days 20/26/27/6/30 of month against high-volume calendar in Section 5.3 | controlling@ via auto-confirm verdict |
| PAF folder scan returns 0 entries | Azure creds missing/expired · OR site URL drift · OR folder genuinely empty for that month | Endpoint response · then SharePoint folder URL 02. SHARED WORKSPACE / 02. PAYMENT RECORDS / 03. CLA BPS PAYROLL | Operator-driven (manual curl) · no scheduled cron yet |
Refacturare suggest returns match: 'none' on a recurring vendor | Vendor name has new typo not yet in fuzzy distance · OR vendor genuinely new this month · OR linked_client never populated historically | Run ?action=suggest&vendor=X · check fuzzy distance · if >2 add to ADJUSTMENTS email | controlling@ |
How a single number on the rendered Cash Daily table is sourced.
┌─────────────────────────────────────────────────────────────────────┐
│ RENDERED CELL (UI) │
│ /cash-daily/index.html · Cash & Bank table · CLA AUDIT row · RON │
└──────────────────────────┬──────────────────────────────────────────┘
│ shared/cash-daily-resolver.js
│ resolveCashBank() · precedence rule
▼
┌─────────────────────────────────────────────────────────────────────┐
│ REPORT BLOB │
│ cla_cash_daily_report_<YYYYMMDD>.cash_bank["CLA AUDIT"].ibans[] │
└──────────────────────────┬──────────────────────────────────────────┘
│ written by /api/daily-brief at 06:30 UTC
│ merges 4 sources by precedence rule
▼
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌──────────────┐ ┌──────────────┐
│ Bank stmt │ │ Elena XLSX │ │ Keez Balanță │
│ ingest │ │ (until 4-Jun)│ │ (books-side) │
│ │ │ │ │ │
│ cla_cd_bank_ │ │ cla_cd_ │ │ cla_cd_keez_ │
│ statements_ │ │ transactions │ │ balanta_ │
│ <date> │ │ _elena_ │ │ <date> │
│ │ │ <date> │ │ │
└──────┬────────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ Playwright / │ daily upload │ /api/keez-sync
│ RezolvIT / │ (Elena) │ every 2h
│ manual POST │ │
▼ ▼ ▼
Bank portals SharePoint Keez Balanță API
(BCR/BRD/BT) Excel upload (treasury class 5
+ 401/411/451/461)
┌─────────────────────────────────────────────────────────────────────┐
│ CROSS-CHECK (07:00 UTC daily) │
│ /api/cash-daily-truth-check?send=true │
│ Compare report cell vs Keez source · Δ > tolerance → email │
└─────────────────────────────────────────────────────────────────────┘
Permanent audit trail of confirmed handover answers. Each entry is a rule the engine applies automatically. Source: cla_cd_elena_decisions_log tool_key. Updated as Elena's inline replies arrive.
| Round · Q | Answered | Answer | Rule active | Code change |
|---|---|---|---|---|
| R4 · Q30 | 2026-06-01 | yes | Vendor names auto-normalized: case-fold + strip punctuation + collapse spaces · plus Levenshtein ≤ 2 fuzzy match at lookup time (merges ACTIV PAYROLL ↔ ACTIVPAYROLL · ALLIANTZ ↔ ALLIANZ · etc.) |
api/cash-daily-refacturare-infer.js · fuzzyLookup() + new match: 'inferred_fuzzy' tier |
| R4 · Q31 | 2026-06-01 | yes | All vendor variants stored UPPERCASE · certSIGN ≡ CERTSIGN · RisCo ≡ Risco · etc. |
normalizeVendor() already uppercases · confirmed permanent |
| (35 questions still awaiting answer · update this table as replies land) | ||||
Patterns I've extracted from the data with confidence labels. CONFIRMED = Elena answered · HYPOTHESIS = best evidence from raw data, awaiting validation · DOCUMENTED = sourced from Elena PDF.
| Pattern | Status | Best-evidence interpretation |
|---|---|---|
| FF NNNN prefix (1,076 rows · 42%) | HYPOTHESIS | Factură Furnizor # · Elena's internal sequence tracking incoming invoices for matching purposes. Same FF# across multiple rows = same invoice paid in tranches. Different FF# for same vendor = different invoices. The number jumps non-sequentially across vendors (FF 569 J&J vs FF 1036 Trade Compliance same week) → likely a single global sequence in Elena's tracking spreadsheet, not per-vendor. Awaiting Round 3 Q17. |
| PAF (Payment Authorization Form) | DOCUMENTED | Elena PDF 2025-12-01 · official 3-stage workflow · 15 BPS Payroll clients · 4 categories. See Section 3. |
| INCASARE 8 sub-types | HYPOTHESIS | All variants of intercompany loan flows. IMPRUMUT ICO + ICO LOAN + RESTITUIRE ICO + IMPRUMUT CLA GLOBAL = different stages (granting · partial repay · full restitution · capital pool). All should hit 451. IPS = third party · unconfirmed identity (Round 3 Q20). |
| SUMA BLOCATA (102 rows) | HYPOTHESIS | "Blocked amount" · most likely BCR/BRD card pre-authorizations that get released within 7 days. Pattern: appears at CLA ROMANIA (30x) and CLA CORPORATE (18x) · these entities have the company cards. Avg −1,475 RON consistent with travel/expense pre-auths. |
| IPS (1.7M RON inflow) | HYPOTHESIS | Two large inflows tagged "INCASARE IPS - Rambursare imprumut" + "INCASARE IPS - Imprumut". 1.077M EUR + 0.652M EUR (so really EUR, not RON). To CLA Romania. Could be: (a) IPS = third-party borrower repaying CLA Romania (loan asset), (b) IPS = subsidiary acronym not yet in our entity list. Round 3 Q20 + Round 4 Q27 pending. |
| BENETTON CLIFF + P RESIDENTIAL EUR transfers | HYPOTHESIS | 1.6M EUR total from CLA GLOBAL ROMANIA SA to two related entities. Both also appear in 451 with static balances (BENETTON −134K · P RES −3.3M). Most likely real-estate capital allocation. Round 4 Q34 pending. |
| DOBANDA DEPOZIT scope | HYPOTHESIS | Only 4 entities have overnight deposits: BPS (52d) · TC&R (33d) · ROMANIA (26d) · CORPORATE (18d). Other 9 entities don't qualify (sold prea mic to make overnight worthwhile) OR don't have the contract. Range 0-356 RON/day → overnight balance varies wildly. Round 2 Q12 pending. |
| Bank fees · 0 categorized rows | HYPOTHESIS | Most likely silently bundled into row amounts at the time Elena reconciled the extras. "Daily bank commisions" appears 5 times as a 0-amount placeholder description. True fee rows likely tagged with vendor name only (e.g., "BCR" or "BRD") rather than a fee keyword. Round 2 Q13 pending. |
| 10 missing weekdays (Jan-May 2026) | HYPOTHESIS | 8 align with known RO holidays (Anul Nou · Bobotează · Paste cluster · 1 Mai). 2 unexplained: 2026-01-27 (Tue) and 2026-05-22 (Fri). 22-May was Vinerea Mare in RO calendar 2026 (Good Friday observed late) · 27-Jan probably Elena absence. Round 4 Q29 pending official calendar. |
| Vendor name typos · auto-dedup | CONFIRMED | Elena Q30+Q31 yes (2026-06-01) · fuzzy match Levenshtein ≤ 2 + case-fold + strip punctuation + collapse spaces all active in refacturare-infer engine. |
Every daily truth-check (07:00 UTC) runs these 16 deterministic checks. Each has a single PASS/FAIL/INFO outcome that controlling@ + Ionut see in the daily email. Click through to /api/cash-daily-truth-check?send=false to see live values.
| # | Check | Formula / data source | Tolerance | What fires when it fails |
|---|---|---|---|---|
| 1 | SP mirror XLSX uploaded | SharePoint file size for /HUB GENERATED DAILY/Daily Cash Report_<DATE>_Hub.xlsx | > 100 KB · OR Hub-primary mode active | UI shows yellow banner · email lists as FAIL |
| 2 | Keez Balances ≥ 13 entities | cla_cd_balances_<date> · count of distinct entities | ≥ 13 | Keez sync failure · all downstream rendering wrong |
| 3 | Keez Balances · sum > 1M RON | SUM(closing_balance) across all entities | > 1,000,000 RON | Mass deletion or sync corruption |
| 4 | AR rows ≥ 100 AND sum > 1M | /api/cash-daily-keez-ar-pull output | ≥ 100 rows AND total > 1M RON | AR ingest broken · AR tab empty |
| 5 | AP rows ≥ 50 AND sum > 1M | /api/cash-daily-keez-ap-pull output | ≥ 50 rows AND total > 1M RON | AP ingest broken · AP tab empty |
| 6 | AR enrichment 100% | % rows with legal_entity_cui + client_canonical_cui populated | 100% | Enrichment v3.0.2 regression · refacturare can't run on AR side |
| 7 | AP enrichment 100% | % rows with legal_entity_cui + supplier_canonical_cui populated | 100% | Same as AR · refacturare blind on AP |
| 8 | Panel · 0 critical missing AND completeness ≥ 50% | Status panel completeness algorithm | missing_critical=[] AND pct ≥ 50% | Money Status banner shows ⚠ |
| 9 | FX rates ≥ 30 AND < 48h fresh | /api/fx-bnr response · count + max age | ≥ 30 rates · age < 48h | BNR scraper down · EUR conversion stale |
| 10 | Money Status ≥ 5 rows | resolved.money_status.rows.length | ≥ 5 | Resolver missed money_status section |
| 11 | format-compare verdict OK | Hub vs Controlling Excel format diff | verdict=OK | Format-compare flagged column drift |
| 12 | Resolved cash_bank dict ≥ 1 entry | resolved.cash_bank Object.keys | ≥ 1 | Resolver completely empty · UI blank |
| 13 | Cron last run < 30h ago | MAX(updated_at) for tool_keys updated_by cash-daily-cron@ | < 30h | Daily-brief silent-killed · catch-all backstop |
| 14 | ICO 451 · top-3 balances stable | Compare top-3 ct451_net (today vs yesterday) by entity_name | |Δ| ≤ 1 RON per top-3 entity | Untracked intercompany movement · Round 3 Q8 hypothesis violated |
| 15 | Currency round-trip · EUR × FX ≈ RON | |(group_RON / group_EUR) − fx_eur_ron| / fx_eur_ron | drift ≤ 1% | FX stale OR per-row currency mis-tagged · group total wrong |
| 16 | PAF folder · entries today | cla_cd_paf_folder_index entries for DATE | info-only · any count | Surfaces filing gap · controlling@ can chase missing OP/MACHETA |
| 17 | Refacturare coverage · CLA BPS | % CLA BPS Keez rows with linked_client populated | ≥ 50% · OR 0 BPS rows | Refacturare engine blind on most BPS rows · low % = new vendors unmapped |
| 18 | Outlier amount · today max ≤ 90d P99 | MAX(abs(amount)) today vs P99(abs(amount)) over 90 days | info-only · today_max > p99 flagged | Major payment day · variance check will likely fire too |
| 19 | New counterparties first-seen today | Today's counterparties NOT in any of last 90 days | info-only · count + sample | New vendor list for controlling@ to set refacturare rule |
| 20 | Salary cluster · ≥ 5 entities pay taxes on day 25-27 | Distinct entity_codes with BUGETUL DE STAT / TAXE MM.YYYY descriptions | ≥ 5 entities · only fires on day 25-27 | Missed monthly tax run for some entity · client wasn't processed |
| 21 | Variance auto-confirm verdict | /api/cash-daily-variance-thresholds?action=check forwarded inline | auto_confirm=true · OR 0 above | Surfaces variance engine output in email · controlling@ has one place to look |
Status semantics: PASS = check passed numerically · FAIL = check failed AND blocks verdict · INFO = neutral check (surfaces info · doesn't count toward verdict). 13 PASS/FAIL checks + 8 INFO checks · daily email verdict only counts the 13 hard ones.
From 5 months of Elena's history. Knowing what SHOULD happen each day = knowing what's normal vs anomaly.
| Day(s) | Expected event | Volume signature |
|---|---|---|
| 1 | Start of month · low activity · prep for tax run | ~20-40 rows |
| 6 | Likely client payroll cycle for some BPS clients | ★ 131 rows (5-mo total) |
| 11-14 | Mid-month settlements · J&J + ACTIV PAYROLL inflows | 114-120 rows/day |
| 15-16 | Mid-month tax + ICO transfers (CLA GLOBAL ROMANIA reconciliation) | 120 rows day-16 |
| 20 | TVA decont · monthly VAT settlement · biggest day | ★ 156 rows (top spike) |
| 21 | VAT-related settlements + intra-month payroll for some clients | 125 rows |
| 25 | Salary day prep · payroll-tax declarations filed | 96 rows |
| 26-27 | SALARY DAY · net salaries to employees + employer taxes to BUGETUL DE STAT for ~9 BPS clients | ★ 282 rows (combined · top monthly event) |
| 30 | End-of-month settlement · ICO balancing · dividend cycles | ★ 122 rows · 20 salaries/dividends |
Romanian public holidays seen as zero-activity gaps in 2026 history: 2026-01-01 (Anul Nou), 2026-01-02 (Anul Nou prelungit), 2026-01-06 (Bobotează), 2026-01-07 (Sf. Ioan), 2026-04-09 to 04-13 (Paste cluster), 2026-05-01 (Ziua Muncii). 2026-01-27 + 2026-05-22 = pending Elena clarification (Round 4 Q29).
What to check each morning from 2026-06-05 onward. Total: ≤ 10 minutes if everything is green.
/cash-daily/ · check the quality strip at top. Variance verdict = "within thresholds" (green) → no action. "above threshold" (red) → click "top variances" detail · cross-reference Section 18 calendar (is today a high-volume day?).| What fired | What to do |
|---|---|
| Check #14 ICO instability | Compare today's ico_loans.rows vs yesterday's in cla_cash_daily_report_* blob · identify which entity moved · cross-reference with INCASARE/IMPRUMUT keywords in today's Keez transactions to confirm the move was recorded |
| Check #15 Currency drift > 1% | Open /api/fx-bnr · verify EUR rate is fresh (< 24h). If stale → BNR scraper down · ping Ionut/Hub admin. If fresh → some entity has currency-tag mismatch (look at money_status rows · find currency=null or unexpected currency) |
| Check #17 Refacturare coverage < 50% | Run ?action=rebuild&cascade=variance on refacturare endpoint (also recomputes variance). If still low → new vendors today · scroll the suggestions list · add ADJUSTMENTS email for any persistent new patterns |
| Check #18 Outlier amount today max > P99 | Open today's Keez transactions · find the row above P99 · cross-reference description for INCASARE / IPS / ACTIV PAYROLL / NUSCO CITY PARK / BENETTON CLIFF (known large-one-shot patterns) |
| Check #19 New counterparty today | If < 5 new · likely organic. If > 10 · investigate. For each: check description for refacturare hint (PAF/INCASARE) · if BPS-related and matches one of 15 PAF clients · no action (engine handles). Otherwise add to ADJUSTMENTS email backlog. |
| Check #20 Salary cluster < 5 entities (day 25-27) | Specific client wasn't run. Cross-reference with BPS Payroll consultants · OR check if the missing entity is dormant (e.g., a paused client). Worth a quick email to BPS leads. |
/cash-daily/methodology/#decisions · ensure decision log reflects any controlling@ rule additions from the week.cla_cd_refacturare_mapping + cla_cd_variance_thresholds for updated_at > 24h ago. If not · manually run the rebuild curl from Section 11.1.hub_audit_log WHERE action='cash_daily_truth_check_email_sent' AND details::jsonb->'fail' > 0) · ensure each was addressed.?action=scan&yyyy_mm=YYYY_MM · review unmatched_client list · add to ADJUSTMENTS if persistent.cla_cd_bps_payroll_clients_v1) reflects any client onboardings/offboardings from BPS Payroll · if drift · update via the loader script and re-run.Patterns the system silently tolerates by design vs patterns that should NEVER appear.
| Pattern | Why it's OK |
|---|---|
| Hub-primary fallback row · YES until ~PM each weekday | Elena historically uploaded XLSX PM Mon-Fri · Hub renders Keez aggregate until her file lands · post-2026-06-04 this state may become permanent (no XLSX upload) |
| 113 zero-amount rows in 5-mo history | Placeholders for DOBANDA DEPOZIT zero-balance days + "Daily bank commisions" placeholder · Elena tracks them for paper-trail · safe to skip in variance check |
| 168 rows with > 2 decimal places · all DOBANDA DEPOZIT | Floating-point interest calculation · not a data quality issue |
| ICO 451 balances static for many days | Loans only change on event (grant/repay/capital injection). 12-entity ICO list typically static for weeks at a time. Movement = event · check #14 surfaces movement specifically. |
| 0 weekend rows ever | Cron runs Mon-Fri only · weekends explicitly empty · don't treat as "missing data" |
| Day-of-month spike on 20 / 26-27 / 6 / 30 | Known monthly cycles · variance check WILL false-flag these days until per-day thresholds ship |
| EUR rows show their native value · not RON-converted | Per-IBAN rows in Cash & Bank table are per-currency · TOTAL column sums per currency · group EUR total at top is FX-converted |
| Anti-pattern | Why it's wrong | Likely cause |
|---|---|---|
| cash-daily-truth-check email lands in > 2 inboxes | Violates feedback_daily_cash_report_confidential_access · cash-daily is Ionut + Elena ONLY · controlling@ added post-2026-06-04 only | Someone added a recipient · revert immediately + check git blame |
| Variance check flags > 10 above-threshold lines on a non-month-end day | Either threshold engine is broken OR a major undocumented event happened · day 1-19 should never see > 5 hits | Run threshold recompute · if still high · investigate Keez sync for missed rows |
| Refacturare suggestions contain a client name NOT in the 15-list or the inferred mapping | Engine is making up names · OR the mapping has been corrupted | Check cla_cd_bps_payroll_clients_v1 + cla_cd_refacturare_mapping for unexpected entries |
| Quality strip shows "auto_confirm=true" while truth-check email shows ❌ FAIL | The two engines disagree · semantic drift | Check that both endpoints read the same DATE · check that variance thresholds aren't 0 (uninitialized) |
| "Iulia" or any other fabricated name appears anywhere in the Hub | Per feedback_never_fabricate_names_or_facts_in_emails · this name was invented · should never resurface | Grep codebase + memory · purge any reference |
| Group cash drops to 0 RON or shows €−X with X > 100K | Resolver fell back to empty · OR a sign-flip bug entered an entity total | Section 14 flow diagram · trace from UI cell upward to source · likely keezByEnt empty |
| Truth-check Sunday rebuild never fires | The piggyback in cash-daily-truth-check.js got removed · variance + refacturare drift stale | Re-add the getUTCDay() === 0 block · invariant cash-daily-elena-zero-dep-crons-scheduled defends this |
Day-by-day actions for controlling@ during Elena's first 5 working days of absence. After this, the daily/weekly/monthly cadence from §19 takes over.
/cash-daily/ · verify quality strip + variance verdictcla_cd_elena_decisions_log via /api/cash-daily-elena-decisions-log · review what rules are already locked in (Q30/Q31 + any other answers that landed)cla_cd_refacturare_mapping and cla_cd_variance_thresholds · both should have updated_at Sunday ~07:01 UTC. PAF folder scan: same time.a16db0b4 deadline · expected per-IBAN feasibility reply/audit-confirmations/) is INTENTIONALLY NOT integrated with cash-daily. Round 12 audit (2026-06-02) confirmed 0 shared tool_keys + 0 code cross-references. The two modules serve different practices (Audit external-confirmation workflow vs Controlling cash-position reporting) and have no semantic overlap. Do NOT wire them together · the request usually comes from misunderstanding the audit-confirmations module's scope (it's about bank/legal confirmation letters for audited entities · not about cash balances).
Per Elena 2025-12-01 PDF · the canonical channel for maintaining the BPS Payroll client list is an email to controlling@cla.com.ro with the subject containing ADJUSTMENTS. The Hub-side parser at /api/cash-daily-adjustments-parser reads the email body and applies the actions.
| Verb | Format | Example |
|---|---|---|
ADD client | ADD client: <CODE> · <FULL NAME> | ADD client: ZEBRA · ZEBRA TECHNOLOGIES SRL |
REMOVE client | REMOVE client: <CODE> | REMOVE client: KAVO |
RENAME client | RENAME client: <OLD> → <NEW> | RENAME client: BUCK → BUCK_PAYROLL |
ADD category | ADD category: <NAME> | ADD category: BONUSURI |
controlling@cla.com.ro · subject must contain "ADJUSTMENTS" (any position · case-insensitive)/api/cash-daily-adjustments-parser?action=apply (partner-level auth) · or pastes into the Hub admin UI (pending)cla_cd_bps_payroll_clients_v1 · invariant-pinned · auto-confirmed by partner rolecurl -sS -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"https://app.cla.com.ro/api/cash-daily-adjustments-parser?action=parse" \
-d '{
"subject": "ADJUSTMENTS · 2026-06-10",
"body": "ADD client: ZEBRA · ZEBRA TECHNOLOGIES SRL\nREMOVE client: KAVO"
}' | jq .
# Returns: { mode: 'dry_run', parsed: 2, actions: [...] }
# Replace ?action=parse with ?action=apply to commit (partner-only).
Each apply writes a new row to hub_tool_data with the full updated client list · de-duplicated by tool_key + updated_at. To see what changed when · query:
SELECT updated_at, updated_by, data->'last_adjustment_applied_at' FROM hub_tool_data WHERE tool_key = 'cla_cd_bps_payroll_clients_v1' ORDER BY updated_at DESC LIMIT 20;
JSDoc-style summary of every endpoint built or extended during the 2026-06-01 Elena-zero-dep sprint. All have setCors + auth (cron-bearer OR validated user · partner-level on writes) + plain INSERT (no ON CONFLICT) + pool.end() in finally.
| Endpoint | Methods · params | Writes to | Auth |
|---|---|---|---|
1. /api/cash-daily-bank-statement-ingestAccept per-IBAN bank statement rows from any source (Playwright local · RezolvIT RPA · manual). Lands gap-coverage data for the 3 accounts NOT in Keez Open Banking. |
POST body: { date, bank, source, rows[] }GET ?date=YYYY-MM-DD |
cla_cd_bank_statements_<YYYYMMDD> |
cron OR partner |
2. /api/cash-daily-variance-thresholdsP95 day-over-day delta per (section, entity) · 6 day-of-month buckets · weekend-skip baseline · auto-confirm verdict. |
?action=recompute · ?action=check&date=Y-M-D · GET (no action) reads thresholds |
cla_cd_variance_thresholds |
partner on recompute · any auth on read |
3. /api/cash-daily-refacturare-infer5-tier vendor→client lookup: PAF description decoder · PAF folder index · inferred exact · inferred fuzzy (Lev≤2) · inferred substring. Supports cascade=variance. |
?action=rebuild · ?action=suggest&vendor=X · ?action=suggest&date=Y-M-D · GET (no action) reads mapping |
cla_cd_refacturare_mapping |
partner on rebuild |
4. /api/cash-daily-paf-folder-scanScans SP 02. PAYMENT RECORDS / 03. CLA BPS PAYROLL / YYYY_MM · parses <CLIENT>_(OP|MACHETA_PLATI)_<CATEGORY> filenames against 15-client list. |
?action=scan&yyyy_mm=YYYY_MM · ?action=scan-all |
cla_cd_paf_folder_index |
partner on scan |
5. /api/cash-daily-adjustments-parserParses ADJUSTMENTS emails for 4 action verbs (ADD/REMOVE/RENAME client · ADD category). Dry-run + apply modes. |
POST body: { subject, body } · ?action=parse dry-run · ?action=apply commits |
cla_cd_bps_payroll_clients_v1 |
partner on apply |
6. /api/cash-daily-balance-trendPer-entity balance history series (max 90 days). 13-entity grid · summary deltas. Powers diagnostics sparklines. |
?entity=NAME&days=30 · ?days=30 all entities |
(read-only) | any auth |
| Tool_key (latest snapshot wins) | Producer endpoint | Consumed by |
|---|---|---|
cla_cd_bank_statements_<YYYYMMDD> | bank-statement-ingest | resolver (fallback row in Cash & Bank table) |
cla_cd_variance_thresholds | variance-thresholds (recompute) | variance check · UI quality strip · daily-brief · truth-check |
cla_cd_refacturare_mapping | refacturare-infer (rebuild) | refacturare suggest · UI quality strip · diagnostics |
cla_cd_paf_folder_index | paf-folder-scan | refacturare-infer (tier 2 lookup) · diagnostics |
cla_cd_bps_payroll_clients_v1 | adjustments-parser (apply) + manual loader | refacturare-infer (tier 1 PAF decoder) · methodology |
cla_cd_elena_decisions_log | manual loader script | methodology §15 · audit trail |
cla_cash_daily_report_<YYYYMMDD> | truth-check (writes checks · variance_verdict · ar_aging) | UI · Excel export · diagnostics · variance UI blob-first read |
| Time (UTC) | Cron path | What it does |
|---|---|---|
00:00 / 02:00 / … (every 2h) | /api/keez-sync?action=sync | Pull Keez Balanță reports |
06:30 Mon-Fri | /api/daily-brief | Generates report blob · now also fetches variance verdict inline |
07:00 daily | /api/cash-daily-truth-check?send=true | 21 checks · email · ON SUNDAY: cascades refacturare-rebuild + variance-recompute + paf-folder-scan-all |
# All 6 endpoints health · paste into terminal SECRET=$(grep '^CRON_SECRET=' .env.local | cut -d= -f2 | tr -d '"') for ep in \ cash-daily-bank-statement-ingest \ cash-daily-variance-thresholds \ cash-daily-refacturare-infer \ cash-daily-paf-folder-scan \ cash-daily-adjustments-parser \ cash-daily-balance-trend; do echo "→ $ep" curl -sS -H "Authorization: Bearer $SECRET" "https://app.cla.com.ro/api/$ep" | jq -r '.ok // .error // "?"' | head -1 done