Files
descrybe/docs/live-public-api-verify.md
T

93 lines
4.5 KiB
Markdown
Raw Normal View History

# Live public API verify — legacy-compatible contract
**When:** 2026-08-04 21:10 +02:00
**Verdict:** **PASS** (process E2E + dual-mode OK; minor shape notes below)
**API:** `http://localhost:8080`
**Web:** `http://localhost:5174`
**Postgres:** `localhost:5433` (`descrybe-v2-postgres`)
**Auth:** Demo API key prefix `dk_demo_lo…` (redacted; full value in [demo-user.md](demo-user.md))
**Worker:** `worker.exe` running (PID observed during run)
No API restart required — responses matched the current OpenAPI / handlers.
## PASS / FAIL by area
| Area | Result | Notes |
|------|--------|-------|
| Auth (missing key) | **PASS** | `401` `{ error: { code: "unauthorized", message: "Unauthorized" } }` |
| Auth (Bearer) | **PASS** | `200` products list |
| Auth (X-API-Key) | **PASS** | `200` products list |
| GET `/products` | **PASS** | `{ data, meta }` — presentProduct fields (`id`, `product_id`, `name`, `category`, `status`, `feed_id`, `quality_score`, `quality_grade`, `created_at`, `updated_at`) |
| GET `/products/quality` | **PASS** | `{ data, meta }` with `quality_checks`; meta has `page/limit/total` (no `totalPages`) |
| POST `/products/process` (items/EAN) | **PASS** | `200` `{ data: { process_id, total_items, processed_items, message } }` |
| GET poll → COMPLETED + `items` | **PASS** | `full` completed in ~4s with 2 items |
| Process variants | **PASS** | `normalize_only`, `title`, `category` all `200``COMPLETED` + `items` |
| Dual-mode `raw_product_ids` | **PASS** | On same path; must be **raw** UUIDs (not processed product list `id`) |
| GET categories / attributes | **PASS** | `{ data, meta }` with page/limit |
| GET feeds (+ one by id) | **PASS** | List `{ data, meta }`; GET one `{ data: {…} }`; sync **not** run |
| GET export-feeds | **PASS** | `{ data, meta }` |
| GET campaigns | **PASS** | `{ data: { year, presets, prepared } }` (no `meta`; matches OpenAPI) |
| OpenAPI process docs | **PASS** | Documents `items` / `process_id`, dual-mode, legacy vs flat `/process` |
## Process outcome (critical)
### Start (`full`, real demo GTINs)
```http
POST /api/v1/products/process
{ "processing_type": "full", "items": [
{ "ean": "8806088803005" },
{ "ean": "8700000000002" }
]}
```
- **HTTP 200**
- `process_id`: `d8f6d996-c0b8-43e7-9372-032fc725a523`
- `total_items`: 2
### Poll
- Status **COMPLETED** on first poll (~4s)
- `data.items` length **2** (Samsung dishwasher + Sample Gadget), with title/description/meta/eprel where applicable
### Variants (quick)
| `processing_type` | Start | Final | `items` |
|-------------------|-------|-------|---------|
| `full` | 200 | COMPLETED | yes |
| `normalize_only` | 200 | COMPLETED | yes |
| `title` | 200 | COMPLETED | yes |
| `category` | 200 | COMPLETED | yes (title may be null) |
### Dual-mode
- Body `{ "processing_type": "normalize_only", "raw_product_ids": ["<raw UUID>"] }`**200** envelope + COMPLETED with `items`.
- Using a **processed** product list `id``400 validation_error` / `no matching products for company` (expected: IDs must be `raw_products.id`).
- Flat surface `POST /api/v1/process` with same `raw_product_ids`**202** flat `ProcessingJob` (documented separate contract).
## OpenAPI spot-check
- `/api/v1/openapi.yaml` **200**, documents:
- Legacy: `POST /products/process` + `items[].ean``200` `{ data: { process_id, … } }`
- Poll: `GET /products/process/{id}` with `items` when COMPLETED
- Alternate body `raw_product_ids` on the same handler
- Flat `/process` surface called out as separate (not legacy envelope)
## Remaining gaps / notes
1. **ID confusion:** ~~OpenAPI under-documented~~ **Closed (docs):** OpenAPI now documents dual IDs explicitly — `GET /products` `id` = processed, `raw_product_id` = raw; `raw_product_ids` must use raw UUIDs; COMPLETED poll items expose `processed_product_id` + `raw_product_id`. Plan gates (402) + gates-before-EnsureRaw on `items[].ean` documented.
2. **Envelope inconsistency (intentional dual contract):** List endpoints use `{ data, meta }`; `GET /products/{id}` and flat `/process*` return **flat** objects (OpenAPI agrees). Not a regression vs docs.
3. **Quality meta:** `totalPages` omitted (products list includes it).
4. **Feed sync:** Skipped (avoid heavy sync spam). Single GET by UUID verified.
5. **DELETE / create:** Skipped (no throwaway unique_ids created).
6. **Export generate:** Not run (avoid large exports).
## Stack check
| Service | Port | Status |
|---------|------|--------|
| Go API | 8080 | Up (`/healthz` ok) |
| Web (Vite) | 5174 | Listening |
| Postgres | 5433 | Healthy |
| Worker | — | Running |