# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

```bash
# Install dependencies
npm install

# Start server (uses supervisor for auto-restart)
npm start
# or directly:
node server.js

# No test suite is configured
```

The server runs on port `8008` by default (overridden via `PORT` env var). It starts an HTTPS server using SSL certs at `/etc/agrimSSL/api.dev.agrim-ai.com/`. In local dev without those certs, swap `https.createServer(sslOptions, app)` for `http.createServer(app)`.

Logs are written to `/app.log` via Winston (not stdout).

## Environment Variables

Copy from `.env` — key vars:

| Variable | Purpose |
|---|---|
| `APP_URL` | PHP backend base URL (token validation, DB ops, webhook forwarding) |
| `SHOPIFY_NODE_APP_URL` | This Node server's public URL (used as webhook callback base) |
| `SHOPIFY_APP_URL` | Frontend URL (OAuth redirect destination for `exceptional_shops`) |
| `PORT` | Server port (default: 8008) |

## Architecture

This is a **Shopify app backend** that acts as a middleware layer between Shopify stores and the Agrim PHP CMS (`APP_URL`). It has no database of its own — all persistent data lives in the PHP backend or the Azure MySQL DB accessed by the WebSocket server.

### OAuth Flow

Two distinct flows exist in `server.js`:

1. **`exceptional_shops`** (e.g. `ja973i-xq.myshopify.com`): Uses `@shopify/shopify-api` SDK for the full OAuth callback. On success, redirects the browser to `APP_URL/Shopify.html`.
2. **All other shops**: Returns a JSON `{ authUrl }` to the frontend, which redirects the user. The callback exchanges the code manually via Shopify's token endpoint, then calls `APP_URL/CreateDBShop` to persist the token.

Both flows register product/order/GDPR webhooks on first install if they don't already exist.

### Per-shop API Credentials

`config/config_store.js` holds a `Config_keys` map from shop domain → `{ api_key, api_secret, app_handle }`. If a shop isn't in the map, it falls back to `Config_keys["other_main"]`. Add new shops here for per-shop app credentials.

### Auth Middleware

**`middleware/verifyToken.js`** — Applied to all `/app/*` data routes. Calls `APP_URL/accessTokenValidation` with the shop name. If the token is expired, it automatically refreshes using the Shopify refresh-token grant and calls `APP_URL/updateUserToken` to persist the new tokens.

**`middleware/verifyHMac.js`** — Applied to GDPR webhook routes. Validates the `X-Shopify-Hmac-Sha256` header against the raw request body using the shop's API secret. Requires `req.rawBody` (set in the `express.json` verify callback in `server.js`).

### Webhook Handlers

- **GDPR webhooks** (`controllers/Webhooks.js`): `customers/data_request`, `customers/redact`, `shop/redact`, `app/uninstalled` — forward events to `APP_URL/CreateWebhook` or `APP_URL/DeleteBotData`
- **Product webhooks** (`webhooks/ProductWebhooks.js`): Forward create/update/delete to `APP_URL/shopifyWebhooks`
- **Order webhooks** (`webhooks/OrderWebhooks.js`): Forward create/update/cancel/paid/fulfilled to `APP_URL/shopifyWebhooks`. Uses per-event-type LRU caches (10 min TTL) to deduplicate duplicate webhook deliveries from Shopify.
- **App subscription** (`webhooks/AppSubscription.js`): Handles billing subscription updates

Webhook registration logic lives in `helper/webhooks.js`. It checks for existing webhooks before registering to avoid duplicates (`isAppUninstalledWebhookExist` checks both topic and address).

### WebSocket Server (`web_socket.js`)

Started alongside Express in `server.js` via `start(server)`. Connects directly to the Azure MySQL DB (`dbagrim.mysql.database.azure.com`) — **not** through `APP_URL`. Opens a new DB connection per push cycle (every 2 seconds). Handles three channels: `whatsapp`, `instagram`, `facebook`.

Message types from client:
- `join` / `refresh_notifications` — triggers `pushChatData` + `pushNotificationData`
- `update_user_list` — triggers `update_user` which also manages `picked_user_by_agent` table state

`web_socket_8may_Allwokring.js` is an archived backup — not loaded anywhere.

### Billing (`controllers/Billing.js`)

Uses Shopify GraphQL Admin API to fetch active subscriptions. If no active plan, returns a redirect URL to the Shopify pricing plans page using the app handle from `Config_keys`.

### Storefront Cart (`controllers/Cart.js`)

Uses the Shopify Storefront API (not Admin API) to create and fetch carts. Requires the `StoreFrontAccessToken` which is fetched via `controllers/Access.js`.
