Edee.one 9.0 – Reimplementace objednávkového modulu, podpora GA4 a další vylepšení

V této verzi přicházíme mj. s kompletně přepracovaným mechanismem tvorby, ukládání a správy objednávek. Vše začíná už ve chvíli vytvoření nového košíku...

Reimplementace objednávkového modulu

Objednávková část našeho řešení byla myšlenkově a technologicky 10 let stará. Plnila svůj účel, ale naši zákazníci i my jsme ji už dávno přerostli, a tak byla devátá verze EdeeShopu především o přepracování této části na základě nejnovějších poznatků z produkčních prostředí. 

Vzhledem k tomu, že objednávky jsou srdcem každého e-shopu, dotklo se přepracování objednávkového modulu průřezově mnoha dalších částí, jako je synchronizace s ERP našich zákazníků, napojení na tržiště, platební systémy a mnoho dalšího.

Současné řešení se dostávalo do úzkých už při nižších desítkách vystavených objednávek za sekundu. Na vině bylo především množství synchronně prováděných operací a počet databázových tabulek, do kterých bylo nutné zapsat nové záznamy v moment vystavení objednávky. Zároveň byl objekt a datový model objednávky příliš složitý, takže se se s ním našim implementátorům obtížně pracovalo a špatně se zpětně dohledávaly potřebné informace (jedním z důvodů bylo i postupné doplňování funkcionality v průběhu oněch 10 let, kdy jsme se spolu s našimi zákazníky učili EdeeShop plno nových věcí).

V této verzi přicházíme s kompletně přepracovaným mechanismem tvorby, ukládání a správy objednávek. Vše začíná už ve chvíli vytvoření nového košíku. Košík již není sada jednotlivých řádků v několika tabulkách databáze, ale jeden velký dokument, který se do databáze ukládá nestrukturovaně. Jeho načtení a uložení je otázkou milisekund, protože naši tabulku košíků používáme v podstatě jako jednoduché key-value úložiště.

Při práci s košíkem máme nově nastavený jednoznačný validační cyklus, který nám zajišťuje potřebné přepočty a kontroly na základě změn v košíku ze strany uživatele. Do tohoto cyklu můžeme nově velmi snadno zapojovat další kousky klientské logiky, které jsou běžné pro většinu našich projektů. 

Košík se stal inteligentním –⁠ sleduje souvislosti v datech, a pokud dojde ke změně na položce A, ihned ví, že tato změna ovlivnila položky B a C, které automaticky přepočte. Vývojáři tedy nemusí detailně znát procesy uvnitř košíku a při rozšiřování logiky košíku si vystačí s pár anotacemi nad novými vlastnostmi.

Dalším kritickým momentem je dokončení nákupu a přidělení unikátního čísla objednávky, které stává typicky základem pro variabilní symbol používaný k platbě. Přidělování unikátního čísla ze sekvence bývá problematické z toho důvodu, že pokud je potřeba vystavit více objednávek současně, musí se vlákna mezi sebou synchronizovat a vyžádat si čísla postupně tak, aby bylo zaručeno, že jedno konkrétní číslo bude použito právě pro jedinou z objednávek. V clusterovaném prostředí je navíc nutné se takto dohodnout mezi různými servery v rámci sítě a to je ještě mnohem pomalejší.

Pro tyto účely jsme nově zavedli mechanismus tzv. kohort –⁠ každý server si při startu z databáze vypůjčí rozsah čísel pro nové objednávky (např. 1000 čísel pro nové objednávky). Tento rozsah si pak udržuje v paměti a přiděluje z něj jedno číslo po druhém v rámci jednoduché paměťové synchronizace (mutexu). Jakmile se blíží ke konci řady, s předstihem si s databázovým serverem vykomunikuje a vypůjčí novou sadu čísel pro přidělování. Celý mechanismus je popisován zjednodušeně –⁠ v reálné implementaci je celá řada drobností a chytáků, které bylo nutné vyřešit, aby vše fungovalo spolehlivě a zajistilo vydání všech čísel z vypůjčených sad.

Při vystavení objednávky se synchronně provedou pouze následující operace:

  1. Pro objednávku se vyhodnotí unikátní číslo objednávky (pouze operace v paměti).
  2. Číslo objednávky se zapíše společně s košíkem do databáze (jediný zápis do databáze).
  3. Zapíšou se rezervace všech položek zboží v objednávce do příslušných záznamů ve skladech (vložení několika nových záznamů do tabulek v databázi).
  4. Zapíše se informace o použití konkrétního voucheru či použití kreditů (vložení několika nových záznamů do tabulek v databázi).
  5. Uživatel je následně přesměrován na platební bránu, nebo jsou mu zobrazeny pokyny k platbě převodem (vložení jednoho řádku transakce do databáze).

Vytváření nových řádků v databázi je z pohledu databáze výkonnostně optimální, protože vyžaduje minimum zámků a eliminuje nutnost čekání na získání zámku.

Oproti původnímu řešení se jedná o naprosté minimum operací, které se musí provést ve chvíli dokončení objednávky. Na pozadí se následně startuje asynchronní proces, který provádí celou řadu dalších operací, které je nutné s objednávkou provést:

  1. Konverze objednávky z dokumentového formátu do formátu relačního, se kterým se mnohem lépe pracuje v následných fázích zpracování objednávky.
  2. Nastartování nakonfigurovaného workflow spojeného s objednávkou
    1. Odeslání notifikace e-mailem nebo jiným komunikačním kanálem.
    2. Přidělení bodů do kreditového systému.
    3. Odeslání informací o objednávce do externích systémů.
  3. Publikace nových ponížených zůstatků zboží do feedů a indexů pro rychlé zobrazování

Data jsou v databázi uložena takovým způsobem, že jsme schopni zpětně přesně popsat, jak došlo k výpočtu finální ceny v objednávce až na úroveň jednotlivých položek, ať už je cenová politika, kreditní systém a systém slev jakkoli složitý a přizpůsobený na míru požadavkům zákazníka. Podrobný rozpis výpočtu jsme nově schopni exportovat společně s objednávkou do ERP systému zákazníka např. ve formě textové poznámky.

Pro naše implementátory je klíčové zjednodušení komunikačních rozhraní a také fakt, že svoje rozšíření mohou psát jednotně jak pro košík, tak pro finální objednávku přestože tyto dvě datové struktury vypadají v databázi naprosto odlišně. Pro tyto účely používáme mechanismus dynamického generování Java tříd, se kterým nám pomáhá open-source knihovna Proxycian, kterou jsme uvolnili pro volné použití pod licencí MIT.

Sjednocení práce s platebními branami

Podobným zeštíhlením a sjednocením prošly i naše integrace s platebními branami. Těch máme v nabídce celou řadu: Comgate, ČSOB platební bránu, Essox, GoPay, GP webpay, iplatba, PaysPayU.

Po několika letech používání a postupného doplňování podpor pro různé poskytovatele platebních řešení již dokážeme odhadnout sadu společných vlastností a funkcí, které mají všichni společné a vyextrahovat speciality, které jsou pro každého poskytovatele unikátní.

To nám umožnilo sjednotit a zjednodušit administrační rozhraní k platebním systémům, které by mělo být teď uživatelsky stravitelnější a zároveň zjednodušilo práci implementátorům, kteří mohou přenášet své znalosti z používání jedné platební brány na jiné. Zároveň jsme zachovali přístup ke specialitám jednotlivých bran tak, aby bylo možné i nadále využívat jejich konkurenční výhody.

To nám mj. umožní i mnohem jednodušší a tím pádem i levnější přidávání podpory nových poskytovatelů platebních řešení.

Přepracování slučovacích skupin parametrů

V této verzi jsme změnili logiku slučovacích skupin parametrů, která našim zákazníkům slouží ke sjednocení parametrů produktů, jenž čerpají z různých dodavatelských číselníků, které se vzájemně překrývají (např. různí dodavatelé mají různé pojmenování pro barvy, velikosti a řadu dalších parametrů, které chceme směrem ke koncovému uživateli komunikovat jednodušeji).

Původní logika vypočítávala sloučení parametrů až při vlastním zobrazování na frontendu, což se ukázalo jako velmi nepraktické a složité. Vzhledem k tomu, že chystáme zcela novou verzi frontendu do další z velké verze EdeeShopu, bylo nutné frontend výrazně zjednodušit a komplexní logika v této části nám nezapadala do dlouhodobých plánů. 

V původním řešení bylo také možné vytvořit takové kombinace sloučených hodnot parametrů skrz různé typy, že bylo obtížné domyslet některé dopady na chování facetových filtrů nad produkty a nešlo dostatečně ovlivnit jejich seřazení ve výpisech.

V novém řešení došlo k několika zjednodušením –⁠ např. hodnoty je vždy možné slučovat pouze ve stejném nadřízeném typu parametru. Pokud se slučují celé typy parametrů (sady hodnot), pak se hodnoty v nich slučují separátně. Sloučené hodnoty je možné pomocí drag’n’drop mechanismu správně zařazovat a tím ovlivňovat jejich pořadí ve výpisech na frontendu a hlavně už v administraci uživatel jasně vidí, jak bude vypadat podoba na frontendu. 

Frontendová část navíc o původních hodnotách, které byly sloučeny, už nic neví a vidí pouze sloučené prvky, které jsou pro něj k nerozeznání od těch, které administrátor nechal v původní nesloučené podobě. 

Podpora Google Analytics v4

Google před časem uvedl novou verzi svého analytického nástroje založenou na událostech. EdeeShop ve verzi 9 má integrovanou podporu pro zasílání těch nejdůležitějších událostí GA4, které zahrnují například zobrazení produktu, zobrazení položky produktového výpisu, přidání/odebrání zboží do/z košíku nebo provedení nákupu. Podpora pro starší verzi Universal Analytics zůstává v produktu zachována, měřit lze tedy paralelně oběma verzemi.

Migrace na nejnovější verze JDK a MySQL

Ve verzi 9.0 jsme přešli na nejnovější dostupné LTS verze klíčových prvků naší platformy. Používáme Java platformu ve verzi 17, Tomcat 9.x a také databázi Percona ve verzi 8.x., Spring Framework 5.3.x.

To má řadu pozitiv –⁠ kromě možnosti používat nejnovější funkce, jsou nové verze použitých prvků výkonnostně lepší a samozřejmě také bezpečnější. Mnohem lépe se nám také reaguje na zjištěné zranitelnosti, protože na nejnovější LTS verze vycházejí opravné záplaty jako první.

Chcete zapojit Edee.one
do budování úspěchu
své společnosti?