Files
SlabUploader/docs/contracts/WOO-API.md
T
Ty 01aa4c52c3 docs(phase2): reconcile requirements and migrate capabilities/contracts
Surface-matrix sweep of every source doc; added nine missed behaviors (METADATA-115, REVIEW-50, APP-55/60/65, SETTINGS-45 mode, Generate-text availability, defaults-off). 153 requirements, 0 coverage gaps.

Migrated capabilities to docs/capabilities/ and contracts to docs/contracts/; added WOO-API, API, DATA-MODEL, PROMPTS, UX, TEST-SPEC. Populated MILESTONES; branch-neutral trunk docs; renamed umbrella term to Woo Slab Taxonomy. Archived reconciliation working records under .audit/archive/.
2026-09-18 21:02:06 -07:00

143 lines
5.9 KiB
Markdown

# WooCommerce API contract
Status: SPEC · 2026-09-18 · external dependency: WooCommerce REST API v3.
Source: official WooCommerce REST API v3 documentation
(https://woocommerce.github.io/woocommerce-rest-api-docs/).
This contract pins the exact WooCommerce surface the app codes against.
`docs/contracts/CONTENT-WOO.md` owns the listing copy and payload intent; this file owns the wire
shape and the external constraints.
## Requirements impact
| Requirement | Impact on this design |
|---|---|
| SETTINGS-5, SETTINGS-10, SETTINGS-15 | base URL, HTTPS, app-password auth |
| SETTINGS-35, SETTINGS-50, SETTINGS-51, SETTINGS-65 | pricing, taxonomy sync, tag scope, create status |
| METADATA-5, METADATA-10, METADATA-15, METADATA-30 | categories, attributes, tags shapes |
| REVIEW-10, REVIEW-25, REVIEW-45, REVIEW-50 | name, price, SKU, field limits |
| PUBLISH-5, PUBLISH-10, PUBLISH-15, PUBLISH-20, PUBLISH-25, PUBLISH-30, PUBLISH-35 | create sequence, draft rule, errors |
| PUBLISH-40, PUBLISH-45, PUBLISH-55, PUBLISH-60 | images, payload fields, sold-individually |
| APP-35, APP-50 | error envelope mapping |
## 1. Transport and auth
- Base path: `${WOO_BASE_URL}/wp-json/wc/v3`.
- `WOO_BASE_URL` is HTTPS only and injected from env.
- Auth: WordPress application password over HTTP Basic. The consumer-key example in the Woo docs
is **not** used.
- Content type `application/json`. Dates ISO8601 (`YYYY-MM-DDTHH:MM:SS`). Monetary values are
strings with two decimals.
## 2. Endpoints used
| Purpose | Method and path |
|---|---|
| Sync categories | `GET /products/categories?per_page=100&page=N` |
| Sync tags | `GET /products/tags?per_page=100&page=N` |
| Sync attributes | `GET /products/attributes?per_page=100` |
| Sync attribute terms | `GET /products/attributes/{id}/terms?per_page=100` |
| SKU lookup | `GET /products?sku={sku}` |
| Create product | `POST /products` |
| Upload media | `POST /wp-json/wp/v2/media` (WordPress core) |
## 3. Product create field alignment
| Our value | Woo field | Woo type | Enum / constraint |
|---|---|---|---|
| title | `name` | string | none documented |
| — | `type` | string | `simple` (default) |
| create status | `status` | string | `draft`, `pending`, `private`, `publish`; default `publish` |
| sku | `sku` | string | unique; no documented format |
| price | `regular_price` | string | monetary string, 2 decimals |
| description | `description` | string | none documented |
| short_description | `short_description` | string | none documented |
| species + wood categories | `categories` | array of `{id: integer}` | leaf ids |
| fig-* / feat-* tags | `tags` | array of `{id: integer}` | tag ids |
| uploaded PNGs | `images` | array of `{id: integer}` | attachment ids, lineup order |
| five locked attributes | `attributes` | array of attribute elements | see §4 |
| — | `virtual` | boolean | default `false` |
| — | `downloadable` | boolean | default `false` |
| — | `catalog_visibility` | string | `visible`, `catalog`, `search`, `hidden`; default `visible` |
| — | `sold_individually` | boolean | default `false`; set `true` |
`sold_individually: true` is the Woo mechanism that enforces "one slab is one unit."
## 4. `attributes` element shape
Global attributes are referenced by `id` (synced from Woo), never created by name. Each element:
```json
{
"id": 8,
"position": 0,
"visible": true,
"variation": false,
"options": ["Live Edge"]
}
```
| Attribute | `options` |
|---|---|
| Edge Type | `[term name]` |
| Figure | `[term name, ...]` |
| Grade | `[term name]` |
| Thickness | `[term name]` |
| Moisture | `[term name]` |
`options` carries term **names**, not ids. `visible` is `true`; `variation` is `false`.
## 5. Categories, tags, images shapes
- `categories`: `[{"id": 9}, {"id": 14}]`
- `tags`: `[{"id": 34}]`
- `images`: `[{"id": 42}, {"id": 793}]`, in photos-ready lineup order.
- Media upload: `POST /wp-json/wp/v2/media` as `multipart/form-data` with the PNG bytes; the
response `id` is the attachment id used in `images`. Keep alpha; PNG only.
## 6. Error shape
```json
{ "code": "woocommerce_rest_term_invalid", "message": "Resource doesn't exist.", "data": { "status": 404 } }
```
`401` auth, `400` bad request, `404` missing, `500` server. These map into the app's uniform
envelope and never reach the owner raw.
## 7. Pagination
`per_page` max 100, `page` 1-based. Read `X-WP-Total` and `X-WP-TotalPages`; follow pages until
exhausted. Taxonomy lists return in full to the client.
## 8. No documented maximum lengths
The Woo v3 docs state no maximum length for `name`, `description`, `short_description`, `sku`, or
`regular_price`. Do not invent caps. The app enforces non-empty required fields and its own local
formats.
## 9. Field length limits
Hard limits are verified from WordPress/WooCommerce source; the display caps are conventions
(Google states no numeric limit).
| Field | Storage | Hard limit | Recommended display cap | Rationale |
|---|---|---|---|---|
| `name` | `wp_posts.post_title` (`text`) | 65,535 | 60 | on-screen title-tag width |
| `short_description` | `wp_posts.post_excerpt` (`text`) | 65,535 | 160 | search snippet / meta description width |
| `description` | `wp_posts.post_content` (`longtext`) | ~16.7M | none | no word-count target; write for the page |
| `sku` | `wc_product_meta_lookup.sku` (`varchar(100)`, index `sku(50)`) | 100 | 50 | index prefix length |
Sources: WordPress `schema.php`, WooCommerce `class-wc-install.php`,
`class-wc-product-data-store-cpt.php`, and Google Search Central (title links, snippets, SEO
starter guide).
## 10. Media size
The store exposes its upload cap read-only as `max_upload_size` on system status. Validate the
processed PNG against it before upload and surface a plain, actionable error if exceeded.
## 11. Versioning
Woo `wc/v3` requires WooCommerce 3.5+ and WordPress 4.4+ with pretty permalinks. Breaking Woo API
changes are handled by the app's own `/api/v1` version, not by pinning the store.