# Backend Implementation Prompt — B2B branch Copy-paste this to a backend developer or an AI agent. It is self-contained; pair it with [`BACKEND-INTEGRATION.md`](BACKEND-INTEGRATION.md) (contract detail) and [`BACKEND.md`](BACKEND.md) (per-domain models). --- ## Prompt You are implementing the backend for the **`B2B` branch** of an Angular marketplace/storefront + admin builder. The frontend is already built and runs offline against mocks. Your job is to expose real HTTP endpoints the frontend already calls. **Do not touch authentication (Telegram QR session) or payments — those contracts are frozen and out of scope.** ### Context you must honor - **Single build, multi-tenant.** Base URL is resolved per-tenant at runtime. Serve each tenant at `https://.api.dexarmarket.ru:445` (template) or get it registered in `environment.tenantApiBaseUrls`. Default tenant → `https://api.dexarmarket.ru:445`. - Every storefront request carries headers: `X-Region` (`Moscow`/`ST. Petersburg`/`Yerevan`), `X-Language` (`RU`/`EN`/`AM`), `Currency` (`RUB`/`USD`/`AMD`), `WebSessionID` (32-char hex). Localize and session-scope responses off these. - The frontend normalizes both legacy and "backOffice" field variants, but you should match the documented models to avoid surprises. ### Part A — Keep existing storefront endpoints working (already in `main`, do not change shapes) - `GET /ping` - `GET /category` - `GET /category/:id?count=&skip=` - `GET /items/:id` - `GET /searchitems?search=&count=&skip=&categoryIDs=&minPrice=&maxPrice=&tag=&sort=` → `{ items, total }` - `GET /items/randomitems?count=&category=` - `POST /websession/:sessionId` (cart lines) - `POST /items/:id/callback` (review), `POST /items/:id/questiion` (question — keep the typo), `POST /purchase-email` ### Part B — New: `GET /bootstrap` (blocking dependency for prod) Return one JSON document of type `BootstrapConfig` per tenant: `tenant, branding, theme, company, featureFlags, apiEndpoints, localization, seo, permissions, navigation, footer, pages, staticPages, widgetRegistry`. - Schema: `src/app/shared/models/config/bootstrap-config.model.ts` - Reference payload to match field-for-field: `src/assets/mock/bootstrap/bootstrap.json` - Must be cacheable; frontend loads it once at startup. ### Part C — New: Builder (Project Editor persistence) — highest priority The editor edits the same `BootstrapConfig` the storefront reads. Implement: - `GET /builder/bootstrap/draft` → current draft - `PUT /builder/bootstrap/draft` ← save draft (whole document) - `POST /builder/bootstrap/publish` → promote draft to the live `GET /bootstrap` - `POST /builder/bootstrap/validate` (optional endpoint) — **but server-side validation on publish is mandatory**; treat the client validator as untrusted. ### Part D — New: Backoffice (admin) CRUD, per domain For each domain — categories, products, orders, transactions, users/roles, dashboard metrics, monitoring, media — expose REST endpoints under `/backoffice/` matching the interfaces the frontend mock gateways implement. Model shapes and required operations per domain: `BACKEND.md` §5–§16 and `features/admin//models/*.model.ts` / `*-gateway.interface.ts`. The frontend swaps mock→api by rebinding one DI token per domain; your endpoints must satisfy the same interface (list/get/create/update/soft-delete/restore/draft-publish where the interface declares them). ### Constraints - No changes to auth or payment endpoints. - Preserve existing storefront request/response shapes exactly. - Populate `apiEndpoints.website / builder / backoffice` in the bootstrap document as you add endpoints, so the frontend can discover them. - Add server-side authorization: admin/builder sessions must be distinguishable from customer sessions server-side (the frontend cannot enforce this). ### Deliverables 1. `GET /bootstrap` per tenant. 2. Builder draft/publish/validate with server-side re-validation. 3. Backoffice CRUD per domain against the documented interfaces. 4. OpenAPI/spec for B, C, D. Storefront (A) is already specified by the client normalizers — do not deviate. Ask before assuming any field you cannot find in the referenced models or `bootstrap.json`.