141 lines
5.6 KiB
Markdown
141 lines
5.6 KiB
Markdown
# E2E: Feeds → Map → Process → Export (Local Demo Co)
|
|||
|
|
|
||
|
|
**When:** 2026-08-04
|
||
|
|
**Tenant:** Local Demo Co (`ee246275-dec0-4446-9e83-58d0c16c258a`)
|
||
|
|
**Web:** http://127.0.0.1:5174 (not 5173 — that port may be another Vite app)
|
||
|
|
**API:** http://127.0.0.1:8080
|
||
|
|
**DB:** `postgres://descrybe:***@localhost:5433/descrybe`
|
||
|
|
|
||
|
|
## Credentials
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Email | `demo@descrybe.local` |
|
||
|
|
| Password | `DemoPass123!` |
|
||
|
|
| API key | `dk_demo_local_descrybe_test_key_v1` |
|
||
|
|
|
||
|
|
Session login needs CSRF: GET any `/api/*` route to set `descrybe_csrf`, then POST `/api/auth/login` with header `X-CSRF-Token`.
|
||
|
|
|
||
|
|
```http
|
||
|
|
Authorization: Bearer dk_demo_local_descrybe_test_key_v1
|
||
|
|
```
|
||
|
|
|
||
|
|
## Pipeline (what “done” looks like)
|
||
|
|
|
||
|
|
```
|
||
|
|
input feeds → PUT mappings → (sync*) → POST process → export generate → public XML/CSV
|
||
|
|
```
|
||
|
|
|
||
|
|
\* Live FTP/FTPS supplier URLs return `400 ftp/ftps feed sync is not supported yet`. Local Demo Co already has migrated raw/processed rows, so process + export work without re-sync.
|
||
|
|
|
||
|
|
## Verified counts (after this E2E)
|
||
|
|
|
||
|
|
| Surface | Result |
|
||
|
|
|---------|--------|
|
||
|
|
| Input feeds | **12** (`active` / `mapped`) |
|
||
|
|
| Feed mappings | Present (e.g. Vama Trade **13** fields) |
|
||
|
|
| Processed products | **~4330** (`GET /api/v1/products`) |
|
||
|
|
| Raw / unprocessed | **23744** (`kind=raw` or `kind=unprocessed`) |
|
||
|
|
| Export generate XML | **4322** products, `status=completed` |
|
||
|
|
| Export generate CSV | **4322** products, `status=completed` |
|
||
|
|
| Process job | **5/5** completed (`normalize` → specs → fill → eprel skipped → ai) |
|
||
|
|
|
||
|
|
## API path (copy/paste)
|
||
|
|
|
||
|
|
### 1. List feeds + mappings
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
$H = @{ Authorization = "Bearer dk_demo_local_descrybe_test_key_v1"; "Content-Type" = "application/json" }
|
||
|
|
Invoke-RestMethod http://127.0.0.1:8080/api/v1/feeds -Headers $H
|
||
|
|
Invoke-RestMethod http://127.0.0.1:8080/api/v1/feeds/b5fc7c4c-830b-4d6e-a90c-9b72800a89a1/mappings -Headers $H
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Save mappings (flips `unmapped` → `mapped`, sets `options.item_path`)
|
||
|
|
|
||
|
|
Body uses the dashboard shape `{ key, mapping: { fieldName, xpath } }`:
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
$body = @{
|
||
|
|
mappings = @(
|
||
|
|
@{ key = "Export/Item/name"; mapping = @{ fieldName = "name"; xpath = "Export/Item/name" } }
|
||
|
|
@{ key = "Export/Item/EAN"; mapping = @{ fieldName = "gtin"; xpath = "Export/Item/EAN" } }
|
||
|
|
)
|
||
|
|
} | ConvertTo-Json -Depth 6
|
||
|
|
Invoke-RestMethod -Method PUT -Uri http://127.0.0.1:8080/api/v1/feeds/<feedId>/mappings -Headers $H -Body $body
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Process sample raw products
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
$raw = Invoke-RestMethod "http://127.0.0.1:8080/api/v1/products?kind=raw&limit=5" -Headers $H
|
||
|
|
$ids = @($raw.products | ForEach-Object { $_.id })
|
||
|
|
$jobBody = @{ raw_product_ids = $ids; processing_type = "normalize" } | ConvertTo-Json
|
||
|
|
$job = Invoke-RestMethod -Method POST -Uri http://127.0.0.1:8080/api/v1/process -Headers $H -Body $jobBody
|
||
|
|
# poll GET /api/v1/process/{id} until status=completed (worker must be running)
|
||
|
|
```
|
||
|
|
|
||
|
|
Dashboard alias: `POST /api/processing/jobs` (same body).
|
||
|
|
|
||
|
|
### 4. Export XML + CSV
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
# Example feed IDs on Local Demo Co
|
||
|
|
$xmlId = "d52bc02c-77ee-4cd5-bcd9-fde652133f38" # XML - Example
|
||
|
|
$csvId = "d6ccb83e-7c76-4328-8b60-820503bd24d0" # CSV - Example
|
||
|
|
Invoke-RestMethod -Method POST -Uri "http://127.0.0.1:8080/api/v1/export-feeds/$xmlId/generate" -Headers $H -Body "{}"
|
||
|
|
Invoke-RestMethod -Method POST -Uri "http://127.0.0.1:8080/api/v1/export-feeds/$csvId/generate" -Headers $H -Body "{}"
|
||
|
|
|
||
|
|
# Public downloads (token from export feed)
|
||
|
|
# GET /api/public/export-feeds/{public_token}.xml
|
||
|
|
# GET /api/public/export-feeds/{public_token}.csv
|
||
|
|
```
|
||
|
|
|
||
|
|
Example tokens after seed/migrate: XML `f2321bf2d18609b7abf5ea0f0f9fbb86`, CSV `7fdea27d7bc9e21aec6403e24ccb3c8a`.
|
||
|
|
|
||
|
|
## UI path
|
||
|
|
|
||
|
|
| Step | URL |
|
||
|
|
|------|-----|
|
||
|
|
| Login | http://127.0.0.1:5174/login |
|
||
|
|
| Feeds | http://127.0.0.1:5174/feeds |
|
||
|
|
| Mapping | http://127.0.0.1:5174/feeds/`{feedId}`/mapping |
|
||
|
|
| Products | http://127.0.0.1:5174/products (Processed / Unprocessed tabs) |
|
||
|
|
| Processing | http://127.0.0.1:5174/processing |
|
||
|
|
| Export feeds | http://127.0.0.1:5174/export-feeds |
|
||
|
|
|
||
|
|
Session-cookie calls go through the Vite proxy (`/api/...` → `:8080`). Same CSRF rules as direct API.
|
||
|
|
|
||
|
|
SSR smoke (logged in): `/dashboard`, `/feeds`, `/products`, `/export-feeds`, `/processing`, `/feeds/.../mapping` → **200**.
|
||
|
|
|
||
|
|
## Blockers fixed in this pass
|
||
|
|
|
||
|
|
| Issue | Fix |
|
||
|
|
|-------|-----|
|
||
|
|
| `parseMappings` ignored UI `{key,mapping}` rows → sync would apply **zero** fields | Unwrap nested `mapping` + `key` as xpath/source in `internal/feeds/mapping.go` |
|
||
|
|
| PUT mappings left feed `status=unmapped` | Derive `item_path` from xpath parents; always set `unmapped`→`mapped` when fields saved (`service.go` / `extract_schema.go`) |
|
||
|
|
| `kind=unprocessed` ignored (returned processed) | Alias to raw list in `catalog_handlers.go` |
|
||
|
|
| Empty-looking processed tab | Data was present (~4.3k); use Unprocessed/`kind=raw` for inventory; API totals verified |
|
||
|
|
|
||
|
|
## Known limits
|
||
|
|
|
||
|
|
- **FTP/FTPS sync** not supported: `POST .../sync` and `.../sync-process-sample` return 400 for supplier FTP URLs (Vama, ComTrade, …).
|
||
|
|
- **Worker required** for process jobs (`scripts/run-api.ps1 worker` or `go run ./cmd/worker`).
|
||
|
|
- Public export **HEAD** may 405; use **GET**.
|
||
|
|
- Web port is **5174** in local docs/smoke; confirm with the Descrybe title before testing.
|
||
|
|
|
||
|
|
## Verification commands
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
cd apps/api
|
||
|
|
go test ./internal/feeds ./internal/httpapi -count=1
|
||
|
|
go build -o bin/api.exe ./cmd/api
|
||
|
|
|
||
|
|
cd ../web
|
||
|
|
npm run check
|
||
|
|
```
|
||
|
|
|
||
|
|
## Related
|
||
|
|
|
||
|
|
- [demo-user.md](demo-user.md) — credentials / API key
|
||
|
|
- [qa-local-demo.md](qa-local-demo.md) — broader Local Demo Co checklist
|
||
|
|
- [local-smoke-results.md](local-smoke-results.md) — prior smoke matrix
|