Skip to main content
LOYALTI — cover

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 balansimagifted, 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 specpurchase, 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 UPDATE dekrementima — 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.