Skip to content

Manually-uploaded Service Invoices → Drive (14d) + storage survey/migrate backfill

What / Why

Manually-uploaded service (vendor) invoices were landing in the aote-pms.firebasestorage.app GCS bucket via uploadReceiptToStorage. Owner expects them on Google Drive alongside WOPCs (14c) and Telegram receipts, organised by category — so the on-Drive expense shelf reads consistently. Extends the ERL expense Drive taxonomy (14a Expense Receipts / 14b Vendor Invoices / 14c WOPC) with 14d. Service Invoices.

DONE (origin/nightly, NOT main)

  • Storage migration (c5f1e5bb, #735)lib/accounting/serviceInvoiceDrive.server.ts: buildServiceInvoiceFilename (<SUB>_Invoice_Service_<YYYYMMDD>_<merchant>[_<invoiceNumber>].<ext>, mirrors Telegram + WOPC naming) + uploadServiceInvoiceToDrive → files land at {subsidiary}/50. Operational Strategy/14. Expenses Records/{YYYY}/14d. Service Invoices/{Category}/{file}. Top two tree levels must pre-exist (refuses to create); year + 14d. + category folder lazy-created on first use (same pattern as WOPCs 14c.). Upload endpoint now writes storagePath: drive:<fileId>. RecordsApp / VendorInvoiceUploadModal / VendorInvoiceDetailDrawer + pages/v/[id] UI rename.
  • Codex follow-ups (47c97739, P2 on #735) — (1) deleteReceiptFromStorage now detects the drive: prefix and routes to trashFile() via the accounting purpose SA (was no-op'ing on Drive ids → orphaned files); trash, not purge. (2) The streaming endpoint /api/accounting/receipts/[id]?redirect=pdf now honours receipt.mimeType instead of hard-coding application/pdf (image-typed Service Invoices were served as PDF, breaking preview/download).
  • Admin survey + migrate (939954d2, #736) — two admin-only endpoints (run server-side with the existing Firestore + Drive SAs, no local credential exposure) to audit + backfill file-archive records uploaded BEFORE the migration (still carry legacy receipts/… GCS paths):
  • GET /api/admin/file-storage-survey — classifies aote-system/file-archive/documents/entries into drive / firebase-storage / empty / unknown, counts grouped by (backend, type, subsidiaryId); ?merchant=<substr> locates a specific doc (e.g. the Lalal.ai invoice) by name.
  • POST /api/admin/migrate-to-drive — backfills legacy GCS-backed records to Drive.

T-044 (GCP/Workspace invoice PDFs on Records via drive: serve) · T-021 (file-archive store migration) · [[project_eop_deploy_and_expense_folders]] (14a/14b/14c Drive taxonomy — now +14d) · [[project_receipts_subsystem_state]]. Cloud agent's records/Drive area.