# Védett végpontok

> Hitelesítési adatokat igénylő API-végpontok — a fiókvégpontokhoz munkamenet-cookie, a haszno.com minden más végpontjához a Haszno csapatával egyeztetett HTTP Basic jelszó kell.

> [!NOTE]
> A Haszno API fejlesztői előzetesben van. A hosztolt demón az oldal összes végpontjához – a [fiók- és munkamenet-végpontok](#auth-account) kivételével – a Haszno csapatától kapott HTTP Basic jelszó szükséges. Az aktuális hitelesítési modellről lásd a [Hitelesítés](authentication.md) oldalt.

## Áttekintés

A `https://haszno.com` hosztolt demóján a [végpontcsoportok](#endpoint-groups) végpontjaihoz HTTP Basic hitelesítési fejléc (`demo:<jelszó>`) kell. Kivételt a [fiók- és munkamenet-végpontok](#auth-account) jelentenek: ezek nincsenek a Basic fal mögött, helyette munkamenet-cookie-t használnak. Ha saját telepítésen be van állítva a `HASZNO_API_KEY`, a Basic hitelesítés helyett ezt a kulcsot küldd az `x-api-key` fejlécben; ha nincs beállítva, az útvonalak nyitottak.

A Basic jelszót a Haszno csapatától szerezheted be. Az ezen az oldalon szereplő példák a `$HASZNO_BASIC` helyőrzőt használják (Basic auth hitelesítési adatok `felhasználó:jelszó` formátumban), amelyet a saját környezetedből olvas be a rendszer. Soha ne égess bele hitelesítési adatokat a kódba.

```bash
# Egyszeri beállítás a shellben:
export HASZNO_BASIC="demo:your-password-here"
```

> [!WARNING]
> **Az írási végpontoknak valódi mellékhatásuk van.** Az adatot létrehozó vagy módosító hívások — árváltoztatások, rendelésbeküldések, feed-importok, szabályfuttatások — nem mindig vonhatók vissza. Mindig ellenőrizd a szándékot egy írási végpont hívása előtt. Az automatizálás leállítókapcsolóját (`GET /api/automation`, `PUT /api/automation`) ismert állapotba kell hozni tömeges műveletek előtt.

---

## Fiók- és munkamenet-végpontok

Ezekhez a végpontokhoz **nem** kell a HTTP Basic jelszó, még a `haszno.com`-on sem. Munkamenet-cookie-val (`haszno_session`, 30 napig érvényes) működnek, amelyet a `register` és a `login` állít be.

| Metódus | Útvonal | Rendeltetés | Mi kell hozzá | Mód |
|---------|---------|-------------|---------------|-----|
| POST | `/api/auth/register` | Fiók, a hozzá tartozó bolt és munkamenet-cookie létrehozása | Semmi. JSON-törzs: `{email, password, name, shopName}`; a jelszó legalább 10 karakter. `201`-et ad vissza. | **Írás** |
| POST | `/api/auth/login` | Bejelentkezés és munkamenet-cookie fogadása | Semmi. JSON-törzs: `{email, password}`. | **Írás** |
| POST | `/api/auth/logout` | Az aktuális munkamenet megszüntetése | Semmi. Ha küldesz munkamenet-cookie-t, törli; mindig `{"ok": true}` a válasz. | **Írás** |
| GET | `/api/auth/me` | Az aktuális felhasználó és bolt | Munkamenet-cookie vagy Bearer-token; egyik nélkül sem `401`. | **Csak olvasás** |
| POST | `/api/auth/tokens` | API Bearer-token létrehozása | Munkamenet-cookie. JSON-törzs: `{name, scope}`; a `scope` értéke `read` (alapértelmezés) vagy `write`. `201`-et ad vissza. | **Írás** |
| GET | `/api/auth/tokens` | Aktív Bearer-tokenek listázása | Munkamenet-cookie. | **Csak olvasás** |
| DELETE | `/api/auth/tokens/:id` | Bearer-token visszavonása | Munkamenet-cookie. | **Írás** |

- A munkamenet-cookie csak ezeket a végpontokat nyitja meg. A `haszno.com`-on a [végpontcsoportok](#endpoint-groups) útvonalaihoz nem ad hozzáférést.
- A tokenvégpontok csak munkamenet-cookie-t fogadnak el, így Bearer-tokennel nem hozhatsz létre, nem listázhatsz és nem vonhatsz vissza tokent.
- Munkamenet-cookie-val a `/api/auth/tokens` `POST` és `DELETE` kérésének az oldal saját eredetéről kell érkeznie (CSRF-ellenőrzés, különben `403`). A `register`, a `login` és a `logout` kivétel.
- Ha saját telepítésen be van állítva a `HASZNO_API_KEY`, a `register`, a `login`, a `logout` és a `me` kihagyja a kulcsellenőrzést, a `/api/auth/tokens` végpontokhoz viszont `x-api-key` is kell.
- A `register` és a `login` sebességkorlátait a [Hibák](errors.md#auth-limits) oldal sorolja fel.

---

## Végpontcsoportok

A `haszno.com`-on az alábbi csoportok minden végpontjához kell a HTTP Basic jelszó.

### Bolt beállításai

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| PUT | `/api/settings` | Árazási szabályok és szállítási piacok frissítése | **Írás** |

### Termékek — saját bolt

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| PATCH | `/api/products/:id` | Piaci ár frissítése vagy kézi árfelülbírálat beállítása | **Írás** |
| POST | `/api/products/:id/listing` | Termék listázása vagy listáról való levétele | **Írás** |
| POST | `/api/products/:id/ai-description` | Magyar termékleírás generálása mesterséges intelligenciával | **Írás** |
| POST | `/api/products/apply-prices` | Ajánlott ár alkalmazása az összes vagy kijelölt termékre | **Írás** |
| GET | `/api/products/:id/offers` | Termék elmúlt 24 órájának piaci ajánlatai | **Csak olvasás** |
| GET | `/api/products/:id/price-history` | Termék árváltozási naplója | **Csak olvasás** |

### Beszállítói hálózat és katalógus

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/network/suppliers` | Hálózati beszállítók csatlakozási állapottal | **Csak olvasás** |
| GET | `/api/network/suppliers/:id/products` | Hálózati beszállító teljes katalógusa | **Csak olvasás** |
| POST | `/api/network/suppliers/:id/connect` | Beszállító csatlakoztatása és katalógus importálása | **Írás** |
| POST | `/api/network/suppliers/:id/disconnect` | Beszállító lecsatlakoztatása | **Írás** |
| POST | `/api/network/suppliers/:id/sync` | Bekerülési ár és készlet frissítése az élő katalógusból | **Írás** |
| GET | `/api/network/supplier-view/:supplierId` | Összesített viszonteladói statisztikák termékenként (k-anonimitás ≥ 5 bolt) | **Csak olvasás** |
| POST | `/api/network/products/:id/import` | Egy hálózati termék hozzáadása a saját bolthoz | **Írás** |
| GET | `/api/catalogue/products` | Partnerkatalógus böngészése (lapozott, keresés, facetek) | **Csak olvasás** |
| POST | `/api/import-list` | Hálózati termékek hozzáadása az importlistához | **Írás** |
| POST | `/api/import-list/push` | Importlista-tételek feltöltése csatlakoztatott webshopba | **Írás** |
| POST | `/api/import-list/discard` | Importlista-tételek elvetése | **Írás** |

### Javaslatok és ötletek

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/recommendations` | Trending és haszonbiztos termékek rövidlistája | **Csak olvasás** |
| POST | `/api/recommendations/ai` | Mesterséges intelligencia által összeállított rövidlista Claude segítségével (24 óráig gyorsítótárazva) | **Csak olvasás** |

### Rendelések

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| POST | `/api/webhooks/order` | Új rendelés fogadása csatlakoztatott boltból | **Írás** |
| POST | `/api/demo/order` | Véletlenszerű demórendelés létrehozása | **Írás** |
| POST | `/api/orders/:id/ship` | Rendelés megjelölése szállítottként | **Írás** |

### Feedek

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| POST | `/api/feeds/import` | Beszállítói termékfeed importálása (CSV vagy XML, legfeljebb 10 MB) | **Írás** |
| POST | `/api/market-prices/import` | Piaci összehasonlítóárak importálása CSV-ből | **Írás** |
| GET | `/feed/arukereso.xml` | Árukereső XML kimeneti termékfeed | **Csak olvasás** |
| GET | `/feed/google.xml` | Google Merchant XML kimeneti termékfeed | **Csak olvasás** |

### Szabályok és automatizálás

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/rules/templates` | Beépített szabálysablonok | **Csak olvasás** |
| GET | `/api/rules` | Konfigurált szabályok listázása | **Csak olvasás** |
| POST | `/api/rules` | Szabály létrehozása | **Írás** |
| PATCH | `/api/rules/:id` | Szabály módosítása | **Írás** |
| DELETE | `/api/rules/:id` | Szabály végleges törlése | **Írás** |
| POST | `/api/rules/:id/run` | Egy szabály kézi futtatása | **Írás** |
| POST | `/api/rules/run-all` | Összes kézi triggerű szabály futtatása | **Írás** |
| POST | `/api/rules/trigger` | Nevesített eseménytrigger indítása | **Írás** |
| GET | `/api/rule-runs` | Szabályfuttatások naplója | **Csak olvasás** |
| POST | `/api/rule-runs/undo` | Utolsó szabályfuttatás visszavonása | **Írás** |
| GET | `/api/automation` | Automatizálás leállítókapcsolójának állapota | **Csak olvasás** |
| PUT | `/api/automation` | Automatizálás szüneteltetési állapotának beállítása | **Írás** |

### Árjavaslatok

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| POST | `/api/proposals/approve` | Árajánlatok jóváhagyása (az összes függő, vagy azonosítólista alapján) | **Írás** |
| POST | `/api/proposals/reject` | Árajánlatok elutasítása | **Írás** |
| POST | `/api/proposals/rollback` | Jóváhagyott árajánlat-köteg visszagörgetése | **Írás** |

### Társkapcsolatok és megosztás

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| POST | `/api/peers/invites` | Társ-meghívó létrehozása beszállító megosztásához | **Írás** |
| GET | `/api/peers/invites/:code` | Meghívó lekérdezése kód alapján | **Csak olvasás** |
| DELETE | `/api/peers/invites/:code` | Meghívó törlése | **Írás** |
| POST | `/api/peers/invites/:code/accept` | Társ-meghívó elfogadása | **Írás** |
| DELETE | `/api/peers/links/:id` | Társ-összekapcsolás megszüntetése | **Írás** |
| PUT | `/api/peers/suppliers/:id/visibility` | Beszállító láthatóságának beállítása (private / network) | **Írás** |

### Bolt-összekapcsolások és piactér

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/shop-connections` | Bolt-összekapcsolások listázása | **Csak olvasás** |
| POST | `/api/shop-connections` | Bolt-összekapcsolás létrehozása | **Írás** |
| GET | `/api/shop-connections/:id` | Összekapcsolás lekérdezése | **Csak olvasás** |
| DELETE | `/api/shop-connections/:id` | Összekapcsolás törlése | **Írás** |
| POST | `/api/shop-connections/:id/test` | Összekapcsolás tesztelése | **Csak olvasás** |
| POST | `/api/shop-connections/:id/sync` | Termékek szinkronizálása csatlakoztatott boltba | **Írás** |
| GET | `/api/shop-connections/:id/runs` | Szinkronizálási futtatások naplója | **Csak olvasás** |
| GET | `/api/shop-connections/:id/pricing` | Boltonkénti árazási szabályok | **Csak olvasás** |
| PUT | `/api/shop-connections/:id/pricing` | Boltonkénti árazási szabályok frissítése | **Írás** |
| POST | `/api/shop-connections/:id/pricing/reprice` | Termékek átárazása egy bolt számára | **Írás** |
| GET | `/api/marketplace/connections` | Piactér-összekapcsolások listázása | **Csak olvasás** |
| POST | `/api/marketplace/connections` | Piactér-összekapcsolás létrehozása | **Írás** |
| GET | `/api/marketplace/connections/:id` | Piactér-összekapcsolás lekérdezése | **Csak olvasás** |
| DELETE | `/api/marketplace/connections/:id` | Piactér-összekapcsolás törlése | **Írás** |
| PUT | `/api/marketplace/connections/:id/credentials` | Hitelesítési adatok frissítése | **Írás** |
| POST | `/api/marketplace/connections/:id/test` | Összekapcsolás tesztelése | **Csak olvasás** |
| GET | `/api/marketplace/connections/:id/listings` | Összekapcsolás listázásai | **Csak olvasás** |
| POST | `/api/marketplace/listings` | Piactéri listázás létrehozása | **Írás** |
| GET | `/api/marketplace/listings/:id/preview` | Listázás előnézete | **Csak olvasás** |
| POST | `/api/marketplace/listings/:id/publish` | Listázás közzététele | **Írás** |
| POST | `/api/marketplace/listings/:id/update` | Élő listázás frissítése | **Írás** |
| POST | `/api/marketplace/listings/:id/unpublish` | Listázás visszavonása | **Írás** |
| GET | `/api/marketplace/listings/:id/price-history` | Listázás árelőzménye | **Csak olvasás** |
| POST | `/api/marketplace/connections/:id/ingest-orders` | Rendelések behúzása piactérről | **Írás** |

### Útválasztás

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/routing/sources` | Összes útválasztási forrás | **Csak olvasás** |
| GET | `/api/routing/sources/:productId` | Termék útválasztási forrásai | **Csak olvasás** |
| PUT | `/api/routing/sources/:productId` | Útválasztási források beállítása | **Írás** |
| DELETE | `/api/routing/sources/:productId/:supplierId` | Útválasztási forrás eltávolítása | **Írás** |
| GET | `/api/routing/decisions` | Legutóbbi útválasztási döntések naplója | **Csak olvasás** |

### Teljesítés

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/fulfilment/settings` | Teljesítési szolgáltató beállításai | **Csak olvasás** |
| GET | `/api/fulfilment/invoices` | Számlalista | **Csak olvasás** |
| GET | `/api/fulfilment/shipments` | Szállítmánylista | **Csak olvasás** |
| GET | `/api/fulfilment/orders/:orderId/label/download` | Szállítási cédula PDF letöltése | **Csak olvasás** |
| GET | `/api/fulfilment/orders/:orderId/tracking` | Követési állapot lekérdezése | **Csak olvasás** |
| GET | `/api/fulfilment/settings/notifications` | Értesítési beállítások | **Csak olvasás** |
| PUT | `/api/fulfilment/settings/notifications` | Értesítési beállítások frissítése | **Írás** |

### Betekintések és riportok

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/insights/network-signals` | Összesített kulcsszójel-adatok (k-anonimitás ≥ 5 bolt) | **Csak olvasás** |
| GET | `/api/insights/network-signal` | Egyetlen kulcsszójel | **Csak olvasás** |
| POST | `/api/trends/keywords` | Hiányzó trendkulcsszavak pótlása mesterséges intelligenciával | **Írás** |
| GET | `/api/reports` | Riportok listázása | **Csak olvasás** |
| GET | `/api/reports/preview` | Aktuális riport előnézete | **Csak olvasás** |
| GET | `/api/reports/:id` | Riport lekérdezése JSON formátumban | **Csak olvasás** |
| GET | `/api/reports/:id/html` | Riport lekérdezése HTML formátumban | **Csak olvasás** |

### Partnerek és metrikák

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/partners/metrics` | Beszállítónkénti teljesítménymutatók | **Csak olvasás** |
| GET | `/api/partners/metrics/:supplierId/history` | Mutató-előzmény egy beszállítóra | **Csak olvasás** |
| POST | `/api/partners/metrics/compute` | Mutatók újraszámítása | **Írás** |

### Számlázás

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/billing/summary` | Aktuális számlázási csomag és felhasználás | **Csak olvasás** |
| GET | `/api/billing/history` | Fizetési előzmények | **Csak olvasás** |
| POST | `/api/billing/plan` | Számlázási csomag módosítása (sebességkorlát: 5 / perc) | **Írás** |

### Csoportos vásárlások

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/groupbuys` | Csoportos vásárlások listázása | **Csak olvasás** |
| GET | `/api/groupbuys/:id` | Csoportos vásárlás lekérdezése | **Csak olvasás** |
| POST | `/api/groupbuys` | Csoportos vásárlás létrehozása | **Írás** |
| POST | `/api/groupbuys/:id/commit` | Csatlakozás csoportos vásárláshoz | **Írás** |
| POST | `/api/groupbuys/:id/close` | Csoportos vásárlás lezárása | **Írás** |
| POST | `/api/groupbuys/:id/cancel` | Csoportos vásárlás lemondása | **Írás** |

### Bolt-connect API, keresés és elemzés

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| POST | `/api/connect/stores` | Bolt regisztrálása | **Írás** |
| GET | `/api/connect/stores` | Boltok listázása | **Csak olvasás** |
| GET | `/api/connect/stores/:id` | Bolt lekérdezése | **Csak olvasás** |
| PUT | `/api/connect/stores/:id/domain` | Bolt domainjének beállítása | **Írás** |
| POST | `/api/connect/stores/:id/verify-domain` | Domain-tulajdonjog ellenőrzése | **Írás** |
| PUT | `/api/connect/stores/:id/credentials` | Hitelesítési adatok frissítése | **Írás** |
| POST | `/api/connect/stores/:id/test` | Bolt-összekapcsolás tesztelése | **Csak olvasás** |
| POST | `/api/connect/stores/:id/push` | Termékfrissítések kiküldése boltba | **Írás** |
| GET | `/api/search/suggest` | Automatikus kiegészítési javaslat katalóguskereséshez | **Csak olvasás** |
| POST | `/api/analysis` | Versenytársi vagy webhely-elemzési feladat indítása | **Írás** |
| GET | `/api/analysis/:id` | Elemzési feladat eredményének lekérdezése | **Csak olvasás** |

### Boltindítás és onboarding

| Metódus | Útvonal | Rendeltetés | Mód |
|---------|---------|-------------|-----|
| GET | `/api/launcher/jobs` | Boltépítési feladatok listázása | **Csak olvasás** |
| POST | `/api/launcher/jobs` | Boltépítési feladat létrehozása | **Írás** |
| GET | `/api/launcher/jobs/:id` | Feladat állapotának lekérdezése | **Csak olvasás** |
| POST | `/api/launcher/jobs/:id/generate` | Bolt tartalmának generálása | **Írás** |
| GET | `/api/launcher/jobs/:id/plan` | Építési terv lekérdezése | **Csak olvasás** |
| GET | `/api/launcher/jobs/:id/download` | Építési artifact letöltése | **Csak olvasás** |
| GET | `/api/launcher/themes` | Elérhető sablonok | **Csak olvasás** |
| GET | `/api/onboarding` | Aktuális onboarding-állapot | **Csak olvasás** |
| PUT | `/api/onboarding` | Onboarding-lépés frissítése | **Írás** |
| POST | `/api/onboarding/complete` | Onboarding befejezettnek jelölése | **Írás** |

---

## Teljes referencia — 10 legfontosabb végpont

### GET /api/recommendations

Visszaad egy rövidlistát a partnerkatalógus termékeiből, trendlendület, haszonpotenciál és piaci elérhetőség szerint rangsorolva. Ezzel derítheted fel, mely termékek érdemes felvenni a boltba.

**Védett** **Csak olvasás**

**Paraméterek**

| Név | Hol | Típus | Kötelező | Alapértelmezés | Leírás |
|-----|-----|-------|----------|----------------|--------|
| `cats` | query | vesszővel elválasztott string | Nem | (mind) | Szűrés kategóriakulcsok szerint, pl. `kert,sport`. |

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  'https://haszno.com/api/recommendations?cats=kert'
```

**Válasz (200)**

| Mező | Típus | Leírás |
|------|-------|--------|
| `anchor` | string | Az összes trendösszehasonlítás alapjául szolgáló referenciakulcsszó. |
| `geo` | string | Mindig `"HU"`. |
| `items` | array | Javasolt termékek — lásd az almezőket alább. |

**Az `items` almezői** (kiválasztott)

| Mező | Típus | Leírás |
|------|-------|--------|
| `id` | integer | Termékazonosító. |
| `name` | string | Terméknév (magyarul). |
| `sku` | string | Beszállítói SKU. |
| `supplierName` | string | Beszállító megjelenítési neve. |
| `wholesaleNet` | integer (HUF) | Nettó nagykereskedelmi bekerülési ár. |
| `rrpGross` | integer \| null | Beszállító ajánlott fogyasztói ára. |
| `stock` | integer | Elérhető készlet. |
| `marginNet` | integer (HUF) | Nettó haszon az ajánlott áron. |
| `marginPct` | number | Haszonkulcs az ajánlott áron. |
| `recommendedPriceGross` | integer (HUF) | Javasolt bruttó eladási ár. |
| `keyword` | string | Elsődleges trendkulcsszó. |
| `interest4w` | number | Trend érdeklődés az elmúlt 4 hétben (0–100). |
| `interest12m` | number | Trend érdeklődés az elmúlt 12 hónapban (0–100). |
| `trend` | string | Trend iránya: `"up"`, `"down"` vagy `"stable"`. |
| `momentum` | number | Összesített lendület-pontszám. |
| `score100` | number | Kombinált rangsorpontszám, 100-as skálán. |

```json
{
  "anchor": "kerti napernyő",
  "geo": "HU",
  "items": [
    {
      "id": 212,
      "name": "Kerti napernyő · Prémium",
      "sku": "DEMO-212",
      "supplierName": "Példa-partner · Kert és növény",
      "wholesaleNet": 3200,
      "rrpGross": 7990,
      "stock": 15,
      "marginNet": 2080,
      "marginPct": 32.8,
      "recommendedPriceGross": 7490,
      "keyword": "kerti napernyő",
      "interest4w": 72,
      "interest12m": 61,
      "trend": "up",
      "momentum": 1.18,
      "score100": 84
    }
  ]
}
```

---

### GET /api/catalogue/products

Keresi a megosztott partnertermék-katalógust. Támogat szabad szöveges keresést, kategória- és beszállítószűrőt, haszon- és ársávokat, valamint lapozást. Ez az új termékek bolthoz adásának fő felderítési végpontja.

**Védett** **Csak olvasás**

**Paraméterek**

| Név | Hol | Típus | Kötelező | Alapértelmezés | Leírás |
|-----|-----|-------|----------|----------------|--------|
| `q` | query | string | Nem | — | Szabad szöveges keresés terméknévre vagy kategóriára. |
| `cats` | query | vesszővel elválasztott string | Nem | (mind) | Belefoglalandó kategóriakulcsok. |
| `partner` | query | integer | Nem | (mind) | Beszállítóazonosító szerinti szűrő. |
| `minMarginPct` | query | number | Nem | — | Minimális haszonkulcs az ajánlott fogyasztói áron. |
| `maxPrice` | query | integer (HUF) | Nem | — | Maximális `rrpGross`. |
| `minPrice` | query | integer (HUF) | Nem | — | Minimális `rrpGross`. |
| `inStock` | query | `"1"` | Nem | — | Ha be van állítva, csak készleten lévő termékeket ad vissza. |
| `hasImage` | query | `"1"` | Nem | — | Ha be van állítva, csak képpel rendelkező termékeket ad vissza. |
| `country` | query | string (2 karakter) | Nem | — | Beszállító országkódja. |
| `sort` | query | string | Nem | `"name_asc"` | Rendezési sorrend: `"margin_desc"`, `"price_asc"`, `"price_desc"`, `"name_asc"`. |
| `page` | query | egész szám ≥ 1 | Nem | `1` | Oldalszám. |
| `pageSize` | query | egész szám 1–100 | Nem | `24` | Elemek oldalanként. |

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  'https://haszno.com/api/catalogue/products?q=napernyő&inStock=1&sort=margin_desc&pageSize=10'
```

**Válasz (200)**

| Mező | Típus | Leírás |
|------|-------|--------|
| `items` | array | Az aktuális oldalon lévő termékek. |
| `total` | integer | Összes egyező termék az összes oldalon. |
| `facets` | object | Összesített szűrődarabszámok (kategóriák, beszállítók, országok). |

Az `items` minden eleme: `id`, `name`, `sku`, `supplierName`, `supplierId`, `category`, `wholesaleNet` (HUF), `rrpGross` (HUF), `stock`, `imageUrl`, `country`, `marginNet` (HUF), `marginPct`.

```json
{
  "items": [
    {
      "id": 212,
      "name": "Kerti napernyő · Prémium",
      "sku": "SUP-212",
      "supplierName": "Minta Kft.",
      "supplierId": 7,
      "category": "kert",
      "wholesaleNet": 3200,
      "rrpGross": 7990,
      "stock": 15,
      "imageUrl": null,
      "country": "HU",
      "marginNet": 2080,
      "marginPct": 32.8
    }
  ],
  "total": 142,
  "facets": {
    "categories": [{"key": "kert", "count": 142}],
    "suppliers": [{"id": 7, "name": "Minta Kft.", "count": 142}]
  }
}
```

---

### POST /api/feeds/import

Importál egy beszállítói termékfeedet. Legfeljebb 10 MB méretű CSV vagy XML formátumot fogad el. Új termékeket hoz létre, és SKU alapján frissíti a meglévőket.

**Védett** **Írás**

> [!WARNING]
> Ez a végpont tömeges írási műveletet hajt végre. Az import felülírja az egyező SKU-k bekerülési ár- és készletadatait. Importálás előtt ellenőrizd a feed tartalmát, hogy ne írj felül hibás nagykereskedelmi bekerülési árakkal helyes adatokat.

**Kéréstörzs** (`Content-Type: application/json`)

| Mező | Típus | Kötelező | Leírás |
|------|-------|----------|--------|
| `supplierId` | integer | Igen | A feedhez tartozó beszállító azonosítója. |
| `format` | string | Igen | `"csv"` vagy `"xml"`. |
| `content` | string | Igen | A teljes feed tartalom sztringként (1 bájt – 10 MB). |

CSV-formátum: egy fejlécsor, majd adatsorok. Kötelező oszlopok: `sku`, `name`, `costNet`, `stock`. Opcionális: `rrpGross`.

```csv
sku,name,costNet,stock,rrpGross
ABC-001,Kerti szék,2100,10,4990
ABC-002,Kerti asztal,8500,3,19990
```

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  -X POST https://haszno.com/api/feeds/import \
  -H 'Content-Type: application/json' \
  -d '{
    "supplierId": 3,
    "format": "csv",
    "content": "sku,name,costNet,stock,rrpGross\nABC-001,Kerti szék,2100,10,4990"
  }'
```

**Válasz (200)**

| Mező | Típus | Leírás |
|------|-------|--------|
| `created` | integer | Létrehozott új termékek száma. |
| `updated` | integer | Frissített meglévő termékek száma. |
| `total` | integer | Összesen feldolgozott sorok száma. |

```json
{"created": 1, "updated": 0, "total": 1}
```

**Hibaválaszok**

| Státusz | Mikor |
|---------|-------|
| 400 | Érvénytelen formátum, hiányzó kötelező oszlopok vagy hibás feed-tartalom. |
| 413 | A feed tartalma meghaladja a 10 MB-ot. |
| 429 | Sebességkorlát túllépve (20 kérés percenként). |

---

### POST /api/webhooks/order

Új rendelést fogad egy csatlakoztatott webshoptól. Az API ellenőrzi az SKU-kat, megvizsgálja a készletet, és rendelésrekordot hoz létre feldolgozásra.

**Védett** **Írás**

> [!WARNING]
> Ez a végpont olyan rendelést hoz létre, amely azonnal lefoglalja a készletet. Ez nem próbafuttatás. Ha 409-es választ kapsz (nincs készleten), a hibát a bolt oldalán kell kezelni — a rendelés nem jön létre.

**Kéréstörzs** (`Content-Type: application/json`)

| Mező | Típus | Kötelező | Leírás |
|------|-------|----------|--------|
| `externalId` | string (1–64) | Igen | Egyedi rendelésazonosító a webshopból. Egyedinek kell lennie az adott bolt összes rendelésén belül. |
| `customerName` | string (1–120) | Igen | Vevő teljes neve. |
| `customerEmail` | string | Nem | Vevő e-mail-címe. |
| `address` | string (1–300) | Igen | Szállítási cím egyetlen sztringként. |
| `items` | array | Igen | Rendelési tételsorok — lásd alább. |

**Az `items` tömb elemei**

| Mező | Típus | Kötelező | Leírás |
|------|-------|----------|--------|
| `sku` | string | Igen | Termék SKU-ja. Meglévő boltterméket kell jelölnie. |
| `qty` | integer > 0 | Igen | Rendelt mennyiség. |

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  -X POST https://haszno.com/api/webhooks/order \
  -H 'Content-Type: application/json' \
  -d '{
    "externalId": "SHOP-20261112-001",
    "customerName": "Kiss Éva",
    "address": "1111 Budapest, Példa utca 1.",
    "items": [
      {"sku": "ABC-001", "qty": 2}
    ]
  }'
```

**Válasz (201)**

| Mező | Típus | Leírás |
|------|-------|--------|
| `id` | integer | A Haszno által kiosztott belső rendelésazonosító. |

```json
{"id": 1047}
```

**Hibaválaszok**

| Státusz | Üzenet | Mikor |
|---------|--------|-------|
| 400 | `"Ismeretlen cikkszám: ABC-999"` | Az SKU nem található a boltban. |
| 409 | `"Elfogyott: ABC-001"` | Az SKU létezik, de nulla a készlete. |

> [!NOTE]
> A hibaüzenetek magyarul kerülnek visszaadásra. A teljes hibaalapú sémáért lásd a [Hibák és sebességkorlátok](errors.md) oldalt.

---

### PUT /api/settings

Frissíti a bolt globális árazási szabályait. Minden mező opcionális; ha kihagyod, az aktuális értéke változatlan marad.

**Védett** **Írás**

> [!WARNING]
> A `shippingMarkets` módosítása azonnal elindítja a `marketMinGross` újraszámítását minden termékre. Nagy katalógusokon ez több másodpercet is igénybe vehet. Az árazási javaslatok ennek megfelelően frissülnek.

**Kéréstörzs** (`Content-Type: application/json`)

| Mező | Típus | Kötelező | Leírás |
|------|-------|----------|--------|
| `undercutPct` | number 0–50 | Nem | Az ajánlott ár kiszámításakor a piaci minimum alatti %-os aláígérés mértéke. |
| `minMarginPct` | number 0–90 | Nem | Az árpadló kiszámításakor érvényesített minimális nettó haszonkulcs %-ban. |
| `vatPct` | number 0–50 | Nem | Minden bruttó/nettó átváltásnál alkalmazott áfakulcs. |
| `shippingMarkets` | string[] | Nem | Piaci árak figyeléséhez szükséges ISO-országkódok. Ha meg van adva, legalább egy értéket kell tartalmaznia. Érvényes kódok: `HU`, `SK`, `DE`, `AT`, `CZ`, `PL`, `RO`. |

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  -X PUT https://haszno.com/api/settings \
  -H 'Content-Type: application/json' \
  -d '{
    "undercutPct": 2,
    "minMarginPct": 15,
    "shippingMarkets": ["HU", "SK"]
  }'
```

**Válasz (200)**

Visszaadja a frissített beállítássort. Ugyanolyan séma, mint a `GET /api/settings` esetén (valódi példányon a `demo` mező nélkül).

```json
{
  "id": 1,
  "undercutPct": 2,
  "minMarginPct": 15,
  "vatPct": 27,
  "shippingMarkets": ["HU", "SK"],
  "automationPaused": false
}
```

---

### PATCH /api/products/:id

Frissíti egy termék piaci áradatait, vagy kézi bruttó árfelülbírálatot állít be.

**Védett** **Írás**

**Útvonalparaméterek**

| Név | Típus | Leírás |
|-----|-------|--------|
| `id` | integer | Termékazonosító. |

**Kéréstörzs** (`Content-Type: application/json`)

Minden mező opcionális. Csak a módosítani kívánt mezőket küldd el.

| Mező | Típus | Leírás |
|------|-------|--------|
| `marketMinGross` | integer > 0 \| null | A legolcsóbb ismert piaci ár kézi beállítása (bruttó, HUF). `null` értékkel törölhető. |
| `marketShop` | string (max 120) \| null | Bolt neve a kézzel beállított piaci árhoz. `null` értékkel törölhető. |
| `priceGross` | integer > 0 | Kézi bruttó árfelülbírálat. Pozitív egész számnak kell lennie. |

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  -X PATCH https://haszno.com/api/products/101 \
  -H 'Content-Type: application/json' \
  -d '{"priceGross": 2990}'
```

**Válasz (200)**

Visszaadja a frissített termékrekordot. Ugyanolyan séma, mint a `GET /api/products` egyetlen eleme.

---

### POST /api/products/apply-prices

Alkalmazza az ajánlott árat a listázott termékekre. Alapértelmezés szerint az összes listázott termékre alkalmazza. Opcionálisan azonosítók vagy beszállító alapján szűkíthető.

**Védett** **Írás**

> [!WARNING]
> Ez tömeges írási művelet. Minden egyező termék `priceGross` értékét frissíti az aktuális `recommended.priceGross`-ra. Az alkalmazás előtt futtasd a `GET /api/products` végpontot, és tekintsd át a javaslatokat.

**Kéréstörzs** (`Content-Type: application/json`)

Minden mező opcionális.

| Mező | Típus | Leírás |
|------|-------|--------|
| `ids` | integer[] | Termékek azonosítói, amelyekre az árakat alkalmazni kell. Ha kihagyod, az összes listázott termékre alkalmazza. `[]` küldése nem hajt végre műveletet. |
| `supplier` | integer[] | Szűkítés ezeknek a beszállítóazonosítóknak megfelelő termékekre. |

**Kérés**

```bash
# Alkalmazás az összes listázott termékre:
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  -X POST https://haszno.com/api/products/apply-prices \
  -H 'Content-Type: application/json' \
  -d '{}'

# Alkalmazás csak megadott termékekre:
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  -X POST https://haszno.com/api/products/apply-prices \
  -H 'Content-Type: application/json' \
  -d '{"ids": [101, 102, 103]}'
```

**Válasz (200)**

| Mező | Típus | Leírás |
|------|-------|--------|
| `changed` | integer | Frissített árú termékek száma. |
| `total` | integer | Kiértékelt termékek száma. |

```json
{"changed": 847, "total": 1400}
```

---

### GET /api/rules

Visszaadja a bolthoz konfigurált összes automatizálási szabályt.

**Védett** **Csak olvasás**

**Paraméterek**

Nincsenek.

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  https://haszno.com/api/rules
```

**Válasz (200)**

Szabályobjektumok tömbjét adja vissza.

| Mező | Típus | Leírás |
|------|-------|--------|
| `id` | integer | Szabályazonosító. |
| `name` | string | Megjelenítési név. |
| `enabled` | boolean | Aktív-e a szabály. |
| `trigger` | string | Mikor fut a szabály — lásd az enumot alább. |
| `conditions` | array | Feltételek, amelyeknek mind teljesülnie kell — lásd az almezőket alább. |
| `actions` | array | A feltételek teljesülése esetén végrehajtott műveletek — lásd az almezőket alább. |
| `template` | string \| null | Beépített sablonkulcs, ha a szabály sablonból lett létrehozva. |
| `createdAt` | ISO-8601 string | Létrehozás időbélyege. |

**A `trigger` enum értékei**

| Érték | Jelentés |
|-------|---------|
| `"feed_import"` | Minden feed-import után fut. |
| `"market_price"` | Piaci árak frissítése után fut. |
| `"manual"` | Csak kézi indításkor, vagy `POST /api/rules/:id/run` híváskor fut. |

**A `conditions` elem almezői**

| Mező | Típus | Leírás |
|------|-------|--------|
| `field` | string | Kiértékelendő termékező, pl. `"current.marginPct"`. |
| `op` | string | Összehasonlítási operátor: `"lt"`, `"lte"`, `"gt"`, `"gte"`, `"eq"`, `"neq"`, `"changed"`. |
| `value` | number \| string | Küszöbérték. |

**Az `actions` elem almezői**

| Mező | Típus | Leírás |
|------|-------|--------|
| `type` | string | Művelet típusa: `"unlist"`, `"propose_price"`, `"notify"`. |

```json
[
  {
    "id": 5,
    "name": "Veszteséges termékek javaslata",
    "enabled": true,
    "trigger": "market_price",
    "conditions": [
      {"field": "current.marginPct", "op": "lt", "value": 0}
    ],
    "actions": [
      {"type": "propose_price"}
    ],
    "template": "loss-guard",
    "createdAt": "2026-10-01T10:00:00.000Z"
  }
]
```

---

### GET /api/network/suppliers

Visszaadja a Haszno hálózatában elérhető összes beszállítót, valamint a bolt csatlakozási állapotát mindegyikhez.

**Védett** **Csak olvasás**

**Paraméterek**

Nincsenek.

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  https://haszno.com/api/network/suppliers
```

**Válasz (200)**

Hálózati-beszállítóobjektumok tömbjét adja vissza.

| Mező | Típus | Leírás |
|------|-------|--------|
| `id` | integer | Beszállítóazonosító. |
| `name` | string | Beszállító megjelenítési neve. |
| `category` | string | Elsődleges kategóriakulcs. |
| `country` | string | ISO-országkód. |
| `productCount` | integer | Felkínált termékek teljes száma. |
| `connected` | boolean | A bolt már csatlakoztatva van-e ehhez a beszállítóhoz. |
| `avgResellerMarginPct` | number \| null | Összesített átlagos viszonteladói haszonkulcs az összes csatlakoztatott boltra vetítve (k-anonimitás ≥ 5 bolt; `null`, ha 5 boltnál kevesebb csatlakozott). |

```json
[
  {
    "id": 7,
    "name": "Minta Kft.",
    "category": "kert",
    "country": "HU",
    "productCount": 340,
    "connected": false,
    "avgResellerMarginPct": 28.4
  }
]
```

> [!NOTE]
> Az `avgResellerMarginPct` legalább 5 bolt adataiból képzett összesített mutató. Az egyes boltok haszonkulcsa ezen a végponton keresztül soha nem kerül nyilvánosságra.

---

### POST /api/products/:id/listing

Listázza vagy leveszi a listáról az adott terméket. Ha korábban listáról levett terméket listáz fel, a `priceGross` automatikusan az aktuális `recommended.priceGross` értékre áll be.

**Védett** **Írás**

**Útvonalparaméterek**

| Név | Típus | Leírás |
|-----|-------|--------|
| `id` | integer | Termékazonosító. |

**Kéréstörzs** (`Content-Type: application/json`)

| Mező | Típus | Kötelező | Leírás |
|------|-------|----------|--------|
| `listed` | boolean | Igen | `true` a listázáshoz; `false` a listáról való levételhez. |

**Kérés**

```bash
curl --fail-with-body \
  -u "$HASZNO_BASIC" \
  -X POST https://haszno.com/api/products/101/listing \
  -H 'Content-Type: application/json' \
  -d '{"listed": true}'
```

**Válasz (200)**

Visszaadja a frissített termékrekordot. Ugyanolyan séma, mint a `GET /api/products` egyetlen eleme. A `listed` mező az új állapotot tükrözi, a `priceGross` pedig a listázáskor automatikusan alkalmazott ajánlott árat.

```json
{
  "id": 101,
  "listed": true,
  "priceGross": 2090,
  "recommended": {
    "priceGross": 2090,
    "status": "versenykepes"
  }
}
```
