What this audit checks
Authentication & access
- OAuth refresh token still valid - token exchange succeeds and is not revoked / expired
- Granted scopes include spreadsheets.readonly AND drive.metadata.readonly (freshness needs Drive)
- Configured spreadsheet_id resolves - spreadsheets.get returns 200, not 404 (deleted) or 403 (access revoked)
- Configured range_a1 / sku_column still resolve against the current tab and header row
Freshness & feed health
- Sheet not edited within expected cadence - Drive modifiedTime older than refresh threshold (default 168h) signals a stalled upstream job
- Row count dropped sharply vs the last run (>20% fewer populated rows = truncated export or accidental over-write)
- Primary tab emptied - populated range collapsed to header-only since last run
Schema integrity
- Header signature drift - header row differs from the last-known-good signature (renamed / reordered / deleted column)
- Named range missing or moved - a namedRange the importer references no longer resolves
- Required column absent - the configured sku_column (or other importer-required header) is gone from the header row
Cell-level data integrity
- Error-cell rate above threshold - #REF!/#N/A/#DIV/0!/#VALUE!/#NAME?/#NULL!/#NUM! cells in read rows (>1%)
- Blank-row rate above threshold - empty rows inside the populated range (>10%) break range-based importers
- Grid bloat - workbook approaching the 10M-cell ceiling (sustained growth from append-only feeds)
Cross-channel: catalogue drift (revenue at risk)
- Price/cost drift - sheet row diverges from the live storefront price for the same SKU by >5% (sibling = bigcommerce.product / shopify.product / adobe_commerce.product on sku)
- Orphan SKUs - SKUs in the sheet missing from the live catalogue (stale feed ran ahead of store sync, or typos)
- Missing SKUs - catalogue SKUs absent from the source-of-truth sheet (override gap; product selling without a managed cost/price row)
Data sources
GET https://sheets.googleapis.com/v4/spreadsheets/{spreadsheet_id}- Workbook metadata, tab list (sheets[]), named ranges, grid sizesGET https://sheets.googleapis.com/v4/spreadsheets/{spreadsheet_id}/values/{range}- Cell values for the read range; FORMATTED_VALUE render surfaces error-cell stringsGET https://sheets.googleapis.com/v4/spreadsheets/{spreadsheet_id}/values:batchGet- Coalesce multi-tab / multi-range reads into one request to stay under quotaGET https://www.googleapis.com/drive/v3/files/{spreadsheet_id}- modifiedTime + owner for freshness (Sheets API does not expose modified-time)GET https://www.googleapis.com/drive/v3/files/{spreadsheet_id}/revisions- Revision history for edit cadence and who-changed-what attribution