# Architecture Documentation ## System Overview This project serves as a bridge between Google Sheets and Shopify. It enables a two-way sync (primarily Sheets to Shopify for products) and allows managing inventory directly from a spreadsheet. ### Core Flows 1. **Product Updates**: - User edits a cell in the "product_inventory" sheet. - `onEditQueue` trigger fires, capturing the SKU and timestamp. - Edits are batched in `PropertiesService` (script properties). - A time-based trigger runs `processBatchedEdits` every minute. - The processing function locks the script, reads the queue, and pushes changes to Shopify via the Admin API. 2. **Order Sync**: - Users can run menu commands to fetch orders from Shopify. - The `Shop` class fetches orders via the REST API, handling pagination. - Data is populated into specific sheets (`_orders`, `_line_items`, `_customer`, etc.). ## Key Components ### 1. Queue System (`src/onEditQueue.ts`) To avoid hitting Shopify API rate limits and Google Apps Script execution time limits, edits are not processed immediately. - **`onEditQueue(e)`**: - Triggered on every cell edit. - Checks if the edit is valid (correct sheet, valid SKU). - Acquires a `DocumentLock`. - Updates a JSON list in `ScriptProperties` (`pendingEdits`). - Debounces edits (updates timestamp if SKU is already pending). - **`processBatchedEdits()`**: - Run via time-based trigger (every 1 minute). - Acquires a `ScriptLock`. - Reads `pendingEdits`. - Filters for edits older than `BATCH_INTERVAL_MS` (30s) to allow for multiple quick edits to the same SKU. - Iterates through valid edits and calls `Product.UpdateShopifyProduct`. ### 2. Shopify Integration (`src/shopifyApi.ts`) The project uses a hybrid approach for the Shopify Admin API: - **REST API**: Used primarily for fetching Orders (legacy support). - **GraphQL API**: Used for fetching and updating Products and Inventory. The `Shop` class handles authentication using credentials stored in the "vars" sheet. ### 3. Configuration (`src/config.ts`) Configuration, including API keys, is stored in a dedicated Google Sheet named "vars". The `Config` class reads these values at runtime using a `vlookup` style helper. **Required "vars" columns:** - `key`: The name of the configuration variable. - `value`: The actual value. ### 4. Global Entry Points (`src/global.ts`) Since Apps Script functions must be top-level to be triggered or attached to buttons, `src/global.ts` explicitly exposes necessary functions from the modules to the global scope. ## Triggers Triggers are managed programmatically via `src/triggers.ts`. Running `reinstallTriggers` will wipe existing project triggers and set up the standard set: - `onEdit` -> `newSkuHandler` - `onEdit` -> `matchProductToShopifyOnEditHandler` - `onEdit` -> `onEditQueue` - `TimeBased (1 min)` -> `processBatchedEdits`