ALBI B2B · interní zadání ← Rozcestník · verze 1.0 · 25. 9. 2026 · k revizi
F06 + P1 + P2 · fáze 1 · nové

Oblíbené produkty, sledování kategorie - a upozornění e‑mailem

Zákazník si srdíčkem uloží produkt a hvězdičkou označí kategorii. Když oblíbený produkt zlevní nebo se naskladní, nebo když ve sledované kategorii přibude produkt, který smí vidět, dostane jednou denně e‑mail. Co chce dostávat, si nastaví v účtu.

Jádro (oblíbené, sledování) + obálka (upozornění) + SFX FrontAPI: 8 nových endpointů Administrace: 1 e‑mailová šablona PBS 121587 Autor: Hana Ortmannová
Co se dělá

Klient položku schválil slovy „toto určitě". Kalkulace slibuje i upozornění, ale zná jen oblíbené produkty. Bez sledování kategorie nejde upozornit na nový produkt, a bez doručovacího kanálu nemají upozornění kde být. Rozhodnuto 23. 9. 2026: kanál je e‑mail, jako u ostatních upozornění. Notifikační centrum v e‑shopu se nestaví.

Kam patří. Jádro MasterShopu (větev front-api): oblíbené nad existujícím modulem Wishlist a sledované kategorie, šest endpointů. Hodí se každému klientovi na headlessu. Obálka: upozornění e‑mailem: nastavení v účtu, denní úloha, šablona souhrnu. Typy upozornění a faktura po splatnosti z AlbiLine jsou šité na ALBI. Obrazovky v SFX. Názvy nových tabulek a endpointů jsou pracovní, v jádru je pojmenuje programátor.

Otevřené otázky

Oblíbené a sledování jdou stavět hned. Upozornění potřebují rozhodnutí D3 o tom, co je „nový produkt", než se napíše denní úloha.

Klient

Rozhoduje ALBI

#Otázka a náš návrh
K1Jsou oblíbené a sledované kategorie per účet, nebo sdílené v rámci firmy? Návrh: per účet. Podúčty jsou různí lidé s různou prací. Sdílení je snadné doplnit později, opačně to nejde.
K2Má se upozornění na fakturu po splatnosti posílat všem účtům firmy, nebo jen hlavnímu účtu? Návrh: jen hlavnímu účtu, ostatním jen když si to zapnou.
K3V kolik hodin má denní souhrn chodit? Návrh: 6:00 místního času.
Vývojář

Rozhoduje vývoj

#Otázka
D1Oblíbené stojí na jádrové tabulce wishlist_items (zákazník, produkt, datum přidání). Její pojmenované seznamy (wishlist_categories) a sdílení se v B2B NEPOUŽÍVAJÍ, položky mají seznam prázdný. Jak pojmenovat nové endpointy jádra a do které skupiny FrontAPI je zařadit, rozhodne programátor. Názvy níže jsou pracovní.
D2Jádro má Watchdog na naskladnění produktu (tabulka watchdog, FrontAPI i SFX stránka, cron po 15 minutách, jeden e‑mail na záznam). Přes FrontAPI dnes umí jen typ naskladnění. Navrhujeme ho v B2B nepoužít a naskladnění oblíbeného řešit v denním souhrnu. Má se Watchdog na B2B prezentacích vypnout?
D3„Nový produkt v kategorii" = produkt s datem přidání po posledním běhu úlohy, který je pro zákazníka viditelný. Produkt, který zákazníkovi přibyl do sortimentu později (nový řádek v povoleném výpisu), se tím NEZACHYTÍ. Zápis povoleného výpisu ze synchronizace nemá událost. Stačí to pro fázi 1, nebo se má porovnávat i změna výpisu?
D4Zlevnění: cena produktu pro zákazníka je z ceníku adresy. Denní úloha porovná uloženou cenu u oblíbeného záznamu s aktuální. Sklad má observer bez události, cena má událost productBasePriceObject.afterSave. Polling v denní úloze je pro obojí jednodušší. Souhlas?
D5Crontab je v samostatném repu mimo workspace. Kdo tam denní úlohu založí?

Shrnutí

Co se ukládá

Jedna existující a jedna nová tabulka v jádru, tři nové tabulky v obálce backendu (albi-b2b-backend). Jádro neví nic o upozorněních, obálka čte jeho tabulky.

TabulkaSloupcePoznámka
wishlist_items · jádro, existujewishlist_item_id, customer_id, product_id, wishlist_category_id (v B2B vždy NULL), add_timeUnikát (zákazník, produkt, seznam). Modul Wishlist, migrace existuje. Struktura se NEMĚNÍ. D1
customer_watched_categories · jádro, nováid, customer_id, category_id, add_timeUnikát (zákazník, kategorie). Sleduje se i podstrom, ten se počítá při běhu úlohy, neukládá se. Název tabulky je pracovní.
b2b_favourite_watch_state · obálkacustomer_id, product_id, last_price (cena bez DPH pro zákazníka při posledním běhu úlohy), last_in_stock (0/1), last_checked_atStav pro upozornění k oblíbeným. Plní jen denní úloha. Chybějící řádek úloha založí bez události, takže nový oblíbený produkt nevyvolá falešné „zlevnilo".
b2b_customer_notification_settings · obálkacustomer_id, type (price_drop · back_in_stock · new_in_category · invoice_overdue), enabled (0/1), update_timeChybějící řádek = výchozí hodnota podle typu (sekce 05). Jádrová tabulka zákazníka nemá kam preference uložit, samostatná tabulka neexistuje.
b2b_notification_events · obálkaid, customer_id, type, product_id (nebo NULL), category_id (nebo NULL), document_code (nebo NULL), payload (JSON: stará a nová cena, název), created_at, sent_at (NULL = neodesláno)Fronta pro denní souhrn. Po odeslání se řádky drží 90 dní pro dohledání, pak se mažou.

Workflow

A. Oblíbený produkt

  1. Zákazník klikne na srdíčko na kartě nebo v detailu. SFX zavolá POST /api-wishlist/products s id produktu. Srdíčko se vyplní hned, bez čekání na odpověď.
    • Neúspěch: srdíčko se vrátí do prázdného stavu a zobrazí se krátká hláška „Nepodařilo se uložit".
    • Úspěch: záznam vznikne v jádrové tabulce wishlist_items. Opakované přidání duplicitu NEVYTVOŘÍ.
  2. Opakované kliknutí zavolá DELETE /api-wishlist/products/{productId}. Srdíčko se vyprázdní hned.
  3. Stránka Oblíbené načte GET /api-wishlist/products: produktové karty ve stejném formátu jako katalog. Produkt, který zákazník už nesmí vidět, v odpovědi NENÍ, ale záznam zůstane, aby se po vrácení do sortimentu objevil.

B. Sledovaná kategorie

  1. Zákazník klikne na hvězdičku u kategorie ve stromu katalogu. SFX zavolá POST /api-watched-categories/categories. Hláška: „Sledujete Hry a puzzle včetně podkategorií."
  2. Sledování podstromu. Kdo sleduje rodiče, nemusí sledovat děti. Hvězdička u dítěte sledovaného rodiče je vyplněná a neaktivní, s nápovědou „sledujete přes Hry a puzzle".
  3. Stránka Oblíbené ukáže sledované kategorie s tlačítkem Přestat sledovat (DELETE /api-watched-categories/categories/{categoryId}).

C. Nastavení upozornění

  1. Zákazník otevře Můj účet → Upozornění e‑mailem. SFX načte GET /api-b2b/notification-settings: čtyři přepínače.
  2. Přepnutí zavolá PUT /api-b2b/notification-settings s celým stavem. Uloží se hned.
  3. Odkaz z e‑mailu vede na tuto stránku. Odhlášení všeho = vypnout čtyři přepínače, samostatná akce NENÍ.

Oblíbené staví na jádrovém modulu Wishlist, vlastní tabulka oblíbených v obálce NEVZNIKÁ. Watchdog jádra se NEPOUŽÍVÁ (D2). Jádrová tabulka zákazníka se NEMĚNÍ.

Upozornění e‑mailem

Denní úloha v obálce backendu, vzor existující CLI úlohy v Local/crons/ se třídou dědící z EshopCLI, která sama řeší mutex a CronMonitor. Odesílá se přes mailSender() stejně, jak to dělá B2BNotificatorService v obálce albi.eu.

Typy upozornění a výchozí stav

TypKdy vznikne událostVýchozíKomu
price_dropCena oblíbeného produktu bez DPH podle ceníku doručovací adresy zákazníka je nižší než last_price v b2b_favourite_watch_state.zapnutoúčet s oblíbeným
back_in_stockOblíbený produkt měl last_in_stock = 0 a teď je skladem.zapnutoúčet s oblíbeným
new_in_categoryVe sledované kategorii nebo jejím podstromu je produkt s datem přidání po posledním běhu úlohy, viditelný pro zákazníka. D3zapnutoúčet se sledováním
invoice_overdueFaktura uzlu firmy přešla do stavu po splatnosti (ze synchronizace AlbiLine) a k ní ještě nevznikla událost.zapnuto jen hlavní účethlavní účet K2

Denní úloha

  1. Sběr událostí. Úloha projde oblíbené produkty všech zákazníků (jádrová wishlist_items): načte aktuální cenu pro zákazníka (ceník jeho aktivní doručovací adresy) a skladovost, porovná se stavem v b2b_favourite_watch_state, založí události, uloží nové hodnoty a last_checked_at. Produkt bez stavu jen zapíše, událost NEZALOŽÍ. Pak sledované kategorie (jádrová customer_watched_categories): pro každý záznam najde nové viditelné produkty v podstromu. Pak faktury: nové stavy po splatnosti. D4
  2. Filtr podle nastavení. Události typu, který má zákazník vypnutý, se založí se sent_at = čas běhu a příznakem v payloadu, že byly potlačené. Neodejdou, ale je vidět, že nastaly.
  3. Sestavení souhrnu. Pro každého zákazníka s aspoň jednou neodeslanou událostí se sestaví jeden e‑mail: sekce podle typů, uvnitř seznam položek s odkazem do e‑shopu. Prázdné sekce se vynechají.
  4. Odeslání. Šablona B2B_DAILY_DIGEST z tabulky šablon pro prezentaci zákazníka. Po odeslání se u událostí nastaví sent_at.
    • Odeslání selže: události zůstanou neodeslané a odejdou při dalším běhu. Úloha pokračuje dalším zákazníkem.
    • Zákazník nemá žádnou událost: žádný e‑mail. Prázdný souhrn se NEPOSÍLÁ.
  5. Úklid. Události odeslané před víc než 90 dny se smažou.

E‑mail

Náhled e‑mailu
WF-M1

Denní souhrn, šablona B2B_DAILY_DIGEST

Od: ALBI velkoobchod · Komu: jana.novakova@ulipy.cz
ALBI B2B: co je nového ve vašem sortimentu

Dobrý den, za posledních 24 hodin se u vašich oblíbených produktů a sledovaných kategorií změnilo tohle.

Zlevnilo
Puzzle Karak 500 dílků · 139 → 129 Kč/ks bez DPH · Zobrazit

Nové v kategorii Hry a puzzle
Puzzle Karak Deluxe 1000 dílků · 219 Kč/ks · Zobrazit
Kvarteto Dinosauři · 59 Kč/ks · Zobrazit

Ceny platí pro vaši doručovací adresu Lípová 12. Nastavit, co chci dostávat.

Sekce „Zase skladem" a „Faktura po splatnosti" se v tomto příkladu vynechaly, protože nenastaly.

Zobrazení na FE

Podle prototypu: katalog (hvězdičky), karty a detail (srdíčko), stránka Oblíbené, Můj účet → Nastavení. Design system ALBI.

MístoPrvek a chování
Produktová kartaSrdíčko vpravo nahoře nad obrázkem. Prázdné / plné. Klik nepřechází na detail. SFX jádro má ikonu wishlistu jen v hlavičce, komponenta srdíčka vzniká v obálce.
Detail produktuTlačítko „Do oblíbených" / „V oblíbených" vedle množství. Pod ním věta „Dáme vědět e‑mailem, když zlevní nebo bude zase skladem."
Strom kategorií v kataloguHvězdička za názvem každé kategorie. Vyplněná = sledováno. U potomka sledovaného rodiče vyplněná a neaktivní s nápovědou.
Stránka Oblíbené (Můj účet)Nahoře karty oblíbených produktů s tlačítkem Do košíku a srdíčkem k odebrání. Dole seznam sledovaných kategorií, u každé Přestat sledovat. Prázdné stavy: „Srdíčkem u produktu si ho uložíte." / „Hvězdičku najdete v katalogu."
Můj účet → Upozornění e‑mailemČtyři přepínače s popisem. Věta nahoře: „Upozornění chodí jednou denně e‑mailem na vaši adresu." Přepínač faktury vidí každý účet, výchozí stav podle role.
Nástěnka (F03)Blok Oblíbené: až 4 karty a odkaz na stránku.
Náhled FE: stránka Oblíbené a nastavení
WF-F1

Můj účet → Oblíbené

Můj účet › Oblíbené
Oblíbené produkty
Puzzle Karak 500 dílků
129 Kč / ks
balení 6 ks · ❤
Hrnek Kočka 330 ml
149 Kč / ks
balení 6 ks · ❤
Sledované kategorie
Hry a puzzle včetně podkategoriíPřestat sledovat
Upozornění na změny chodí e‑mailem. Nastavit, co chci dostávat →
WF-F2

Můj účet → Upozornění e‑mailem

Upozornění e‑mailem
Chodí jednou denně na jana.novakova@ulipy.cz, jen když je co říct.
Oblíbený produkt zlevnilzapnuto
Oblíbený produkt je zase sklademzapnuto
Nový produkt ve sledované kategoriizapnuto
Faktura po splatnostivypnuto

Přepínače ukládají hned. U podúčtu je faktura ve výchozím stavu vypnutá, u hlavního účtu zapnutá.

FrontAPI

Osm nových endpointů, všechny s JWT zákazníka. Šest v jádru MasterShopu (modul FrontApi), dva v obálce backendu ve skupině /api-b2b/. Názvy jsou pracovní. D1

EndpointStavK čemu
GET /api-wishlist/productsnový · jádroProduktové karty oblíbených, jen viditelné. Parametr idsOnly=1 vrátí jen pole id produktů pro vyplnění srdíček v katalogu.
POST /api-wishlist/productsnový · jádroTělo { "productId" }. Idempotentní: opakované volání nevytvoří duplicitu, vrátí 200.
DELETE /api-wishlist/products/{productId}nový · jádroOdebere. Neexistující záznam → 204, ne chyba.
GET /api-watched-categories/categoriesnový · jádroSeznam { categoryId, name, slug }.
POST /api-watched-categories/categoriesnový · jádroTělo { "categoryId" }. Kategorie, kterou zákazník nesmí vidět → 404.
DELETE /api-watched-categories/categories/{categoryId}nový · jádroOdebere.
GET /api-b2b/notification-settingsnový · obálkaČtyři typy s hodnotou. Chybějící řádek vrátí výchozí hodnotu.
PUT /api-b2b/notification-settingsnový · obálkaTělo { "price_drop": true, "back_in_stock": true, "new_in_category": true, "invoice_overdue": false }. Ukládá celý stav.

Administrace

Jedna e‑mailová šablona ve stávajícím modulu šablon. Nic dalšího.

Náhled administrace: e‑mailová šablona
WF-A1

E‑mailové šablony → B2B_DAILY_DIGEST

E‑mailová šablona
Prezentace: B2B CZ
Základní údaje
Kód
B2B_DAILY_DIGEST
Předmět
ALBI B2B: co je nového ve vašem sortimentu
Text
HTML šablona se sekcemi a proměnnými …
Uložit

Stávající obrazovka modulu šablon, přibývá jen nový kód šablony. Stejně vzniknou řádky pro SK, PL a EN.

Pravidla a validace

Mimo rozsah a nasazení

Mimo rozsah

Nasazení

Kontrola po nasazení