Izabrani projekti
LOYALTI
Multi-tenant platforma lojalnosti i bonusa sa PremiumBonus-kompatibilnim POS API-jem, tipiziranim novčanicima i targeted-bonus alokatorom.
- PHP 8.4
- Symfony 8
- PostgreSQL 18
- Doctrine
- Bitrix D7
- Docker Swarm
- GitLab CI
- PHPStan L9
Problem
Program lojalnosti je lako demonstrirati, a teško uraditi kako treba. Novac je na putanji iskorišćenja: parcijalni write-off-ovi, targeted pokloni koji važe samo za deo artikala, reservation hold-ovi koji se ne smeju dvaput potrošiti, i POS koji isti zahtev ponovi tri puta preko loše veze. Pogrešiš bilo gde — ili daš novac dvaput ili odbiješ legitiman popust na kasi.
Arhitektura
LOYALTI je heksagonalni backend na Symfony 8 / PostgreSQL 18. Svaki član ima novčanik sa tipiziranim balansima — gifted, promo, earned — jer ističu i troše se po različitim pravilima. Iskorišćenje ide kroz dvofazni alokator:
- Faza 1 — targeted: prvo se troše grant-ovi vezani za artikle/korpu, uz per-item i per-cart limite, FIFO po najbližem isteku, sa reservation lock-ovima da ostatak targeted grant-ova ne potroši drugi tok.
- Faza 2 — baseline: ostatak se povlači sa opštih balansa pod tenant max-redeem limitom, targeted potrošnja iznad limita se izuzima.
POS površina implementira PremiumBonus Purchase200 spec — purchase, reserve, write-off, reversal — svi idempotentni po external purchase id, pa ponovljen zahtev vraća originalni rezultat umesto da naplati dvaput.
Highlights
- Reservation flow sa TTL hold-ovima i atomskim
SQL UPDATEdekrementima — bez lost update-a pri konkurentnim kasama. - Bitrix D7 modul ugrađuje platformu u postojeći e-commerce: sekcije kataloga, sync plaćanja/dostave i 4-step redeem widget.
- Pun GitLab CI/CD na Docker Swarm: lint → PHPUnit (sa jednokratnim Postgres/Redis/RabbitMQ) → build →
docker stack deploy.
Rezultat
721 PHPUnit test / 1798 asertacija, PHPStan level 9 čisto, plus blackbox flow suite koji poziva realne POS endpoint-e. Multi-tenant od prvog dana — jedan deploy, mnogo trgovaca.
Lekcije
- Kod o novcu želi ključeve idempotentnosti pre nego funkcije. Ugovor po purchase id uklonio je čitavu klasu double-spend bagova.
- Tipizirani balansi su bolji od jednog broja. Pravila žive u tipu, ne u razbacanim
if-ovima.