# 04 — API and Web Routes ## API Endpoints ### Setup | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/setup` | Initial setup page | | POST | `/setup` | Save connection settings | | POST | `/setup/test` | Test MariaDB connection | | GET | `/setup/status` | Setup status | ### Components | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/api/components` | List components (metadata only) | | GET | `/api/components/:lot_name` | Component by lot_name | | GET | `/api/categories` | List categories | ### Quote | Method | Endpoint | Purpose | |--------|----------|---------| | POST | `/api/quote/validate` | Validate line items | | POST | `/api/quote/calculate` | Calculate quote (prices from pricelist) | | POST | `/api/quote/price-levels` | Prices by level (estimate/warehouse/competitor) | ### Pricelists (read-only) | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/api/pricelists` | List pricelists (`source`, `active_only`, pagination) | | GET | `/api/pricelists/latest` | Latest pricelist by source | | GET | `/api/pricelists/:id` | Pricelist by ID | | GET | `/api/pricelists/:id/items` | Pricelist line items | | GET | `/api/pricelists/:id/lots` | Lot names in pricelist | `GET /api/pricelists?active_only=true` returns only pricelists that have synced items (`item_count > 0`). ### Configurations | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/api/configs` | List configurations | | POST | `/api/configs` | Create configuration | | GET | `/api/configs/:uuid` | Get configuration | | PUT | `/api/configs/:uuid` | Update configuration | | DELETE | `/api/configs/:uuid` | Archive configuration | | POST | `/api/configs/:uuid/refresh-prices` | Refresh prices from pricelist | | POST | `/api/configs/:uuid/clone` | Clone configuration | | POST | `/api/configs/:uuid/reactivate` | Restore archived configuration | | POST | `/api/configs/:uuid/rename` | Rename configuration | | POST | `/api/configs/preview-article` | Preview generated article for a configuration | | POST | `/api/configs/:uuid/rollback` | Roll back to a version | | GET | `/api/configs/:uuid/versions` | List versions | | GET | `/api/configs/:uuid/versions/:version` | Get specific version | `line` field in configuration payloads is backed by persistent `line_no` in DB. ### Projects | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/api/projects` | List projects | | POST | `/api/projects` | Create project | | GET | `/api/projects/:uuid` | Get project | | PUT | `/api/projects/:uuid` | Update project | | DELETE | `/api/projects/:uuid` | Archive project variant (soft-delete via `is_active=false`; fails if project has no `variant` set — main projects cannot be deleted this way) | | GET | `/api/projects/:uuid/configs` | Project configurations | | PATCH | `/api/projects/:uuid/configs/reorder` | Reorder active project configurations (`ordered_uuids`) and persist `line_no` | | POST | `/api/projects/:uuid/vendor-import` | Import a vendor `CFXML` workspace into the existing project | `GET /api/projects/:uuid/configs` ordering: `line ASC`, then `created_at DESC`, then `id DESC`. `POST /api/projects/:uuid/vendor-import` accepts `multipart/form-data` with one required file field: - `file` — vendor configurator export in `CFXML` format ### Sync | Method | Endpoint | Purpose | Flow | |--------|----------|---------|------| | GET | `/api/sync/status` | Overall sync status | read-only | | GET | `/api/sync/readiness` | Preflight status (ready/blocked/unknown) | read-only | | GET | `/api/sync/info` | Data for sync modal | read-only | | GET | `/api/sync/users-status` | Users status | read-only | | GET | `/api/sync/pending` | List pending changes | read-only | | GET | `/api/sync/pending/count` | Count of pending changes | read-only | | POST | `/api/sync/push` | Push pending → MariaDB | SQLite → MariaDB | | POST | `/api/sync/components` | Pull components | MariaDB → SQLite | | POST | `/api/sync/pricelists` | Pull pricelists | MariaDB → SQLite | | POST | `/api/sync/all` | Full sync: push + pull + import | bidirectional | | POST | `/api/sync/repair` | Repair broken entries in pending_changes | SQLite | | POST | `/api/sync/partnumber-seen` | Report unresolved/ignored vendor PNs for server-side tracking | QuoteForge → MariaDB | **If sync is blocked by the readiness guard:** all POST sync methods return `423 Locked` with `reason_code` and `reason_text`. ### Vendor Spec (BOM) | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/api/configs/:uuid/vendor-spec` | Fetch stored vendor BOM | | PUT | `/api/configs/:uuid/vendor-spec` | Replace vendor BOM (full update) | | POST | `/api/configs/:uuid/vendor-spec/resolve` | Resolve PNs → LOTs (read-only) | | POST | `/api/configs/:uuid/vendor-spec/apply` | Apply resolved LOTs to cart | Notes: - `GET` / `PUT /api/configs/:uuid/vendor-spec` exchange normalized BOM rows (`vendor_spec`), not raw pasted Excel layout. - BOM row contract stores canonical LOT mapping list as seen in BOM UI: - `lot_mappings[]` - each mapping contains `lot_name` + `quantity_per_pn` - `POST /api/configs/:uuid/vendor-spec/apply` rebuilds cart items from explicit BOM mappings: - all LOTs from `lot_mappings[]` ### Partnumber Books (read-only) | Method | Endpoint | Purpose | |--------|----------|---------| | GET | `/api/partnumber-books` | List local book snapshots | | GET | `/api/partnumber-books/:id` | Items for a book by `server_id` (`page`, `per_page`, `search`) | | POST | `/api/sync/partnumber-books` | Pull book snapshots from MariaDB | See [09-vendor-spec.md](09-vendor-spec.md) for schema and pull logic. See [09-vendor-spec.md](09-vendor-spec.md) for `vendor_spec` JSON schema and BOM UI mapping contract. ### Export | Method | Endpoint | Purpose | |--------|----------|---------| | POST | `/api/export/csv` | Export configuration to CSV | | GET | `/api/projects/:uuid/export` | Legacy project CSV export in block BOM format | | POST | `/api/projects/:uuid/export` | Project CSV export in pricing-tab format with selectable columns (`include_lot`, `include_bom`, `include_estimate`, `include_stock`, `include_competitor`) | **Export filename format:** `YYYY-MM-DD (ProjectCode) ConfigName Article.csv` (uses `project.Code`, not `project.Name`) --- ## Web Routes | Route | Page | |-------|------| | `/configs` | Configuration list | | `/configurator` | Configurator | | `/configs/:uuid/revisions` | Configuration revision history | | `/projects` | Project list | | `/projects/:uuid` | Project details | | `/pricelists` | Pricelist list | | `/pricelists/:id` | Pricelist details | | `/partnumber-books` | Partnumber books (active book summary + snapshot history) | | `/setup` | Connection settings | --- ## Rollback API (details) ```bash POST /api/configs/:uuid/rollback Content-Type: application/json { "target_version": 3, "note": "optional comment" } ``` Response: updated configuration with the new version.