Files
product_inventory/docs/ARCHITECTURE.md
Ben Miller 85cdfe1443 feat: implement status automation and router pattern
- Implemented modular status automation system (statusHandlers.ts).
- Added handlers for 'Published' (Active/Qty 1), 'Sold' (Active/Qty 0), and 'Drafted'.
- Refactored onEdit triggers into a central Router pattern in OnEditHandler.ts.
- Updated Product.ts to support explicit quantity setting (fixed 0 value bug).
- Updated shopifyApi.ts to implement SetInventoryItemQuantity (using ignoreCompareQuantity).
- Consolidated triggers into single onEditHandler.
- Updated project documentation.
2025-12-24 23:55:28 -07:00

89 lines
3.9 KiB
Markdown

# 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.
### 5. Status Automation (`src/statusHandlers.ts`)
A modular system handles changes to the `status` column. It uses a registry of `StatusHandler` implementations:
- **Published**: Sets Shopify Status `ACTIVE`, Quantity `1`.
- **Sold/Artist Swap**: Sets Shopify Status `ACTIVE`, Quantity `0`.
- **Drafted**: Sets Shopify Status `DRAFT`.
## Triggers
Triggers are managed programmatically via `src/triggers.ts`. Running `reinstallTriggers` will wipe existing project triggers and set up the standard set:
- `onEdit` -> `onEditHandler` (Main Router)
- `TimeBased (1 min)` -> `processBatchedEdits`
- `TimeBased (10 min)` -> `checkRecentSales`
### 5. Troubleshooting Panel (`src/sidebar.ts`, `src/Sidebar.html`)
A dedicated side panel provides visibility into the background queue system.
- **Backend (`src/sidebar.ts`)**:
- `getQueueStatus()`: Returns the current state of the queue and global toggle.
- `setQueueEnabled()`: Toggles the global `queueEnabled` script property.
- `deleteEdit()` / `pushEdit()`: Manages specific items in the queue with safety checks.
- **Frontend (`src/Sidebar.html`)**:
- Displays pending edits with timestamps.
- Provides controls to globally enable/disable processing.
- Allows manual intervention (delete/push) for individual items.