Bonusy do každé rodiny

O radosti z releasů jsem tady na blogu psal už dříve a teď budu psát znovu, ale z jiného úhlu pohledu. Téměř po roce od začátku analytických prací jde do produkce jeden z mých největších dosavadních projektů - Ok Bonus portál pro slovenskou společnost DOXX. Podstatou projektu je poskytnout technické řešení maloobchodům a jednotlivcům pro tvorbu věrnostních (bonusových) programů, které si dokáží ušít samy sobě na míru.

Řešení je složeno z několika částí: desktopové aplikace postavené nad NetBeans RCP - tzv. terminálu, který bude provozován vedle pokladního systému a bude umožňovat zápis informací o nákupech a také čerpání odměn. Nákupy a bonusy se evidují na libovolnou NFC kartu, kterých v současné době po světě běhá více než dost (samozřejmě bude možné získat u provozovatelů systému i brandované Ok Bonus NFC karty). Druhou část představuje tzv. "platební brána", která zpracovává transakce ze všech desktopových klientů a spravuje zákaznické účty. Třetí část je potom webový portál Ok Bonus, který představuje prostředníka mezi zákazníky, obchodníky a platební branou. Na portále jsou k dispozici výpisy z účtů (tj. evidence nákupů, přidělování bonusů atd.), pro obchodníky potom rozhraní pro tvorbu bonusových programů, správu autorizovaných karet a terminálů, statistiky, e-shop a vyúčtování.

Fungování věrnostního systému

Princip fungování by měl být velmi prostý. Majitel obchodu se zaregistruje na www.okbonus.sk a pro své provozovny si vytvoří bonusové akce. V rámci bonus editoru je možné nastavit celou škálu akcí. Všechny akce pracují přímo s reálnými produkty - tj. útratou v EUR, konkrétním typem zboží nebo služby (např. každé 10 pivo zdarma apod.). Zvažovali jsme jednodušší variantu - zavést bodový systém, kde by se vše převádělo přes konverzní poměr na nějaké virtuální body, za které by se daly odměny "nakupovat". Nakonec jsme však tuto variantu po diskusi zamítli, protože jsou virtuální body velmi odosobněné a my jsme chtěli, aby akce byly co nejčitelnější pro koncové spotřebitele.

Po publikaci akce se na terminálech (instalovaných na počítačích s pokladním systémem) zobrazí sbíraný produkt a obsluha pokladny (číšník, prodavač) může začít klientům zapisovat na jejich NFC karty jejich nákupy / platby. Nevýhodou je aktuálně absence integrací do pokladních systémů - tj. při platbě je nutné zaevidovat daný produkt 2krát.

Z pohledu spotřebitele stačí na místě, kde akce probíhá zakoupit Ok bonus kartu nebo si zaregistrovat u prodavače na terminálu libovolnou jinou NFC kartu, kterou již zákazník vlastní. V dnešní době je velmi pravděpodobné, že takovou kartu už má - použitelné NFC karty kupříkladu jsou In-karty ČD, městké karty (pražská Opencard, pardubická / hradecká městská karta), novější typy Android telefonů (Nexus S, Galaxy II atd.), nové typy kreditních karet atd. Registrace vyžaduje pouze sdělení své e-mailové adresy a od té chvíle je již je možné sbírat produkty na všech provozovnách provozujících své varianty Ok bonus akcí. Zákazník tím automaticky získává přístup do portálu, kde vidí všechny své nákupy, zůstatky a odměny.

Obchodníci mohou přes systém vypisovat i poukázkové akce, jak je známe třeba ze Slevomat.cz a stovky dalších. V této oblasti však existuje taková konkurence, že nemá smysl se je snažit porazit právě v tomto segmentu. Výhodou může být jen to, že obchodník neplatí za vypsání každé jednotlivé akce, ale formou předplatného a v předplaceném období si bude moci vypsat libovolné množství poukázkových akcí, jaké uzná za vhodné.

Pár dat ze zákulisí vývoje

Na konci projektu je čas pro retrospektivu a tak jsem si vyjel pár informací, které mě zajímaly. Zdrojové kódy čítají aktuálně 80 tisíc ručně psaných řádků kódu a dalších 82 tisíc řádků generovaného kódu (web servicy). Na třídu připadá průměrně 90 řádek kódu s tím, že na portále je největším mackem třída o 1138 řádcích a na platební bráně o 567 řádcích. Při vydělení časem vynaloženým na vývoj nám vychází produktivita 31 řádků za hodinu (ne že by to číslo něco znamenalo).

Problémem vidím v některých případech s cyklomatickou komplexitou (cca u 30 metod někde okolo 13) a komplexitou některých tříd (cca 11 tříd okolo 130). Tedy nějaký ten refaktoring nás ještě čeká.

Z celkového počtu připadá 30% řádků na  celkově 930 automatických testů. Valná většina testů jsou integrační testy (Spring+db). V průběhu vývoje jsme se nijak nesnažili sledovat ani cílit na nějaké metriky pokrytí kódu testy a tak jsem analýzu provedl až v závěru. Pokrytí kódů testy nám vychází na portále na žalostných 36% a na platební bráně 70%. Nízké číslo pokrytí na portále mi samozřejmě nedalo spát a proto jsem se pustil do hlubšího průzkumu, proč tomu tak je.

Jednou z příčin jsou velmi rozsáhlé modelové třídy (tj. plain POJO), kde je celá řada atributů (gettery/settery) pouze nositelem dat z DB (ceklově 3800 řádek a z toho jen 1500 je volaných v rámci testů) a druhou neexistence testů pro view vrstvu. Pokrytí vlastní business vrstvy, která je nejdůležitější, je 61%. Chybějící testy na business vrstvě se týkají většinou generování PDF, přípravy dat pro e-mailing a získávání statistických údajů, u kterých je automatizace testů sporná (tj. testovat obsah lze jen velmi obtížně - lze jen testovat, že metoda proběhla bez chyby). Z toho také vyplývá, proč máme na platební bráně úplně jiné výsledky - ta totiž představuje pouze business vrstvu s exportem do web servis.

Poznámka na okraj: Ještě se na chvilku zastavím u webové vrstvy, abych trochu elaboroval na téma 0% pokrytí testy. Webovou vrstvu naší architektuře tvoří jen velmi jednoduché implementace rozhraní pro získávání dat do datové vrstvy nebo akce. Ty pouze získají uživatelská data z komponent na stránce a převolají business vrstvu, výsledek případně zkonvertují a předají dál. Akce vypíší informační respektive chybové hlášky a to je vše.

Jsou to tedy jen velmi tenké implementace, které jsou úzce spojeny s konfiguračními XML soubory, které definují komponentovou strukturu stránek, a také s připojenými Freemarker šablonami. Testovat je samostatně mi nepřipadá vhodné - aby to mělo nějaký efekt musely by se testovat integračně - pravděpodobně pomocí Selenium testů. Jenže Selenium testy u zakázkového projektu, jehož supportní fáze je teprve před námi je velmi drahá záležitost. Výsledkem je tedy 0% pokrytí testy s nutností ručního přetestování případných změn na webové vrstvě.

Z hlediska zastoupení formátů - kromě Java souborů je v projektu 7 tisíc řádků ve Freemarkerových šablonách (průměrně 42 řádků na soubor, maximálně 1046), 15 tisíc řádků v CSS souborech (průměrně 240 a maximálně 4797 řádků v souboru), 26 tisíc řádků v JavaScript souborech (průměrně 221 a maximálně 4781 řádků v souboru), 37 tisíc řádků v XML souborech (průměrně 105 a maximálně 1597 řádků na soubor). Jinými slovy v doprovodných souborech tvořících webovou vrstvu a konfigurace (Spring soubory, XSD, naše vlastní konfigurace komponentového GUI a nastavení modulů) je stejný počet řádek jako v Java kódu.

Pro ilustraci - aplikaci tvoří 165 typově různých obrazovek na frontendu a něco kolem 100 obrazovek v administraci. Zdojem dat je 75 specifických aplikačních tabulek a dalších 75 tabulek víceúčelových modulů v databázi Percona.

Technologicky tvoří systém náš více méně odzkoušený stack - Spring Framework, Spring Security, Spring WebServicesMyBatis, RamJet, JaxB, iText a Edee CMS.

Koukněte se sami ...

Doufám, že se projekt na trhu uchytí a my budeme mít šanci se na jeho rozvoji dále podílet. Přestože jsme se snažili odvést tu nejlepší práci co umíme, myslím, že je celá řada míst, kde by se mohlo zlepšovat (slovy našeho grafika - "tak teď když vidím, jak to má celé fungovat, tak bych plno věcí navrhl jinak"). Bohužel některé věci jsou vidět až tehdy, když je systém hotový a jsem si jistý, že na leccos po pár měsících provozu ještě přijdeme.

Dost řečí - sami si můžete proklepnout alespoň část projektu na adrese www.okbonus.sk a přikládám také pár fotek z míst, která nejsou na první pohled vidět (jsou přístupná až po registraci a jenom někomu):

[gallery link="file" columns="4" orderby="title" exclude="2120"]