Skip to content

I-038 — Bank statements hit Drive as the wrong service account

✅ Attestation: read AGENTS.md · board checked by scope (no open T/I covers statement filing — T-167/I-033 are Airwallex-API-side; this is the Drive filing layer) · ticket-only fix (one-line purpose at three call sites). Source: Bank Access (Diagnosticcs) · https://claude.ai/code/session_01S4ztAsDZfR97qXjhPdwLn4

Symptom

Owner (2026-08-27): bell notification "Airwallex statement check — No new statements (cross-checked against your filed history). 3 period(s)/currency could not be fetched — see server logs." The three errors (from the notification's own metadata.results) are HKD 2026-06, HKD 2026-07, USD 2026-07 — each File not found: 1unDRIJsAQKyuwBogEm2cLKWfbc4x_00c. (the ERL "i. Bank Statements (For Airwallex)" Drive folder). Every sync run since 2026-07-23 shows the same failures — those three statements were fetched from Airwallex fine but have never been filed.

Root cause

lib/drive/client.ts reads per-workload SA creds; getDriveClient's bare default is 'receipts' (drive-receipts@, Manager on the Telegram receipts subtree ONLY). The bank-statement surface never passed purpose, so in production (where DRIVE_RECEIPTS_* env vars exist) it authenticates as the receipts SA — which cannot see the ERL shared drive. Drive reports inaccessible items as File not found (404), which masqueraded as a missing folder.

Verified empirically (2026-08-27): - Folder exists, not trashed; ACL = drive-accounting@ (fileOrganizer), service@ (fileOrganizer), owner + Jake (organizer). drive-receipts@ absent. - Replayed the exact failing op as drive-accounting@ with the production key from Vercel: files.create in that folder → 200. (Probe file trashed after.)

Fix (this commit)

purpose: 'accounting' at the three bank-statement Drive call sites:

  • lib/bankStatements/store.ts — uploadFile in storeStatement (the filing failure; shared by the Airwallex AND OCBC statement syncs — OCBC was latently exposed, just had nothing new to file)
  • pages/api/bank-statements/download-zip.ts — downloadFile (bulk ZIP download)
  • pages/api/bank-statements/[id]/file.ts — downloadFile (single-statement viewer)

No infra change: drive-accounting@ already holds the right access; granting the receipts SA access to the ERL drive was rejected as it defeats the per-workload key isolation the split exists for.

Activation requires the next production deploy (🚷 owner-commanded only). The sync is idempotent — the first run after that deploy backfills the three missing statements automatically.

Log

  • 2026-08-27 — Diagnosed from the notification's stored metadata.results (Firestore aote-system / notifications) + live Drive/Vercel probes; fixed all three call sites; ships via GitHub PR. Source: Bank Access (Diagnosticcs) · https://claude.ai/code/session_01S4ztAsDZfR97qXjhPdwLn4