# Project Memory ## Project Context This project (`product_inventory`) integrates Google Sheets with Shopify. It serves as a master inventory management tool where users edit product data in a Google Sheet, and scripts automatically sync those changes to Shopify. **Critical Components:** - **Google Apps Script**: Runs the logic. - **"vars" Sheet**: Holds all configuration and API keys. NEVER hardcode credentials. - **Shopify Admin API**: Used for syncing. REST for Orders, GraphQL for Products. ## Work Patterns & Agreements 1. **Documentation First**: Before implementing complex features, we update the plan and often the documentation (README/ARCHITECTURE). 2. **Safety First**: We use `SafeToAutoRun: false` for commands that deploy or modify external state until verified. 3. **Strict Typing**: We use TypeScript. No `any` unless absolutely necessary (and even then, we try to avoid it). 4. **TDD**: We follow Test Driven Development (Red/Green/Refactor). Write failing tests before implementing features. 5. **Artifact Usage**: We use `task.md`, `implementation_plan.md`, and `walkthrough.md` to track state. ## Key Technical Decisions - **Queue System**: We implemented `onEditQueue.ts` to batch edits. This prevents hitting Shopify API rate limits and Google Apps Script execution limits during rapid manual edits. - **Hybrid API**: We use REST for retrieving Orders (legacy/easier for flat data) and GraphQL for Products (more efficient/flexible). - **Global Exports**: Functions in `src/global.ts` are explicitly exposed to be callable by Apps Script triggers. ## User Preferences - **OS**: Windows. - **Shell**: PowerShell. - **Node Manager**: `fnm`. 28: 29: ## Integrated Media Manager 30: We implemented a "Sidebar-First" architecture for product media (Option 2): 31: - **Frontend**: `MediaSidebar.html` uses Glassmorphism CSS and Client-Side Polling to detect SKU changes. 32: - **Google Picker**: Integrated via `picker.js` using an API Key and OAuth Token passed securely from backend. 33: - **Drive as Source of Truth**: All uploads go to Drive first (Folder structure: `Root/SKU/Files`). 34: - **Shopify Sync**: `MediaService` orchestrates the complex `Staged Uploads` -> `Create Media` mutation flow. 35: - **Security**: `appsscript.json` requires explicit scopes for `userinfo.email` (Picker), `drive` (Files), and `drive` (Advanced Service). API Keys are stored in `vars` sheet, never hardcoded. ### Media Handling Quirks - **Google Photos Picker**: - The `baseUrl` returned by the Picker API is hidden inside `mediaFile.baseUrl` (not top-level). - Downloading this URL requires an **Authorization header** with the script's OAuth token, or it returns 403. 1. Sanitize with `Utilities.newBlob()`. 2. Fallback to **Advanced Drive Service** (`Drive.Files.create` / `v3`) if standard creation fails. - **Video Previews**: - HTML5 `