Benjamin Harris пре 2 недеља
комит
2290a31219
2 измењених фајлова са 171 додато и 0 уклоњено
  1. 170 0
      CLAUDE.md
  2. 1 0
      README.md

+ 170 - 0
CLAUDE.md

@@ -0,0 +1,170 @@
+# Reverb OpenCart Integration
+
+An OpenCart extension that syncs products, stock, prices, orders, and images between an OpenCart store and a Reverb.com marketplace listing.
+
+## Project Overview
+
+**Type:** OpenCart 3.x Extension (with planned OpenCart 4.x compatibility)
+
+**Primary Market:** Australia (reverb.com/au)
+
+**Sync Direction:** Bidirectional (OpenCart ↔ Reverb)
+
+## Reference Documentation
+
+- [Reverb Developer Integrations](https://reverb.com/au/page/integrations)
+- [Reverb Help: Developer Sections](https://help.reverb.com/hc/en-us/sections/40908931289883)
+- [OpenCart Extension Development Guide](https://github.com/opencart/opencart/wiki/OpenCart-Extension-Development-Guide)
+- Reverb API Base URL: `https://api.reverb.com/api/`
+- Auth: `Authorization: Bearer <token>` + `Accept-Version: 3.0` headers
+
+## Requirements
+
+### Admin Settings Page
+
+The extension must provide an admin panel (`Admin > Extensions > Modules > Reverb`) that allows the store owner to:
+
+- Enter and save their personal Reverb.com API token
+- Select sync direction: One-way (OpenCart → Reverb) or Both-ways (bidirectional)
+- Select which OpenCart categories are eligible for sync
+- Manually trigger a full catalogue sync
+
+### Product Page Integration
+
+Each product in the OpenCart admin must show a toggle/checkbox to:
+
+- Enable or disable syncing that individual product to Reverb
+- Show the Reverb listing ID and a direct link once the product is listed
+
+### Sync Scope (Bidirectional)
+
+| Field        | OC → Reverb | Reverb → OC |
+|--------------|:-----------:|:-----------:|
+| Title / Name | ✓           | ✓           |
+| Description  | ✓           | ✓           |
+| Price        | ✓           | ✓           |
+| Stock / Qty  | ✓           | ✓           |
+| Images       | ✓           | —           |
+| Orders       | —           | ✓           |
+
+## Extension Architecture (OpenCart 3.x)
+
+### File Structure
+
+```
+upload/
+├── admin/
+│   ├── controller/extension/module/
+│   │   └── reverb.php              # Admin settings + manual sync trigger
+│   ├── language/en-gb/extension/module/
+│   │   └── reverb.php              # All user-facing strings
+│   ├── model/extension/module/
+│   │   └── reverb.php              # DB interactions (token storage, product map)
+│   └── view/template/extension/module/
+│       └── reverb.twig             # Admin settings form
+├── catalog/
+│   └── controller/extension/module/
+│       └── reverb.php              # Webhook endpoint for Reverb callbacks
+└── system/
+    └── library/reverb/
+        ├── ReverbApi.php           # HTTP client wrapping the Reverb REST API
+        ├── ProductMapper.php       # Maps OC product fields ↔ Reverb listing fields
+        └── OrderMapper.php         # Maps Reverb order payload → OC order format
+```
+
+OCMOD patch file (`reverb.ocmod.xml`) injects the per-product toggle into the product edit page without modifying core files.
+
+### Database Tables
+
+The extension creates and manages the following tables.
+
+**`oc_reverb_product_map`**
+
+| Column             | Type         | Notes                              |
+|--------------------|--------------|------------------------------------|
+| `product_id`       | INT          | FK to `oc_product`                 |
+| `reverb_listing_id`| VARCHAR(64)  | Reverb's listing ID once synced    |
+| `sync_enabled`     | TINYINT(1)   | Per-product on/off toggle          |
+| `last_synced_at`   | DATETIME     | Timestamp of last successful sync  |
+
+**`oc_reverb_sync_log`**
+
+| Column       | Type                      | Notes                   |
+|--------------|---------------------------|-------------------------|
+| `log_id`     | INT AUTO_INCREMENT        |                         |
+| `product_id` | INT                       |                         |
+| `direction`  | ENUM('push','pull')       |                         |
+| `status`     | ENUM('success','error')   |                         |
+| `message`    | TEXT                      | Error detail or summary |
+| `created_at` | DATETIME                  |                         |
+
+API token, sync mode, and category whitelist are stored in OpenCart's native `oc_setting` table via `$this->config` — no custom config table needed.
+
+### Key Design Decisions
+
+1. **API Token storage:** Stored via OpenCart's native settings system (`oc_setting`) with the key prefix `module_reverb_`. Never stored in a raw custom table.
+2. **Per-product toggle:** Stored in `oc_reverb_product_map.sync_enabled`; defaults to `0` (disabled) for all products.
+3. **Category filter:** Admin selects OpenCart categories; only products in those categories AND with `sync_enabled = 1` are synced.
+4. **Webhooks vs polling:** Use Reverb webhooks for real-time order/listing updates; fall back to a scheduled cURL ping (OpenCart cron or system cron calling `catalog/controller/extension/module/reverb/cron`) for stock/price polling.
+5. **Image sync:** Upload OpenCart product images to Reverb via `POST /listings/{id}/photos`. Only push images OC → Reverb; do not pull images back.
+
+## Reverb API Essentials
+
+Base URL: `https://api.reverb.com/api/`
+
+Required headers on every request:
+
+```
+Authorization: Bearer <token>
+Accept-Version: 3.0
+Content-Type: application/hal+json
+```
+
+Rate limit: ~100 requests/min on the standard plan — batch operations where possible.
+
+Key endpoints:
+
+| Endpoint                    | Method | Purpose                            |
+|-----------------------------|--------|------------------------------------|
+| `/my/listings`              | GET    | Fetch the seller's existing listings |
+| `/listings`                 | POST   | Create a new listing               |
+| `/listings/{id}`            | PUT    | Update an existing listing         |
+| `/listings/{id}/end`        | PUT    | End/delist a listing               |
+| `/listings/{id}/photos`     | POST   | Upload a photo to a listing        |
+| `/my/orders`                | GET    | Fetch seller orders                |
+| `/my/orders/{order_number}` | GET    | Fetch a single order               |
+| `/webhooks`                 | POST   | Register a webhook endpoint        |
+| `/categories/flat`          | GET    | Fetch the full Reverb category tree |
+
+## Sync Flow
+
+### OpenCart → Reverb (triggered on product save event or manual sync)
+
+1. Check product has `sync_enabled = 1` AND is in an allowed category.
+2. Map OC product fields to a Reverb listing payload via `ProductMapper::toReverb()`.
+3. If `reverb_listing_id` exists in the map → `PUT /listings/{id}`; otherwise → `POST /listings` and store the returned ID.
+4. Upload any new/changed images via `POST /listings/{id}/photos`.
+5. Update `last_synced_at` and log result in `oc_reverb_sync_log`.
+
+### Reverb → OpenCart (webhook or scheduled poll)
+
+1. Receive webhook POST to `catalog/controller/extension/module/reverb/webhook` (or poll `/my/listings` + `/my/orders`).
+2. For listing updates: look up OC product by `reverb_listing_id`, update price / stock / description via model.
+3. For new orders: map Reverb order payload to OC order via `OrderMapper::toOpenCart()`, create via `$this->model_checkout_order->addOrder()`.
+4. Log result.
+
+## OpenCart 4.x Compatibility Notes
+
+- OC 4.x uses PHP namespaces: `namespace Opencart\Admin\Controller\Extension\Module;`
+- Controllers must extend `\Opencart\System\Engine\Controller`
+- Template paths and module structure differ from 3.x
+- Planned approach: ship separate 4.x controller files; share `system/library/reverb/` classes between both versions (they are framework-agnostic)
+
+## Development Guidelines
+
+- PHP 7.4+ required; PHP 8.1+ preferred
+- Use `$this->db->query()` and `$this->db->escape()` for all database access — never raw PDO or unsanitised input
+- All user-visible strings must be defined in the language file, not hardcoded in controllers or templates
+- Wrap all Reverb API calls in try/catch; log errors to `oc_reverb_sync_log` rather than surfacing raw exceptions to the UI
+- The OCMOD XML file is required for injecting the per-product toggle without modifying core OpenCart files
+- Test against a Reverb sandbox account before connecting a live store

+ 1 - 0
README.md

@@ -0,0 +1 @@
+# Reverb Opencart Extension