Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# WooCommerce demo & local setup
|
||||
|
||||
Descrybe v2 pulls **products** (push), **orders**, and **reviews** from WooCommerce REST API, then uses synced orders for campaign audiences (`purchased` / `not_purchased`).
|
||||
|
||||
## Point at a Woo store
|
||||
|
||||
1. In WordPress/WooCommerce: **WooCommerce → Settings → Advanced → REST API** → Add key (Read/Write).
|
||||
2. Copy **Consumer key** (`ck_…`) and **Consumer secret** (`cs_…`).
|
||||
3. In Descrybe: open **`/woocommerce`** → enable sync → paste **Store URL** (https; `http://localhost` allowed for local) + credentials → **Save** → **Test Connection**.
|
||||
4. Queue **product sync**, then **Orders** / **Reviews**. Run the worker (`make worker` / `go run ./cmd/worker`) so pending flags are claimed.
|
||||
|
||||
### Env vars (optional live path)
|
||||
|
||||
Set in process env or untracked `.env` (never commit secrets):
|
||||
|
||||
| Variable | Purpose |
|
||||
|---|---|
|
||||
| `WOO_STORE_URL` | Store base URL, e.g. `https://shop.example.com` or `http://localhost/myshop` |
|
||||
| `WOO_CONSUMER_KEY` | REST consumer key |
|
||||
| `WOO_CONSUMER_SECRET` | REST consumer secret |
|
||||
|
||||
Aliases `WOOCOMMERCE_STORE_URL` / `WOOCOMMERCE_CONSUMER_KEY` / `WOOCOMMERCE_CONSUMER_SECRET` also work.
|
||||
|
||||
Credentials saved via the UI are encrypted at rest (`CREDENTIALS_ENCRYPTION_KEY` — see [ops-runtime.md](ops-runtime.md)).
|
||||
|
||||
### Local Laragon / XAMPP Woo
|
||||
|
||||
If you already run WordPress+Woo under Laragon, use that URL (often `http://localhost/...`). Descrybe allows **http only for localhost/loopback**; private LAN IPs are blocked by SSRF guards — tunnel or use public/https hosts for remote shops.
|
||||
|
||||
### No live Woo? Seed demo data
|
||||
|
||||
Full WordPress+Woo docker is intentionally **not** bundled (heavy). Use the DB seed instead:
|
||||
|
||||
```powershell
|
||||
cd apps/api
|
||||
$env:DATABASE_URL = "postgres://descrybe:descrybe@localhost:5433/descrybe?sslmode=disable"
|
||||
# Optional: load CREDENTIALS_ENCRYPTION_KEY / TOKEN_SIGNING_SECRET from root .env so config encrypt matches the API
|
||||
go run ./cmd/seed-woo-demo -postgres $env:DATABASE_URL -company "Local Demo Co"
|
||||
```
|
||||
|
||||
Or from repo root: `make seed-woo`.
|
||||
|
||||
What it inserts (idempotent upserts):
|
||||
|
||||
- Category **Demo Electronics**
|
||||
- 3 demo `processed_products` (`DEMO-WOO-*` SKUs)
|
||||
- 4 `woo_orders` + line items (3 buyers of Demo Electronics, 1 Accessories-only)
|
||||
- 3 `product_reviews`
|
||||
- `woocommerce_configs` row (placeholder URL unless `WOO_*` set)
|
||||
- Draft campaign **Woo demo — purchased electronics** with `audience_filter.type=purchased`
|
||||
|
||||
If `WOO_*` is set, the seed encrypts those credentials, enables sync, and tests REST (`-live` fails closed on connection errors).
|
||||
|
||||
## APIs to exercise
|
||||
|
||||
| Method | Path | Notes |
|
||||
|---|---|---|
|
||||
| GET | `/api/woocommerce` | Config + sync badges |
|
||||
| PUT | `/api/woocommerce` | Save store URL + credentials |
|
||||
| POST | `/api/woocommerce/test` | Live REST system status |
|
||||
| POST | `/api/woocommerce/sync` | Queue product push |
|
||||
| POST | `/api/woocommerce/sync-orders` | Queue orders pull |
|
||||
| POST | `/api/woocommerce/sync-reviews` | Queue reviews pull |
|
||||
| GET | `/api/woocommerce/orders` | List synced orders |
|
||||
| GET | `/api/woocommerce/reviews` | List synced reviews |
|
||||
| POST | `/api/woocommerce/audience` | `{ "bought_category": "Demo Electronics" }` |
|
||||
|
||||
Campaign send resolves `audience_filter` with `type` + `category_ids` (UI) or `bought_category` (API).
|
||||
|
||||
## Sync → audience → campaigns
|
||||
|
||||
1. `go run ./cmd/seed-woo-demo` (or live sync orders).
|
||||
2. UI: `/woocommerce` → Orders / Reviews populated.
|
||||
3. `POST /api/woocommerce/audience` with `bought_category: "Demo Electronics"` → Anna / Ben / Cara.
|
||||
4. `/campaigns` → open draft **Woo demo — purchased electronics** (purchased audience on Demo Electronics).
|
||||
5. Wizard also exposes **Purchased in category** when any orders exist.
|
||||
|
||||
## Quick verify SQL
|
||||
|
||||
```sql
|
||||
SELECT count(*) FROM woo_orders WHERE company_id = (SELECT id FROM companies WHERE name = 'Local Demo Co');
|
||||
SELECT count(*) FROM product_reviews WHERE company_id = (SELECT id FROM companies WHERE name = 'Local Demo Co');
|
||||
SELECT name, audience_filter FROM email_campaigns WHERE name ILIKE 'Woo demo%';
|
||||
```
|
||||
Reference in New Issue
Block a user