Preskoči na sadržaj
XPay

Verzije

Sve verzije,
od prve do današnje.

526 verzija, isti tekst koji stoji u repozitoriju, pa se ne može razići od onoga što je pušteno. Nazad na status

0.76.240

18. oktobar 2026.

Trenutna

Novo

  • Plaćeno na konobarovom tabletu. Kad gost plati cijeli račun telefonom, a sto se ne zatvori sam, na stolu piše "Plaćeno" zelenom bojom. U računu stola stoji "Gost je platio cijeli račun" i jedno dugme, "Zatvori sto, plaćeno". Taj novac se ne knjiži kao gotovina, jer je već stigao na račun. Gotovinu i karticu konobar i dalje naplaćuje i zatvara kao do sada.
  • Plaćanja po poslovnicama (#25). Firma sa više poslovnica vidi za ovaj mjesec, za svaku poslovnicu, koliko je plaćanja stiglo, za koliko i koliko ih još čeka uplatu. Klik na poslovnicu, ili izbor u novom polju "Poslovnica", sužava listu plaćanja na nju.

Popravljeno

  • Dugme za čuvanje isplate napojnica nije se vidjelo (#24). Prozor se otvarao unutar kartice napojnica umjesto preko cijele stranice, pa mu je dno bilo odsječeno. Sada se svaki prozor u konzoli otvara preko cijele stranice, bijel, a dugmad na dnu ostaju vidljiva i kad je forma duga.

0.76.239

18. oktobar 2026.

Popravljeno

  • Osoblje na app.xpay.rs nije vidjelo nijednu narudžbu nakon prijave (#21). Čim se konobar, kuhar ili šanker prijavio PIN-om, tablet bi ostao prazan, jer server nije pustio oznaku prijavljene osobe. Na xpay.ba se to nije vidjelo. Sada radi u obje zemlje, a test pazi da se ne ponovi.
  • Kuhar vidi samo hranu, šanker samo pića (#21). Na kuhinjskom ekranu bez podešene stanice kuhar je vidio sve narudžbe, i pića, sa svim dugmadima. Sada ekran prati ulogu prijavljene osobe.

Promijenjeno

  • Dugmad po ulozi (#21): kuhar i šanker imaju "U pripremi", pa "Spremno". Konobar nosi narudžbu i ima samo "Preuzeto", odnosno "Servirano" na tabletu. Otkazivanje narudžbe konobar više nema podrazumijevano; vlasnik ga može dati u Osoblju.
  • Ekran gosta dok čeka narudžbu (#22) prikazuje korake kao demo na sajtu: Primljeno, Prihvaćeno, U pripremi, Spremno, Posluženo. Umjesto odbrojavanja, gost vidi tačno ono što su kuhinja, šank i konobar pritisnuli, i to se mijenja samo.

0.76.238

17. oktobar 2026.

Promijenjeno

  • Paket uključuje svoje objekte. Start ima 1 objekat, Business do 3, Premium do 5, i za njih se ne plaća ništa dodatno. Start sa jednim restoranom je 49 KM, odnosno 2.900 RSD mjesečno. Svaki objekat preko broja u paketu je 49 KM, odnosno 2.900 RSD mjesečno, uz sve funkcije paketa. Ranije se uz paket plaćao svaki objekat sa naručivanjem, i prvi.
  • Premium je do 5 objekata, po istoj cijeni od 199 KM, odnosno 11.900 RSD.
  • Novi objekat preko paketa se više ne odbija. Vlasnik ga otvara u Poslovnicama, a prozor za novu poslovnicu kaže koliko košta. Na fakturi i u pregledu potrošnje taj red se zove "Dodatni objekti" i pojavljuje se samo kada takvih objekata ima.
  • Ugovor 2.3, na xpay.ba i xpay.rs: paketi sa brojem objekata, naknada za dodatni objekat i novi primjer obračuna.
  • Cijene na sajtu: ispod svakog paketa piše šta je u cijeni ("mjesečno, do 3 objekta"), a ispod svih paketa jedan red za dodatni objekat. Kartice paketa na početnoj stranici navode sve što paket uključuje, a kalkulator je ispod njih. Kalkulator dodaje samo objekte preko paketa. Stranica cijena ima dio "Dodatni objekat" umjesto starog dodatka za ugostiteljstvo.
  • Manje stručnih riječi na sajtu: "IPS" i "po transakciji" su uklonjeni iz teksta za ugostitelje. Gost "plaća QR kodom iz aplikacije svoje banke".
  • Slika koja se pojavi kada se link na xpay.ba ili xpay.rs podijeli je svijetla, u bojama sajta.

0.76.237

17. oktobar 2026.

Novo

  • Tema "XPay", u bojama sajta, je sada podrazumijevana za konzolu, kasu, ekrane kuhinje i šanka i meni koji gost otvori: svijetla podloga, tamnoplavi tekst i tirkizna dugmad. Firme na staroj podrazumijevanoj temi prelaze na nju, a vlasnik i dalje bira bilo koju od šest tema u Postavkama, Izgled (XPay, XPay Dark, Light, Green, Red, Blue).
  • Slike aplikacije na sajtu (telefon sa menijem, konzola) nacrtane su u toj temi, pa sajt pokazuje aplikaciju kakva stvarno izgleda.
  • Tamnozelena traka "Restoran, kafić, bar ili pult" na početnoj stranici: kartica za restorane, kafiće, barove i pekare i brzu hranu, svaka sa svojom ilustracijom nacrtanom za XPay i dugmetom za prezentaciju.

Popravljeno

  • Male krive u karticama na slici konzole imale su crnu ispunu na svijetloj podlozi.

0.76.236

17. oktobar 2026.

Novo

  • Svijetao izgled sajta. Bijela pozadina, tamnoplavi tekst i tirkizno dugme, bez mreža i sjaja. Konzola i aplikacije ostaju kakve jesu, a slike aplikacije na sajtu i dalje pokazuju njen tamni ekran.
  • Početna stranica, istim redom na obje adrese: "Meni. Narudžba. Plaćeno." (u Srbiji "Porudžbina"), tri koristi, demo, kako radi u tri koraka, kartice Restorani / Kafići / Barovi, šta nas razlikuje, kuda ide novac ("Vaš novac. Vaš račun. Vaša kontrola."), pregled platforme, kalkulator cijene, česta pitanja i formular za prezentaciju. U Bosni stranica kaže da gost danas plaća konobaru, gotovinom ili karticom, a plaćanje telefonom dolazi s IPS-om; u Srbiji IPS QR.
  • Interaktivni demo na /demo. Demo restoran, sto 7: meni sa slikama, korpa, narudžba, statusi iz kuhinje i sa šanka, pa simulirano plaćanje. Bez registracije, bez prave narudžbe i bez prave uplate; QR kod u demu je samo crtež.
  • Kalkulator cijene. Izaberete paket i broj objekata i vidite ukupnu mjesečnu cijenu (npr. Business sa tri objekta: 99 + 3 × 49 = 246 KM, u Srbiji 5.900 + 3 × 2.900 = 14.600 RSD), sa granicama paketa.
  • Pravi formular za upit. Prezentacija, ponuda ili pitanje, sa vrstom objekta, paketom i brojem objekata koji dolaze iz klika (kalkulator, demo, kartice). Upit se sprema u XPay i šalje mail na adresu firme; ponovljen klik istog dana ne pravi drugi upit. Ranije je formular samo otvarao mail program. Upiti su vidljivi operateru (GET /v1/admin/leads).
  • Glavno dugme u zaglavlju je "Zakažite prezentaciju", a meni ima stavku Demo.
  • Mjerenje toka posjete. Klik na prezentaciju i demo, početak i kraj dema, kalkulator i poslan upit broje se po danu, bez imena, maila i kolačića.
  • SEO. Naslov i opis početne stranice po zemlji, /demo u sitemapu.

Za programere

  • Nova provjera scripts/smoke-leads.mjs u CI-ju; test cjenovnika provjerava i cijene u kalkulatoru.

0.76.235

17. oktobar 2026.

Novo

  • Pića idu na šank sama. Jelo bez izabrane stanice dobija je po kategoriji: Pića, Napici, Kafe, Pivo, Sokovi, Vina, Kokteli, Rakije (i engleski nazivi) idu na šank, ostalo u kuhinju. Pite, pice i picerije ostaju u kuhinji. Postojeći meniji su prebačeni na isti način. Svako jelo se i dalje može ručno premjestiti u meniju.
  • Kuhar i šanker na tabletu vide svoj red. Kad se kuhar prijavi na konobarski tablet, tablet pokazuje narudžbe za kuhinju (samo hranu). Kad se prijavi šanker, pokazuje narudžbe za šank (samo pića). Kad se odjave, tablet se vraća na stolove. Ekran šanka pokazuje samo pića, a ekran kuhinje samo hranu.
  • Svaka stanica kaže "Spremno" za svoj dio. Šanker ima jedno dugme "Spremno" čim narudžba stigne. Kuhar prihvata, priprema i kaže "Spremno". Narudžba je spremna kad su gotove sve njene stanice.
  • Konobar vidi šta može nositi. Sto pokazuje "Spremno za nošenje" i kad je gotov samo dio (na narudžbi piše "Pića spremna" ili "Hrana spremna"), a konobar kad odnese klikne "Izneseno".
  • Brisanje osoblja. Na stranici Osoblje svako ima dugme "Obriši". Osoba nestaje sa liste i sa tableta i ne može se prijaviti; ime ostaje na narudžbama i u izvještajima koje je radila.

Za programere

  • Provjera scripts/smoke-staff.mjs proširena na tok narudžbe i brisanje (36 tačaka).

0.76.234

17. oktobar 2026.

Popravljeno

  • Konzola na app.xpay.rs mogla je biti na bosanskom. Jezik se čitao iz izbora sačuvanog u pregledniku i iz jezika firme, pa je izbor BS ili srpska firma upisana kao bosanska prebacivala konzolu na bosanski, a dugme je nudilo BS. Sada svaka adresa nudi samo svoj jezik i engleski: app.xpay.rs SR i EN, app.xpay.ba BS i EN. Izbor koji adresa ne nudi se zanemaruje.
  • Jezik firme prema zemlji. Srpska firma upisana kao bosanska prebačena je na srpski, pa i gosti njenih lokala vide srpski. Firma u Srbiji može izabrati srpski ili engleski, a u Bosni bosanski ili engleski. Srpska firma ranije nije mogla izabrati srpski.
  • Srpska konzola ne govori bosanske činjenice. Primjer adrese na prijavi i zaboravljenoj lozinki je [email protected], na računu gostu [email protected], iznosi u uputstvu za uvoz menija i u prvom koraku su u dinarima, preuzimanje pluginova ide sa xpay.rs, a link na stranicu integracija (koje na xpay.rs nema) se ne nudi. Panel podataka o ličnosti ne navodi zakon dok ne zna zemlju firme (srpskoj firmi je u međuvremenu pisao bosanski zakon).
  • Bosanski tekst na stranici Osoblje kaže "Dodaje narudžbu", ne "porudžbinu".

Za programere

  • scripts/serbian-console-facts.json: po ključu, ono što srpska konzola kaže drugačije osim riječi (adrese, novac). translate-sr.mjs ga primjenjuje i pada kad činjenica više ne odgovara tekstu.
  • Pregledani su svi ekrani konzole kao srpska firma na srpskoj adresi i kao bosanska na bosanskoj.

0.76.233

17. oktobar 2026.

Novo

  • Osoblje po restoranu. Vlasnik sa više restorana u konzoli, Osoblje, bira gdje osoba radi: jedan restoran ili svi. Bira se pri dodavanju i mijenja se kasnije, kao i uloga. Lista se može suziti na jedan restoran, a izvještaj o radu ide za taj restoran. Tablet u restoranu nudi za prijavu samo ljude koji tu rade.
  • Ko šta smije na tabletu. Prijavljena osoba na konobarskom tabletu ili kasi vidi samo ono što njena uloga smije, a API odbija ostalo:
  • Konobar: dodaje porudžbinu, premješta sto, naplaćuje i štampa račun, otkazuje stavku, označava izneseno.
  • Šanker: dodaje porudžbinu i označava izneseno, ne naplaćuje.
  • Kuhar: ništa na konobarskom tabletu; radi na ekranu kuhinje. Vlasnik to mijenja po restoranu u tabeli "Ko šta smije na tabletu" na stranici Osoblje (na primjer, da šanker u kafiću i naplaćuje). Tablet na kojem niko nije prijavljen radi kao i do sada.

Za programere

  • Nova provjera scripts/smoke-staff.mjs (23 tačke), u CI-ju.

0.76.232

17. oktobar 2026.

Promijenjeno

  • Padajući meni na xpay.ba i xpay.rs više nema uvodni red ("Dva proizvoda i alati oko njih", "Isti QR kod, prilagođen djelatnosti", "Sve što restoran ili kafić treba...") ni uputu "Pređite mišem preko stavke". Panel se otvara odmah na stavkama, i na telefonu.

Za programere

  • Provjera teksta na sajtu više ne zabranjuje "mjesečno po objektu": od 0.76.227 to je tačna cijena (naknada po objektu uz paket).

0.76.231

17. oktobar 2026.

Za programere

  • Sigurnosni test čeka limit prijava. Dvije nove provjere (paketi i dostava) prijavljuju se prije njega, pa je u 0.76.230 dobio "previše pokušaja" i pao, iako su sve provjere prije njega prošle. Sada sačeka i pokuša ponovo, kao i ostale provjere.

0.76.230

17. oktobar 2026.

Za programere

  • Naziv za isplatu platforme u aplikaciji za banke. Novi način naplate (isplata platforme za dostavu) nije imao naziv u katalogu aplikacije za banke, pa je 0.76.229 pao na provjeri kataloga. Lokalno je sada pokrenuta ista provjera kao u CI-ju, za konzolu i za banke.

0.76.229

17. oktobar 2026.

Novo

  • Postavke, Dostava. Za svaki objekat konzola nudi platforme koje rade u njegovoj zemlji: Wolt i Glovo u Srbiji, Korpu u Bosni. Vlasnik upiše ID objekta na platformi i token koji je platforma dala, izabere testne ili prave servere platforme i po želji automatsko prihvatanje. Dobija adresu na koju platforma šalje narudžbe i tajnu kojom ih potpisuje; tajna se prikazuje samo jednom i može se zamijeniti novom.
  • Narudžba ide u kuhinju sama. Svaka narudžba otvara svoj račun na uređaju platforme, pa je na ekranu kuhinje i šanka pod imenom "Wolt", "Glovo" ili "Korpa", sa brojem narudžbe, kodom za preuzimanje i vremenom. Cijena je ona koju je naplatila platforma, ništa se ne odbija (platforma bi narudžbu sama poništila), a zalihe se skidaju kao za sto. Artikal koji se ne može povezati sa menijem piše se na tiketu i u konzoli.
  • Platforma dobija odgovor. Prihvaćeno, odbijeno, spremno i predato idu nazad platformi. Glovo nema odbijanje, pa se otkazuje telefonom. Kad je narudžba predata, račun se zatvara kao gotovina (kurir platio) ili kao isplata platforme.
  • Novi način naplate: isplata platforme. U bosanskom fiskalnom zapisu je bezgotovinsko, a na srpskom računu "drugo bezgotovinsko plaćanje" dok računovođa ne kaže drugačije.
  • Probna narudžba iz vlastitog menija, za platformu postavljenu na testne servere. Platformi se ništa ne šalje.
  • Korpa nema javni API, pa joj XPay daje svoj format narudžbe, potpisan istom tajnom (docs/en/13-delivery-platforms.md). Narudžbe stižu čim Korpa pristane da ih šalje.

Šta još čeka

  • Prijave kod Wolta i Glova i razgovor sa Korpom (vlasnik).
  • Woltovo povezivanje preko OAuth-a i obnova tokena; do tada se token upisuje ručno.
  • Slanje menija i dostupnosti platformama, pauza dostave, uparivanje isplata.

Za programere

  • Nova provjera scripts/smoke-delivery.mjs (38 tačaka), u CI-ju: Korpa, Glovo i Wolt šalju narudžbe onako kako ih šalju platforme, kroz kuhinju do zatvorenog računa. Ne zove nijednu pravu platformu.

0.76.228

17. oktobar 2026.

Za programere

  • Nova provjera paketa (scripts/smoke-packages.mjs), u CI-ju. Za Bosnu i za Srbiju napravi novu firmu na paketu Start, pa je podigne na Business, zatim na Premium i vrati na Start. Na svakom koraku isproba svaku funkciju: rezervacije, izvoz analitike i zaliha, API ključeve, webhookove, recepture, nabavku, Uvide, broj jezika menija (2, 4, 8), broj objekata (1, 3, 10), podjelu računa i rezervaciju na gostovoj stranici i vlastiti brend koji gost vidi samo na Premiumu. Ono čega u paketu nema mora biti odbijeno, uz naziv paketa od kojeg je dostupno, a ono što paket ima mora raditi. Provjeru čini 99 tačaka i sve prolaze. Zamjenjuje staru provjeru samo za Srbiju.

0.76.227

17. oktobar 2026.

Novo

  • Paketi za xpay.ba. Start 49 KM, Business 99 KM i Premium 199 KM mjesečno, uz 49 KM po objektu sa naručivanjem za stolom, a Enterprise po dogovoru. Nema naplate po transakciji ni procenta od prometa. Flex se više ne prodaje, a uključene transakcije i cijena preko njih više se ne prikazuju ni na stranici cijena, ni u konzoli, ni u ugovoru.
  • Paket je stvarno ograničen i u Bosni, isto kao u Srbiji:
  • Start: jedan objekat, naplata QR kodom, fakture, meni, naručivanje, napojnice, zalihe, ekrani za kuhinju i šank, osnovni izvještaji, meni na bosanskom i engleskom.
  • Business: do tri objekta, plus podjela računa, rezervacije, recepture i nabavka, izvoz izvještaja, API i webhookovi, dva jezika menija više.
  • Premium: do deset objekata, plus Uvidi (AI), integracija sa kasom, vlastiti brend i šest jezika menija više. API odbija ono čega u paketu nema i kaže od kojeg paketa je dostupno.
  • xpay.ba nudi sve što i xpay.rs. Početna stranica ima dva nova dijela: Za osoblje (ekrani za kuhinju i šank, statusi narudžbe, stolovi, gotovina, meni po poslovnici, jezici, zalihe, recepture, popis, analitika) i Uvidi. Meni na vrhu ima novu stavku Ugostiteljstvo: digitalni meni, naručivanje, plaćanje, fiskalni račun, ekrani, analitika, zalihe i recepture, Uvidi.
  • Pro se zove Premium u obje zemlje, na sajtu i u konzoli.
  • Ugovor 2.2. Odredbe o cijeni prepisane su za pakete: osnov naplate je paket i broj objekata, primjer Business sa tri objekta iznosi 246 KM mjesečno, a odredbe o mekom limitu i Flexu su izbačene. Rok plaćanja od 8 dana ostaje.

Popravljeno

  • Paketi na početnoj stranici nisu bili centrirani. Četiri paketa stajala su u mreži od pet kolona, pa je desno ostajalo prazno mjesto. Sada su u četiri kolone, na xpay.rs i na xpay.ba.

Važno za postojeće firme

  • Bosanska firma na paketu Start više nema podjelu računa, rezervacije, recepture i nabavku, izvoz, API ključeve ni više od dva jezika menija; to je od paketa Business. Firmu koja to koristi treba prebaciti na Business.

0.76.226

16. oktobar 2026.

Za programere

  • Test cjenovnika u zajedničkom paketu. Još je tražio dinarske cijene po transakciji i čitao ih iz starog izvora, pa je 0.76.225 pao u CI-ju. Sada provjerava da Srbija nema naplatu po transakciji i da su cijene paketa iste kao na xpay.rs (serbia-prices.ts). Lokalno su prije slanja pokrenuti testovi i typecheck svih paketa, kao u CI-ju.

0.76.225

16. oktobar 2026.

Novo

  • Paketi za xpay.rs. Start 2.900 RSD, Business 5.900 RSD i Premium 11.900 RSD mjesečno, uz 2.900 RSD po objektu, a Enterprise po dogovoru. Nema naplate po transakciji ni procenta od prometa, pa u Srbiji nema ni Flexa ni uključenih transakcija. Stranica s cijenama, početna stranica, opis za pretraživače i ugovor na xpay.rs napisani su ispočetka na srpskom.
  • Paket je stvarno ograničen. Srpska firma koristi samo ono što njen paket ima, a ostalo API odbija i kaže od kojeg paketa je dostupno:
  • Start: meni, poručivanje, IPS QR plaćanje, napojnice, zalihe (stanje, minimum, skidanje pri porudžbini), ekran za kuhinju, osnovni izvještaji, meni na srpskom i engleskom, 1 objekat.
  • Business, plus: do 3 objekta i zbirni izvještaji, podjela računa, rezervacije, recepture, food cost i nabavka, izvoz izvještaja, API i webhookovi, još 2 jezika menija.
  • Premium, plus: do 10 objekata, Uvidi (AI analitika, prognoza, neobični obrasci), integracija s kasom, vlastiti brend, još 6 jezika menija.
  • Konzola i gost znaju za paket. Licenca u konzoli pokazuje šta svaki paket ima umjesto broja transakcija, a u bočnoj traci PRO piše kao Premium. Odbijanje kaže "Ovo je u paketu Business i većim". Gostova stranica ne nudi podjelu računa ni rezervaciju ako ih paket nema, a stranica za rezervaciju tada kaže da se sto dogovara telefonom.

Bez promjene u Bosni

  • Bosanski paketi ostaju kakvi jesu: licenca s uključenim transakcijama, Flex i ugostiteljski dodatak. Bosanska firma ne gubi ništa od onoga što je imala.

Za programere

  • Jedna tabela paketa po zemlji, featuresFor u packages/shared/src/plan-features.ts, koju čitaju čuvar paketa, provjere na javnim rutama, konzola i test sajta.
  • Novi smoke test scripts/smoke-plans-rs.mjs je u CI-ju.

0.76.224

16. oktobar 2026.

Dokumentacija

  • Wolt i Glovo u XPay, plan. docs/en/13-delivery-platforms.md opisuje kako bi narudžba s Wolta ili Glova sama stigla u XPay: na ekran za kuhinju, sa skidanjem sa zaliha, fiskalnim računom i uparivanjem s isplatom platforme, bez prepisivanja. Uz izvore: kako se dobija pristup, kako narudžba stiže, šta se šalje nazad i u kojem roku (Wolt odbija narudžbu koja nije prihvaćena za 3 minute), meni i dostupnost, cijena.
  • Samo Srbija, zasad. Wolt nikad nije došao u Bosnu i Hercegovinu, a Glovo je u BiH prestao raditi 10. avgusta 2026. U Bosni je glavna platforma Korpa, za koju javni API nismo našli; plan je napisan tako da se ona doda kad ga bude.
  • Šta treba vlasnik, a šta kod. Plan u sedam faza: prijave kod Wolta i Glova, probni lokal u Srbiji i pitanje za knjigovođu o načinu plaćanja na fiskalnom računu su na vlasniku; jezgro kanala, simulator i sinhronizacija menija mogu se graditi bez čekanja partnera.

0.76.223

16. oktobar 2026.

Novo

  • Kartice kao na ekranu u brzoj hrani. Narudžbe su uske kartice poredane od najstarije, gore lijevo, pa ih na zidu stane mnogo. Zaglavlje kartice nosi sto, broj narudžbe i sat koji teče u minutama i sekundama, a boja kaže koliko čeka: zelena dok je svježa, žuta od 8 minuta, crvena od 15 minuta ili kad prođe obećano vrijeme, ljubičasta kad je spremno i čeka konobara. Nova narudžba prvih 15 sekundi treperi.
  • Precrtavanje stavki. Dodir na stavku je precrta, kao olovkom na papiru, a kartica pokazuje koliko je stavki gotovo (npr. 1/4). Pamti se na tom ekranu.
  • Zbirno. Dugme "Zbirno" otvara spisak sa strane: koliko čega ukupno još treba spremiti iz narudžbi koje nisu spremne (npr. 5× Ćevapi), samo za ono što taj ekran pravi.
  • Cijeli ekran. Dugme za prikaz preko cijelog ekrana, za televizor ili tablet na zidu.

Popravljeno

  • Vrijeme u 24 sata. "Do 22:52", a ne "do 10:52 PM", koji god jezik ima tablet.

0.76.222

16. oktobar 2026.

Za programere

  • Smoke za Uvide uzima jelo koje gost vidi. Za provjeru prevoda uzimao je prvo aktivno jelo iz cijelog konzolnog menija, a konzola prikazuje kategorije svih poslovnica, i isključene. Kad se prije njega izvrši smoke za meni po poslovnicama, to je bilo jelo iz kategorije koju je taj smoke isključio, pa ga gost nije vidio i četiri provjere su pale. Sada uzima jelo s gostovog menija za taj sto.

0.76.221

16. oktobar 2026.

Za programere

  • Smoke za Uvide čeka ograničenje prijava. U CI-ju se izvršava poslije novog smokea za meni po poslovnicama, čije dvije prijave napune ograničenje prijava, pa je smoke za Uvide odustao na prvoj prijavi sa 429, a 0.76.220 nije prošao CI. Sada, kao i ostali smoke testovi, sačeka koliko server kaže (najviše minut) i pokuša ponovo, samo kod prijave.

0.76.220

16. oktobar 2026.

Novo

  • Izabrane poslovnice. Nova kategorija se pravi u prozoru s kućicom za svaku poslovnicu: sve, jedna ili nekoliko njih. Kategorija na nekoliko poslovnica je jedna, pa izmjena cijene ili artikla važi za sve te poslovnice. Dugme "Poslovnice" kod kategorije mijenja na kojim je poslovnicama, a pod kategorijom piše na kojim je.
  • Odvoji za poslovnicu. Kad je na ekranu Meni izabrana jedna poslovnica, zajednička kategorija ima dugme "Odvoji za" tu poslovnicu. Poslovnica dobija svoju kopiju s artiklima, cijenama i recepturama i dalje je mijenja sama, a ostale poslovnice zadržavaju zajedničku.
  • Meni nove poslovnice. Pri otvaranju poslovnice bira se zajednički meni, prazan meni ili kopija menija druge poslovnice.
  • Zajednički meni mijenja vlasnik. Kategoriju i artikle koje dijeli više poslovnica mijenja samo vlasnik; menadžer i dalje mijenja meni svoje poslovnice. Firma s jednom poslovnicom ne primjećuje promjenu.

Za programere

  • Postojeći meniji nisu premještani: kategorija bez poslovnice i dalje je na svim poslovnicama, pa svaka poslovnica ima isti meni kao prije. Novo polje venueIds (migracija 20261215000000) čuva izabrane poslovnice.
  • Novi smoke test scripts/smoke-menu-venues.mjs je u CI-ju.

0.76.219

16. oktobar 2026.

Novo

  • Meni po poslovnici. Na ekranu Meni je birač "Meni za": sve poslovnice ili jedna poslovnica, tačno kako je vide njeni gosti i konobari. Kod svake kategorije piše čija je. Nova kategorija ide u poslovnicu koja je izabrana, ili u sve kad nije izabrana nijedna.
  • Posebno po poslovnicama. Zajednička kategorija se jednim dugmetom dijeli na posebnu kopiju za svaku poslovnicu, s artiklima, opcijama, cijenama i recepturama. Svaka poslovnica zatim mijenja svoje cijene i artikle odvojeno.
  • Isto za sve poslovnice. Kategorija jedne poslovnice jednim dugmetom postaje meni svih poslovnica. Istoimene kategorije drugih poslovnica se sakrivaju, ne brišu, pa nijedna poslovnica ne prikazuje istu kategoriju dvaput. Oba dugmeta su za vlasnika.

Popravljeno

  • Ime lokala na meniju. Gostova stranica je u naslovu pisala ime firme, pa je gost u lokalu "Miloš 2" vidio "Milos". Kad firma ima više lokala, gost sada vidi ime lokala u kojem sjedi; kad ima jedan, ime firme kao i do sada. Isto važi za naslov stranice u pregledniku i za ekran plaćanja.

0.76.218

16. oktobar 2026.

Novo

  • Stanje pada čim se naruči. Do sada se zaliha skidala tek kad je narudžba označena kao poslužena ili kad se račun zatvorio, pa vlasnik na Zalihama nije vidio da je sto naručio. Sada se skida u trenutku narudžbe, i to samo jednom, a otkazana narudžba vraća ono što je skinula. Prodaja na kasi i dalje skida kad je plaćena, jer kupac može odustati od QR koda.
  • Meni i skladište povezani. Na Zalihama je novi dio "Meni i skladište". "Poveži s menijem" povezuje svaki artikal iz menija s artiklom istog imena na skladištu, jedan komad po porciji, bez obzira na velika slova i kvačice (Đus, Djus i Dus su isto). "Poveži i dodaj što fali" dodaje na skladište artikal za svako jelo koje ga nema. Jela od više sastojaka i artikli koji se vode na kilogram ili litar ostaju za recepturu, i ekran kaže zašto.
  • Prati na skladištu, iz obrasca jela. Novi artikal u meniju može se odmah pratiti na skladištu: kućica "Prati na skladištu", količina na stanju i minimum za obavještenje. Ako artikal istog imena postoji, povezuje se s njim.

Popravljeno

  • Kasa bez duplih artikala. Artikal sa skladišta koji je povezan s jelom više se ne prikazuje drugi put u kartici skladišta na kasi, pod drugim imenom. Prodaje se kao jelo iz menija, pod imenom iz menija.
  • Isti redoslijed u konzoli i u aplikacijama. Konzola je ređala artikle bajt po bajt (velika slova prije malih, Č, Š i Ž poslije z), a telefon konobara i gost po bosanskom abecednom redu. Sada svi ređaju isto.
  • Sakriveni artikli. Artikal koji je sakriven (na primjer po preporuci Uvida) konzola je prikazivala kao običan, a aplikacije ga nisu prikazivale. Sada ima oznaku "Sakriveno" i dugme "Prikaži".
  • Zalihe u dinarima. Cijene, nabavne cijene, popis i nabavka na Zalihama ispisivali su iznose u KM i za lokale u Srbiji. Sada su u valuti poslovnice.

0.76.217

16. oktobar 2026.

Novo

  • Zbirni pregled ili jedna poslovnica. Kao na Analitici, Pregled vlasniku koji ima više poslovnica nudi izbor "Sve poslovnice" ili jednu poslovnicu. Sve poslovnice zajedno su početni izbor, a izabrana poslovnica važi za naplatu, grafikon i poređenje, uplate, otvorene stolove, stanje potvrda i jutarnji pregled. Izbor se pamti u tom pregledniku. Menadžer i konobar izbor ne vide i gledaju ono što im je dozvoljeno, kao i do sada.

Popravljeno

  • Stanje potvrda po poslovnici. Kartica o tome koliko je uplata banka potvrdila sama brojala je uvijek cijelu firmu, pa je menadžer jedne poslovnice vidio i račune druge. Sada broji samo poslovnice koje korisnik smije vidjeti, ili onu koja je izabrana.

0.76.216

16. oktobar 2026.

Popravljeno

  • "Šta je povezano, a šta još nije". Lista koja je skinuta s Pregleda u 0.76.215 sada stoji samo u Pomoći i više se ne zove "Prvi dan": svaki red kaže da li je podešen (podaci firme, bankovni račun, QR profil, stolovi, meni, osoblje, ekran za osoblje, načini plaćanja, naručivanje, fiskalizacija) i vodi na ekran gdje se podešava.

0.76.215

16. oktobar 2026.

Popravljeno

  • Bez liste "Prvi dan" na Pregledu. Od 0.76.194 prvi ekran konzole počinjao je listom koraka za prvi dan, koja je brojke dana gurala ekran niže. Lista je skinuta s Pregleda. Podaci firme i ostalo upisuju se kao i prije u Podešavanjima, Poslovnicama, Meniju i Stolovima, a ista lista se po potrebi može pogledati u Pomoći.

0.76.214

16. oktobar 2026.

Novo

  • Pošiljalac za Srbiju. Svako mjesto koje šalje poštu sada kaže za koju je zemlju pismo: odobrenje probnog naloga, obavještenje o zalihama, jutarnja narudžbenica, narudžbenica dobavljaču, rezervacije, račun gostu, sedmični izvještaj Uvida, pozivnice i nova lozinka. Kada se na serveru upiše MAIL_FROM_RS s podacima .rs sandučeta, srpska pisma idu s te adrese preko servera za xpay.rs. Dok nije upisan, idu sa [email protected] kao do sada, a pismo koje .rs server odbije odmah ode sa glavne adrese, pa se ništa ne gubi. Operater pod E-mail vidi pošiljaoca za Srbiju i ima posebno dugme za probnu poruku samo preko .rs servera.

Ispravljeno

  • Račun gostu u dinarima. Račun koji srpski lokal pošalje gostu e-mailom bio je iscrtan u KM, jer je valuta bila upisana fiksno. Sada je valuta lokala, a podnožje kaže "Poslato na zahtev kupca".
  • Nova lozinka i pozivnica za Srbiju. Vlasnik ili konobar iz Srbije dobijao je link na app.xpay.ba, bosansku konzolu, da postavi lozinku. Link sada vodi na app.xpay.rs, a tekst je na srpskom ("Link važi sat vremena").
  • Rezervacija za Srbiju. Link za status rezervacije koji gost dobije vodio je na app.xpay.ba; sada vodi na app.xpay.rs. Lokal dobija "Zahtev za rezervaciju".

0.76.213

16. oktobar 2026.

Ispravljeno

  • Brojevi ispod odgovora na Analitici pišu iznos kao ostatak konzole, "1.234,50 KM" (na engleskom "1,234.50 KM"), a ne "1234.50 BAM", i porcije sa pravim oblikom broja: 1 porcija, 42 porcije, 12 porcija. Isti zapis dobija i model za rečenice jutarnjeg pregleda, pa se brojevi u tekstu i na kartici poklapaju.
  • Jutarnji pregled, zalihe: umjesto "ispod nule 0, na minimumu 0, pred kraj u 3 dana 2" kartica navodi samo ono čega ima, npr. "2 pred kraj u 3 dana".
  • Jutarnji pregled bez ranijeg istog dana kaže "Za ovaj dan u sedmici još nema ranijih računa za poređenje" (na srpskom "u nedelji").
  • Period ispod odgovora više ne završava sa dvije tačke iza datuma.

Razvoj

  • Testovi za zapis iznosa (marka, dinar, engleski, minus, pare) i oblike broja porcija.

0.76.212

16. oktobar 2026.

Ispravljeno

  • scripts/smoke-stock.mjs na CI-ju. Obavještenje "odbijen jer nema na stanju" upisuje se uz odbijanje, ne prije njega, da odbijanje gostu ne bi čekalo na zvono. Provjera je listu čitala odmah poslije odbijanja: na ovoj mašini obavještenje je redovno stizalo prvo, a na sporijem CI-ju ne, pa je CI za 0.76.208 pao sa "0 -> 1". Provjera sada čeka obavještenje do tri sekunde, kao što već čeka webhook stock.low, i daje drugom odbijanju istu sekundu prije nego što kaže da drugog obavještenja nema.
  • Jedinični test revizijskog traga koji je pao na CI-ju za 0.76.206 popravljen je u 0.76.208 (upisi u revizijski trag napisani kao i ostali); CI za 0.76.208 je prošao jedinične testove i stao samo na provjeri iznad.

0.76.211

16. oktobar 2026.

Ispravljeno

  • Bez neprovjerenog koda na serveru. Zahtjev za ažuriranje može navesti commit, i server tada instalira baš taj commit. Do sada je uzimao ono što je u trenutku izvršavanja bilo zadnje na glavnoj grani, pa je 16. oktobra stigla i verzija čiji test još nije bio prošao (server je radio, ali bez provjere). Dugme Ažuriraj u konzoli radi kao i do sada; commit navodi automatski deploy koji šalje samo commit sa zelenim provjerama. Vrijedi od sljedećeg ažuriranja.

0.76.210

16. oktobar 2026.

Novo

  • "Sedmični izvještaj je spreman" u zvonu konzole kad se napravi izvještaj sa dovoljno podataka (ponedjeljkom ujutro ili na prvo otvaranje Uvida), sa sedmicom i vezom na Uvide. Paket Pro, kao i izvještaj.
  • "N stavki za provjeru u sedmičnom izvještaju" kad sedmica ima neobične brojeve po osobi ili stolu, kao mjesto koje vrijedi pogledati, ne kao optužba.
  • Oba jednom po poslovnici i sedmici, koliko god puta se izvještaj otvorio ili ponovo izračunao; ispod praga podataka ništa. Vide ih menadžer i vlasnik, na jeziku firme: na srpskom "Nedeljni izveštaj je spreman", "za proveru", "objekat".

Razvoj

  • Dvije nove vrste obavještenja u notification-text.ts sa testovima za sva tri jezika i oblike broja (1 stavka, 3 stavke, 12 stavki); smoke-insights: sedmica sa dovoljno podataka zvoni tačno jednom, ispod praga nijednom.

0.76.209

16. oktobar 2026.

Novo

  • Jutarnji pregled na vrhu početne strane, za sve pakete. Četiri dijela, svaki sa vezom na ekran sa ostatkom:
  • Jučer: promet i broj računa, prema prosjeku istog dana u sedmici u zadnje četiri sedmice (samo sedmice u kojima je tog dana bilo računa, pa lokal star tri sedmice ne izgleda tiše nego što jeste), promjena u procentima i najprodavaniji artikal, sa velikom narudžbom jednog stola brojanom najviše kao tri uobičajene.
  • Zalihe: koliko je artikala ispod nule, na minimumu i pred kraj u danima upozorenja poslovnice, i do pet po imenu, najhitniji prvi.
  • Rezervacije danas: broj, osobe, prva u koliko sati i koliko ih čeka potvrdu.
  • Za provjeru: neuparena plaćanja, stolovi otvoreni od ranije i, na paketu Pro, stavke za provjeru iz sedmičnog izvještaja.
  • Izračunato jednom dnevno po poslovnici, na prvo otvaranje poslije ponoći u zoni poslovnice, i sačuvano; kartica kaže u koliko sati je izračunata, jer su zalihe i rezervacije kakve su bile tada. Lanac bira poslovnicu na kartici.
  • Na paketu Pro, sa modelom, iznad brojeva stoji tri do pet rečenica napisanih samo iz tih brojeva, jednom po jeziku. Bez ključa, ili na drugom paketu, kartica su brojevi, uz rečenicu šta Pro dodaje. Model koji ne odgovori ponovo se pita najranije za sat.
  • API: GET /v1/insights/morning?locationId=&locale=.

Razvoj

  • apps/api/src/modules/insights/morning-brief.ts: čist modul sa osam jediničnih testova; tabela insight_brief (samo dodata, bez veze na poslovnicu, jer je keš); upis sa preskakanjem duplikata, pa dva prva otvaranja u istom trenutku prave jedan red.
  • Srpska lista riječi: izvještaju, sedmičnom, sedmičnog i prodano, pa su i postojeći tekstovi na srpskom ispravljeni (nedeljni izveštaj, prodato).
  • smoke-insights: dan poslovnice, poređenje sa istim danom, zalihe po stanju, zbir stavki za provjeru, Pro kupuje rečenice, drugo čitanje na drugom jeziku je isti pregled, Starter dobija brojeve bez rečenica.

0.76.208

15. oktobar 2026.

Novo

  • Jutarnji sažetak nabavke. Svako jutro u 7:00 po satu poslovnice (ljeti i zimi, po vremenskoj zoni poslovnice) firma dobija na svoj e-mail listu onoga što treba naručiti, po poslovnici i dobavljaču, sa predloženom količinom i koliko artikal još traje, i vezu na Zalihe sa uključenim filterom. Šalje se samo kad ima šta naručiti, jednom pismom za sve poslovnice kojima je tada sedam sati, riječima države firme. Uključuje se isključivo u Postavkama, pod Zalihe, i isključen je dok ga vlasnik ne uključi (stockDigestMail).
  • Nova kolona merchants.stockDigestMail (migracija 20261212000000_stock_digest); PATCH /v1/merchant je prima, a GET /v1/merchant vraća.
  • Jedinični testovi za sat po zoni (ljetno i zimsko vrijeme, Sarajevo i Beograd) i za pismo (prazno se ne šalje, redoslijed po poslovnici i dobavljaču, srpske riječi za Srbiju); scripts/smoke-stock.mjs: prekidač se sprema i čita nazad.

Ispravljeno

  • Jedinični test revizijskog traga u 0.76.206. Šest upisa u revizijski trag u modulu nabavke bilo je napisano u jednom redu, a test koji provjerava da svaki upis kaže ko je to uradio čita samo upise koji se zatvaraju u svom redu, pa je CI za 0.76.206 pao na tom testu. Upisi su sada napisani kao svi ostali; svih 1.746 jediničnih testova API-ja prolazi.

0.76.207

16. oktobar 2026.

Novo

  • Dugme "Zašto?" u zaglavlju tri glavna grafikona na stranici Analitika: promet po danu, kad je najviše posla i artikli. Otvara kratko objašnjenje promjene prema istom broju dana prije: koliko je naručeno sada i prije, razlika, i ono što je najviše nosi. Uz promet po danu dani u sedmici i artikli, uz sate sati i artikli, uz artikle artikli; po tri koja su najviše narasla i tri koja su najviše pala, svaki sa iznosom sada i prije.
  • Za sve pakete koji imaju analitiku, jer to računa kod, bez modela i bez limita. Uvijek za tačno one dane koje grafikon crta, i za izabranu poslovnicu ili sve.
  • Isti pragovi kao Uvidi. Ispod 20 računa sa bilo koje strane objašnjenja nema, i to piše, sa brojem računa sada i prije. Poredi se vrijednost naručenog, stavka po stavka, a velika narudžba jednog stola broji se najviše kao tri uobičajene; zato se zbir može malo razlikovati od naplaćenog na grafikonu, i objašnjenje to kaže.
  • API: GET /v1/insights/why?from=&to=&locationId= (najviše 92 dana).

Razvoj

  • Isti modul period-figures.ts kao pitanje na Analitici; smoke-insights: 30 dana prema 30 prije, prag naveden i poštovan, najviše tri rasta i tri pada sa pravim znakom, razlika je sada manje prije, Starter ga ima, a obrnut period, više od 92 dana i datum koji nije dan su odbijeni.

0.76.206

15. oktobar 2026.

Novo

  • Dobavljači. Naziv, e-mail, telefon, JIB ili PIB i rok isporuke u danima; artiklu se dodjeljuje dobavljač i pakovanje u kojem dolazi. GET/POST/PATCH /v1/purchasing/suppliers, PUT /v1/purchasing/items/:id.
  • Prijedlog nabavke. Za svaki artikal na ili ispod minimuma ili u upozorenju poslovnice: potrošnja za rok isporuke dobavljača i još sedam dana, plus minimum, minus stanje (negativno stanje se računa kao nula), zaokruženo naviše na pakovanje; artikal kojem treba naručiti a nema iz čega računati dobija jedno pakovanje ili jednu jedinicu. Grupisano po dobavljaču, artikli bez dobavljača na kraju. GET /v1/purchasing/suggestions.
  • Narudžbenica. "Napravi narudžbenicu" pravi dokument u seriji poslovnice (NAR-2026-0001, broj se uzima jednim upisom u bazu, pa dvije narudžbe ne dobiju isti broj), PDF u stilu ostalih dokumenata, sa zadnjom poznatom cijenom kad je ima; "Pošalji dobavljaču" ga šalje e-mailom sa PDF-om, riječima države poslovnice, a odgovor ide na adresu firme. Statusi: napravljena, poslana, primljena, otkazana.
  • Prijem robe. "Primi robu" otvara prijemnicu popunjenu iz narudžbenice: šta je stvarno stiglo, po kojoj cijeni i broj otpremnice ili računa dobavljača. Svaka stavka postaje uobičajeni prijem (RECEIVED) sa dobavljačem, dokumentom i cijenom, pa se stanje, nabavna cijena i istorija ponašaju kao da je prijem upisan ručno; narudžbenica postaje primljena i drugi prijem se odbija (order_closed).
  • Ekran Zalihe. Panel "Za naručiti" (za vlasnika i menadžera): po dobavljaču, sa predloženom količinom koja se može promijeniti, izborom dobavljača za artikle bez njega, listom narudžbenica sa PDF-om, slanjem, prijemom i otkazivanjem, i dijalogom "Dobavljači". Riječi na bosanskom, engleskom i srpskom.
  • Nove tabele suppliers, purchase_orders, purchase_order_lines i kolone supplierId i packMilli na artiklu (migracija 20261211000000_purchasing); nove šifre odbijanja supplier_unknown, supplier_no_email, order_empty i order_closed u packages/shared/src/reasons.ts.
  • Jedinični testovi za prijedlog količine i pakovanje; scripts/smoke-stock.mjs: artikal bez dobavljača čeka pod "Bez dobavljača", sa dobavljačem i pakovanjem od šest predlaže se 18, narudžbenica je u seriji i PDF, slanje šalje ili jasno kaže da server nema poštu, sljedeća narudžbenica dobija sljedeći broj, prijem stavlja 18 na stanje kao prijem od tog dobavljača sa dokumentom i cijenom, a drugi prijem je odbijen.

0.76.205

16. oktobar 2026.

Novo

  • Pitajte o prometu (paket Pro). Na stranici Analitika, ispod grafikona, polje za pitanje: "zašto je subota slabija", "šta se najviše prodaje petkom poslije 20h", "koliko je otpisano ovog mjeseca". Sistem prvo sam pročita pitanje: period (danas, jučer, ova ili prošla sedmica, ovaj ili prošli mjesec; bez perioda zadnje četiri pune sedmice), dane (petkom, subota, vikend) i sate (poslije 20h, između 18 i 22). Za tačno te dane i sate izračuna brojeve iz narudžbi, zatvorenih računa i kretanja zaliha, uz isto toliko dana prije za poređenje, i tek ih onda da modelu da ih opiše.
  • Uz odgovor brojevi na kojima počiva. Model navede koje brojeve koristi, a ekran ih ispisuje iz sistemove liste sa nazivom i vrijednošću, pa broj ispod odgovora nikad nije broj koji je model napisao. Ispod je period i period sa kojim se poredi, i veza na izvještaj sa ostatkom: promet po danima, kad je najviše posla, artikli ili zalihe.
  • Isti principi kao Uvidi. Model dobija samo zbirne brojeve i nazive artikala, nikad račun, gosta ili osobu. Ispod 20 računa u periodu dani, sati i ono što nosi razliku se ne računaju, jer to ne bi bio obrazac, i odgovor to kaže. Velika narudžba jednog stola broji se najviše kao tri uobičajene. Promet je iz zatvorenih računa, a artikli i sati iz vrijednosti naručenog, i odgovor ih ne miješa.
  • Limit od 20 pitanja po poslovnici dnevno, odvojeno od pitanja o sedmici na stranici Uvidi; odbijeno pitanje se ne broji. Na drugim paketima umjesto polja stoji rečenica šta Pro daje.
  • API: GET /v1/insights/period-ask (da li model postoji, poslovnica, preostala pitanja) i POST /v1/insights/period-ask (answer, figures sa ključem, nazivom i vrijednošću, report, period, covered). Razlozi odbijanja su postojeći: ai_unavailable, insufficient_data, questions_daily.

Razvoj

  • apps/api/src/modules/insights/period-figures.ts: čist modul koji računa period i period prije njega (promet, dani u sedmici po kalendarskom danu, sati, artikli, dan i doba dana, šta nosi razliku, fokus pitanja, zalihe po nabavnoj cijeni), čita period, dane i sate iz pitanja na bosanskom, srpskom i engleskom, i daje brojeve sa ključem i nazivom na sva tri jezika.
  • Jedinični testovi (34 nova i jedan u testovima modela); scripts/smoke-insights.mjs: Starter dobija paket umjesto polja, Pro dobija stanje polja, pitanje bez modela je odbijeno i ne broji se, sa modelom je pročitan petak poslije 20h i pitanje se broji jednom.

0.76.204

15. oktobar 2026.

Novo

  • Koliko artikal još traje. Za svaki artikal prosječna dnevna potrošnja iz prodaje i otpisa u zadnjih 28 dana (isti prozor kao Uvidi; mlađi artikal se dijeli svojom starošću, pa kafa otvorena prošle sedmice ne izgleda kao četvrtina stvarne potrošnje) i broj dana koliko traje uz tu potrošnju. Prijem, popis i povrat nisu potrošnja. Lista zaliha nosi dailyUse, daysLeft, reorder i warningDays.
  • Obavještenje prije minimuma. Kretanje koje spusti artikal na upozorenje poslovnice (podrazumijevano 3 dana, postavka stock.endingDays od 1 do 60) zvoni jednom: "Mlijeko je pred kraj za oko 3 dana", sa vezom na Zalihe sa uključenim filterom. Ne kad je pao i na minimum, jer to ima svoje obavještenje; isti artikal najviše jednom dnevno.
  • Ekran Zalihe. Nova kolona "Traje" (ljubičasto kad je u upozorenju, uz dnevnu potrošnju u opisu) i dugme "Treba naručiti (N)" koje ostavi samo artikle na ili ispod minimuma ili u upozorenju.
  • Jedinični testovi za dane potrošnje, dnevni tempo, preostale dane, prelaz upozorenja i postavku; scripts/smoke-stock.mjs: artikal otvoren sa 10 i 2,5 prodano isti dan troši 2,5 dnevno, traje 3 dana, označen je za naručiti i zvono kaže da je pred kraj za oko 3 dana.

0.76.203

15. oktobar 2026.

Novo

  • Zvono u zaglavlju konzole. Broj nepročitanih obavještenja i lista najnovijih, svako na jeziku firme (bosanski, za firmu iz Srbije srpski, za konzolu na engleskom engleski), sa vezom na ekran gdje se stvar rješava; klik ga označi pročitanim i vodi tamo, "Označi sve pročitanim" briše tačke. Novo obavještenje stiže odmah preko postojećeg realtime kanala konzole, bez osvježavanja stranice. Osoba vidi samo obavještenja za ekrane koje njena uloga smije otvoriti: obavještenje o polici vidi onaj ko smije gledati zalihe po postavci poslovnice.
  • Prve tri vrste. Artikal pao na minimum (uz postojeći e-mail i webhook stock.low); narudžba odbijena jer nema na stanju (stock_short), jednom dnevno po jelu, pa dvadeset odbijanja istog jela u petak naveče ostaje jedno obavještenje; popis zatvoren sa manjkom iznad praga (50 KM, odnosno 3.000 dinara, ili iznos koji poslovnica sama upiše).
  • Za druge module. NotificationsService.notify({...}) sa vrstom, činjenicama, vezom, ulogom i ključem protiv ponavljanja; upis ne pada na duplikatu i nikad ne obara prodaju, narudžbu ni popis. API: GET /v1/notifications, POST /v1/notifications/read.
  • Nova tabela notifications (migracija 20261210000000_notifications).
  • scripts/smoke-stock.mjs: polica ispod minimuma daje jedno nepročitano obavještenje koje vodi na Zalihe i postaje pročitano kad se otvori; odbijeno jelo daje obavještenje sa traženim i pokrivenim brojem, a drugo odbijanje istog dana ne dodaje novo. Jedinični testovi za tekstove na tri jezika, za to ko šta vidi i za prag manjka.

0.76.202

16. oktobar 2026.

Ispravljeno

  • Ključ za Uvide nije stizao do API-ja. Produkcijski server navodi postavke koje API dobija jednu po jednu, a ključ za Uvide (ANTHROPIC_API_KEY) na tom spisku nije bio, pa bi upisan ključ ostao bez dejstva. Isto je bilo sa dinarskim računom za predračune (LEGAL_COMPANY_IBAN_RS), adresom srpske konzole u pismima (DASHBOARD_BASE_URL_RS), starim ključevima šifrovanja poslije zamjene (ENCRYPTION_KEYS_OLD), SMS postavkama, ograničenjima zahtjeva i domenom za statusnu stranicu. Sada su sve na spisku.
  • Provjera koja to drži. scripts/check-deploy.mjs (dio CI-ja) pada čim API čita postavku koju server ne prosljeđuje, pa se ovo ne može ponoviti tiho.

0.76.201

16. oktobar 2026.

Ispravljeno

  • Bez predračuna koji niko ne može platiti. Firma koja izdaje račune za XPay je u osnivanju i još nema bankovni račun, pa je predračun iz konzole odlazio bez računa za uplatu, bez PDF-a i bez QR koda, a ipak je trošio broj iz serije. Sada, dok račun u novcu firme nije podešen na serveru (marke ili dinari), stranica Licenca umjesto "Naruči predračun" ima dugme "Javite nam se" koje otvara mail sa izabranim paketom i periodom, uz rečenicu da se paket do tada ugovara direktno. Firma iz Bosne piše na [email protected], firma iz Srbije na [email protected]. Kad se račun upiše, naručivanje se otvara samo.
  • API: GET /v1/billing/plans vraća selfServe (open i contactEmail); POST /v1/billing/orders bez računa platforme odgovara 409 payee_unconfigured sa adresom za javljanje.
  • Provjere za naplatu u CI-ju dobile su probni račun i naziv firme, a prijava u tim provjerama sačeka kad je ograničenje prijava puno.

0.76.200

16. oktobar 2026.

Razvoj

  • Zalihe (1712 na 920 linija): popis i list popisa u stocktakes.tsx, potrošnja u consumption.tsx, kartica artikla, sastav i cijena na kasi u item-dialogs.tsx, zajednički oblici u stock-types.ts.
  • Meni (1639 na 982): obrazac jela sa recepturom i njenom cijenom u item-form.tsx, oblici jela u menu-types.ts.
  • Fakture (1506 na 1427): dodavanje primaoca i jedna oznaka sa brojkom u invoice-parts.tsx.
  • Stranica gosta (4569 na 3903): oblici koje čita iz API-ja i pravilo za rezervisan sto u guest-model.ts, učitavanje polja za karticu u monri.ts, dijelovi ekrana za plaćanje u pay-pieces.tsx. Ostatak je jedna komponenta od oko 3700 linija koja dijeli desetine stanja; dijeli se kad se stranica može gledati uživo, ne naslijepo.
  • Svaki dio je premješten kakav jeste: provjera red po red pokazuje da je svaki od 8812 redova koda iz četiri stare datoteke na novom mjestu nepromijenjen, a dodani su samo uvozi, oznake izvoza i jedan red opisa po datoteci. Provjera tipova, svi testovi konzole (152) i produkcijski build prolaze, veličine stranica su iste.

0.76.199

16. oktobar 2026.

Razvoj

  • Razlozi odbijanja su popisani na jednom mjestu. packages/shared/src/reasons.ts drži svih 327 razloga koje API daje (REASONS, tip Reason), od toga 32 problema po redu u pregledu uvezenog fajla (ROW_PROBLEMS). Novi test u API-ju pada kad kod baci razlog kojeg nema na popisu, ili kad je na popisu razlog koji se više ne baca; @Refusals u OpenAPI-ju i mape razloga u konzoli primaju samo imena sa popisa, pa je greška u kucanju greška tipa. Dva para su bila dva imena za istu stvar i sada imaju jedno: not_a_proforma je not_proforma kao na fakturama, a tax_id_format iz srpskog zahtjeva (još nije bio u produkciji) je bad_tax_id kao kod kupaca.
  • Spojeni pomoćnici. Kalendarski dan u zoni lokala bio je napisan pet puta (analitika, meni, narudžbe, mjesečni obračun, posjete sajtu) i sada je jedan dayIn; ljestvica uloga bila je napisana tri puta (provjera uloga, uloge na zalihama, ekran Zalihe) i sada je ROLE_RANK i roleAtLeast u packages/shared/src/roles.ts, sa testom; jezik lokala po državi u Uvidima ide preko istog sourceLanguageFor; deset pisama spaja redove istim NEWLINE iz apps/api/src/common/letter.ts umjesto svojih kopija.
  • Mrtav kod. Uklonjeno je deset izvoza koje niko ne koristi (između ostalog corsOrigins, listPaymentProviders, useWatchPayment, withFiscalRs), jedanaest uvoza koje niko ne čita, dva neiskorištena loggera, tri nepotrebna ubrizgavanja servisa u kontrolere, jedan upit u izvještaju čiji je rezultat išao u mapu koju niko ne čita, i nekoliko imena u konzoli.
  • Tri provjere tipa i svi unit testovi prolaze: API 1684, konzola 152, sajt 52, zajednički paket 131.

0.76.198

15. oktobar 2026.

Ispravljeno

  • scripts/smoke-billing.mjs na svježoj bazi. Prijavljivao se kao seedovani fakturista i prolazio je samo na bazi koju su njegovi raniji prolazi već pomjerili. Na svježem seedu fakturista ima godinu Startera, čiji neiskorišteni dio pokriva mjesec Businessa, pa je prva narudžba odbijena kao nothing_to_pay, a Starter nema webhooke; 21 od 43 provjere padalo je od prve narudžbe nadalje. Sada pravi svoju firmu za prolaz, na Businessu, i naručuje Pro, pa nadogradnja uvijek ima šta da se plati; --email i dalje bira postojeću firmu. Na svježoj bazi 43 od 43.
  • scripts/ci-local.mjs se nije pokretao. CI je dobio korak koji podiže tragove bank testova u pregledniku kad padnu, a lokalni prolaz ne zna za tu akciju i s pravom staje prije prvog koraka. Sada zna: tragovi su ovdje već na disku, u apps/bank/test-results/.

CI

  • Verify posao pokreće i smoke-billing (paket, predračun, uplata sa izvoda, zatvaranje firme i karantin broja), smoke-webshop (hostovana stranica, webhook, ključevi dodataka) i smoke-signup (proba iz forme u Bosni i u Srbiji). Docker poslovi se i dalje ne pokreću zbog naplate računa, pa je ovo dodano samo u verify.

Regresija, svježa baza, jedan po jedan

    0.76.197

    15. oktobar 2026.

    Srbija

    • Konzola govori jezikom firme od prve prijave. Jezik konzole dolazio je samo sa adrese (app.xpay.rs srpski, app.xpay.ba bosanski) ili iz izbora u prekidaču; lokal iz Srbije prijavljen na bosanskoj adresi, iz starog linka, gledao je bosansku konzolu sa srpskom firmom u njoj. Pri prvoj prijavi bez zapamćenog izbora konzola uzima jezik firme; izbor iz prekidača i dalje važi. Prekidač jezika tada nudi srpski i engleski, a ne bosanski i engleski sa ničim izabranim.
    • Lista prvog dana imenuje PIB, ne JIB, firmi u Srbiji; "IBAN na koji sjeda novac" i "zalijepiti" su na srpskoj konzoli bili ijekavski, pa su ušli u zajedničku listu riječi (seda, zalepiti).
    • Odbijanje paketa na jeziku vlasnika. Vlasnik na probnom paketu je na prvom ekranu čitao "Plan TRIAL does not include analytics", rečenicu API-ja na engleskom; konzola sada kaže da paket ne uključuje tu mogućnost i gdje se paket mijenja, na sva tri jezika.
    • app.xpay.rs.localhost je srpska konzola na razvojnoj mašini, kao što je xpay.rs.localhost srpski sajt, pa se obje adrese mogu proći lokalno.

    0.76.196

    15. oktobar 2026.

    Novo

    • Uvoz menija iz tabele. Na stranici Meni dugme "Uvezi meni iz tabele": CSV sa kolonama Kategorija, Naziv i Cijena, a po želji Opis, Stanica (kuhinja, šank, ništa), Šifra i Dostupno (da, ne); tačka-zarez ili zarez, sa ili bez oznake redoslijeda bajtova, cijena sa zarezom ili tačkom, može i "2,50 KM"; kategorija upisana jednom važi za redove ispod, a red sa samom kategorijom je naslov. Isti stil kao uvoz recepture: šablon (sa postojećim menijem, ili dva primjera kad je meni prazan), pregled sa onim što bi se upisalo (nova, izmjena, ista) i problemima po redu (cijena nije broj, nepoznata stanica, dupla stavka), pa potvrda. Stavka koju lokal već ima dobija cijenu, opis, stanicu, šifru i dostupnost iz tabele; nova se pravi; nepoznata kategorija se pravi za cijelu firmu; ništa se ne briše ni ne premješta, pa ista tabela poslije služi kao cjenovnik. API: POST /v1/menu/import (preview: true ne piše ništa) i GET /v1/menu/template.csv; upis ide u revizijski trag kao menu.imported.
    • Uvoz kupaca iz CSV-a za fakturiste već postoji (Kupci, "Uvoz iz datoteke": primjer datoteke, pregled, potvrda), pa se ovdje ne ponavlja; korak "Prvi kupac" u vodiču za prvi dan na njega upućuje.
    • scripts/smoke.mjs: na svježem lokalu tabela se pregleda, loša cijena imenuje redom i ništa ne piše, upis pravi kategorije i stavke jednom, promijenjena cijena čita se kao izmjena a ostatak kao isto, šablon nosi upisano, a korak "Meni" u vodiču za prvi dan se okrene. Jedinični testovi za čitanje datoteke: oba razdvajanja, bosanska i engleska zaglavlja, kategorija koja se spušta niz redove, greške po redu.

    0.76.195

    15. oktobar 2026.

    Srbija

    • Obrazac na xpay.rs šalje zahtjev u API, isti kao bosanski probni nalog, sa državom RS: firma nastaje pod srpskim pravilima (valuta RSD, cjenovnik u dinarima, PIB sa provjerom kontrolne cifre umjesto JIB-a, srpski jezik konzole, gostu SR i EN, IPS_QR kao format koda, lokal je ugostiteljstvo jer se u Srbiji ništa drugo ne prodaje, fiskalni račun preko ESIR-a lokala). Do sada je stranica /registracija na xpay.rs samo otvarala mail program.
    • Zahtjev čeka čovjeka. Firma je na probnom paketu sa statusom na čekanju: vlasnik se ne može prijaviti dok je super admin ne aktivira u /admin (dugme Aktiviraj, uz državu u listi), a prijava prije toga kaže da nalog čeka odobrenje umjesto da je lozinka pogrešna. Probni period traje sedam dana od zahtjeva, koliko srpski sajt obećava prije prve pretplate; bosanski probni nalog i dalje otvara odmah, na 48 sati.
    • Dva pisma na srpskom sa adrese pošiljaoca servera: da je zahtjev primljen i da je nalog otvoren, sa adresom konzole za Srbiju (DASHBOARD_BASE_URL_RS, app.xpay.rs; bez nje adresa domaće konzole).
    • scripts/smoke-signup.mjs: pogrešan PIB odbijen po imenu, radnja u Srbiji odbijena, zahtjev primljen sa sedam dana, prijava odbijena kao pending, admin vidi RS i na čekanju, aktivacija, prijava, firma RS/RSD/sr sa PIB-om, soba RSD i IPS_QR, cjenovnik u dinarima, srpski račun i prvi sto, gostova stranica sr/RSD/IPS_QR sa sr i en; bosanski nalog i dalje odmah i u markama. Devetnaest provjera, sve prolaze lokalno.

    0.76.194

    15. oktobar 2026.

    Novo

    • GET /v1/merchant/readiness: prvi dan firme kao lista koraka sa stanjem urađeno ili nije, istim pravilima kao scripts/venue-ready.mjs (jedan izvor istine: skripta je jutarnja provjera koju neko pokrene, ovo je ono što konzola crta). Oblik firme čita se iz prve poslovnice: ugostiteljstvo (podaci firme i PDV, poslovnica sa bankovnim računom, poslovnica izdaje svoje kodove, QR profil potvrđen s bankom, stolovi i naljepnice, meni, osoblje i kod za konobarski telefon, ekran za osoblje, načini plaćanja, naručivanje sa stola, fiskalizacija), prodavnica i usluge (podaci, račun, artikli, načini plaćanja, kasa, fiskalizacija), fakturista (podaci, račun, prvi kupac, prva faktura, fiskalizacija). Svaki korak kaže da li blokira naplatu, na koji ekran vodi i broj gdje pomaže (naljepnice, artikli, osoblje). QR profil je zelen samo kad ga je banka potvrdila, a blokira samo tamo gdje bi server odbio kod, kao i u skripti. Odgovor done znači da je sve urađeno. Fiskalizacija u Srbiji čita se iz ESIR-a poslovnice.
    • Vodič za prvi dan na pregledu konzole. Panel sa koracima redom kojim se rade, kvačica za urađeno, oznaka "potrebno" za ono što blokira naplatu, "Idi" na ekran gdje se radi. Nestaje sa pregleda kad je sve urađeno; u Pomoći stoji uvijek, pa se može vratiti. Riječi na bosanskom, engleskom i srpskom; napomena za fiskalizaciju zavisi od države firme.
    • scripts/smoke.mjs: nova firma čita se kao ugostiteljstvo sa prvim danom pred sobom; bankovni račun pomjeri korak računa, prva naljepnica korak stolova, i broj urađenih koraka raste tačno za jedan svaki put. Jedinični testovi pokrivaju sva tri oblika firme, PDV kao odluku, blokade i QR pravilo.

    0.76.193

    15. oktobar 2026.

    Server

    • Zdravstvena kapija poslije ažuriranja. Dugme Ažuriraj do sada je upisivalo "uspjelo" čim se stack podigne, prije nego API uopšte odgovori; izdanje koje padne na prvom zahtjevu bilo je uspješno ažuriranje, a prvi ko bi saznao bio je gost za stolom. Updater sada poslije podizanja čeka do pet minuta da API odgovori na /readyz (tek kad vidi bazu i migracije prođu), da /v1/status ne kaže down (degraded prolazi: kopija koja nikad nije napravljena nije razlog da se izdanje baci), i da konzola i sajt vrate po jednu stranicu; tek tada upisuje ok: true.
    • Vraćanje prethodnog izdanja. Ako gradnja, migracije ili kapija ne prođu, updater ponovo pokrene instalaciju prikovanu za commit koji je zapamtio prije povlačenja (install.sh --commit, slike iz keša), podigne i provjeri i to. U update-result.json piše rolledBack, rollbackOk, reason (rečenica kapije) i zadnjih 40 linija loga; /admin to pokazuje narandžasto kad je prethodno vraćeno, crveno kad se ni ono nije vratilo, a javna statusna stranica dobija komponentu Ažuriranja samo kad ima šta reći. Migracije koje je palo izdanje primijenilo ostaju; zato su migracije od sada samo aditivne, pravilo je zapisano u docs/en/06-deployment.md i docs/en/12-update-rollback.md.
    • Ručno vraćanje iz /admin. Dugme Vrati prethodno izdanje, uz potvrdu koja imenuje commit, istim mehanizmom (POST /v1/admin/update/rollback); odbija se dok ažuriranje traje ili čeka i dok server ne pamti prethodno izdanje. Sa servera isto radi deploy/install.sh --commit <sha>.
    • Runbook: docs/en/12-update-rollback.md i docs/bs/11-azuriranje-i-vracanje.md, šta se radi kad ažuriranje padne, kako se čita rezultat, kako se vraća ručno. Jedinica xpay-updater.service dobija sat vremena umjesto pola (ponovo kopirati u /etc/systemd/system i daemon-reload).

    0.76.192

    15. oktobar 2026.

    Novo

    • Dnevno brisanje isteklih probnih naloga. Politika privatnosti obećava da se podaci iz probnog naloga koji ne pređe u ugovorni odnos brišu najkasnije šest mjeseci nakon isteka probe; komentar u samoj politici je pisao da je to obaveza, a ne opis, i da posao koji to radi treba napisati. Sada postoji: u 6:15 se briše svaka firma na planu TRIAL kojoj je proba istekla prije više od šest mjeseci (RETENTION.trialMonths), koja nikad nije izdala nijedno plaćanje i nikad nije platila XPay-u. Briše se firma sa svime ispod nje (poslovnica, meni, podešavanja), njeni revizijski zapisi i nalog vlasnika ako ne vodi nijednu drugu firmu; na platformskom tragu ostaje zapis platform.trial_deleted sa brojem firme i datumom isteka. Firma koja je ikad izdala plaćanje ili platila paket nije istekla proba nego posao i ovdje se ne dira; njen broj nikad ne ide drugome ovim putem, jer firma bez plaćanja nema nijedan poziv na broj u opticaju.
    • Jedinični testovi: upit bira tačno po roku i uslovima, redoslijed brisanja je trag, firma, vlasnik, dan bez isteklih proba ne piše ništa. Četvrti i posljednji raskorak iz 0.76.187 je zatvoren; retention.test.ts prolazi bez izuzetaka.

    0.76.191

    15. oktobar 2026.

    Pravni dokumenti

    • Revizijski trag. Politika je obećavala "zapisi o radnjama u konzoli: do 24 mjeseca", a trag je heš lanac u kojem se svaki zapis poziva na prethodni, pa se pojedinačni zapisi ne mogu brisati a da se ne obezvrijedi dokaz o ostalima. Sada piše: za vrijeme trajanja ugovora i nakon prestanka u roku zastare potraživanja; sa brisanjem naloga briše se i trag.
    • Ključ gosta koji se vraća. Politika je tvrdila da se skeniranja ne povezuju sa ranijim posjetama. Telefon gosta pri prvom otvaranju menija dobija nasumičan ključ bez imena koji preglednik čuva za taj objekat; uz njega objekat broji posjete i potrošnju tog telefona i nudi mu ono što je ranije naručivao. Politika to sada kaže, zajedno sa granicama: samo taj objekat, bez ikakvog podatka o osobi, brisanje dvanaest mjeseci poslije posljednje posjete, uklanjanje brisanjem podataka preglednika.
    • Gost koji rezerviše sto dobija svoju tačku: šta se upisuje, za čiji račun, veza za stanje i otkazivanje, i anonimizacija dvanaest mjeseci poslije termina. Rok ulazi i u spisak rokova čuvanja, kao i rok za kriptografski otisak sesije gosta (dvanaest mjeseci poslije zatvaranja računa) i za ključ gosta.
    • Politika privatnosti je verzija 1.4 od 15. oktobra 2026; srpska verzija na xpay.rs je 1.4-RS3 istog dana, istim riječima po srpskom zakonu. Strana je i dalje NoLimitDevelopments FZ-LLC. Spisak podobrađivača se ne mijenja.

    Kod koji čita politiku

    • retention.ts više nema broj za revizijski trag (nema šta da se sprovodi), a ima rok za otisak sesije gosta i za ključ gosta; dnevno čišćenje čita ta dva. retention.test.ts prolazi bez izuzetaka: svaka rečenica sa rokom postoji u politici 1.4, i nijednu srpska verzija ne prepisuje.

    0.76.190

    15. oktobar 2026.

    Sajt

    • Opis stranice i kartica za dijeljenje stoje u zaglavlju za svakog posjetioca. Next ih je običnom pregledniku slao u tijelo stranice, pa ih alati za provjeru i svaki čitač koji gleda samo zaglavlje nisu nalazili; Lighthouse SEO sa 92 na 100 na svakoj stranici, na oba sajta.
    • Kontrast i veze. Puno dugme (Odaberi paket, Pošalji) bilo je bijelo na svijetlo ljubičastoj, 3,1:1; sada na punoj ljubičastoj, 6:1. Veza na Politiku privatnosti u obrascu za probni nalog je podvučena, pa se razlikuje od teksta oko sebe i bez boje. Tabela u prikazu konzole na naslovnoj je oznaka, ne podaci, pa je čitač ne nabraja kao tabelu. Lighthouse pristupačnost 96 i 97 na 100 na cijenama i probnom nalogu.
    • Tastatura. Dugme za slanje u obrascu za kontakt je u redoslijedu tabulatora i dok obrazac nije popunjen (prije se nije moglo doći do njega), a kvačica saglasnosti na probnom nalogu je veća.
    • Slike. Logotip je bio 148 KB (i 129 KB svijetla verzija) za 36 piksela visine; sada 18 KB, znak 230 na 22 KB, ikona 214 na 60 KB. Četiri jela na prikazu telefona na xpay.rs bila su 55 do 82 KB svako kao PNG; sada 6 do 8 KB kao WebP. Slike po stranici sa 148 na 18 KB, naslovna sa 278 na 36 KB, xpay.rs naslovna sa 318 na 29 KB; ukupan prenos cijena i kontakta sa 543 i 525 na 412 i 394 KB.
    • Logotip u prikazu telefona drži svoje proporcije umjesto da ga red spljošti. scripts/site-dishes.mjs od sada pravi WebP od 128 piksela.

    0.76.189

    15. oktobar 2026.

    Brže

    • Gost više ne preuzima konzolu. Svaki sken stola nosio je u HTML-u cijeli katalog prevoda konzole (admin, zalihe, Uvidi, pomoć), a stranica stola je u svom paketu imala sva tri jezika istog kataloga. Gostove rute sada dobijaju samo gostove riječi: HTML stola sa 82 na 18 KB, JavaScript sa 375 na 158 KB, rezervacija sa 156 na 20 KB HTML-a.
    • Meni se traži u istom trenutku kad i sto, ne poslije njega, pa prva fotografija stiže jedan krug ranije. Na simuliranom sporom 4G telefonu (Lighthouse, mobilni): najveći prikaz sa 6,1 s na 4,3 s, rezervacija sa 3,5 s na 2,9 s; ocjena brzine sa 76 na 84 i sa 88 na 94.
    • Boja trake preglednika na gostovoj stranici je boja gostove podloge (krem ili topla tamna, ili tema koju je lokal zakačio), ne zelena konzole.

    Pristupačnost

    • Tastatura kroz cijeli tok. List jela (sheet) uzima fokus kad se otvori, Tab ostaje u njemu, Escape ga zatvara i fokus se vraća na jelo; zatamnjena pozadina ima natpis Zatvori, ne naziv jela. Fokus sa tastature crta se u boji lokala na svakom dugmetu.
    • Kontrast. Prigušeni i sitni tekst (opisi, natpisi polja na rezervaciji) bio je 3,9 i 4,0:1; sada najmanje 4,5:1 na svijetloj i tamnoj podlozi. Lighthouse pristupačnost: sto sa 95 na 100, rezervacija sa 96 na 100.
    • Dodirne površine. Dugmad za jezik sa 35 x 29 na 44 x 40 piksela; naziv jela bez opisa, koji je bio visok 20 piksela, sada je najmanje 40.
    • Jezik dokumenta prati izabrani jezik dugmadi (čitač ekrana mijenja glas), a greška na rezervaciji je povezana sa obrascem kojem pripada.

    Razvoj

    • NEXT_DIST_DIR bira direktorij produkcijskog builda konzole, pa se mjerenje može raditi pored pokrenutog dev servera koji briše .next.

    0.76.188

    15. oktobar 2026.

    Novo

    • Lični podaci jedne osobe u konzoli. Na stranici Kupci (izdavaoci računa) i na stranici Rezervacije (ugostitelji) vlasnik i menadžer upišu e-mail ili telefon osobe, vide šta XPay drži o njoj (kartice kupca, računi, rezervacije, poruke) i preuzmu kopiju kao JSON ili CSV; vlasnik je može anonimizirati uz potvrdu, a odgovor kaže koliko je kartica i rezervacija anonimizirano i koliko računa ostaje kako su izdani. Rečenica ispod naslova imenuje zakon po državi firme: Zakon o zaštiti ličnih podataka Bosne i Hercegovine, odnosno Zakon o zaštiti podataka o ličnosti Republike Srbije; riječi su na bosanskom, engleskom i srpskom.
    • Super admin isto za firmu. Na admin stranici panel "Lični podaci kod firme": odabere se firma, pa isti izvoz i anonimizacija na pisani zahtjev vlasnika.

    0.76.187

    15. oktobar 2026.

    Novo

    • Rokovi čuvanja na jednom mjestu. apps/api/src/common/retention.ts nosi svaki rok iz politike privatnosti (1.3 bs, RS2 sr): zapisi o radnjama u konzoli 24 mjeseca, tehnički zapisi i zapisi o pristupu 12 mjeseci, probni nalog šest mjeseci, komunikacija sa podrškom 24 mjeseca, odgovor na zahtjev u 30 dana. Test retention.test.ts čita tekst politike na apps/web i pada kad se broj u kodu i broj u politici raziđu, i kad bi srpska verzija prepisala neku od tih rečenica.
    • Pravo na pristup. GET /v1/privacy/person?email=... ili ?phone=... (format=json ili csv) daje sve što firma drži o jednoj osobi: kartice kupca sa računima i uplatom koja je svaki račun zatvorila, rezervacije, poruke poslane osobi ili o njoj. Telefon se poredi kako god je upisan (+387 61 234 567, 061/234-567, 0038761234567 su isti broj), e-mail bez obzira na velika slova. Radi samo prijavljena osoba (menadžer ili vlasnik); API ključ dobija 403 console_only. Izvoz ide u revizijski trag sa otiskom osobe, nikad sa adresom ili brojem.
    • Pravo na brisanje. POST /v1/privacy/person/anonymise (vlasnik) briše ime, poreski broj, e-mail, telefon, adresu, referencu i napomenu na karticama kupca i ime, telefon, e-mail i napomenu na rezervacijama (postaju "Anonimizirano"), a kartica se povlači. Računi i fiskalni zapisi ostaju kako su izdani jer ih zakon traži; odgovor kaže koliko ih je ostalo (invoicesKept). U revizijskom tragu ostaje ko, kada, otisak i brojevi.
    • Super admin isto za firmu, na zahtjev vlasnika: GET /v1/admin/privacy/merchants/:id/person i POST /v1/admin/privacy/merchants/:id/person/anonymise.
    • Dnevno čišćenje po politici. U 5:30 brišu se gostovi tokeni sesije (otisak u session_guests) za račune zatvorene prije više od 12 mjeseci i ključevi gosta koji se vraća (venue_guests) bez posjete 12 mjeseci; narudžbe i račun ostaju kao dokument firme. U 5:45 rezervacije starije od 12 mjeseci od termina gube ime, telefon, e-mail i napomenu, a red ostaje (dan, broj osoba, ishod). Jedinični test provjerava da oba posla koriste rok iz retention.ts i ne diraju ništa drugo.
    • scripts/smoke.mjs dobija sekciju: osoba na kartici kupca i rezervaciji, kopija po e-mailu i po telefonu, JSON i CSV, ključ odbijen, druga firma ne vidi ništa, anonimizacija, poslije nje osobe nema, trag bez adrese.

    Gdje politika i kod nisu bili usklađeni

    • Politika ne pominje rezervacije stola iako one nose ime, telefon i e-mail gosta; do dopune politike na njih se primjenjuje rok za zapise o pristupu (12 mjeseci od termina), i test to drži.
    • Politika obećava da se zapisi o radnjama u konzoli čuvaju do 24 mjeseca, a ništa ih ne briše: revizijski trag je heš lanac i ne može izgubiti početak bez kontrolne tačke. Ostaje za posebno izdanje.
    • Politika obećava brisanje probnog naloga najkasnije šest mjeseci po isteku probe; posao koji bi to radio ne postoji. Brisanje cijele firme traži odluku, pa je rok upisan, a posao nije uključen.
    • Politika kaže da se skeniranja ne povezuju u profil gosta, a ključ gosta koji se vraća (venue_guests) broji posjete i potrošnju po telefonu koji ga je sam zatražio; sada se briše poslije 12 mjeseci bez posjete.

    0.76.186

    15. oktobar 2026.

    Ispravljeno

    • Iz admin konzole: zatvorena firma prebačena u "suspendovana" zadržavala je datum zatvaranja i dan puštanja broja. Samo prelazak u "aktivna" išao je kroz ponovno otvaranje; prelazak u "suspendovana" mijenjao je samo status, pa je firma istovremeno bila van reda karantina (po statusu) i u njemu (po datumu), a odgovor je nosio stari closedAt. Svaki izlazak iz "zatvorena" sada prvo poništi zatvaranje (datum, dan puštanja, otkaz pretplate), pa tek onda postavi traženi status. Provjera u scripts/smoke.mjs koja to traži od 0.76.171 padala je na CI od tada (lokalno je prošla na bazi koja je već imala te firme); od ovog izdanja verify posao prolazi.

    0.76.185

    15. oktobar 2026.

    Ispravljeno

    • Zatvorena firma u aplikaciji za banke. Lista Firme uz ime nosi oznaku "zatvorena" s datumom i red je prigušen, a zaglavlje liste broji zatvorene uz one s uvidom i bez uvida. Detalj firme na vrhu kaže kad se firma zatvorila i da banka i dalje vidi ono što je firma dijelila dok je radila, a obrazac za označavanje veze se ne nudi; odbijanje merchant_closed ima svoju rečenicu. Portfolio zatvorenu firmu drži na dnu s njenim brojkama, bez signala, s oznakom i datumom umjesto signala, a brojač "Dijele podatke" kaže koliko zatvorenih ostaje u knjizi.
    • Integracije na 390 px. Kartica okruženja (šta tvrdi da može, kredencijali, spremnost za UAT, šta je okruženje poslalo) širila je stranicu na 492 px, pa se cijeli ekran vodoravno pomjerao; polja mreže sada smiju biti uža od svog sadržaja (min-w-0) i stranica ostaje na širini telefona. Sve ostale sekcije na 390 px i na desktopu prošle bez prelijevanja i bez greške.
    • Segmenti na pregledu. Uz broj povezanih firmi po segmentu pisalo je "2" pa odmah "0 s uvidom", što se čitalo kao "20 s uvidom"; podnaslov uz svaku traku sada počinje tačkom razmaka, pa je "2 · 0 s uvidom". Isto vrijedi za svaku listu traka u analitici.

    0.76.184

    15. oktobar 2026.

    Ispravljeno

    • Firma koja je dijelila podatke s bankom pa se zatvorila nestajala je iz banke sa svom istorijom. Skup firmi koje banka smije čitati tražio je samo aktivne, pa je sljedeći prolaz projekcije obrisao sve njene redove iz pogleda banke i ponovo sabrao dane bez nje: pregled, analitika, izvještaj za upravu i portfolio mijenjali su se unazad (na lokalnoj bazi 39 uplata i 1.211,30 KM za tri mjeseca palo je na nulu), lista Firme je nije više imala ni među onima bez uvida, a detalj je odgovarao 404. Zatvaranjem firma ne povlači pristanak: uplate su primljene dok je radila i dijelila, pa zatvorena firma ostaje čitljiva, njena istorija ostaje u pogledu, a mjeseci banke se ne mijenjaju. Samo prekidač koji firma sama isključi odnosi njene brojke, kao i do sada.
    • Banka vidi da je firma zatvorena. Red u listi Firme i detalj nose closedAt, lista i portfolio broje zatvorene posebno (closed), red u portfoliju ide na dno bez signala, radar je ne nudi, segmenti i usvajanje je ne broje od dana zatvaranja, analitika firmi broji povezane i segmente samo među otvorenim, a zdravlje sistema broji firme s kojima banka danas radi. Označavanje veze zatvorene firme odbija se sa 409 merchant_closed. Druga banka i dalje ne zna da firma postoji.
    • scripts/smoke-bank.mjs dobija sekciju: firma na računu banke pristane, zatvori se iz admin konzole, ostaje u brojkama i na listi kao zatvorena, ne prima oznaku, nema signal ni segment, a ponovo otvorena je živa firma.

    0.76.183

    15. oktobar 2026.

    Konzola

    • Pet novih uputstava na stranici Pomoć, na bosanskom, srpskom i engleskom, kao i dosadašnja: korak po korak i samo ono što proizvod stvarno radi. Zalihe (uključivanje po poslovnici, ko šta smije, prijem, recepture i uvoz iz fajla, poluproizvodi, popis, kartica artikla, potrošnja i izvoz za knjigovođu), Uvidi (Pro paket, šta model radi a šta ne, preporuke, prognoza i kupovna lista, izvještaj e-mailom), meni na jeziku gosta (jezici, prevodi, Prevedi meni, šta vidi telefon gosta), kupovina paketa (ponuda, predračun, uplata, kad paket važi) i zatvaranje firme (šta staje, šta ostaje, ko može ponovo otvoriti). Svako vodi na ekran o kojem govori.
    • Srpska riječ za dvjesto u zajedničkoj listi riječi, pa je i to uputstvo na xpay.rs napisano kako se tamo kaže.

    0.76.182

    15. oktobar 2026.

    Novo

    • Webhook stock.low. Kad kretanje spusti artikal s iznad minimuma na minimum ili ispod, uz e-mail vlasniku izlazi i događaj sa artiklom, šifrom, poslovnicom, stanjem i minimumom; jednom po prelasku, a sljedeći prijem koji ga digne iznad ponovo ga naoruža. Program za nabavku pretplati se na njega i ne čita poštu.
    • Webhook proforma.paid. Kad uplata za predračun legne i faktura se izda, firma dobija događaj s brojem predračuna i fakture, paketom, iznosom, periodom i trenutkom od kojeg paket važi. Oba su u listi na sajtu, u dokumentaciji i u check:webhooks, koji potvrđuje da se sve tri liste slažu; smoke-stock i smoke-billing dokazuju da svaki stvarno izlazi.

    Dokumentacija

    • docs/en/11-stock-insights-api.md i docs/bs/10-zalihe-i-uvidi.md: zalihe kroz API od uključivanja do fajla za knjigovođu (artikli, kretanja, popis, potrošnja, poluproizvodi, šta kasa smije prodati, recepture iz fajla), meni na jezicima gosta, Uvidi sa dnevnim ograničenjima, paket i predračun, sto, zatvaranje firme, status, i tabela svakog razloga odbijanja sa statusom i rutom. Vodič za kase dobija ta dva događaja i upućuje na razloge odbijanja.
    • SDK @xpay/sdk 0.2.0 dobija xpay.stock (polica, dodavanje, kretanje, kartica, popis od otvaranja do zatvaranja, šta kasa smije prodati) i xpay.insights (izvještaj, osvježavanje, pitanje), tipove za oba nova događaja, primjere u README-ju i testove; količine idu kao tekst, a broj se pretvara, nikad ne zaokružuje.

    0.76.181

    15. oktobar 2026.

    Dokumentacija

    • Svaka nova ruta ima opis, šta odgovor nosi i zašto može biti odbijena. Zalihe (polica, dodavanje artikla, izbor artikala sa cijenom, izvoz za knjigovođu, potrošnja i njen fajl, popis od otvaranja do zatvaranja, šta kasa smije prodati, kretanja i kartica artikla, sastav poluproizvoda), meni (zalihe jela sa kalom, uvoz i šablon receptura, prevodi jela, meni gosta na njegovom jeziku), Uvidi (izvještaj, kupovna lista, osvježavanje, pitanje, primjena preporuke, opis jela, prevod menija, prijedlog recepture), plan i predračun (cjenovnik, ponuda, narudžba, otkazivanje, QR za plaćanje), licenca i izvod platforme, podešavanja poslovnice (vođenje zaliha, uloge na zalihama, jezici gosta), sto i raspored sale, zatvaranje firme, status (kako pošta izlazi) i narudžba gosta kad police nema dovoljno.
    • Razlozi odbijanja su dio ugovora. Pored svake rute piše status, kod i details.reason po kojem klijent može granati: stock_short, stock_role, note_required, stocktake_open, stocktake_closed, moved_underneath, sku_taken, label_in_use, order_open, not_open, wrong_password, open_tabs, ai_unavailable, insufficient_data, dnevni limiti Uvida i ostali. Svaki je provjeren prema kodu koji ga baca; gdje odbijanje nema razlog, piše samo kada dolazi.
    • Referenca se gradi iz dva pomoćnika u apps/api/src/common/api-docs.ts: Refusals(status, razlozi) i Answer(opis), pa sljedeća ruta dobija isti oblik bez prepisivanja. Swagger na /docs i /docs-json učitavaju se bez greške, 393 rute.

    0.76.180

    15. oktobar 2026.

    Ubrzano

    • Provjera pokrivenosti sa police (meni za gosta i svaka narudžba) tražila je otvorene stavke kroz sve narudžbe koje je lokal ikad primio; sada kreće od otvorenih stolova, kojih je nekoliko, pa posao ne raste sa sezonom. Meni za gosta 80 ms na 62 ms, narudžba sa zaključanom policom 83 ms na 64 ms (cilj ispod 150 ms za meni).
    • Gradnja sedmičnog izvještaja Uvida pravila je formater sata za svaku narudžbu, svaki račun i svaki prolaz prognoze; sada ga drži po vremenskoj zoni. Uz to više ne spaja cijenu jela na svaku stavku ni ne broji narudžbe po stolu posebnim upitom, nego čita oboje iz podataka koje već ima. Prvi poziv Uvida za sedmicu sa 12.700 narudžbi 3,9 s na 1,2 s; sabiranje sedmica 465 ms na 57 ms. Keširani poziv ostaje 15 ms. Ostatak su redovi narudžbi sami; gradi se jednom sedmično po lokalu.

    0.76.179

    15. oktobar 2026.

    Ubrzano

    • Potrošnja, CSV potrošnje i izvoz za knjigovodstvo čitali su svako kretanje poslovnice od početka perioda i sabirali ga u programu; poslije sezone to je 85.000 redova za 300 linija izvještaja. Sada baza sabira po artiklu, razlogu, strani perioda i predznaku, a ista aritmetika čita zbirove kao što je čitala redove (isti rezultat, provjereno red po red na lokalu sa teretom). Novi indeks kretanja po poslovnici i vremenu.
    • Na lokalu Teret Zalihe (medijan): potrošnja 30 dana 165 ms na 24 ms, potrošnja 90 dana 391 ms na 47 ms, CSV potrošnje 148 ms na 28 ms, izvoz 132 ms na 32 ms; sam upit 355 ms na 77 ms. Vrijeme više ne raste sa sezonom.

    0.76.178

    15. oktobar 2026.

    Alat

    • scripts/load-stock.mjs pravi lokal Teret Zalihe (vlasnik [email protected] / teret-2026) sa 300 artikala, 150 jela sa recepturama, devedeset dana prodaje (oko 20.000 narudžbi, 40.000 stavki i 85.000 kretanja), isporukom sedmično i dvanaest popisa, upisano direktno u bazu u velikim serijama. Ponovljivo i bez dupliranja: svaki red ima oznaku iz plana, postojeći se preskaču, stanja police se na kraju izračunaju iz kretanja.
    • scripts/measure-stock.mjs mjeri na tom lokalu polici, potrošnju i njen CSV, karticu artikla, popise, izvoz, Uvide (prvi i keširani poziv), meni za gosta sa provjerom pokrivenosti, narudžbu sa zaključanom policom i račun gosta; cilj ništa preko 500 ms, meni za gosta ispod 150 ms. scripts/time-queries.mjs mjeri pojedinačne upite iza teških izvještaja.

    0.76.177

    15. oktobar 2026.

    Sigurnost

    • API ključ ne mijenja ko smije šta na zalihama, jezike gosta ni uvid banke. PATCH /v1/locations/:id traži payments:write, koji nosi svaki ključ, pa je ključ koji vodi kasu mogao promijeniti uloge na zalihama (0.76.123), jezike gosta (0.76.139), vođenje zaliha, oznaku osjetljive poslovnice i samo uparivanje. Ta polja sada prima samo prijavljena osoba u konzoli; ključ i dalje mijenja ono što kasa postavlja (naziv, adresu, QR format, naručivanje, načine plaćanja, fiskalne oznake). Odgovor kaže koja polja su odbijena.
    • Ključ se pravi samo sa opsezima koje API poznaje. Lista opsega pri pravljenju ključa primala je bilo koji tekst, pa i *, koji zaobilazi svaku provjeru opsega. Sada je lista zatvorena na dvanaest opsega koje rute traže; nepoznat opseg i zvjezdica su 400.
    • scripts/pentest.mjs dobija 58 napada na ono što je stiglo od 0.76.114: druga firma po našem id-u na zalihe, izvoz, potrošnju, popis, raspored sala, podešavanja poslovnice, sto i Uvide (404); član osoblja sa prijavom na konzolu na Uvide, podešavanja, zalihe, izvoz, raspored, zatvaranje firme, članove, ključeve, uvoz receptura i prevod (403); ključ za kasu na zalihe, Uvide, uvoz, uloge, jezike, oznaku banke i zatvaranje (403); zvjezdica i nepoznat opseg pri pravljenju ključa (400); sedam adresa koje nisu slika na rasporedu, logu i kategoriji (400); nepoznat jezik gosta, uloga van liste, kontrolni znakovi u nazivu artikla, uvoz receptura preko pet megabajta; zatvaranje firme pogrešnom lozinkom ne zatvara ništa; pitanje modelu bez modela ne ruši API; javni status, lista webhooka i zapis firme ne nose ključ, tajnu ni heš lozinke. Pregledano i ostalo bez nalaza: potpis i prozor od pet minuta na webhooku dodatka, CSV izvozi kroz zaštitu od formula, dnevne kvote na pozivima modelu, dedupe uvoza izvoda platforme po hešu, otvoren predračun blokira drugu narudžbu paketa, ključ pošte nikad u dnevniku ni u odgovoru, prevodi i opisi iz modela na gostovoj stranici idu kroz React escape.

    0.76.176

    15. oktobar 2026.

    Sigurnost

    • Adresa slike mora biti http(s) na javnom hostu. Logo firme, slika kategorije i jela i slika ispod rasporeda stolova primali su bilo koju adresu sa shemom: javascript:, data:, file:, adresu iz privatne mreže ili sa oblaka (169.254.169.254), ime sa kancelarijske mreže, korisničko ime i lozinku u adresi. Svaki ekran tu adresu stavlja u img ili u background-image, pa je to bio način da se tuđem pregledniku podmetne adresa koju niko nije mislio. Sada prolazi samo http ili https, bez podataka za prijavu, na javnom hostu; jedini izuzetak je sam API (API_BASE_URL), odakle se služe snimljene slike, i na razvojnoj mašini je to localhost. Pravilo je u apps/api/src/common/public-url.ts sa unit testom; napadi u scripts/pentest.mjs stižu sa sljedećom verzijom.

    0.76.175

    15. oktobar 2026.

    Promjene

    • Broj zatvorene firme čeka 24 mjeseca, ne 90 dana. Četverocifreni broj firme stoji u svakom pozivu na broj koji je firma ikad odštampala, a stari uplatioci ga drže na trajnim nalozima i u bankovnim aplikacijama dugo poslije skidanja naljepnice. Firma koja se zatvori bez ijedne uplate oslobađa broj tek poslije 24 mjeseca, a datum oslobađanja se upisuje uz firmu pri zatvaranju; firma koja je ikad izdala uplatu zadržava broj zauvijek, kao i do sada, pa njena stara referenca nikad ne može stići na tuđi račun. Brojevi koji su jednom bili u prometu ne idu nikome drugom.
    • Pločica Brojevi firmi u /admin pokazuje i koliko je brojeva zatvorenih firmi u karantinu i kad se prvi oslobađa.

    Ostaje

    • Skaliranje broja preko različitih IBAN-a ne radi, po odluci vlasnika; ovaj dio kartice ostaje otvoren.

    0.76.174

    15. oktobar 2026.

    Ispravke

    • Sitemap xpay.ba sada nosi /hospitality i /integracije. Obje stranice stoje u meniju i vode s početne, a sitemap ih nije imao, pa ih je pretraživač nalazio kasno ili nikako.
    • Beacon posjeta sa xpay.rs na razvojnoj mašini. API-jeva podrazumijevana lista CORS adresa dobija http://xpay.rs.localhost:3001, pa srpski sajt lokalno više ne puni konzolu preglednika CORS greškama na /v1/telemetry/site. Na serveru listu daje CORS_ORIGINS u .env; .env.example sada kaže da u produkciji mora nositi i xpay.rs i app.xpay.rs, inače posjete srpskog sajta ne stižu u statistiku.

    0.76.173

    15. oktobar 2026.

    Ispravke

    • Statusna stranica više ne nosi cijelu historiju verzija. Svih 457 verzija stajalo je u HTML-u stranice, starije sklopljene iza "Prikaži još", pa je stranica koju neko otvori da vidi radi li naplata imala 5,8 MB. Sada nosi šest najnovijih (205 KB), a cijela historija je na /status/verzije, na istoj liniji, jednim klikom; stranica je u sitemapu, a na xpay.rs vodi na početnu kao i /status.
    • Stavke verzija na 390 px više ne izlaze dva piksela preko ruba: dugačka riječ u stavci sada se prelama.

    0.76.172

    15. oktobar 2026.

    Ispravke

    • Uslovi korišćenja na xpay.rs kažu "na srpskom i engleskom jeziku". Rečenica o podršci glasila je "na bosanskom i engleskom jeziku" i na srpskom sajtu, jer tabela srpskih pravnih prepravki nije imala tu rečenicu. Sada ima; test uz tabelu i dalje traži da svaka bosanska rečenica koju prepravlja postoji u izvoru.

    0.76.171

    15. oktobar 2026.

    Novo

    • Zatvaranje firme. Vlasnik u Postavkama, uz razlog i lozinku ponovo, ili super admin u /admin uz razlog: firma dobija stanje Zatvorena sa datumom, razlogom i ko je zatvorio. Prijave u konzolu, API ključevi, uređaji (kasa, konobarski ekran, kuhinja) i naljepnice prestaju odmah; gost na stolu zatvorene firme vidi "Ovaj objekat više ne koristi XPay", a uređaj koji se pokuša povezati rečenicu umjesto greške. Otvoreni kodovi za plaćanje se poništavaju, webhook pozivi i pretplata se zaustavljaju, prijavljene sesije se odjavljuju. Otvoreni stolovi se zatvaraju kao neplaćeni samo kad to ko zatvara izričito kaže; inače zatvaranje odbija i kaže koliko ih ima.
    • Ništa se ne briše. Računi, fiskalni zapisi, izvodi i izvještaji ostaju u zakonskom roku čuvanja koji Ugovor već navodi (propisi o računovodstvu i porezima) i mogu se izvesti; tekstovi Ugovora i DPA ostaju kakvi jesu, jer o tome već govore. Broj firme ostaje rezervisan 24 mjeseca, zapisano uz firmu kad se oslobađa.
    • Ponovo otvaranje radi super admin iz /admin: datum zatvaranja se briše, pretplata stoji ako joj period nije istekao, webhook pozivi ostaju isključeni dok ih vlasnik ne uključi.

    0.76.170

    15. oktobar 2026.

    Novo

    • Dodaci za prodavnice na stranici Za programere. Panel sa WooCommerce, PrestaShop i OpenCart arhivama za preuzimanje (sa sajta, gdje se grade pri svakom izdanju) i linkom na uputstvo, pored API ključeva i webhooka koje dodatak traži.
    • Uputstva: docs/en/09-webshop.md (engleski, tri poziva, podaci za uplatu na vlastitoj stranici preko javne stranice računa, WooCommerce podešavanja), docs/rs/07-webshop.md (srpski, za prodavnicu u dinarima sa IPS QR kodom), uz postojeće docs/bs/07-webshop.md.
    • scripts/smoke-webshop.mjs: pozivi koje dodaci rade, protiv pokrenutog API-ja, mjereni po onome što je ovaj prolaz napravio: račun u obliku kakav dodatak šalje (idempotencija, isti ključ drugo tijelo 409), čitanje po id-u, po broju narudžbe i preko javne stranice računa bez ključa, slika koda, registracija i brisanje webhooka sa tajnom oblika whsec_. PHP se u CI-ju ne pokreće, pa je ovo druga polovina provjere; harnessi dodataka prolaze uz php na putanji (pnpm run check:plugins).
    • Shopify, skica (docs/en/10-shopify-sketch.md): zašto to nije dodatak nego Payments App koju Shopify hostuje i odobrava, od čega bi se sastojala i kad se isplati. Samo tekst, bez koda.

    0.76.169

    15. oktobar 2026.

    Novo

    • Panel "Predračuni i izvod platforme" na stranici Pretplate. Dugme za uvoz izvoda sa rezultatom u riječima (zatvorilo, za provjeru, bez predračuna, već postojalo), otvoreni predračuni sa firmom, paketom, pozivom na broj, koliko dana čekaju i rokom (crveno kad kasni), uplate za provjeru sa razlogom i izborom predračuna kojim se zatvaraju ili dugmetom "Nije predračun", i zadnje zatvoreno sa izvoda. Ručna potvrda dugmetom Plaćeno na spisku faktura ostaje kao rezerva.

    0.76.168

    15. oktobar 2026.

    Novo

    • Dodatak za WooCommerce, integrations/woocommerce: način plaćanja "Plaćanje bankovnim prenosom uz QR (XPay)". Pri narudžbi dodatak preko API ključa lokala napravi XPay zahtjev za plaćanje (POST /v1/payments) u valuti prodavnice, pošalje kupca na XPay stranicu s kodom, a webhook s provjerom potpisa označi narudžbu plaćenom; stranica narudžbe i sama provjeri stanje kad se kupac vrati. Sve to je postojalo od septembra; novo:
    • Kod i podaci za uplatu na stranici narudžbe i u e-mailu kupcu. Dok narudžba čeka uplatu, stranica "hvala" i e-mail kupcu (ne kopija prodavnici) nose QR kod, iznos, primaoca, račun, banku, poziv na broj, rok i link na stranicu za plaćanje, u HTML-u i u običnom tekstu. Podaci se čitaju jednom s javne stranice računa (GET /v1/payments/checkout/:token) i pamte na narudžbi; plaćena narudžba ih ne pokazuje.
    • Jezik kupca u podešavanju dodatka: bosanski, srpski ili engleski, za naziv i opis na kasi, poruke na stranici narudžbe i podatke za uplatu. Naziv i opis koje prodavnica sama upiše imaju prednost.
    • Dinari. Dodatak se nudi prodavnici u KM ili u RSD, zahtjev ide u valuti narudžbe, a XPay iz valute bira kod (IPS QR za Srbiju); bilješke na narudžbi nose KM ili RSD.
    • Harness bez WordPressa (integrations/woocommerce/test/harness.php) provjerava i valute, jezike, zahtjev za račun i podatke za uplatu; readme.txt dodatka opisuje podešavanja.

    0.76.167

    15. oktobar 2026.

    Novo

    • Izvod računa NoLimitDevelopments kao izvor uplata. Super admin uvozi camt.052/053/054 ili CSV izvod (kolone se prepoznaju po nazivu: datum, iznos, valuta, poziv na broj ili svrha, uplatilac, račun uplatioca); svaka uplata se pamti jednom po oznaci banke, pa isti izvod učitan dvaput ne zatvara ništa dvaput. Uplate idu kroz isti matcher kojim XPay uparuje uplate lokalima: poziv na broj sa kontrolnim ciframa i tačan iznos zatvaraju predračun kao dugme Plaćeno (paket se uključuje, račun se izdaje, firma dobija e-mail); drugačiji iznos, više kandidata, poziv bez kontrolnih cifara ili tačan iznos bez poziva otvaraju slučaj za čovjeka; uplata koja ne imenuje ništa čeka da je neko pripiše predračunu ili skloni. Nikad po samom iznosu. Platforma nije zakupac, pa njene uplate stoje u svojoj tabeli, a pravila su zajednička sa lokalima.

    0.76.166

    15. oktobar 2026.

    Novo

    • Predračun u dinarima sa IPS kodom. Firma iz Srbije dobija cjenovnik, ponudu i predračun iz dinarskog cjenovnika (Start 2.900, Business 5.900, Pro 11.900 RSD mjesečno, ugostiteljstvo 2.900 RSD po poslovnici), a kod za plaćanje je NBS IPS QR na srpski račun platforme iz podešavanja servera (LEGAL_COMPANY_IBAN_RS, opisano u .env.example). Dok taj račun nije upisan, dinarski predračun izlazi bez računa i bez koda i to kaže, umjesto da izmisli podatke firme.

    Ostaje

    • PDF i pismo predračuna i računa platforme su na bosanskom i za srpsku firmu; sloj dokumenata zna samo bosanski i engleski.

    0.76.165

    15. oktobar 2026.

    Novo

    • Paket i plaćanje na stranici Licenca. Pet paketa sa cijenama u novcu firme, period mjesec ili godina, pregled iznosa prije narudžbe (licenca, ugostiteljstvo, transakcije preko uključenih, odbitak kod nadogradnje) sa periodom i rečenicom kad paket počinje. Dugme Naruči predračun; otvoreni predračun stoji na vrhu sa računom primaoca, primaocem, pozivom na broj, kodom za skeniranje, PDF-om i dugmetom Povuci.
    • Predračuni i računi. Sve što je XPay izdao firmi, sa stanjem i PDF-om, na istoj stranici; koraci "Kako se dolazi do paketa" prepisani po novom toku, a polje za ključ ostaje za ključ koji stigne mailom.
    • /admin: predračun u spisku. Operater vidi oznaku Predračun i poziv na broj uz svaki otvoreni, pa uplatu potvrđuje po onom što piše na izvodu.

    0.76.164

    15. oktobar 2026.

    Novo

    • Narudžba paketa iz konzole, na serveru. Novi pozivi pod /v1/billing: cjenovnik u novcu firme (KM ili dinari) sa pet paketa i periodom mjesec ili godina (godina je dvanaest mjeseci bez popusta); ponuda prije narudžbe sa licencom, dodatkom za ugostiteljstvo po poslovnici sa stolovima, transakcijama preko uključenih od zadnjeg računa i, kod nadogradnje usred perioda, odbijenim neiskorištenim dijelom tekućeg perioda srazmjerno danima; Start, Business i Pro se naručuju, Flex i Enterprise su po dogovoru.
    • Predračun sa kodom za plaćanje. Narudžba pravi predračun u posebnoj seriji (PR-2026-0001) sa računom primaoca iz podešavanja servera, pozivom na broj sa kontrolnim ciframa kakav nijedna firma ne može imati, i istim kodom za bankovnu aplikaciju kakav nose fakture lokala; PDF i e-mail firmi. Jedan otvoren predračun u isto vrijeme, vlasnik ga može povući.
    • Uplata uključuje paket. Kad operater potvrdi uplatu predračuna u /admin, paket se mijenja, rok se pomjera, licencni ključ se izdaje kao i do sada, a iz predračuna se izdaje plaćen račun u seriji računa i šalje na e-mail. Početak, nadogradnja i produženje važe odmah; sniženje od isteka plaćenog perioda, što server primjenjuje sat po satu. Uključeni broj transakcija ostaje meka granica: ništa se ne gasi.

    0.76.163

    15. oktobar 2026.

    Novo

    • Drugi prenos pošte: HTTPS API provajdera. Uz SMTP, pismo može otići preko API-ja na portu 443, koji hosting ne filtrira i za koji ne treba PTR zapis: MAIL_TRANSPORT="resend" (ili postmark, brevo) i MAIL_API_KEY u .env, MAIL_FROM kao i do sada. Bez ključa sve ostaje na SMTP-u kao do sada, a dnevnik to kaže jednom. Isto pismo ide oba puta: tekst i HTML, adresa za odgovor, zaglavlja (List-Unsubscribe na obavijestima) i prilozi (PDF fakture). Jedan adapter po provajderu u apps/api/src/modules/mail/http-transport.ts, sa unit testovima na lažnom fetch-u: oblik zahtjeva, prilog u base64, id poruke, odbijen ključ, nepotvrđen pošiljalac, provajder koji ne odgovara.
    • Status i /admin kažu kojim putem pošta ide. Javna statusna stranica uz komponentu Pošta kaže kad ide preko HTTPS API-ja provajdera; Operater → E-mail uz "Šalje se sa" pokazuje prenos (SMTP, Resend, Postmark ili Brevo) i host, zadnji rezultat provjere ili slanja bilježi se za oba prenosa, a Pošalji probnu poruku ide aktivnim prenosom i u pismu kaže kojim.
    • Šta ostaje na vlasniku (docs/en/07-email.md, odjeljak "Over HTTPS"): izbor provajdera i ugovor, domena xpay.ba, a prije prve srpske poruke i xpay.rs, potvrđena kod provajdera sa SPF i DKIM zapisima koje on pokaže, i gdje se podaci drže: Brevo obrađuje u EU, Resend nudi EU regiju pri prijavi, Postmark obrađuje u SAD uz DPA i standardne ugovorne klauzule; provjeriti na stranici provajdera prije potpisa, jer se to mijenja. Ključ ide u .env na serveru i nigdje drugdje. .env.example i deploy/docker-compose.prod.yml nose nove postavke.

    0.76.162

    15. oktobar 2026.

    Ispravke

    • Udio grupe artikala sa zarezom. Lista "Grupe artikala" ispod najprodavanijih ispisivala je udio s tačkom ("86.2%") i poslije 0.76.158, koja je popravila samo listu artikala. Sada i grupe idu kroz isti zapis: "86,2%" na bosanskom i srpskom.

    0.76.161

    15. oktobar 2026.

    Ispravke

    • Brojevi na Statistici korištenja grupisani po naški. Narudžbe, računi i otvoreni meniji ispisivali su se kao "2,082" (engleski zarez za hiljade) pored iznosa "6.776,00 KM", jer je preglednik bez bosanskih podataka za Intl pao na engleski zapis. Brojevi sada idu kroz istu tabelu razdvajača kao količine u konzoli: "2.082" na bosanskom i srpskom, "2,082" na engleskom; skraćeni zapis ("12,3K") isto.

    0.76.160

    15. oktobar 2026.

    Ispravke

    • Odbijen licencni ključ objašnjen na jeziku konzole. Stranica Licenca prikazivala je rečenicu API-ja na engleskom ("That does not look like a licence key...") kad ključ nije prošao. API sada uz svako odbijanje šalje razlog (pogrešan oblik, nije ispravan, izdat drugoj firmi, istekao, stariji od važeće licence) i brojke uz njega, a konzola iz toga piše rečenicu na bosanskom, srpskom ili engleskom, sa brojem firme i datumima. API: POST /v1/license/redeem u error.details.reason vraća malformed_license, invalid_license, other_company, license_expired (sa expiresAt) ili superseded_license.

    0.76.159

    15. oktobar 2026.

    Ispravke

    • Stranica Za programere na Starteru više ne viče na engleskom. Pri svakom otvaranju gore se pojavljivala crvena traka "Plan STARTER does not include webhooks", jer stranica pita za webhook endpointe, a paket ih nema. Sada panel Webhook endpointi kaže na jeziku konzole da webhookovi dolaze s paketima Business, Pro i Enterprise, dugme Novi endpoint je isključeno, a API ključevi rade kao i do sada.

    0.76.158

    15. oktobar 2026.

    Ispravke

    • Udio artikla na Analitici sa zarezom. U listi najprodavanijih artikala udio u prometu ispisivao se s tačkom ("60.2%") pored iznosa sa zarezom; sada ide kroz isti zapis kao količine, pa je na bosanskom i srpskom "60,2%", a na engleskom "60.2%".

    0.76.157

    15. oktobar 2026.

    Ispravke

    • Stranica rezervacije gostu više ne tvrdi da je ostavio e-mail. Dok lokal ne odgovori, stranica je govorila "ostavili ste e-mail, stiže i tamo" i gostu koji e-mail nije upisao. Sada kaže "ako ste ostavili e-mail, stiže i tamo", kao što engleska verzija već kaže.

    0.76.156

    15. oktobar 2026.

    Ispravke

    • Prodavnici i fakturistu konzola više ne govori "gost" i "lokal". Na ekranima koje vidi svaka djelatnost, rečenice su bile pisane za restoran: "bez obzira čime je gost platio", "čim gost plati prvi račun", "sve što je objekat naplatio ... na stolu", naslov grupe "Lokal" u navigaciji, "neka gost skenira kod" pri pravljenju koda, "gost skenira kod" na kasi i pet koraka zaliha sa menijem i posluživanjem. Sada te rečenice biraju riječ po djelatnosti: kupac, poslovnica, prodavnica ili skladište, kasa umjesto stola, prodaja umjesto posluživanja. Ugostiteljski ekrani čitaju se kao i do sada.

    0.76.155

    15. oktobar 2026.

    Ispravke

    • Prodavnica, veleprodaja, usluge i fakturisti ne plaćaju dodatak za ugostiteljstvo. Dodatak od 49 KM po poslovnici brojao se po prekidaču "naručivanje za stolom", koji se može uključiti na bilo kojoj poslovnici; uključen na prodavnici, račun je rastao za prostoriju ekrana za naručivanje koje ta djelatnost i nema. Sada se broji samo poslovnica čija djelatnost (sa svojim izuzecima) nudi naručivanje za stolom i koja ga ima uključeno, isto na ekranu Transakcije i na mjesečnom računu. Unit test i provjera razlike u smoke-invoices.

    0.76.154

    15. oktobar 2026.

    Ispravke

    • Probni podaci: ispravne kontrolne cifre na IBAN-ima. Tri od četiri bankovna računa u probnim podacima imala su pogrešne kontrolne cifre, pa bi bankovna aplikacija odbila kod sa računa Studija Vrbas, Mrkve Ilidža i Željinog lokala; sada su ispravni. Produkcijski podaci nisu dirani.

    0.76.153

    15. oktobar 2026.

    Ispravke

    • Dnevno zaključenje broji račune, ne stolove. Pregled prije zaključenja pisao je "nijedan sto 587,10 KM" za lokal sa prometom preko banke i "1 sto" za prodavnicu bez stolova; broj zatvorenih računa sada se tako i zove: "nijedan račun", "1 račun", "2 računa".

    0.76.152

    15. oktobar 2026.

    Ispravke

    • Nepoznat status narudžbe u API-ju vraća 400, ne 500. Upit na tablu narudžbi sa statusom koji ne postoji (naprimjer "open") rušio se u bazi i vraćao grešku servera; sada odgovara 400 sa spiskom dozvoljenih statusa.

    0.76.151

    15. oktobar 2026.

    Ispravke

    • Izvodi: stanje izvora riječima, a ne šifrom. Uz svaki izvor pisalo je "ACTIVE"; sada piše "radi", "pauziran" ili "greška". Izvor ručnih potvrda, koji server pravi sam, zvao se "Manual confirmation" i na bosanskoj konzoli; sada se zove "Potvrde rukom iz konzole".

    0.76.150

    15. oktobar 2026.

    Ispravke

    • Dva odbijanja servera na jeziku konzole. "Pošalji kupcu" na serveru bez podešenog e-maila i "Izdaj" na poslovnici bez upisanog bankovnog računa javljali su englesku rečenicu servera; sada konzola kaže svojim riječima da e-mail nije podešen, odnosno da poslovnica nema račun i gdje se upisuje.

    0.76.149

    15. oktobar 2026.

    Ispravke

    • Količina na fakturi u zapisu čitaoca. Stavka od 2,5 sata pisala je "2.5" na pregledu fakture u konzoli i na stranici kupca, pored "60,00 KM"; sada piše "2,5" na bosanskom i "2.5" na engleskom, cijeli broj bez decimala, najviše tri decimale kako ih server i čuva. PDF je to već radio.

    0.76.148

    15. oktobar 2026.

    Promijenjeno

    • Početna xpay.rs: lista "Šta gost može" i odgovor "Da li XPay drži moj novac?" napisani su na srpskom umjesto da se bosanski tekst pretvara riječ po riječ pri svakom učitavanju. Gost "zove konobara", "plaća svoj deo", napojnicu "bira pre nego što se kod napravi".
    • Rečenice koje lokal u Srbiji kaže drugačije. Stranica cijena i kontakt su jedan izvor za oba sajta; rečenice koje u Srbiji ne stoje ni s promijenjenim samoglasnicima sada su napisane cijele u apps/web/src/content/serbia.ts i sajt ih kaže umjesto pretvorene bosanske: "Gost plaća tačno onoliko koliko piše na računu" (ne kupac), "Račun za sto i podela računa" (ne "stol"), Start "Za jedan lokal", Pro "Za više lokala", Enterprise "Lanci restorana i hoteli" (xpay.rs ne prodaje komunalnim preduzećima ni telekomima), opis Hospitality dodatka "za lokale u kojima se naručuje za stolom", završna traka "Spremni da sto sam naručuje i plaća? Pokažite gostima da dobra usluga ne mora da uključuje čekanje" i kontakt "Pokažimo vam kako XPay radi u vašem lokalu. Recite nam kakav je lokal i kako sada naplaćujete."
    • Test čuva izvor. Svaka takva rečenica je vezana za bosansku; test pada ako se bosanska promijeni a srpska ostane, i ako srpska spomene kupca, stol ili marku.

    0.76.147

    15. oktobar 2026.

    Novo

    • Stranica Hospitality na xpay.ba. Pod "Šta objekat dobija" šest novih stavki: meni na jeziku gosta (bosanski, srpski, engleski i sedam svjetskih jezika po poslovnici), uređivanje stolova i pozadina rasporeda, zalihe po izboru sa e-mailom kad artikal padne na minimum, receptura sa nabavnom cijenom i food costom, popis koji se zaključava sa teorijskom prema stvarnoj potrošnji i CSV-om za knjigovođu, i uloge na zalihama. Nova sekcija "Šta brojevi kažu da se uradi" nabraja Uvide (sedmični izvještaj na e-mail, meni po maržama, za provjeru, nabavka, raspored osoblja, ponude gostu, prijedlog recepture i opisa, prevod menija) i kaže da su u paketima Pro i Enterprise.
    • Početna xpay.rs, na srpskom: iste stavke pod "Za osoblje", napisane za Srbiju (gostu se nudi srpski i engleski, nikad bosanski), nova traka "Uvidi, u paketu Pro" i meni u zaglavlju sa stavkama Zalihe i recepture i Uvidi. Konzolne pločice na obje početne dobijaju Zalihe i Uvidi.
    • Stranica cijena (xpay.ba i xpay.rs u dinarima): Hospitality dodatak nabraja meni na jeziku gosta, zalihe, recepture i popis, i uređivanje stolova; u detaljnom poređenju paketa red "Uvidi" (Pro i Enterprise, po aiInsights u packages/shared) i grupa "Uz Hospitality dodatak" sa četiri reda, od kojih ponude gostu i prijedlozi iz Uvida traže Pro. Kartica Pro spominje Uvide.
    • Rječnik za srpski dobija njemački, ponedjeljkom, svjetskim, smiju, nalijevo i množinu prijedloga; konzolni katalog je ponovo izveden, pa Jezici gosta na srpskom kažu "nemački".

    0.76.146

    15. oktobar 2026.

    Ispravke

    • Broj QR kodova u toku na konobarskom ekranu u padežu. Umjesto "1 kod(ova) u toku" piše "1 kod u toku", "2 koda u toku", "5 kodova u toku"; isto i na engleskom.

    0.76.145

    15. oktobar 2026.

    Ispravke

    • Ekran "Konobar dolazi" zna kada je račun zatvoren. Gost koji je zatražio naplatu karticom ili gotovinom ostajao je na tom ekranu i poslije konobarove naplate, dok sam ne osvježi stranicu; ekran sada provjerava račun kao i ostali i, čim ga konobar zatvori, prelazi na zahvalu sa povratkom na meni.

    0.76.144

    15. oktobar 2026.

    Ispravke

    • Narudžba sa koraka "Želite li još nešto?" opet odlazi. Gost koji je iz korpe prošao kroz prijedloge i pritisnuo Pošalji dobijao je grešku umjesto narudžbe, jer je dugme slalo sam klik tamo gdje stranica očekuje stavke; sada šalje korpu kakva jeste, kuhinja je dobija i konobar je vidi na stolu.

    0.76.143

    15. oktobar 2026.

    Ispravljeno

    • Prevod na arapski, španski, turski i kineski nije se mogao snimiti iz obrasca jela: provjera na PATCH /v1/menu/items/:id primala je samo šest jezika iz 0.76.138 iako je 0.76.139 dodala još četiri. Sada prima svih deset; smoke provjera snima i arapski.
    • Zapamćeni jezik gosta se zaboravljao nakon ponovnog učitavanja kad je bio njemački ili neki drugi od novih jezika: pamćenje je prihvatalo samo bosanski, srpski i engleski. Sada pamti svaki jezik menija.
    • Prekidači "Šalji sedmični izvještaj na e-mail" i "Nudi gostu šta ide uz narudžbu" vidjeli su se samo kad izvještaj ima dovoljno podataka; sada su na stranici Uvidi i ispod praga, jer su podešavanja lokala, ne sedmice.
    • Decimale na Uvidima (narudžbi na sat, udio u procentima, prognoza porcija, najjači sat) ispisivale su se s tačkom; sada sa zarezom na bosanskom i srpskom. Dvije množine ispravljene ("1 stavka je izostavljena", "8 sedmica").
    • Dugmad uz naziv kategorije na Meniju (slika, uredi, obriši) nisu stala u 375 px i panel ih je odsijecao; sada se prelamaju u novi red.

    0.76.142

    15. oktobar 2026.

    Ispravke

    • Početno stanje ima cijenu dana. Artikal dodan sa nabavnom cijenom dobijao je zapis cijene trenutak poslije zapisa početnog stanja, pa je kartica početnu količinu vrednovala po sadašnjoj cijeni i javljala "1 kretanje bez cijene dana". Zapis početnog stanja i prvi zapis cijene sada nose isti trenutak, pa se početno stanje vrednuje po cijeni s kojom je artikal dodan. Smoke dodaje artikal sa cijenom i provjerava da ništa ne pada na sadašnju cijenu.

    0.76.141

    15. oktobar 2026.

    Ispravke

    • Početno stanje se ne računa kao višak. Količina upisana pri dodavanju artikla upisuje se kao popis, pa ju je izvještaj "Teorijska prema stvarnoj potrošnji" prikazivao kao višak po popisu (artikal dodan sa 10 kg je odmah imao višak 10). Izvještaj sada prepoznaje taj zapis po njegovoj napomeni ("Početno stanje") i ne broji ga ni u manjak ni u višak; u knjigovodstvenom izvozu i na kartici ostaje kao popis, jer tu i pripada. Unit test to drži.

    0.76.140

    15. oktobar 2026.

    Ispravke

    • Prekidač Vođenje zaliha vidi samo menadžer. Osoblju kojem poslovnica dozvoli pregled Zaliha prikazivao se i prekidač za isključivanje vođenja zaliha, koji server odbija; sada osoblje vidi samo rečenicu, prekidač ostaje vlasniku i menadžeru.
    • Novi popis traži bar jedan artikal. Dugme je bilo aktivno i na praznoj polici, pa je otvaralo popis bez ijednog reda; sada čeka prvi artikal.
    • "Sačuvano." se ne zadržava poslije zaključavanja. Poruka o snimljenom prebrojanom ostajala je u prozoru i kad je popis zaključan; zaključan popis kaže svoje i poruka se briše.

    0.76.139

    15. oktobar 2026.

    Novo

    • Jezici gosta po poslovnici. Na stranici Meni, panel Jezici gosta: uz bosanski, srpski i engleski lokal uključuje njemački, italijanski, francuski, španski, turski, arapski i kineski (tradicionalni) za svoju poslovnicu (podešavanje guestLanguages, PATCH /v1/locations/:id). Podrazumijevano kao do sada: BiH bosanski, srpski i engleski; Srbija srpski i engleski, bez bosanskog. Jezik lokala je uvijek uključen.
    • Gostova stranica nudi samo uključene jezike u postojećem izboru jezika; nazivi i opisi jela i kategorija dolaze iz prevoda na izabranom jeziku. Dugmad i poruke postoje na bosanskom, srpskom i engleskom, pa gost na njemačkom ili drugom jeziku dobija dugmad na engleskom i meni na svom jeziku. Arapski se čita zdesna nalijevo samo na dijelu menija.
    • Telefon na njemačkom dobija njemački sam, kad je uključen: na stranici kroz postojeće pregovaranje jezika, a meni za gosta (GET /v1/t/:slug/menu) čita i Accept-Language kad stranica ne kaže jezik, pa prvi jezik telefona koji lokal nudi dobija prevedene nazive; inače kao do sada. Prevedi meni prevodi na sve uključene jezike (isti limit), a obrazac jela ima polja za svaki uključeni jezik.
    • Smoke provjera uključi njemački na probnoj poslovnici, upiše njemački naziv jednom jelu, provjeri da telefon sa Accept-Language de dobija njemački naziv a francuski original, pa vrati podešavanje.

    0.76.138

    15. oktobar 2026.

    Novo

    • Prevodi za gosta. Jelo i kategorija nose naziv i opis na jezicima koje gost može izabrati (translations po jeziku: u BiH srpski i engleski, u Srbiji engleski; njemački, italijanski i francuski su predviđeni u strukturi, ali se gostu još ne nude, issue #9). Meni za gosta (GET /v1/t/:slug/menu?lang=) vraća naziv i opis na jeziku koji je gost izabrao kad prevod postoji, inače original; gostova stranica traži meni na svom jeziku i ponovo kad gost promijeni jezik. U obrascu jela su polja za ručni prevod naziva i opisa po jeziku (PATCH /v1/menu/items/:id sa translations; prazno vraća gosta na original), i kategorija prima isto.
    • Prevedi meni (Meni, vrh stranice, paket Pro): model prevede sve stavke i kategorije bez prevoda odjednom, u turama po 40; već prevedeno se ne dira, pa se nakon novog jela prevodi samo ono. Najviše 5 puta dnevno po poslovnici (POST /v1/insights/translate). Naziv jela ostaje naziv (ćevapi, burek), brend i mjesto se ne prevode.
    • Predloži opis u obrascu jela (paket Pro): model iz naziva, kategorije i recepture napiše jednu do dvije rečenice bez izmišljanja sastojaka, bez cijene, alergena i superlativa; vlasnik pročita, doradi i snimi. Najviše 60 dnevno po poslovnici (POST /v1/insights/describe). Bez ključa oba dugmeta kažu da nisu dostupna. Smoke provjera pokriva odbijanja, ručni prevod, meni za gosta na engleskom i vraćanje na zatečeno.

    0.76.137

    15. oktobar 2026.

    Novo

    • Uvezi recepture na stranici Meni. Dugme otvara uvoz CSV fajla sa kolonama Jelo (naziv iz menija ili id), Artikal zaliha (šifra sa Zaliha ili naziv), Količina po porciji i Kalo %. Tačka-zarez, zarez ili tab, UTF-8 sa ili bez BOM-a, nazivi kolona na bosanskom ili engleskom. Redovi jednog jela su njegova cijela receptura i zamjenjuju postojeću; red sa jelom bez artikla se preskače, pa šablon može ostati kakav jeste gdje recepture još nema. Excel (xlsx) se snima kao CSV: čitač xlsx-a nije u sistemu, i uputstvo to kaže.
    • Prvo pregled, pa upis. Fajl se prvo pročita: koliko redova, koja jela su prepoznata i šta bi se promijenilo (nova receptura, mijenja se, već isto), koje kolone se preskaču, i svaki problem po redu (jelo nije u meniju, artikal nije na Zalihama, dva jela ili dva artikla istog imena, količina ili kalo nisu broj, isti sastojak dva puta). Dok ima ijedan problem ništa se ne upisuje, ni dobri redovi. Upis ide kroz isto mjesto kao obrazac jela, pa važe uloga Receptura po poslovnici i sva pravila.
    • Šablon sa vašim jelima. Preuzimanje daje CSV sa svim jelima, po red za svaki sastojak gdje receptura postoji i prazan red gdje je nema; police sa šiframa su u prozoru uvoza.
    • API: POST /v1/menu/recipes/import (csv, preview), GET /v1/menu/recipes/template.csv; oba za menadžera uz menu:write.

    0.76.136

    15. oktobar 2026.

    Novo

    • Izvještaj na e-mail. Kad se sedmični izvještaj napravi (ponedjeljkom u šest, ili pri prvom otvaranju), pismo ide na kontakt e-mail firme: rečenice izvještaja (kad ih model napiše, inače napomena da nisu napisane), brojevi sedmice naspram prosjeka prethodne tri, preporuke kao redovi sa pouzdanošću i rečenicom modela uz svaku, stavke za provjeru samo kao broj bez imena, i link na stranicu Uvidi gdje su dugmad Primijeni. Na jeziku države poslovnice: bosanski u BiH, srpski (ekavica) u Srbiji. Jednom po poslovnici i sedmici (sentAt na izvještaju), ne ispod praga podataka, ne bez adrese i ne kad slanje e-maila nije podešeno; pismo koje ne ode ne ruši izvještaj.
    • Prekidač po firmi "Šalji sedmični izvještaj na e-mail" na stranici Uvidi, uključen dok ga vlasnik ne isključi (POST /v1/insights/mail, Merchant.weeklyReportMail). Stranica kaže kuda pismo ide, da li je slanje podešeno i kad je ove sedmice poslano. Smoke provjera pokriva prekidač i vraćanje na zatečeno.

    0.76.135

    15. oktobar 2026.

    Ispravke

    • Marža na Uvidima uključuje kalo. Meni po maržama čitao je recepturu bez kala, pa je nabavna cijena porcije tamo bila niža nego u meniju i na Zalihama. Sada ide kroz isto mjesto (recipe-waste.ts) kao i ostatak sistema, pa su marža u meniju, food cost i Uvidi jedna brojka.
    • Prognoza nabavke kupuje bruto količinu. Lista za nabavku množi prognozirane porcije količinom uvećanom za kalo, tačno onom koju prodaja skida sa police, pa 80 kafa po 7 g uz 10 % kala traži 616 g, ne 560 g. Unit testovi drže oboje.

    0.76.134

    15. oktobar 2026.

    Novo

    • Svaka promjena nabavne cijene ostaje zapisana. Ručni upis, prijemnica koja ponovo računa prosjek i preračun iz sastava poluproizvoda upisuju red sa cijenom prije i poslije, izvorom, brojem dokumenta kad ga ima, ko i kada. Artikal i dalje nosi samo sadašnju cijenu; historija je ono što omogućava da se kilogram prodan u martu vrednuje po martovskoj cijeni.
    • Kartica artikla po cijeni dana. U prozoru Historija prijem, prodano, otpis, povrat, popis i proizvodnja se vrednuju po nabavnoj cijeni koja je važila kad se kretanje desilo, a početno i krajnje stanje po cijeni na početku i na kraju perioda. Zaglavlje pokazuje zadnje tri promjene cijene (iznos, datum, izvor, prije). Kretanje starije od historije računa se po sadašnjoj cijeni i kartica kaže koliko ih je.
    • API: GET /v1/stock/:id/movements u summary vraća costChanges (zadnje tri, najnovija prva, sa before, after, source, reference, at), valuedAt: day i atFallback. Nova tabela promjena cijene sa izvorom TYPED, RECEIPT ili COMPONENTS.

    0.76.133

    14. oktobar 2026.

    Novo

    • Gostov telefon nudi šta ide uz narudžbu. Uz jelo u korpi, na izlazu iz korpe, meni ponudi ono što se u tom lokalu najčešće naručuje uz njega: parovi iz sedmičnog izvještaja (zajedničke narudžbe, najmanje 10 narudžbi, iz zadnjeg izvještaja sa dovoljno podataka), po dva partnera za svako jelo, u oba smjera (kafa nudi kroasan, kroasan nudi kafu). Ponuda ide ispred postojećih prijedloga po kategoriji i kroz isti mehanizam: nikad jelo koje je već u korpi, koje je rasprodato ili koje traži izbor.
    • Samo kad lokal uključi, samo u paketu Pro. Prekidač na stranici Uvidi, sekcija Preporuke gostu (POST /v1/insights/guest-suggestions, podešavanje guestSuggestions po poslovnici, isključeno dok se ne uključi). Meni za gosta (GET /v1/t/:slug/menu) nosi parove kao listu id-ova; telefon prikaže jelo iz menija koji već ima, pa modelu i gostu ne ide ništa osim onoga što meni već pokazuje. Smoke provjera pokriva prekidač, parove u meniju za gosta i vraćanje na zatečeno stanje.

    0.76.132

    14. oktobar 2026.

    Novo

    • Sastav artikla. Na Zalihama uz artikal dugme Sastav: od čega se pravi jedna jedinica (litar sosa je 0,8 kg paradajza i 0,1 l ulja), sastojci iz iste poslovnice. Nabavna cijena takvog artikla se računa iz sastojaka čim svi imaju cijenu i mijenja se sama kad sastojak poskupi, pa ulazi u recepture jela kao i svaka druga. Ručni upis cijene na takav artikal je odbijen: cijena se mijenja na sastojcima. Artikal ne može biti sastojak samog sebe, ni posredno.
    • Proizvedeno. U prozoru Promjena, za artikal koji ima sastav, razlog Proizvedeno: upiše se koliko je napravljeno, poluproizvod poraste, a sastojci se skinu u istoj transakciji, svaki sa zapisom koji imenuje šaržu. Obrazac unaprijed kaže šta će se skinuti. Uloga je Popis i prijem.
    • Izvještaji. Knjigovodstveni izvoz i kartica artikla dobijaju kolonu Proizvedeno (+/-), izvještaj potrošnje kolonu Proizvodnja (+/-): plus na polici poluproizvoda, minus na policama sastojaka. Proizvodnja se ne računa u stvarnu potrošnju, jer roba nije otišla nego promijenila policu.
    • API: GET i PUT /v1/stock/:id/components (lista sastojaka sa količinom po jedinici, uloga recipes, odbijanja component_cycle, component_unknown, duplicate_component); PATCH /v1/stock/:id sa cost na artikal sa sastavom odgovara 409 cost_from_components; POST /v1/stock/:id/movements prima reason: PRODUCED sa pozitivnom količinom (no_components za kupovni artikal); lista zaliha vraća madeFrom i costSource. Nova tabela sastojaka i vrijednost PRODUCED u razlozima.

    0.76.131

    14. oktobar 2026.

    Novo

    • Sekcija "Raspored osoblja" na stranici Uvidi. Iz prosječnih narudžbi po satu za svaki dan u sedmici (zadnje četiri sedmice) preporučeni broj konobara po smjeni i danu: dan se dijeli na dvije smjene na sredini radnog vremena (jedna smjena kad lokal radi devet sati ili manje), smjena traži onoliko konobara koliko njen najjači sat traži, nikad manje od jednog, uz najjači sat i broj narudžbi u njemu i pouzdanost po broju sedmica i narudžbi.
    • Pretpostavka koju vlasnik mijenja: koliko narudžbi na sat nosi jedan konobar. Podrazumijevano iz podataka lokala (koliko je jedna osoba nosila u najjačim satima, kad narudžbe kažu ko ih je uzeo), inače 20. Polje na stranici preračuna raspored dok se kuca (GET /v1/insights?waiterLoad=), Sačuvaj pamti vrijednost na poslovnici (POST /v1/insights/staffing, null je vraća na podrazumijevano); vrijednost je ograničena na 5 do 80.
    • Modelu ide najjači sat po danu, bez imena. Izvještaj iz prethodne verzije se jednom ponovo izračuna. Smoke provjera pokriva raspored, probanje vrijednosti bez snimanja, snimanje, odbijanje i vraćanje.

    0.76.130

    14. oktobar 2026.

    Novo

    • Sekcija "Nabavka za sedmicu" na stranici Uvidi. Za sedam dana poslije sedmice izvještaja, prognoza porcija po jelu i po danu u sedmici iz prodaje zadnjih do osam sedmica (novije sedmice vrijede više, isti rez jednokratnih velikih narudžbi, jelo skinuto s menija se ne prognozira), sa pouzdanošću po broju sedmica u kojima se jelo prodavalo. Preko receptura prognoza se pretvara u potrebne količine po artiklu zaliha, umanjuje za stanje i daje kao lista: artikal, treba, na stanju, naručiti, nabavna cijena i vrijednost naručenog po njoj, broj jela koja ga troše. Lista postoji samo gdje poslovnica vodi zalihe; prognoza porcija i inače. Stranica kaže koliko artikala za naručiti nema nabavnu cijenu i koliko prognoziranih jela nema recepturu.
    • CSV lista za nabavku: GET /v1/insights/purchase.csv i dugme Preuzmi CSV, u istom obliku kao ostale datoteke (tačka-zarez, BOM, decimalni zarez), nazvana Nabavka-datum.csv.
    • Modelu idu ukupne očekivane porcije, prvih pet jela i vrijednost liste, samo izračunato. Izvještaj iz prethodne verzije se jednom ponovo izračuna. Smoke provjera pokriva sedam dana prognoze, listu i datoteku.

    0.76.129

    14. oktobar 2026.

    Novo

    • Kalo % uz svaki sastojak. U obrascu jela, uz količinu po porciji, upisuje se kalo u procentima (0 do 90). Sedam grama kafe uz 10 % kala skida 7,7 g sa police i košta koliko 7,7 g; obrazac to uračunava u nabavnu cijenu porcije dok se kuca.
    • Jedno mjesto za račun. Skidanje pri prodaji, nabavna cijena porcije i provjera koliko porcija polica još pokriva računaju količinu uvećanu za kalo iz istog mjesta, sa jednim zaokruživanjem na kraju: 7,7 g se piše kao 8 kad se skida jedna porcija, a dvije porcije kao 15, pa se polica i marža slažu.
    • API: PUT /v1/menu/items/:id/stock prima wastePercent po stavci (cijeli broj 0 do 90, podrazumijevano 0); jelo vraća wastePercent i grossQuantity uz svaku stavku. Migracija dodaje wastePercent na vezu jela i artikla.

    0.76.128

    14. oktobar 2026.

    Novo

    • Sekcija "Za provjeru" na stranici Uvidi. Neobični brojevi sedmice prema uobičajenom u samom lokalu (prethodne tri sedmice), po osobi ili po stolu, uvijek kao stavka za provjeru i nikad kao optužba: brojevi kažu šta, razlog pita vlasnik. Prati se neobično mnogo otkazanih narudžbi, računi naplaćeni manje nego što je naručeno, računi zatvoreni kao neplaćeni, računi zatvoreni bez ijedne narudžbe, popusti iznad uobičajenog (razlika cjenovnika i naplaćenog po narudžbi) i otpisi na zalihama iznad uobičajenog sedmičnog iznosa po nabavnoj cijeni (za lokal i po osobi koja ih je zapisala). Stavka se pojavi tek kad je sedmica najmanje dvostruko iznad uobičajenog i kad brojeva ima dovoljno (jedna otkazana runda nije uzorak), sa pouzdanošću i brojevima na kojima počiva. Osoba se imenuje samo kad je zabilježena osoba; zajednički uređaj (tablet na šanku, ekran u kuhinji) nikad se ne prikazuje kao osoba. Ista granica podataka kao i ostatak izvještaja.
    • Modelu idu samo brojevi stavki po vrsti, nikad imena; rečeno mu je da o njima piše kao o stvarima za provjeru. Izvještaj iz prethodne verzije se pri otvaranju jednom ponovo izračuna da dobije sekciju. Smoke provjera pokriva oblik stavki i da uređaj nije osoba.

    0.76.127

    14. oktobar 2026.

    Ispravljeno

    • Zalihe za osoblje. Kad poslovnica dozvoli osoblju pregled, ekran je prikazivao i dugmad Dodaj artikal, cijenu i Novi popis, i sve razloge promjene, a server ih je odbijao. Sada osoba vidi samo ono što smije po ulogama iz Postavki: popis, prijem i prodaju samo ako smije popis, otpis i povrat samo ako smije otpis, a dodavanje artikla i cijene ostaju menadžeru.

    0.76.126

    14. oktobar 2026.

    Novo

    • Meni po maržama na stranici Uvidi. Iz prodaje u četiri sedmice (porcije po jelu, poslije istog reza jednokratnih velikih narudžbi) i nabavne cijene porcije (receptura kad je potpuna, inače upisana procjena) svako jelo sa poznatom cijenom ide u jednu od četiri grupe: zvijezde (prodaju se i zarađuju), konji za vuču (prodaju se, slaba marža), zagonetke (zarađuju, slabo se prodaju) i psi. Granica popularnosti je 70% prosječnog udjela u prodaji, granica marže prosječna marža po porciji ponderisana prodajom. Četiri kvadranta sa brojem jela, tabela sa porcijama, udjelom, maržom i porijeklom cijene, i posebna lista jela bez nabavne cijene sa pozivom da se upiše. Jelo čija je cijena procjena je tako i označeno.
    • Preporuke po grupi, sa pouzdanošću i brojevima na kojima počivaju: zagonetka na vrh kategorije i u ponudu uz druge narudžbe (Primijeni to i uradi), konj za vuču na cijenu koja ga dovodi na prosječnu maržu (najviše 15% više, Primijeni uz potvrdu), pas s menija (Primijeni uz potvrdu; vraća se na Meniju jednim klikom). Pouzdanost zavisi od udaljenosti od obje granice i broja porcija; jelo sa procjenom umjesto recepture nikad nije visoke pouzdanosti. Model o grupama piše samo iz izračunatog.
    • Predloži recepturu na obrascu jela, u dijelu Skida se sa zaliha: model iz naziva i opisa jela i liste zaliha (naziv i jedinica) predloži šta porcija skida i koliko. Prijedlog je procjena koju vlasnik pregleda i tek snimanjem jela potvrdi; ništa se ne upisuje samim pitanjem. Bez ključa dugme kaže da nije dostupno; izvan paketa Pro da je dio tog paketa. Najviše 30 prijedloga dnevno po poslovnici (nova tabela InsightUsage).
    • API: POST /v1/insights/recipe-suggestion (vlasnik ili menadžer, Pro); GET /v1/insights sada nosi i meni po maržama, a izvještaj iz prethodne verzije se jednom ponovo izračuna da ga dobije. Smoke provjera pokriva kvadrante, lista bez cijene i odbijanja prijedloga recepture.

    0.76.125

    14. oktobar 2026.

    Novo

    • Zaglavlje u prozoru Historija. Izbor perioda kao u analitici (danas, jučer, 7 dana, 30 dana ili po datumima; podrazumijevano 30 dana) i sedam polja: početno stanje, prijem, prodano, otpis, povrat, popis sa predznakom i stanje na kraju, svako sa količinom i vrijednošću po sadašnjoj prosječnoj nabavnoj cijeni. Ispod je historija samo za taj period. Cijena sa svake prijemnice ostaje na njenom redu.
    • API: GET /v1/stock/:id/movements?from=&to=&limit= vraća summary (period, valuta, količine i vrijednosti po razlogu, nabavna cijena, vrijednost stanja na kraju) uz data; bez datuma data je kao do sada, a kartica pokriva cijelo vrijeme.

    0.76.124

    14. oktobar 2026.

    Novo

    • Novi popis na Zalihama. Dugme "Novi popis" otvara popis sa svim aktivnim artiklima poslovnice i stanjem u tom trenutku. Prebrojano se upisuje uz svaki artikal i čuva, može i u više navrata dok je popis otvoren; ekran pokazuje stanje pri otvaranju, sadašnje stanje, prebrojano i razliku, i zbir manjka i viška po nabavnoj cijeni. Jedan otvoren popis po poslovnici: drugi klik vodi na otvoreni.
    • Zaključavanje uz potvrdu. "Zaključaj popis" traži potvrdu, pa za svaki prebrojani artikal upiše popis (manjak ili višak) prema stanju u tom trenutku, a ne pri otvaranju, da prodaja za vrijeme popisa ne postane manjak. Artikal bez prebrojane količine ostaje kakav jeste. Popis dobija datum i ime onoga ko je zaključao i više se ne mijenja; razlika se vrednuje po nabavnoj cijeni koju je artikal imao pri otvaranju.
    • Lista popisa. Ispod zaliha su prošli popisi sa datumom, ko je zaključao, koliko je artikala prebrojano i manjak u novcu; otvoreni se nastavlja, zaključeni se gleda. Brzi popis jednog artikla pod Promjena ostaje.
    • API: POST /v1/stock/stocktakes (locationId, note), GET /v1/stock/stocktakes?locationId=, GET /v1/stock/stocktakes/:id, PATCH /v1/stock/stocktakes/:id/lines (prebrojano po artiklu, null briše), POST /v1/stock/stocktakes/:id/close; zaključen popis odgovara sa 409 stocktake_closed, drugi otvoreni sa 409 stocktake_open. Uloga je stocktake iz podešavanja poslovnice, pregled view.

    0.76.123

    14. oktobar 2026.

    Novo

    • Podešavanje po poslovnici. U Postavkama, pod Vođenje zaliha, uz prekidač svaka poslovnica ima četiri izbora: Otpis i povrat, Popis i prijem (uključuje i ručno upisanu prodaju), Receptura (veza jela sa policom) i Pregled. Prva tri biraju Vlasnik, Menadžer ili Osoblje, a Pregled Menadžer ili Osoblje. Podrazumijevano je Menadžer za sve, kako je bilo do sada, pa ko ne otvori podešavanje ne primjećuje promjenu.
    • Server odlučuje po podešavanju, ne po ruti. Ko nema potrebnu ulogu dobija odbijanje sa razlogom stock_role i imenom radnje; dodavanje i izmjena artikla ostaju za menadžera. Osoblje vidi stavku Zalihe u navigaciji tek kad mu neka poslovnica dozvoli pregled.
    • Osoblje može dobiti prijavu na konzolu. Dodavanje člana prima i ulogu Osoblje; takva prijava vidi ono što joj podešavanja dozvole.
    • API: PATCH /v1/locations/:id prima stockRoles sa ključevima writeOff, stocktake, recipes i view, a poslovnica ih vraća; /v1/merchant vraća stockView. Zalihe, kretanja, izvještaji i PUT /v1/menu/items/:id/stock propuštaju osoblje do provjere po podešavanju; POST /v1/merchant/members prima role: STAFF.

    0.76.122

    14. oktobar 2026.

    Novo

    • Panel "Teorijska prema stvarnoj potrošnji" na Zalihama. Za izabrani period (danas, jučer, 7 dana, 30 dana ili po datumima, kao u analitici), po artiklu: prodano kroz XPay (teorijska potrošnja), otpis, manjak i višak po popisu, stvarna potrošnja (prodano plus otpis plus manjak), razlika u jedinicama i razlika u novcu po prosječnoj nabavnoj cijeni. Na dnu je zbir razlike u valuti poslovnice, podijeljen na otpis i manjak, i broj artikala bez nabavne cijene, koji se računaju kao nula. Višak i povrat dobavljaču se vide, ali se ne računaju u potrošnju. Svaki popis se broji za sebe, pa se manjak iz prve sedmice i višak iz treće ne poništavaju.
    • CSV istog izvještaja. Dugme CSV uz izbor perioda; isti oblik kao knjigovodstveni izvoz (BOM, tačka-zarez, decimalni zarez).
    • API: GET /v1/stock/consumption?locationId=&from=&to= vraća redove, valutu i zbir; GET /v1/stock/consumption.csv isto kao fajl. Datumi su kalendarski dani u zoni poslovnice, bez njih je danas.

    0.76.121

    14. oktobar 2026.

    Novo

    • Vođenje zaliha se uključuje i isključuje po poslovnici. Prekidač je na vrhu ekrana Zalihe i u Postavkama (odjeljak Vođenje zaliha). Uključeno: vlasnik unese artikle koje ima i količine, prodaja ih skida sama, a narudžba se provjerava prema polici. Isključeno: nema ekrana Zalihe, ništa se ne provjerava pri narudžbi i ništa se ne skida pri prodaji, pa lokal koji ne želi da vodi zalihe nema ni jedan ekran viška. Ostalo što poslovnica radi (naručivanje, stolovi, kasa) ostaje kako jeste.
    • E-mail kad artikal padne na minimum. Kad prijem, prodaja, otpis ili popis spusti artikal sa iznad minimuma na minimum ili ispod, firma dobija e-mail sa nazivom artikla, stanjem i minimumom, na jeziku države poslovnice. Jednom po padu, ne po svakoj prodaji: sljedeće obavještenje stiže tek kad prijem podigne artikal iznad minimuma pa opet padne.
    • API: PATCH /v1/locations/:id prima stockTracking, a poslovnica vraća stockTracking uz capabilities.

    0.76.120

    14. oktobar 2026.

    Novo

    • Stranica Uvidi u konzoli, pod Analitikom, za vlasnika i menadžera. Jednom sedmično, za zadnju punu sedmicu (ponedjeljak do nedjelja), uz četiri sedmice iza nje: promet po danu i satu, najprodavanije i najslabije stavke, šta se naručuje zajedno u kom dijelu dana, prazni sati, prosječan račun. Brojeve računa XPay, determinističkim upitima; model nikad ne pravi broj.
    • Preporuke sa oznakom pouzdanosti (visoka, srednja, niska) i rečenicom na čemu se zasniva svaka: paket za dva artikla koja gosti naručuju zajedno (npr. kafa i kroasan ujutro, sa predloženom cijenom 10% ispod zbira), happy hour u satima kad je lokal prazan (20% popusta na cijeli meni u tim satima, na danima kad je prazno), i jelo koje pada iz sedmice u sedmicu. Dugme Primijeni stavlja paket u meni kao novu stavku u kategoriji prvog artikla, a happy hour kao postojeće pravilo cijene; primijenjeno ostaje označeno.
    • Pragovi podataka. Ispod četiri sedmice i 200 zatvorenih računa izvještaj kaže "Potrebno je još podataka" i koliko fali. Jedna narudžba od 22 porcije ne pravi trend: količina na liniji se broji najviše do trostruke uobičajene linije tog jela, a parovi se broje po narudžbama, ne po porcijama.
    • Tekst izvještaja, pet do sedam rečenica i po jedna ili dvije uz svaku preporuku, na jeziku konzole (bosanski, srpski, engleski), piše model Claude iz izračunatih brojeva. Modelu idu samo zbirni brojevi i nazivi jela, nikad pojedinačni računi, gosti ni osoblje. Bez ključa (ANTHROPIC_API_KEY u .env) modul radi bez proze: brojevi i preporuke su tu, a stranica kaže da tekst nije napisan.
    • Pitanja običnim jezikom nad istim brojevima ("zašto je subota bila slabija"), najviše 20 dnevno po poslovnici.
    • Jednom sedmično, keširano. Izvještaj se pravi ponedjeljkom u šest za svaku poslovnicu na paketu koji ga ima, ili pri prvom otvaranju, i čuva se po poslovnici i sedmici (nova tabela InsightReport); vlasnik ga može ponovo izračunati najviše jednom dnevno.
    • Paket. Novi feature flag aiInsights u paketima: Pro i Enterprise ga imaju. Ostali na stranici vide šta modul daje i dugme za prelazak na paket.
    • API /v1/insights (izvještaj), /v1/insights/refresh, /v1/insights/ask, /v1/insights/apply, sve za vlasnika ili menadžera. Nova smoke provjera scripts/smoke-insights.mjs pokriva ogradu po paketu, prag podataka, keširanje, dnevni limit i odbijanja; agregati, pravila i priprema teksta za model imaju unit testove.

    0.76.119

    14. oktobar 2026.

    Novo

    • Izvoz za knjigovodstvo na Zalihama. Dva dugmeta ispod tabele: ovaj mjesec i prošli mjesec. Fajl ima red po artiklu: šifra, naziv, jedinica, početno stanje, ulaz (prijem), izlaz (prodaja), otpis, vraćeno dobavljaču, popis sa predznakom (manjak minus, višak plus), stanje na kraju, prosječna nabavna cijena i nabavna vrijednost stanja na kraju. Arhivirani artikal koji se u periodu kretao je na spisku, jer je u tom mjesecu bio roba.
    • Isti oblik kao fajl prometa. UTF-8 sa oznakom redoslijeda bajtova, tačka-zarez između kolona, decimalni zarez, CRLF, da se otvori u Excelu na računaru podešenom za našu regiju bez ikakvog uvoza.
    • Računa se unazad iz današnjeg stanja. Stanje na kraju perioda je današnje stanje umanjeno za sve što se desilo poslije perioda, a početno stanje je krajnje umanjeno za promet u periodu, pa se fajl do hiljaditog dijela slaže sa historijom artikla.
    • API: GET /v1/stock/export.csv?locationId=&from=&to=; datumi su kalendarski dani u zoni poslovnice, bez njih je danas, najviše 400 dana.

    0.76.118

    14. oktobar 2026.

    Novo

    • Razlog uz otpis i povrat. U prozoru Promjena, pod Otpis i Vraćeno dobavljaču, napomena postaje obavezna i polje to kaže (razbijeno, pokvareno, istekao rok; pogrešna isporuka, oštećeno). Dugme Zapiši čeka dok se razlog ne upiše. Prijem, prodaja i popis ostaju kao do sada: prijem ima svoj dokument, prodaja svoj račun, a popis je sam sebi objašnjenje.
    • Kartica artikla kaže zašto. U historiji se otpis i povrat čitaju kao "Otpis: vreća pukla", pa se mjesec kasnije ne nagađa šta se desilo sa robom koja je otišla, a nije prodana.
    • API: POST /v1/stock/:id/movements uz reason: WASTED ili RETURNED bez note odgovara sa 400 i reason: note_required, field: note. Prazna napomena od samih razmaka je isto što i nikakva.

    0.76.117

    14. oktobar 2026.

    Novo

    • Prijemnica. U prozoru Promjena, pod Prijem, upisuju se dobavljač, broj otpremnice ili fakture, nabavna cijena po jedinici (bez PDV-a, prije rabata) i rabat u procentima. Sve ostaje na zapisu, pa historija artikla za svaki prijem kaže ko je dostavio, po kom dokumentu i po kojoj cijeni.
    • Prosječna ponderisana nabavna cijena. Prijem sa cijenom ponovo računa nabavnu cijenu artikla: staro stanje po staroj cijeni i primljeno po novoj (neto, poslije rabata), podijeljeno sa ukupnom količinom. Dvanaest kilograma po 10,00 KM i šest po 19,00 KM je osamnaest po 13,00 KM. Receptura jela i marža odmah računaju sa novom cijenom. Artikal koji nije imao cijenu, ili mu je stanje nula ili manje od nule, dobija cijenu sa prijemnice. Prijem bez cijene ne dira nabavnu cijenu.
    • API: POST /v1/stock/:id/movements uz reason: RECEIVED prima supplier, document, unitCost i discountPercent; unitCost i rabat na drugom razlogu su odbijeni. GET /v1/stock/:id/movements vraća supplier, document, unitCost, discountPercent i netUnitCost.

    0.76.116

    14. oktobar 2026.

    Novo

    • Nabavna cijena po jedinici na Zalihama. Uz artikal se upisuje koliko košta jedna jedinica (kilogram kafe, litar mlijeka, flaša piva), bez PDV-a. Kolona je u tabeli, polje u obrascu za novi artikal i u prozoru za cijenu.
    • Nabavna cijena porcije iz recepture. Jelo koje skida sa zaliha (0,007 kg kafe i 0,05 l mlijeka) dobija nabavnu cijenu porcije sabranu iz tih sastojaka i njihovih cijena, uz food cost u procentima (nabavna cijena kroz prodajnu). Kad kafa poskupi, poskupi i svaka porcija koja je troši, bez diranja jela. Receptura se računa samo kad svaki sastojak ima cijenu; dok nema, obrazac imenuje koje police još treba upisati.
    • Procjena ostaje. Ručno upisana nabavna cijena jela i dalje važi kao procjena dok receptura nije potpuna, a marža u meniju kaže iz čega je: "iz recepture, food cost X %" ili "procjena, upisana ručno". Kad receptura postane potpuna, ona ima prednost, a upisani iznos ostaje sačuvan.
    • U obrascu jela se nabavna cijena porcije i food cost vide dok se sastojci upisuju, prije snimanja.
    • API: POST i PATCH /v1/stock primaju cost; artikal, izbor polica (/v1/stock/choices) i svaka veza jela vraćaju cost; jelo vraća costSource (recipe ili estimate), costTyped i foodCostPercent, a cost i marža su iz recepture kad je potpuna.

    0.76.115

    14. oktobar 2026.

    Novo

    • Uređivanje stolova sa ekrana Stolovi. Vlasnik i menadžer na ekranu Stolovi imaju dugmad "Uredi raspored" (vodi na uređivač prostorije) i "Uredi stolove": dodavanje stolova, promjena naziva klikom na naziv (kod i naljepnica ostaju isti), i označavanje više stolova odjednom pa brisanje ili povlačenje jednim klikom. Osoblje ta dugmad ne vidi, a server ih i ne prima od njih.
    • Više stolova odjednom i na stranici poslovnice. Na stranici "Stolovi, kodovi i raspored" svaki sto ima kvadratić; "Označi sve", "Obriši označene" i "Povuci označene" rade nad svima. Sto koji ima račune u historiji ne može se obrisati, pa ga poruka imenuje i nudi povlačenje. Klik na naziv stola mijenja naziv.
    • Pozadina rasporeda. U uređivaču prostorije, uz oblik, bira se pozadina sprata: jedna od boja (kamen, drvo, tamna, pijesak, zelena, bordo, plava) ili vlastita slika, recimo fotografija prostorije ili nacrt. Istu pozadinu vide ekran Stolovi i konobarski telefon. Svaki sprat ima svoju.
    • API: PATCH /v1/tables/:id prima label; naziv koji već nosi drugi aktivni sto u istoj poslovnici odbija se sa label_in_use. Raspored (PUT /v1/locations/:id/floor-plan) prima backgrounds po spratu, sa color i imageUrl.

    0.76.114

    14. oktobar 2026.

    Ispravljeno

    • Narudžba više ne može preći stanje zaliha. Jelo koje je vezano za artikal u Zalihama (porcija pasulja skida jednu porciju sa police) moglo se naručiti i kad police nema toliko: na stanju je bilo deset, a jedan sto je naručio sedamnaest. Sada se prije upisa narudžbe gleda šta police mogu pokriti, umanjeno za ono što su otvoreni računi u lokalu već naručili a još nije skinuto. Ako nema dovoljno, gost dobije poruku koliko porcija ima i dugme da naruči toliko ili ukloni jelo iz korpe; konobar na svom ekranu vidi isto. Jelo čija je polica prazna u meniju stoji kao rasprodano, a uz njega piše koliko porcija još ima. Jela koja nisu vezana za zalihe ne mijenjaju se.
    • Boja dugmadi na gostovoj stranici se mijenjala sa zakašnjenjem: ko je u Podešavanjima izabrao zelenu pa odmah ljubičastu, na stolu je vidio zelenu još do pet minuta, jer je stranica boju čitala iz keširanog odgovora. Sada se boja, kao i tema, ispravi iz svježeg odgovora čim se meni učita.
    • Stranica rezervacije za gosta se nije sama osvježavala: kad lokal potvrdi rezervaciju, gost je vidio "čeka se" dok ne učita stranicu ponovo. Sada stranica, dok je zahtjev otvoren, svakih petnaest sekundi i pri povratku na karticu sama provjeri odgovor i prikaže ga.

    0.76.113

    12. oktobar 2026.

    Ispravljeno

    0.76.112

    12. oktobar 2026.

    Ispravljeno

    • Firma iza XPay-a je NoLimitDevelopments FZ-LLC. Registrovana je u slobodnoj zoni IFZA u Dubaiju, sa sjedištem u IFZA Business Park, Dubai Silicon Oasis, a evropska kancelarija joj je u Beču (Gregorygasse 10a, 1230 Beč, Austrija). Tako piše u podnožju, na kontaktu, u pravnim podacima i u svim pravnim dokumentima, na xpay.ba i na xpay.rs, jer u Bosni i Srbiji firma još ne postoji. Broj licence bit će objavljen kada ga potvrdimo.
    • Sarajevo i Srbija su plan. Na xpay.ba piše da se kompanija uskoro otvara u Sarajevu i da će to biti NoLimitDevelopment d.o.o., razvojni centar i dom XPay-a, a na xpay.rs da se uskoro otvara i u Srbiji.
    • Politika privatnosti navodi da se lični podaci obrađuju i izvan Bosne i Hercegovine, odnosno Srbije, jer je sjedište kompanije u Ujedinjenim Arapskim Emiratima, a kancelarija u Austriji. Spisak podobrađivača ima verziju 1.2.

    0.76.111

    12. oktobar 2026.

    Ispravljeno

    • xpay.ba bez sarajevske adrese. Podnožje, kontakt i pravni podaci navode NoLimitDevelopment d.o.o. kao društvo u osnivanju u Bosni i Hercegovini, koje se uskoro otvara u Sarajevu. Adresa, registarski i poreski brojevi bit će objavljeni čim postoje. Ranije je stajala poslovna adresa na kojoj firma nije.
    • Pravni dokumenti na xpay.ba imenuju stranu kao društvo u osnivanju, kontakt je e-poštom, a uz to piše da XPay razvija NoLimitDevelopments. Nove verzije: Ugovor 2.1, Uslovi korištenja 2.1, Pravila prihvatljivog korištenja 1.2, Ugovor o obradi ličnih podataka 1.2, Politika privatnosti 1.3 i Uslovi za kupce i goste 1.1.
    • xpay.rs je i dalje bez ičega bosanskog: strana je NoLimitDevelopment, društvo u osnivanju u Republici Srbiji.

    0.76.110

    12. oktobar 2026.

    Novo

    • Ko pravi XPay. U podnožju svake stranice, na kontaktu i u pravnim podacima piše da je XPay softverski proizvod kompanije NoLimitDevelopments, sa linkom na nolimitdevelopments.com. Na xpay.ba uz to piše da se kompanija uskoro otvara u Sarajevu, a na xpay.rs da se uskoro otvara i u Srbiji.
    • Pravni podaci po državi. Na xpay.ba ostaje NoLimitDevelopment d.o.o. sa adresom u Sarajevu, uz napomenu da se društvo uskoro otvara pa brojevi još nisu dodijeljeni. Na xpay.rs je strana u ugovoru, u politici privatnosti i u ostalim pravnim dokumentima NoLimitDevelopment, društvo u osnivanju u Republici Srbiji. Sarajevske adrese tamo više nema, kontakt je e-poštom, a pravni oblik, sjedište, matični broj i PIB bit će objavljeni čim se društvo registruje.
    • Konzola u podnožju piše "softverski proizvod kompanije NoLimitDevelopments", na jeziku konzole (do sada uvijek na bosanskom).

    Ispravljeno

    • U pravnim podacima na xpay.ba više ne stoji dvostruka tačka iza "d.o.o.".

    0.76.109

    12. oktobar 2026.

    Novo

    • Srpske riječi, ne samo ekavica. Srpska konzola i xpay.rs kažu "porudžbina" umjesto "narudžba", a tu su i "kuvar", "kasir", "magacioner", "procenat", "sopstveni", "spoljni", "poslednji", "izaberite" i "pozovite". Gost vidi "Treba mi konobar" i "Za mališane". Sajt i konzola koriste isti rječnik.
    • Konzola srpskog lokala po srpskim podacima. Savjet uz bankovni račun traži srpski račun (IBAN RS35 ili 18 cifara, npr. 160-0000000012345-95), ne bosanski. Panel za banku navodi PIB umjesto JIB-a, uz kartice piše da Monri radi u Srbiji, a kasa za račun mailom nudi primjer adrese sa .rs. Vrijeme se piše "pre 8 dana" umjesto "prije 8 dana".
    • Gost lokala u Srbiji bira srpski ili engleski. Meni za stolom i stranice za rezervaciju srpskog lokala nude SR i EN, bez BS. Telefon na bosanskom, hrvatskom ili crnogorskom tamo dobije srpski. Lokali u Bosni nude sva tri jezika kao i do sada.
    • Srpski pravni dokumenti imaju svoju verziju i datum. Oznaka je sada -RS2 (samo srpsko pravo, sud u Beogradu i srpske riječi), a datum zadnje izmjene je datum srpskog teksta.

    Ispravljeno

    • Na stranici Kasa u konzoli i u spisku tima relativno vrijeme ("prije 8 dana") bilo je na bosanskom i kad je konzola na engleskom ili srpskom. Sada je na jeziku konzole.
    • Na xpay.rs je u pitanjima na stranici cijena ostala bosanska rečenica o tome da XPay ne drži novac; sada je srpska, kao i rečenica za goste u pravnim podacima.
    • U srpskoj politici privatnosti "u lokalnoj skladištu pregledača" je sada "u lokalnom skladištu pregledača".
    • Konzola na bosanskom svuda kaže "sačuvati" za snimanje, kao i dugme "Sačuvaj": i dok se bankovni račun snima i kad promjena stola nije sačuvana, gdje je ranije pisalo "spremiti".

    0.76.108

    12. oktobar 2026.

    Ispravljeno

    • Provjera proxy adrese (proxy-addr 2.0.8): ispod expressa, na kojem radi API. Kod mreža zapisanih kao IPv4 adresa unutar IPv6 provjera povjerenja mogla je pogriješiti, pa bi se zahtjev mogao predstaviti lažnom IP adresom.
    • Čitač source mapa (source-map-js 1.2.2): ispod postcss-a, koji gradi stilove sajta i konzola. Posebno napravljena source mapa mogla je blokirati proces (DoS).
    • Obrada slika (sharp 0.35.5): ispod Next.js-a i naših skripti za slike menija. Zakrpa ispravlja grešku u biblioteci librsvg koju sharp nosi.

    0.76.107

    12. oktobar 2026.

    Novo

    • Sav tekst na xpay.rs je na srpskom (ekavica). Naslovna, cijene, kontakt, zahtjev za XPay, pravni podaci, svi pravni dokumenti, meni, podnožje i naslovi u pretraživaču: "cene", "mesečno", "nalepnica", "pregledač", "biće". Prevod ide riječ po riječ iz istog rječnika kao srpska konzola, nikad po pravilu na slovima, a test ne pušta srpsku stranicu sa bosanskom riječju koju rječnik poznaje.
    • Pravni dokumenti na xpay.rs samo po srpskom pravu. Ugovori i uslovi se ravnaju po pravu Republike Srbije, a za sporove je nadležan sud u Beogradu. Politika privatnosti i ugovor o obradi koriste izraze Zakona o zaštiti podataka o ličnosti (rukovalac, lice na koje se podaci odnose, podaci o ličnosti), pritužba ide Povereniku, a bosanski zakon i bosanska agencija se više ne spominju. Od Bosne na njima ostaju samo naziv i sjedište kompanije, jer ih ugovor i politika privatnosti moraju navesti, i rečenica da se podaci obrađuju u Bosni i Hercegovini i na osnovu čega, jer to traži srpski zakon.
    • Srpske adrese stranica. Cijene su na xpay.rs/cene, a pravila korištenja na xpay.rs/pravila-koriscenja. Stare adrese vode na nove, a na xpay.ba /cene vodi na /cijene. Sitemap i linkovi koriste srpske adrese.
    • Bez sarajevske adrese u podnožju i na kontaktu. Na xpay.rs podnožje i stranica kontakta navode kompaniju i vode na Pravne podatke, gdje je adresa ostala jer je zakon traži. Stranica statusa sa bosanskim bilješkama o izdanjima više nije na srpskom sajtu.
    • Jezik stranice je sr-Latn za preglednik i pretraživače.
    • Srpski prevod konzole sada pravi skripta u repozitoriju (scripts/translate-sr.mjs) iz istog rječnika kao sajt, pa se više ne može izgubiti. Usput je srpska konzola dobila "pregledač", "bezbednost", "leti" i "podatke o ličnosti".

    0.76.106

    4. oktobar 2026.

    Novo

    • Zadnjih 30 dana na vrhu Analitike. Četiri kartice: promet, broj naplata, prosječan račun i najbolji dan. Svaka ima mini-krivu po danima i promjenu u odnosu na prethodnih 30 dana. Ispod je promet po danu kao stupci koji rastu, sa prethodnih 30 dana kao sjenom iza njih i velikim zbirom iznad.
    • Kad je najviše posla pokazuje cijeli radni dan, od 08 do 23 h (i ranije ako je objekat tada imao promet), u ćelijama normalne veličine. Objekat sa jednom večeri na mapi više nema četiri razvučene trake preko cijelog ekrana. Pored mape su stupci "Po danima": prosječan dan za svaki dan u sedmici, najjači svijetli.
    • Najprodavaniji artikli: prvih pet kao kartice iznad tabele, sa rangom, iznosom, količinom i trakom koja svijetli. Grupe artikala imaju deblje trake sa sjajem.
    • Iznosi na karticama pišu valutu manjim slovima pored broja, pa se "4.750,00 RSD" ili "1.248,50 KM" više ne lomi u dva reda.

    0.76.105

    4. oktobar 2026.

    Novo

    • Prikaz konzole na xpay.rs (početna stranica i odjeljak o konzoli) je nacrtan kao prava konzola: kartice s mini-krivom do ivice i promjenom, promet po satima kao linija koja se sama iscrta i svijetli preko blijede površine, prošli utorak isprekidano ispod, stakleni okvir za 20:00 sa iznosom, brojem uplata i promjenom, tačka koja pulsira na sadašnjem satu, krug od zaobljenih dijelova s razmakom (IPS QR, gotovina, kartica) i mapa "Kad je najviše posla" po danima i satima. Sve u dinarima i na srpskom kako konzola govori na app.xpay.rs, i sve se sabira: promet dana je zbir sati, a promjena je dan prema prošlom utorku.
    • Prikaz konzole na xpay.ba ima isti izgled za firmu koja izdaje račune, u KM: avgust po danima, poređenje s julom i naplata po mjesecima kao stupci koji rastu.
    • Prazna konzola više ne izgleda pokvareno. Objekat koji danas još nema prometa, na primjer novi kafić, umjesto ravne linije i ose 0, 0, 1 vidi blijedi oblik dana i stakleni natpis da se linija iscrta sama s prvim plaćenim računom. Krug "Struktura naplate" pokazuje svoje kanale na 0%, a mapa najprometnijih sati svoja polja.
    • Trake po poslovnici imaju gradijent i sjaj kao ostali grafikoni.

    Ispravljeno

    • Sto koji se već zove "Sto 2" ili "Bašta 3" više se ne piše kao "Sto Sto 2" u listi plaćanja i u uparivanju uplata. Sto sa samo brojem i dalje dobija riječ "Sto".

    0.76.104

    4. oktobar 2026.

    Novo

    • Ugovor na xpay.rs u dinarima. Cijene paketa, transakcija i ugostiteljskog modula u Ugovoru o korištenju stoje u dinarima, iste kao na stranici cijena, a primjeri obračuna su preračunati: Business primjer je 8.300 RSD, Flex primjer 13.146 RSD. Srpska verzija dokumenta nosi oznaku RS uz broj verzije, jer se uz prihvatanje bilježi tačna verzija.
    • Politika privatnosti za Srbiju. Za lica u Srbiji navodi Zakon o zaštiti podataka o ličnosti ("Službeni glasnik RS", br. 87/2018), pravo na pritužbu Povereniku za informacije od javnog značaja i zaštitu podataka o ličnosti i osnov za obradu podataka srpskog objekta u Bosni i Hercegovini: BiH je članica Konvencije 108 i nalazi se na srpskoj listi država sa primjerenim nivoom zaštite ("Službeni glasnik RS", br. 55/2019).
    • Pravila korištenja. Srpski objekat je dužan poštovati propise Republike Srbije. Fiskalni račun izdaje preko svog odobrenog ESIR-a, a elektronsku fakturu, kada je propisana, kroz SEF.
    • Ugovor o obradi podataka. Za kontrolora iz Srbije to je i ugovor iz člana 45. Zakona o zaštiti podataka o ličnosti.

    0.76.103

    4. oktobar 2026.

    Novo

    • Izbor države na statistici. Pored perioda je izbor Sve, BiH ili Srbija, i pamti se. Za jednu državu sve brojke na stranici važe samo za nju: aktivne firme, posjete sajtu (xpay.ba ili xpay.rs), otvoreni meniji, narudžbe, plaćanja, uspješnost plaćanja, način plaćanja, stanje sistema i tabela firmi. Kad je izabrana jedna država, traka udjela xpay.ba i xpay.rs se ne prikazuje jer nema šta da dijeli.
    • Država firme u tabeli dolazi sa same firme, ne više sa njene prve poslovnice.

    0.76.102

    4. oktobar 2026.

    Novo

    • Paketi u dinarima. Firma iz Srbije plaća Start 2.900 RSD, Business 5.900 RSD i Pro 11.900 RSD mjesečno. Transakcija preko uključenog broja je 3 RSD na Flexu, 1,80 RSD na Startu, 1,20 RSD na Businessu i 0,60 RSD na Pro paketu, a ugostiteljski modul 2.900 RSD po lokaciji. To su iste cijene kao na xpay.rs, a test pazi da se aplikacija i sajt ne raziđu.
    • Faktura za XPay u valuti firme. Pretplata, produženje i mjesečni obračun transakcija za srpsku firmu izdaju se u dinarima. Iznos koji operater upiše za srpsku firmu čita se kao dinari.
    • Nova firma dobija valutu po državi. Firma otvorena s državom Srbija plaća u dinarima od prvog dana. Postojeća srpska firma bez posebno dogovorene cijene prebačena je na dinare, a iznos dogovoren u KM ostaje kako je dogovoren.
    • Konzola, panel Transakcije ovaj mjesec. Licenca, transakcije preko uključenog broja, ugostiteljski modul i iznos za mjesec pišu se u valuti firme, a cijena po transakciji kako se čita: 0,03 KM ili 1,80 RSD.
    • Postavke firme. Srpska firma upisuje PIB od devet cifara i nema posebno polje za PDV broj, jer je u Srbiji PIB i broj u sistemu PDV-a. Bosanska firma i dalje upisuje JIB i PDV broj.
    • Admin, Pretplate. Svaka firma ima cijenu u svojoj valuti, a gdje cijena nije dogovorena piše iznos po cjenovniku. Mjesečni prihod i nenaplaćeno stoje posebno u KM i posebno u RSD, nikad sabrani u jedan broj. U prozoru za uređivanje piše cijena po cjenovniku, a promjena paketa ili mjesečne i godišnje naplate povlači novu cijenu iz cjenovnika ako stara nije ručno upisana.
    • Admin, Firme. Uz svaku firmu stoji oznaka BiH ili RS, a promet u zadnja 24 sata prikazan je posebno za svaku valutu.
    • U Srbiji samo ugostiteljstvo. Za Srbiju admin forma nudi samo restorane i kafiće. API odbija drugu djelatnost i uključivanje faktura za srpski objekat, jer se faktura između firmi u Srbiji izdaje kroz SEF.
    • Srpske riječi. Datum na grafikonu piše "avg", skraćeni dan u analitici je "Sre", a gost koji rezerviše sto u srpskom objektu vidi "sreda", "nedelja" i "ponedeljak".

    0.76.101

    4. oktobar 2026.

    Novo

    • Grafikon prometa na pregledu: linija u boji objekta s gradijentom i sjajem, iscrtava se sama s lijeva na desno, a ispod nje je jača boja. Gore desno se bira linija ili stupci, i izbor se pamti. Stupci rastu iz osnove jedan za drugim, a iza njih je sjena prošlog perioda za poređenje. Iznad grafikona je veliki zbir i promjena u odnosu na poređenje.
    • Tooltip od mutnog stakla pokazuje iznos, broj uplata, promjenu i iznos iz perioda s kojim se poredi. Danas tačka koja pulsira pokazuje gdje je sada.
    • Kartice imaju mini-krivu sa sjajem preko cijele donje ivice.
    • Struktura naplate: krug od zaobljenih dijelova s razmakom među njima, koji se okrene na mjesto. Prelaz mišem podebljava dio i u sredini pokazuje njegov iznos. Pored svakog načina plaćanja je traka udjela.
    • Kad je najviše posla: polja ulaze jedno za drugim, polje pod pokazivačem svijetli, a najjači sat je stalno označen.
    • Analitika: trake za artikle, kategorije i stanice imaju gradijent i rastu kad se otvore.
    • Admin statistika: linije u svojim bojama sa sjajem, kartice s mini-krivom do ivice i isti stakleni tooltip.

    0.76.100

    4. oktobar 2026.

    Novo

    • Kad je najviše posla. Na vrhu Analitike je mreža dana u sedmici i sati, i što je polje tamnije, to je promet u tom satu veći. Računa se kao prosjek zadnje četiri sedmice, za izabranu poslovnicu ili za sve. Iznad mreže piše najprometniji sat (npr. "petak od 20 do 21 h, prosječno 345,00 RSD"). Pokazivač na polju pokazuje prosječan promet i broj naplata tog sata, a ispod mreže je tabela s petnaest najjačih sati. Pomaže da se zna koje večeri treba još jedan konobar, a koje jutro šank može raditi sa jednim.

    Ispravljeno

    • Analitika, kategorije: šank i jela bez kategorije više ne dijele isti ključ u listi, pa se nijedan red ne gubi pri osvježavanju.

    0.76.99

    4. oktobar 2026.

    Ispravljeno

    • Kartica i IPS su na fiskalnom računu lokala gotovina. Za hranu i piće koji se služe u objektu Pravilnik o vrstama fiskalnih računa (član 6) dozvoljava samo četiri načina plaćanja, a gotovina tu obuhvata i karticu i instant plaćanje. XPay je do sada karticu slao kao karticu, a IPS kao instant plaćanje.
    • U Srbiji štampani račun za sto više nema QR kod za plaćanje. Zakon o fiskalizaciji (član 12, stav 5) za račun s QR kodom koji nije generisao sistem Poreske uprave predviđa zabranu rada od godinu dana. Na papiru ostaje poziv na broj, a gost plaća kodom sa stola ili sa svog telefona.
    • Lokalni fiskalni uređaj mora biti odobreni ESIR. Ako je u podešavanjima izabran samo L-PFR, XPay mu ne šalje račune i kaže zašto: tada bi XPay sam bio ESIR, a nije odobren.
    • Konektor 0.4.3 ne izdaje isti račun dvaput. Kad odgovor na raniji pokušaj nije stigao, konektor prvo pita uređaj da li je račun već izdat i uzima taj odgovor, umjesto da račun pošalje ponovo.

    Novo

    • U dokumentaciji projekta je plan za odobrenje XPay-a kao ESIR-a u Srbiji: ko može podnijeti zahtjev (samo firma ili preduzetnik iz Srbije), koraci na razvojnom portalu Poreske uprave, šta XPay još mora imati, odgovori na osam pitanja za proizvođača ESIR-a i pitanja za računovođu u Srbiji.

    0.76.98

    4. oktobar 2026.

    Novo

    • Grafikon prometa s poređenjem. Pregled prometa sada ima iznose na osi, sate ili datume ispod nje i isprekidanu liniju za poređenje. Danas se poredi s istim danom prošle sedmice, do istog sata. Jedan dan se poredi s istim danom sedmicu ranije, a više dana s istim brojem dana prije njih. Pokazivač na grafikonu pokazuje oba iznosa, broj uplata i promjenu u postocima. Legenda daje zbir za oba perioda, a grafikon se može otvoriti i kao tabela. Linija više ne pada ispod nule tamo gdje promet nije padao.
    • Kartice na pregledu imaju ikonu i objašnjenje na prelazak mišem. Kod naplaćenog i prosječnog računa stoji i promjena u odnosu na poređenje: zelena strelica gore, crvena dolje. Naplaćeno kaže i broj naplata.
    • Struktura naplate pokazuje i iznos za svaki način plaćanja, ne samo udio, u bojama grafikona umjesto boja statusa.
    • Kod prometa po poslovnici svaka poslovnica ima traku sa svojim dijelom.

    Ispravljeno

    • Analitika (artikli, kuhinja i šank, osoblje, stolovi): kad se period brzo promijeni, sporiji odgovor više ne može prepisati noviji, a greška ranijeg zahtjeva ne ostaje preko ispravne tabele.

    0.76.97

    4. oktobar 2026.

    Novo

    • Zalihe u restoranu i kafiću. Ekran Zalihe je sada otvoren i za ugostiteljske objekte. Upišite šta brojite (npr. Jelen 0,5 u komadima, kafu u zrnu u kilogramima, mlijeko u litrima), koliko sada ima i minimum za upozorenje. Prijem robe, otpis i popis rade kao u prodavnici, i svaka promjena ostaje zapisana s razlogom.
    • Artikal iz menija skida sa zaliha. U Meniju, u formi artikla, pod "Skida se sa zaliha" upišete koliko jedna porcija troši: pivo 0,5 l je 1 flaša, espresso je 0,007 kg kafe, kafa s mlijekom je 0,007 kg kafe i 0,05 l mlijeka. Kad konobar ili šank označi narudžbu kao posluženu, zaliha se smanji sama. Ako to niko ne označi, smanji se kad se račun zatvori. Svaka stavka se skida tačno jednom, a otkazana narudžba ne skida ništa.
    • Na Zalihama svaka stavka kaže koji je artikli iz menija troše, a kratko uputstvo u pet koraka objašnjava kako sve radi.
    • Dugme "Broji zalihu" kod artikla u Meniju sada se zove "Porcije danas", jer je to dnevni broj porcija, a ne zaliha.

    Ispravljeno

    • Prozor i drugi okrenuti dijelovi u rasporedu sale idu do zida. Dio okrenut pod uglom, npr. uspravan prozor, zaustavljao se pola svoje dužine prije zida, jer se mjerio kao da nije okrenut. Sada se mjeri stvarni okrenuti oblik, u editoru i na serveru.
    • "Otvori sto" kod rezervacije se moglo pritisnuti danima unaprijed. Time je sto trajno prestajao da se čuva za tu rezervaciju, a red je pisao samo "Sto otvoren ranije". Dugme se sada zove "Gosti su stigli" i pojavljuje se tek tri sata prije termina. Red jasno kaže šta se dešava: od kada do kada se sto čuva, da se čuva upravo sada, ili da su gosti sjeli i da sto prima narudžbe. Do termina se to može poništiti. Rezervacije kojima je sto ovako greškom otvoren više od tri sata unaprijed ponovo čuvaju svoj sto.

    0.76.96

    3. oktobar 2026.

    Novo

    • Statistika korištenja (admin, "Statistika"). Za izabranih 7, 30 ili 90 dana, uz poređenje sa istim brojem dana prije: aktivne firme, posjete sajtu, otvoreni meniji, narudžbe, plaćeno i uspješnost plaćanja. Ispod su grafikoni po danu za aktivnost (narudžbe, plaćanja i otvoreni računi), posjete sajtu i otvorene menije, zatim kako se plaćaju zatvoreni računi, najčitanije stranice sajta, odakle posjetioci dolaze, telefon ili računar i xpay.ba ili xpay.rs. Pokazivač na grafikonu pokazuje sve brojeve za taj dan, a svaki grafikon se može otvoriti i kao tabela.
    • Da li sve radi. Otvoreni slučajevi, ugašeni webhookovi, odbijeni fiskalni računi, neuparene uplate, udio uplata uparenih bez čovjeka i konektori na vezi. Svako polje kaže stanje riječju i ikonom, a na prelazak mišem objašnjava šta broji.
    • Firme. Tabela svih firmi sa brojem objekata, otvorenih menija, narudžbi, računa i plaćanja u periodu, kretanjem po danu i zadnjom aktivnošću. Filteri: aktivne, nove, utihnule i neaktivne; pretraga po nazivu ili gradu; sortiranje klikom na naslov kolone. "Nova" je firma otvorena u periodu koja još nema narudžbi ni plaćanja u zadnjih 7 dana: nju vrijedi nazvati.
    • U statistici nema nijednog iznosa, cijene ni stavke narudžbe. Server ih i ne šalje.

    Brojanje posjeta

    • Sajt broji posjete samo kao zbirne dnevne brojeve: stranicu bez dijela adrese iza znaka pitanja, da li je posjeta počela na telefonu ili računaru i domen sa kojeg je posjetilac došao. Bez kolačića, bez IP adrese i bez ičega sačuvanog u pregledniku. Preglednik koji traži da ne bude praćen (Do Not Track, Global Privacy Control) ne šalje ništa, a pretraživači i drugi programi se ne broje.
    • Otvaranje menija za stolom se broji kao jedan broj po objektu i danu, bez veze sa gostom ili telefonom.
    • Politika privatnosti (verzija 1.2) opisuje oba brojanja, a spisak podobrađivača (verzija 1.1) kaže da alata trećih strana za analitiku posjeta i dalje nema.

    0.76.95

    3. oktobar 2026.

    Novo

    • Meni koji objašnjava. "Proizvodi" i "Rješenja" se otvaraju u panel: svaka stavka ima ikonu, naziv i jednu rečenicu o tome šta je. Dok je miš na stavci, pored liste piše kako radi u tri koraka i šta je firmi potrebno da počne. "Cijene" i "Kontakt" na prelazak mišem kažu šta je iza linka. Na telefonu se meni otvara kao harmonika sa istim opisima.
    • Na xpay.rs meni vodi kroz ono što lokal dobija: digitalni meni, naručivanje za stolom, plaćanje IPS QR kodom, fiskalni račun, ekrane za kuhinju i šank i analitiku.

    Promijenjeno

    • Pored logotipa više ne stoji ".ba" ili ".rs". Stoji samo logo.

    0.76.94

    3. oktobar 2026.

    Ispravljeno

    • Kod za cijeli račun izdat dok je neko naručivao. Iznos koda se računao prije nego što je kod izdat, pa je narudžba s drugog telefona u tom trenutku (desert od 6,00) ostavljala kod od 30,00 na računu od 36,00. Sto se zaključavao za plaćanje, gost je platio 30,00 i vidio "plaćeno", a 6,00 je ostalo bez koda. Sada se takav kod odbija i gost osvježi račun. Isto važi i za kod koji izdaje konobar. Sto se za plaćanje zaključava samo iz otvorenog stanja i u istom koraku.
    • Otkazivanje narudžbe na stolu koji se upravo zatvorio više ne smanjuje iznos zatvorenog stola nakon što je račun izdat. Takva narudžba se vraća kao povrat.
    • Poziv osoblja se više ne upisuje na sto koji se u međuvremenu zatvorio, a automatsko zatvaranje praznog stola više ne zatvara sto gostu koji se baš tada vratio na stranicu.
    • Obavijest banke s iznosom nula ili manjim više se ne prima kao uplata. Feed koji dugovanja šalje kao negativne iznose umanjivao je djelimično plaćen račun. Takve linije se sada preskaču.
    • Uplata preko naljepnice stola iz izvora koji ne smije sam zatvarati račune (izvod unesen ručno, izvor kojem je oduzeto ovlaštenje) više ne pravi plaćen račun, nego račun koji čeka osobu u Uparivanju.

    0.76.93

    3. oktobar 2026.

    Ispravljeno

    • Odbijen PIN se više ne šalje ponovo. Kad fiskalni uređaj odbije PIN bezbjednosnog elementa (kartice), konektor ga je slao opet za svaki sljedeći račun, a server je neuspjele račune ponavljao svakih pet minuta. Kartica se zaključava nakon nekoliko pogrešnih PIN-ova. Sada konektor pamti da je PIN odbijen i ne šalje ga dok se na njegovoj stranici ne upiše novi, a server takav račun ne ponavlja sam. Potreban je konektor 0.4.2.
    • Ponovno slanje fiskalnog računa ide samo konektoru kojem je račun predat, dok se ne zna šta je uređaj s njim uradio. Ranije je mogao otići drugom konektoru, pa bi drugi uređaj izdao isti račun još jednom. Ako taj konektor nije dostupan, račun ostaje označen kao neizvjestan, a ne kao "nije poslat".
    • Kartica: procesor se ne može mijenjati ni dok odobrenje može stići na nedavno otkazan ili istekao kartični račun (sat vremena). Oznake koje Monri javlja (odbijeno, povrat u portalu, druga naplata) više ne brišu jedna drugu kad stignu u isto vrijeme.
    • Kuhinjski ekran dobija detalj stola s narudžbama i stavkama, bez cijena i iznosa (dopuna izmjene iz 0.76.92).
    • Raspored sale: komad s imenom (šank, kuhinja, natpis) okrenut za četvrtinu kruga zadržava svoje ime. Ranije je postajao pretanak da ga prikaže.
    • Konektor prihvata kasu na mreži koja ga zove punim imenom računara (npr. kasa-pc.firma.local), kad zahtjev ne dolazi sa web stranice.

    0.76.92

    3. oktobar 2026.

    Ispravljeno

    • Opozvan ili ugašen pristup i dalje je primao sve uživo. Kad vlasnik izda novi kod za uparivanje (izgubljen tablet), ugasi uređaj, osobu ili API ključ, ili kad se poslovanje suspenduje, obični zahtjevi su odmah odbijani, ali već otvorena veza nastavljala je primati svaku uplatu, narudžbu i sto. Sada se svaka otvorena veza provjerava svake minute i zatvara čim pristup više ne važi.
    • Zidni ekran u kuhinji više ne vidi novac. Lista otvorenih stolova vraćala mu je iznos, plaćeno i dug po stolu, a događaji zatvaranja stola i zahtjeva za plaćanje nosili su iznose. Ekran sada dobija samo sto, ko čeka i koliko dugo, a detalj stola samo sa narudžbama i stavkama, bez cijena i iznosa.
    • Uređaj suspendovanog poslovanja ne može otvoriti vezu uživo.

    0.76.91

    3. oktobar 2026.

    Ispravljeno

    • Dvije uplate za isti račun u istoj sekundi. Svaka je čitala iznos prije upisa, pa je druga prepisivala prvu (10,00 i 20,00 postajalo je 20,00), a kod istih iznosa bila je označena kao uparena iako nije bila ni na jednom računu. Sada se upis odbija ako se iznos u međuvremenu promijenio, uplata se čita ponovo i dodaje na ono što je prva ostavila. Isto vrijedi i za ručno priključivanje uplate u Uparivanju.
    • "Potvrdi" dok banka upravo upisuje uplatu. Račun od 25,00 koji je banka upravo platila postajao je 50,00 i preplaćen, a povrat cijelih 50,00 bio je dozvoljen. Ručna potvrda sada pamti stanje računa u trenutku pritiska; ako je banka u međuvremenu upisala novac, potvrda se odlaže i ništa se ne dodaje.
    • Uplata koja navodi već plaćen, otkazan ili vraćen račun više ne traži drugi račun po iznosu. Takva uplata je mogla postati jedini prijedlog za drugi otvoreni račun istog iznosa, pa bi jedan klik stavio novac na pogrešan račun. Sada se otvara slučaj na računu koji uplata navodi. Ako je taj račun ranije ručno potvrđen, bankovna uplata se veže uz njega kao potvrda, bez dodavanja novca.
    • Uplata preko naljepnice stola zabilježena dvaput. Kad webhook stigne bez bankovnog broja transfera, a noćni izvod s njim, nastajala je druga plaćena uplata i promet se duplirao. Ista uplata iz drugog izvora istog dana sada ide osobi na provjeru. "NOTPROVIDED", koji neke banke pišu na svaku liniju, više se ne smatra brojem transfera, a i poređenje po broju gleda samo isti dan, pa se kasnija prava uplata za isti sto ne veže uz staru.
    • Dvije prave uplate istog iznosa istog dana (npr. 30,00 i 30,00 za račun od 60,00) više se ne proglašavaju duplikatom kad obje imaju svoj broj transfera.
    • Odluka banke "duplikat" mora navesti račun iz tog slučaja, a vezivanje bez novca je dozvoljeno samo kad je ista uplata već na računu iz drugog izvora. Ranije je mogla prebaciti račun koji čeka uplatu u djelimično plaćen sa 0,00.
    • Povrat sa izvoda (banka vrati uplatu platiocu) više se ne upisuje dvaput. Ako je isti povrat već upisan u konzoli ili preko zahtjeva banke, linija izvoda se veže uz njega. Isti izvod uvezen dvaput u isto vrijeme daje jedan povrat, a uzimaju se samo pozivi na broj sa ispravnim kontrolnim brojem.

    0.76.90

    3. oktobar 2026.

    Ispravljeno

    • Uplata koja stigne manja odmah se računa na stolu. Gost pošalje 15,00 za kod od 20,00. Do sada sto nije vidio ništa od tih 15,00 i dalje je tražio cijelih 20,00, pa je konobar naplaćivao 20,00 u gotovini za kasu u kojoj je bilo 5,00. Z-izvještaj je bilježio 20,00 gotovine a uplatu nigdje, fiskalni račun je navodio 35,00 uplata za 20,00 hrane, a kad bi gost poslao ostatak, sto je dobijao cijelih 20,00 ponovo. Sada na sto ide ono što je stiglo (najviše do iznosa hrane), a ostatak kad stigne, pa sto duguje tačno razliku.
    • Stavke plaćene kratkom uplatom ostaju tog gosta. Drugi telefon ih više ne može odabrati i platiti ponovo.
    • Z-izvještaj broji kratku uplatu na dan kad je novac stigao. Ranije je nije brojao nijedan dnevni zaključak.
    • Srpski fiskalni račun navodi kratku uplatu kao plaćanje prenosom, a gotovinu samo za razliku koju je konobar uzeo.
    • Povrat kratke uplate skida sa stola samo ono što je ta uplata stavila, a napojnica se vraća samo ako je zaista stigla.
    • Stolovi otvoreni u trenutku ove verzije dobijaju već pristigle kratke uplate.

    0.76.89

    3. oktobar 2026.

    Ispravljeno

    • Z-izvještaj (dnevni zaključak):
    • Račun plaćen i vraćen u cijelosti istog dana skidao se dvaput: nije ulazio u uplate preko banke, a povrat se ipak oduzimao, pa je neto bio manji za iznos računa. Sada ulazi u uplate, a povrat se oduzima jednom.
    • Povrat skida s neto iznosa samo hranu i piće. Napojnica i preplata vraćene gostu nisu bile u prometu, pa ga više ne umanjuju. PDF navodi koliko je ukupno vraćeno i koliko od toga otpada na napojnice i preplate.
    • Iznos po osobi ("Ko je zatvarao stolove") bio je dupliran za stolove zatvorene gotovinom ili karticom. Sada je tačan, a pored njega stoji i gotovina koju je ta osoba uzela za stolom, za brojanje kase.
    • Povrat preplate više ne vraća dug na sto. Gost pošalje 16,00 za svoj dio od 10,00 i dobije nazad 6,00 dok sto još nije zatvoren: sto je tada ponovo tražio 6,00 za hranu koja je već plaćena. Povrat se sada prvo uzima iz preplate, pa iz napojnice, pa iz hrane, i to isto vrijedi na stolu, u Z-izvještaju, u napojnicama, u izvozu za knjigovođu i u fiskalnom ispravku.
    • Povrat čita račun ponovo kad ga zaključa. Ako bi uplata stigla baš dok menadžer vraća novac, povrat se računao prema starom iznosu i mogao je ostaviti novac koji se više nije mogao vratiti.
    • Fiskalna evidencija (FBiH):
    • Lokali u Srbiji više ne dobijaju FBiH dokumente. Svaka narudžba, zatvaranje i povrat tamo pravili su i numerisani FBiH dokument u dinarima označenim kao KM. Srbija se fiskalizuje preko svog ESIR-a.
    • Korektivni račun se pravi samo za povrat poslije izdatog računa. Povrat dok je sto još bio otvoren već je u računu (račun sada navodi uplatu umanjenu za taj povrat), a sto koji je samo primao uplate nema račun iz XPay-a, pa ni ispravak.
    • Brojevi ne idu unazad na Novu godinu. Sto zatvoren u 23:58 i upisan poslije prvog januarskog računa dobija broj u novoj godini, umjesto da zapne na broju koji već postoji.
    • Provjera propuštenih dokumenata gleda sve što nema dokument, do 30 dana unazad, stranicu po stranicu. Do sada je gledala samo prvih 500 stolova na cijeloj platformi u posljednja 24 sata.
    • Dnevni zaključak na stranici Fiskalizacija prikazuje iznose u valuti lokala.

    0.76.88

    3. oktobar 2026.

    Novo

    • Analitika, odmah ispod Pregleda, u četiri kartice:
    • Artikli: najprodavaniji artikli za danas, 7, 30 ili 90 dana, po iznosu ili po količini, sa udjelom u prometu i koliko puta je koji naručen. Ispod su grupe menija i koliko koja donosi. Otkazane narudžbe se ne broje u prodaju nego stoje posebno, s brojem i vrijednošću. Artikal na težinu je u svojoj mjeri (kg, l), ne u komadima. Iznos je vrijednost naručenog, pa se razlikuje od uplaćenog na Pregledu za napojnice, za još neplaćeno i za otpisane stolove.
    • Kuhinja i šank: srednje vrijeme pripreme po stanici, vrijeme za koje je gotovo 9 od 10 narudžbi, koliko se čeka da neko primi narudžbu i koliko da spremljeno ode gostu, koliko narudžbi kasni prema vremenu pripreme upisanom na artiklima, gužva po satu i ko je spremio koliko narudžbi. Narudžbe samo za kuhinju, samo za šank i za oboje prikazane su odvojeno, jer stanice ne bilježe kad je koja završila svoj dio.
    • Osoblje i Stolovi: izvještaji koji su do sada stajali ispod plana sale. Na ekranu Stolovi ostaje veza do njih.
    • Lokal sa više poslovnica bira jednu ili sve.
    • Kuhinju i osoblje vidi vlasnik i menadžer, jer navode kolege po imenu.
    • Meni konzole u grupama: Pregled i Analitika na vrhu, pa Lokal (narudžbe, stolovi, rezervacije, osoblje, meni), Novac (plaćanja, fakture, izvodi, uparivanje, povrati, fiskalizacija) i Podešavanja. Na uskom ekranu grupe dijeli linija.

    0.76.87

    3. oktobar 2026.

    Ispravljeno

    • Narudžba je mogla završiti na stolu koji se upravo zatvara ili plaća. Gost pošalje turu dok konobar naplaćuje gotovinu (ili dok se sto zatvara uplatom): kuhinja je dobijala narudžbu, a niko je nije naplatio. Narudžba sada zaključava sto i provjerava ga u istom koraku u kojem se dodaje, pa se kasna narudžba odbija kao svaka narudžba za sto koji plaća.
    • Uplata koja zatvara sto zatvara ga samo ako i dalje pokriva račun. Tura naručena u istom trenutku više se ne zatvori "preko", a dvije uplate koje zajedno završe račun više ne zatvaraju sto dva puta (zalihe i obavještenja su išli dvaput).
    • Otkazivanje stavke dok istekli kod još može biti plaćen: banka prihvata zakasnjelu uplatu sat vremena poslije isteka koda, pa se otkazivanje sada odbija i tada, kao i dok je kod živ; konobar prvo otkaže kod.
    • Račun na papiru je nosio prvi živi kod sa stola, i kad je to bio dio jednog gosta (trećina, njegove stavke ili kartica). Ko bi platio sa papira, platio bi tuđi dio. Sada papir nosi kod samo kad je to kod za cijeli preostali iznos, a dok neko plaća svoj dio, papir ide bez koda.
    • "Isto ponovo" više ne zaobilazi rezervaciju stola.

    0.76.86

    3. oktobar 2026.

    Ispravljeno

    • Slanje e-pošte (nodemailer 10.0.13): objavljene su dvije ranjivosti koje su posebno napravljenom adresom mogle zauzeti server (DoS). Prelazak na verziju 10 traži Node.js 20 ili noviji; produkcija radi na Node.js 22.
    • Veza u stvarnom vremenu (engine.io 6.6.11): klijent sa drugom verzijom protokola mogao je zaustaviti server. Zakrpa je na istoj liniji koju socket.io već koristi.

    0.76.85

    3. oktobar 2026.

    Ispravljeno

    • Ctrl+Z je brisao oblik prostorije na svim spratovima čim je neki sprat imao svoj oblik (bašta kvadratna, sprat dugačak): poništavanje je snimalo plan bez oblika. Sada poništavanje i ponavljanje vraćaju cijeli plan.
    • Zid okrenut tipkom R nije mogao do zida prostorije: stajao je šestinu prostorije dalje, a krajevi su mu virili van. Okret za četvrtinu sada uspravi sam dio, u proporcijama prostorije, pa staje uz rub; isto i ručica za okretanje i polje za ugao.
    • Ctrl+R (osvježavanje stranice) prvo je okretao izabrani sto, a Ctrl+L i Alt sa strelicama mijenjali su zaključavanje i položaj. Pojedinačne tipke sada rade samo bez Ctrl, Cmd i Alt.
    • Pomjeranje strelicama pa odmah nešto drugo (R, Delete, prevlačenje, Ctrl+Z) kvarilo je istoriju poništavanja, a drugi sto pomjeren u tom trenutku nije se snimao. Sada se pomjeranje završi i snimi prije sljedeće radnje, i kad se uređivač zatvori.
    • Poslije Ctrl+Z na dodatom dijelu, Delete je tražio sto koji ne postoji (crvena greška "Table not found"). Izbor se sada očisti kad dio nestane ili ode na drugi sprat, a polja desno pokazuju samo dijelove sa ovog sprata.
    • Najviše 200 dijelova u planu: dodavanje i dupliranje stanu na granici, umjesto da svako sljedeće snimanje padne. Neuspjelo snimanje se sada vidi (Nije sačuvano) dok ga sljedeće ne popravi.
    • Naprijed i Nazad mijenjaju mjesto sa susjedom na istom spratu; ranije često sa dijelom na drugom spratu, pa se ništa nije pomjeralo.
    • Brzo povlačenje (pritisak, pomak i puštanje u istom trenutku) više ne ostavlja sto pomjeren na ekranu a nesnimljen.
    • Polja za veličinu i položaj: obrisano polje se ne tumači kao nula (dio više ne skoči uz zid), veličina ne pada ispod najmanje dozvoljene, a kod zaključanog dijela zaključana su i ova polja.
    • Ctrl+Z izvan uređivača (na primjer poslije povlačenja stola iz upotrebe u listi ispod) više ne poništava plan koji se ne vidi.
    • Brisanje stola dok gost baš tada skenira naljepnicu: provjera istorije i brisanje sada idu pod istom bravom, a sukob je odgovor 409, ne greška servera.
    • Dio plana koji viri van prostorije (poslat iz integracije) server sada uvuče unutra, pa snimanje plana ne pada zbog njega.
    • Čitač ekrana više ne kaže "Sto Sto 3".

    0.76.84

    3. oktobar 2026.

    Ispravljeno

    • Naljepnica "direktno u banci" za lokal u Srbiji nosila je iznos u KM (I:BAM0,00), kod koji nijedna srpska banka ne prima. Sada je u dinarima.
    • Srpski IPS kod uvijek nosi 18 cifara računa, i kad je server podešen da bosanski kod piše IBAN.
    • Sačuvaj kod u galeriju na iPhone-u javljao je da kod nije sačuvan: slika se preuzimala tek na dodir, pa je iOS odbijao dijeljenje. Sada se slika pripremi čim se kod prikaže; ako dijeljenje ipak ne uspije, kod se otvori kao slika koja se sačuva dugim pritiskom.
    • Prepišite podatke, za gosta u Srbiji: pored IBAN-a sada stoji i broj računa od 18 cifara (260-0056010016113-79), kako ga traži domaći dinarski nalog.
    • Lista plaćanja: sto naplaćen gotovinom poslije dva odustala koda pokazivao je dva reda "Naplaćeno gotovinom" za isti iznos, a sto plaćen karticom na telefonu označavao je odustali kod kao "Naplaćeno karticom (POS)". Sada samo najnoviji odustali kod stola koji je osoblje naplatilo stoji za tu naplatu.
    • PDV u meniju: forma artikla nudila je 17 % (stopu BiH) i lokalima u Srbiji, a fiskalni račun u Srbiji tu stopu odbija. Sada nudi stope zemlje lokala, u Srbiji 20 % i 10 %.
    • KM na dinarskim ekranima: napojnice (zbir i isplate), izvještaj po stolovima i po osoblju, cijena u formi menija i iznos u usklađivanju sada pišu valutu lokala; isplata napojnice se bilježi u valuti lokala.
    • Cijene na ekranu gosta sada imaju razdvajanje hiljada (2.900,00 RSD) i na dugmetu za dodavanje, kao svuda drugdje.
    • Isti tekst za Srbiju na svim ekranima gosta: izbor načina plaćanja i ekran sa kodom sada odlučuju po istom, po formatu koda lokala.

    0.76.83

    3. oktobar 2026.

    Ispravljeno

    • Kartica odobrena nakon otkazivanja računa se gubila. Gost potvrdi plaćanje u aplikaciji banke dok konobar otkaže račun (ili gost izađe sa ekrana sekundu prekasno): kartica je naplaćena, a račun je ostajao otkazan i gost je trebao platiti ponovo. Sada potvrđena naplata od procesora zatvara račun i sto, a ako je sto već naplaćen drugačije, plaćanje se označi kao dvostruko, kao i kod prenosa.
    • Monri u probnom načinu mogao je zatvoriti pravi račun bez novca, jer svako može platiti objavljenom probnom karticom. Na pravom sistemu probno odobrenje sada samo provjeri vezu: zapiše se, gost vidi da račun nije zatvoren, a račun ostaje otvoren. U podešavanjima piše šta probni način radi.
    • Osvježena stranica prikazivala je podatke za uplatu na račun ispod kartičnog računa. Sada se gost vraća na polja kartice; kartični račun nema bankovnih podataka. Drugi dodir na Plati karticom otvara isti račun umjesto greške, a istekao kartični račun traži karticu ponovo, ne IPS kod.
    • Monri skripta koja se jednom nije učitala blokirala je svaki sljedeći pokušaj do osvježavanja stranice. Sada se učitava ponovo.
    • Monri ponavlja povratnu poruku dok ne dobije odgovor 200, a XPay je odgovarao 201. Sada odgovara 200.
    • Promjena procesora ili ključa dok gost plaća činila je da se njegovo odobrenje ne može provjeriti. Sada se odbija dok traje kartično plaćanje u toj poslovnici, a odgovor procesora se provjerava prema procesoru sa kojim je plaćanje počelo.
    • Prazan e-mail se više ne šalje Monri-ju.
    • Podešavanja kartica: otvaranje jedne pa druge poslovnice moglo je prikazati token prve poslovnice u formi druge.
    • Povrat ili poništenje urađeno u Monri portalu, druga naplata istog računa i pogrešna valuta sada se zapisuju na plaćanju i u tragu promjena, umjesto da nestanu.
    • Rotacija ključa za šifrovanje sada obuhvata i Monri ključ i ključ ESIR-a u oblaku, sačuvane u podešavanjima lokala; ranije bi poslije rotacije svako kartično plaćanje prestalo raditi.

    0.76.82

    3. oktobar 2026.

    Ispravljeno

    • Fiskalni račun mogao je otići na uređaj drugog lokala. Konektor uparen bez poslovnice čuo je račune svih lokala firme, pa je račun iz jednog lokala mogao biti fiskalizovan na uređaju drugog. Sada XPay šalje račun samo konektoru uparenom za tu poslovnicu (ili jedinom, kad firma ima jednu poslovnicu), i samo konektoru uparenom iz konzole. Firma sa više poslovnica pri uparivanju bira poslovnicu.
    • Odgovor uređaja prima se samo od konektora kome je račun poslat. Ranije je bilo koji ključ koji čita plaćanja mogao upisati broj računa i link koje gost vidi kao fiskalni račun.
    • Pošalji ponovo nije stizalo do uređaja dok se konektor ne restartuje, ako je uređaj prvi put odbio (nema kartice, traži PIN). Sada stiže.
    • Izdat račun se ne gubi kad u lokalu padne internet: konektor čuva odgovor uređaja i šalje ga ponovo dok ga XPay ne primi.
    • Svaki sto koji se sam zatvorio prazan pravio je neizdat fiskalni račun u konzoli. Prazan sto i sto otpisan kao neplaćen više se ne šalju.
    • Fiskalni račun brojao je i uplatu koja nije pokrila sto (nedovoljna uplata), pa je gotovina na računu bila manja nego u kasi. Sada se broji samo novac koji je stvarno pokrio sto.
    • Ponovljen pokušaj šalje isti račun, ne ponovo sastavljen. Kad se ne zna da li je ESIR izdao račun, ide isti sadržaj, pod istim ključem, istom ESIR-u. Ako je lokal u međuvremenu promijenio ESIR, takav račun čeka osobu umjesto da ode drugom ESIR-u.
    • Mjerna jedinica: vino na litru više ne piše "/kg", niti 350 grama sira "350 kg".
    • Lista fiskalnih računa za osoblje sa više poslovnica pokazivala je račune svih njihovih poslovnica kad su tražili jednu.
    • Gost poslije drugog plaćenog računa više ne vidi fiskalni račun prethodnog, a "Fiskalni račun se izdaje..." ne stoji zauvijek kad račun ne stigne.
    • Terminal, kasa, Novi račun u konzoli i konektor nisu mogli izdati kod u Srbiji: slali su KM. Kod se sada izdaje u valuti lokala, u Srbiji u dinarima.
    • Kartica koju procesor nije pokrenuo zaključavala je sto: račun je ostajao otvoren, sto nije mogao naručivati, a konobar nije mogao naplatiti gotovinom. Sada se takav račun otkazuje i sto se otvara.
    • Snimanje rasporeda stolova moglo je pregaziti upravo upisan Monri ključ ili fiskalnu vezu, jer sve stoji u istim podešavanjima lokala. Sada se svaka postavka upisuje zasebno.

    Novo

    • Bez fiskalnog računa: u konzoli, pod Fiskalizacija, lista naplaćenih stolova koje XPay još nije poslao ESIR-u, sa dugmetom Izdaj fiskalni račun. Kad je automatsko izdavanje isključeno, odatle se šalju (do sada nije bilo načina).
    • Provjera svakih pet minuta: XPay sam ponovo šalje račune na koje uređaj ili ESIR nije odgovorio i stolove čije zatvaranje nije stiglo do fiskalizacije, najviše dan unazad i najviše pet pokušaja po računu.
    • Konektor 0.4.1: stranica konektora odbija zahtjeve sa drugih sajtova, pa web stranica otvorena na računaru kase ne može upariti konektor niti preusmjeriti fiskalni uređaj; promjena adrese uređaja briše sačuvani ključ i PIN.

    0.76.81

    2. oktobar 2026.

    Novo

    • Fiskalizacija za lokale u Srbiji. U konzoli, pod Fiskalizacija, lokal prvo pronađe svoju fiskalnu kasu u zvaničnom registru Poreske uprave (svih 968 odobrenih elemenata: 810 ESIR-a i 158 L-PFR-ova, pretraga po nazivu, dobavljaču ili broju elementa, latinicom ili ćirilicom), pa izabere kako je XPay doseže: Otkucaj ili FiskalAPI (odobreni ESIR-i u oblaku sa API-jem, ključ iz njihovih podešavanja), lokalni fiskalni uređaj preko konektora (uređaj čiji odobreni ESIR ima API, npr. OFS P5 EFU), ili ručno na kasi kao do sada. Od tada se svaki račun plaćen preko XPay-a ili zatvoren na terminalu (gotovina, kartica na POS-u) fiskalizuje jednom: stavke sa jedinicom mjere i poreskom oznakom (Ђ 20 %, Е 10 %, А van PDV-a), plaćanja tačno do ukupnog iznosa (kartica, instant plaćanje za IPS kod, gotovina), bez napojnice. Račun bez navedene stope PDV-a se odbija, ne pogađa.
    • XPay nije ESIR i ne razgovara sa PFR-om. Fiskalni račun izdaje vaš odobreni ESIR, kako zakon traži; XPay mu šalje račun pod jednim ključem, pa ponovljen pokušaj vrati već izdat račun umjesto drugog.
    • Gost vidi fiskalni račun na telefonu, odmah na ekranu Plaćeno: broj, link za provjeru kod Poreske uprave i cijeli račun na dodir.
    • Štampa fiskalnog računa na štampaču u lokalu preko konektora, tačno kako ga je ESIR izdao, ćirilicom (kodna strana 1251), sa QR kodom za provjeru iznad završne linije; lokalni uređaj štampa sam.
    • Konektor 0.4.0: na njegovoj stranici novi dio Fiskalni uređaj (adresa, API ključ, PIN, koji ostaju samo na tom računaru); konektor uđe PIN-om kad uređaj traži, pošalje račun i javi rezultat. Izbor kodne strane štampača: obična slova, 852 latinica ili 1251 ćirilica.
    • U konzoli lista fiskalnih računa sa statusom, prikazom računa i dugmetom Pošalji ponovo; Provjeri vezu pita ESIR bez izdavanja računa i ispiše njegove poreske oznake.

    Ispravljeno

    • Račun za sto štampan iz konzole pisao je KM i na dinarskim računima. Konektor sada piše valutu lokala (RSD u Srbiji).

    0.76.80

    29. septembar 2026.

    Novo

    • Gost plaća karticom na svom telefonu. Uz "Bankovnom aplikacijom" i "Gotovinom", izbor "Karticom ovdje, na telefonu" otvara formu: ime i prezime, e-mail, pa polja za broj kartice, datum isteka i CVV koja crta sam procesor (Monri Components) unutar naše stranice, tako da podaci kartice nikad ne dođu do XPaya (PCI SAQ A). Kad procesor odobri, račun se zatvara kao kartica, potvrda ide gostu, konzola vidi plaćen račun. Kartica na konobarevom terminalu ostaje kao druga opcija.
    • Novac ide sa kartice gosta na račun lokala kod procesora. Lokal ima svoj ugovor sa Monrijem i bankom prihvatiocem; XPay čuva samo dva ključa koja Monri izda (authenticity token i merchant key, drugi šifrovan) i pokreće plaćanje u ime lokala. XPay nikad ne prima novac.
    • Podešavanje u konzoli, Postavke, "Kartice na telefonu": procesor, ključevi, test ili pravi promet, po poslovnici. Dok nije podešeno, kartica znači konobarev terminal, kao i do sada. Adresa za povratni poziv se šalje uz svako plaćanje, ništa se ne upisuje kod Monrija.
    • Monri odgovor se provjerava potpisom (SHA-512 nad sirovim tijelom i ključem lokala) prije nego što se išta povjeruje; plaćanje se knjiži samo za tačan iznos u valuti računa, drugačiji iznos ostaje osobi na pregled, odbijena kartica ostavlja račun otvorenim za drugu karticu, ponovljeni poziv se prihvati i ignoriše.
    • Probni procesor za razvojnu mašinu i testove: obična polja, ništa se ne naplaćuje, plaćanje se odobri ili odbije na klik. Na pravom sistemu se ne može uključiti.
    • API: PUT /v1/locations/:id/card-provider, POST /v1/t/:slug/session/pay sa method: "CARD", POST /v1/card/monri/callback; poslovnica u /v1/locations nosi cardProvider, naljepnica u /v1/t/:slug nosi payments.cardOnline.

    0.76.79

    29. septembar 2026.

    Novo

    • Spratovi. Raspored lokala ima padajući meni: podrum, prizemlje, sprat, drugi sprat, bašta, terasa. Svaki sprat je svoja prostorija sa svojim oblikom, zidovima i stolovima; sto ili dio prostorije se premješta na drugi sprat izborom u panelu. Ekran "Stolovi" i konobarev telefon nude spratove kao kartice čim lokal ima više od jednog; lokal sa jednom prostorijom ne vidi nikakav izbor. Sve što je nacrtano do sada je u prizemlju.
    • Srpski kod za plaćanje je proizvodni. NBS IPS QR kod, onaj koji čita svaka bankarska aplikacija u Srbiji, provjeren je na zvaničnom NBS generatoru/validatoru i za račun sa iznosom i za naljepnicu bez iznosa; oba su vratila "OK". Srpski lokal zato izdaje kodove bez posebne dozvole.
    • Gost u Srbiji plaća sa jednog telefona bez prepisivanja. Na ekranu čekanja stoji dugme "Sačuvaj kod u galeriju" (na telefonu se otvori dijeljenje, gdje je "Sačuvaj sliku"), a koraci kažu: u aplikaciji banke IPS skeniraj, učitaj iz galerije, sva polja se popune sama, potvrdi PIN-om. Svaka srpska bankarska aplikacija učitava IPS kod iz galerije, jer tako plaćaju račune koji stignu mejlom. Izbor "Bankovnom aplikacijom" to i kaže srpskom gostu. Podaci za ručni nalog ostaju ispod za svaki slučaj.

    Ispravljeno

    • Račun naplaćen gotovinom pisao je "Otkazano" na listi plaćanja. Konobar prvo povuče kod za uplatu pa zatvori račun gotovinom, a lista je pokazivala samo sudbinu koda. Sada red kaže "Naplaćeno gotovinom" ili "Naplaćeno karticom (POS)", a ispod sitno "kod za uplatu otkazan" ili "istekao". API uz svaki kod vraća i kako je račun iza njega na kraju naplaćen.

    0.76.78

    29. septembar 2026.

    Novo

    • Okretanje koje stvarno okreće. Dugme "Okreni" je do sada samo zamjenjivalo širinu i visinu, pa se ništa nije vidjelo na kvadratnom stolu i ništa nije moglo stati ukoso. Sada svaki dio prostorije i svaki sto ima ugao: ručka iznad izabranog komada okreće ga povlačenjem (uz mrežu ili Shift u koracima od 15 stepeni), a u panelu su dugmad za 15 i 90 stepeni i polje za tačan broj. Ugao se vidi i na ekranu sa stolovima i na konobarevom telefonu; natpis stola ostaje uspravan ma kako sto stajao, a naziv šanka ide uz šank i nikad naglavačke.
    • Sto se može obrisati. Do sada se sto mogao samo povući, pa je pogrešno napravljen raspored s prvog dana zauvijek stajao na listi. Novo dugme "Obriši" na listi i na rasporedu briše sto i njegov kod za stalno, ali samo ako za njim nema ničega: sto koji ima račune, narudžbe, uplate ili rezervacije server odbija i objašnjava da ga treba povući, jer izvještaji računaju na te podatke. Sa rasporeda se sto može i povući i vratiti u upotrebu bez odlaska na listu.
    • Razvlačenje i za stolove, ugao za ugao, uz polja za širinu, visinu i položaj u procentima za sve što stoji u prostoriji.
    • Prostorija dobija oblik: standardna 4:3, široka 16:9, dugačka 2:1, kvadratna ili duboka 3:4. Isti oblik crtaju sva tri ekrana.
    • Još dijelova prostorije: stub, stepenice, biljka i slobodan natpis, uz zid, vrata, prozor, šank, kuhinju, WC i zonu. Vrsta postojećeg dijela se može promijeniti bez brisanja.
    • Mreža za poravnanje (uključena, isključi se dugmetom ili držanjem Alt tokom povlačenja), zaključavanje gotovih dijelova da se ne pomjere slučajno, dupliranje, dovođenje ispred ili iza drugog dijela, i Poništi / Ponovi za svaku promjenu, uključujući pomjeranje stolova.
    • Tastatura: strelice pomjeraju izabrano (sa Shift više), Delete briše dio ili skida sto sa rasporeda, R okreće za 90 stepeni, Ctrl+Z i Ctrl+Y vraćaju, Ctrl+D duplira, Esc skida izbor.
    • Snimanja se sada nižu u red i sažimaju, pa brza ruka više ne može poslati stariju verziju prostorije poslije novije. Stanje "Snima se / Sve je sačuvano" stoji u traci iznad rasporeda.

    0.76.77

    29. septembar 2026.

    Novo

    • Srpski jezik u konzoli, na terminalu, na kasi i na gostovoj stranici. Treći katalog, sr.json, ekavica na latinici, sa svih 2.856 poruka koje imaju bosanski i engleski. Napravljen je iz bosanskog rječnikom od 1.700 cijelih oblika riječi (mjesec u mesec, vrijeme u vreme, riješi u reši, dvije u dve, uvjet u uslov, porezna u poreska, sedmica u nedelja, obavijest u obaveštenje), nikad pravilom po slovima, jer bi ono od nije napravilo ne; svaka riječ koju rječnik nije pokrio ispisana je i pregledana. Ista provjera koja drži bosanski i engleski u korak sada drži i srpski: ključ koji nedostaje u bilo kojem od tri ruši build.
    • Na srpskoj adresi konzola se otvara na srpskom, a prekidač jezika nudi SR i EN; na bosanskoj BS i EN, kao i do sada. Ko je već izabrao jezik, zadržava izbor na obje adrese.
    • Gostu čiji je telefon na srpskom stranica se otvara na srpskom, a hrvatski i crnogorski telefoni i dalje dobijaju bosanski, koji im je ijekavicom bliži. Birač jezika na gostovoj stranici nudi i SR.

    0.76.76

    29. septembar 2026.

    Novo

    • Raspored lokala je sada prostorija, ne samo stolovi na mreži. Na stranici stolova poslovnice, iznad naljepnica, vlasnik dodaje zidove, šank, kuhinju, vrata, prozore, WC i zone (bašta, terasa, pušački dio), povlači ih gdje stoje, razvlači za ugao na pravu veličinu, okreće, boji jednom od osam boja i imenuje kako lokal zove taj dio. Stolovi zadržavaju ime sa naljepnice. Sve se čuva čim se pusti miš, na samoj poslovnici, bez nove tabele. Konzola uveče crta istu prostoriju ispod stolova.
    • Konobar vidi prostoriju na telefonu. Ekran sa stolovima na terminalu je dosad bio mreža sortirana po šifri naljepnice; čim je lokal raspoređen, konobar dobija prostoriju sa stolovima gdje stoje, istim bojama stanja i prekidačem na listu za mali ekran. Izbor se pamti na uređaju.
    • Do stolova se sada dolazi. Prazna stranica Stolovi vodi dugmetom na stranicu gdje se stolovi, kodovi i raspored prave, a link na kartici poslovnice više se ne zove samo Kodovi za stolove nego Stolovi, kodovi i raspored. Dosad je stajao sitan gore desno i tražio se.

    Ispravljeno

    • Zaostale marke na ekranima lokala iz Srbije. U prevodima je KM bilo otkucano u dvadesetak poruka (potvrde naplate, marža jela, dugme Pošalji, zaključenje dana, promjena cijene, granica instant plaćanja), a nekoliko ekrana je iznose formatiralo bez valute: pregled (Pregled poslovanja), stolovi, dnevni zaključak, izvještaji po stolovima i osoblju. Sad iznos dolazi iz koda već sa svojom valutom, granica instant plaćanja se više ne navodi kao broj u markama, a izvještaji i dnevni zaključak broje u valuti lokala. Bosanski lokali vide isto kao prije.
    • Firma napravljena za Srbiju dobija srpski kao jezik lokala (za gostovu stranicu i prvi prikaz konzole), umjesto bosanskog; vlasnik ga može promijeniti u podešavanjima.

    0.76.75

    29. septembar 2026.

    Ispravljeno

    • Dugme Kreiraj se gasilo bez riječi. Kad je vlasnik na dnu dugog obrasca bio nepopunjen, ili je upisana lozinka bila kraća od 10 znakova, dugme je bilo sivo i ništa nije govorilo zašto; operater sa upisanom firmom, poslovnicom i računom vidio je mrtvo dugme i zaključio da se firma ne može napraviti. Pored dugmeta sada piše šta još nedostaje, po imenu polja, u podnožju koje je uvijek na ekranu.
    • Za Srbiju polje poreskog broja se zove PIB, sa napomenom da ima 9 cifara, a napomena uz račun kaže da može i broj od 18 cifara i IBAN koji počinje sa RS. Do sada je i za srpsku firmu pisalo PDV / JIB.

    0.76.74

    29. septembar 2026.

    Ispravljeno

    • Bankarski smoke test je padao od 25. septembra na prijavi preko demo providera. Pravilo iz pregleda bankarske platforme kaže da se OIDC adresa uzima samo kad provider tvrdi da ju je potvrdio (email_verified), a demo provider u sandboxu, koji glumi bankin imenik, tu tvrdnju nije slao, pa je svaka demo prijava odbijena sa email_unverified i šest provjera je padalo. Demo token sada nosi tvrdnju, kao što je nosi imenik banke za adresu pod kojom čovjeka zna. Pravilo ostaje kakvo jeste.

    0.76.73

    29. septembar 2026.

    Ispravljeno

    • Lokal iz Srbije je gostima pokazivao marke. Sloj države je od 0.76.56 znao da lokal u Srbiji broji u dinarima, i plaćanja i linkovi su to poštovali, ali tok narudžbi nije: servis narudžbi je u svaki pregled stola, narudžbe, zatvaranja i zahtjeva za plaćanje upisivao BAM, stavke menija su dobijale podrazumijevanu valutu kolone, štampani račun je bio u markama, a gostova stranica, terminal konobara, raspored stolova, lista za narudžbe, kasa, pregled stolova i meni u konzoli imali su slovo KM otkucano pored svake cifre. Sada svaki iznos nosi valutu lokala: iz države lokacije, jednom po lokaciji, i ekrani ispisuju ono što dobiju. Lokal u Bosni vidi isto što i do sada; lokal u Srbiji vidi dinare na meniju, na računu, na telefonu gosta i na kasi.
    • Pregled lokacije i uparivanje uređaja kažu valutu. Lista lokacija nosi državu i valutu, uparen terminal i kasa dobiju valutu lokala pri uparivanju; uređaj uparen prije ove verzije je bosanski i ostaje na markama dok se ne upari ponovo ili ne pročita listu lokacija, što kasa radi sama.
    • Terminal i kasa više ne šalju valutu API-ju. Slali su BAM uz svako plaćanje; sada plaćanje uzima valutu lokacije, kao što je servis plaćanja odavno umio.

    0.76.72

    29. septembar 2026.

    Novo

    • Srpska naslovnica je bosanska naslovnica, traka po traka, za jedan proizvod. Do sada je xpay.rs otvarao stranicu ugostiteljstva kakva je na bosanskom sajtu: lista šta gost može i šta lokal dobija, pisana kao dio većeg sajta koji je već objasnio kako proizvod radi, šta košta i čiji je novac. Sada je naslovnica na srpskoj adresi ista kao na bosanskoj: naslov u tri riječi (Meni. Narudžba. Plaćeno.), konzola, stalak i telefon u tri dubine, traka sa šest oznaka, šest vrsta lokala umjesto šest vrsta firmi, proizvod sa računom za sto koji zna kako da bude plaćen, četiri koraka od koda na stolu do plaćenog računa, čiji je novac (gost, banka, račun lokala), šta osoblje vidi, konzola kakvu vidi lokal (stolovi večeras, u dinarima), paketi u dinarima sa ugostiteljskim dodatkom i unosom menija, i umjesto trake o Sarajevu traka o fiskalnoj kasi: ostaje vaša, XPay stoji pored nje, konektor za ESIR i L-PFR se razvija po uputstvu Poreske uprave. Slike proizvoda su u dinarima: meni sa ćevapima, čorbom, burekom i kafom po cijenama iz Srbije, račun u dinarima, konzola sa stolovima.
    • Sajt zna na kojoj je adresi. Na xpay.rs je kanonska adresa xpay.rs, naslov i opis su za restorane i kafiće u Srbiji, strukturirani podaci nude pakete u dinarima, sitemap i robots navode xpay.rs, logo piše .rs, a slika koja ide uz link u Viberu govori o Srbiji i piše xpay.rs. Do sada je svaka stranica na xpay.rs govorila pretraživaču da je kopija xpay.ba.
    • Jedan proizvod, jedna vrata. Srpski sajt prodaje ugostiteljstvo i ništa drugo, pa stranice za firme, banke i integracije, kao i stranica ugostiteljstva čiji je sadržaj već na naslovnici, vode na naslovnicu. Meni gore ima proizvod, kako radi, cijene i kontakt; podnožje isto. Stranica cijena u dinarima navodi i tabelu poređenja i pitanja za lokal; nijedna marka ne ostaje ni u opisu za pretraživač.
    • Zatraži XPay na srpskoj adresi je zahtjev, ne probni nalog. Probni obrazac otvara bosansku firmu u markama, i lokal iz Srbije bi na prvom ekranu vidio pogrešan novac. Prvi lokali u Srbiji dobijaju postavku uz nas, što bosanski sajt već obećava; sada to piše i na adresi koju su ukucali.
    • app.xpay.rs. Konzola se otvara i na srpskoj adresi, sa certifikatom i dozvolom za API. Prijava i podnožje na xpay.rs vode tamo. Obje adrese su ista konzola i ista baza: svejedno je gdje se operater prijavi.
    • Država pri dodavanju firme. Operater u admin konzoli bira Bosnu i Hercegovinu ili Srbiju. API je to polje primao od uvođenja sloja države, a obrazac ga nikad nije slao, pa je svaka firma napravljena tu bila bosanska bez obzira na namjeru. Srbija daje dinar, PIB, stope 20 i 10 posto, IPS kod Narodne banke Srbije i račun od 18 cifara.

    Ispravljeno

    • Meni gore je na xpay.rs prvo pokazivao bosanski meni pa se mijenjao. Sada zaglavlje dobija tržište od servera i prvi prikaz je tačan na obje adrese.

    0.76.71

    29. septembar 2026.

    Novo

    • 2D raspored lokala. Na stranici stolova poslovnice vlasnik povuče svaki sto tamo gdje stvarno stoji: sjedeći, visoki, šank, bašta. Ekran sa stolovima uveče onda pokazuje prostoriju kakva jeste, sa istim bojama stanja kao i dosad, umjesto rešetke sortirane po šifri naljepnice, što je redoslijed u kojem su naljepnice štampane i ni po čemu drugom. Ko ne rasporedi ništa, vidi listu kao i prije; ko rasporedi, bira između rasporeda i liste i izbor se pamti na tom uređaju. Raspored se čuva na samom stolu, bez nove tabele.
    • xpay.rs u dinarima. Stranica cijena na srpskoj adresi navodi dinare u svakom paketu, stopi, dodatku i usluzi: Flex 0 RSD uz 3 RSD po transakciji, Start 2.900, Business 5.900, Pro 11.900, ugostiteljstvo 2.900 po poslovnici, prekoračenja 1,80, 1,20 i 0,60, unos menija 90 po stavci. Iste brojke koje su do sada stajale u jednom pasusu ispod tabele u markama. Test ne dozvoljava nijednu marku na srpskoj stranici: nova cijena u markama padne na provjeri dok joj se ne napiše dinar.

    Ispravljeno

    • Naslovnica xpay.rs se nije otvarala na stranicu ugostiteljstva iako je to od 0.76.70 trebala. Uzrok nije bio u sajtu nego u nginxu: kad location blok ima svoj proxy_set_header, ne nasljeđuje nijedan iz server bloka, pa je sajt dobijao Host: 127.0.0.1:3001 i nikad nije saznao na kojoj je adresi tražen. Popravljeno na serveru istog dana, i u instalacionoj skripti za sve adrese, jer je ista greška stajala u sva četiri bloka.
    • Konzola na app.xpay.rs. Instalacija sada u dozvoljene adrese za API uvrsti i app. ispred svake dodatne domene, jer se konzola sa srpske adrese prijavljuje preko API-ja na bosanskoj. Sam nginx blok i certifikat za app.xpay.rs se postavljaju kad DNS zapis postoji kod nadležnih nameservera.

    0.76.70

    29. septembar 2026.

    Novo

    • xpay.rs je sajt za restorane i kafiće. Naslovnica te adrese je stranica ugostiteljstva, a meni nudi ugostiteljstvo, cijene i kontakt. Ostalih sedam djelatnosti se u Srbiji ne prodaje, pa ih sajt tamo ni ne nudi. Adresa ostaje "/", stranica ispod nje je prava.
    • Cijena unosa menija umjesto vas, na stranici cijena. Meni se i dalje unosi sam, besplatno. Ko bi radije da to uradimo mi: 1,50 KM po stavci, najmanje 49 KM po meniju, slike iz XPay biblioteke uključene; fotografisanje vaših jela 5 KM po jelu uz najmanje 20 jela. U Srbiji 90 RSD po stavci, najmanje 2.900 RSD, fotografisanje 290 RSD po jelu.
    • Šta u Srbiji stoji iza kase, pročitano iz izvora i zapisano u docs/en/SERBIA_POS_AND_STANDARDS.md. Registar odobrenih kasa ima oko hiljadu unosa, pa se ne integriše kasa po kasa. Ali zvanično uputstvo Poreske uprave kaže da svaka kasa sa svojim fiskalnim procesorom govori jednim HTTP protokolom po Tehničkom vodiču, i taj protokol nosi cijeli račun. Plan za Srbiju je zato jedan konektor koji stoji između kase i procesora, ništa ne mijenja i vidi svaki račun. Za probu treba registracija na razvojnom portalu Poreske uprave, što je na bordu.

    Ispravljeno

    • Limit po instant nalogu u Srbiji je 300.000 dinara, iz opisa sistema Narodne banke Srbije. Do sada je namjerno bio prazan, jer pogođen broj griješi u oba smjera; sada račun preko tog iznosa biva odbijen prije nego se odštampa kod koji bi banka gosta odbila.
    • Test srpskog QR koda je tvrdio račun od 16 cifara, jer je tekao nad bosanskim IBAN-om uz dinarski iznos. Srpski račun ima 18. Kod je bio ispravan, test nije; sada tvrdi ono što srpska banka stvarno izdaje.

    0.76.69

    29. septembar 2026.

    Promijenjeno

    • Ćirilica je izbačena. Konzola i bankarska aplikacija nude bosanski i engleski, kao prije 0.76.60. Izbor pisma je odgovarao na pitanje koje niko nije postavio: čitalac u Beogradu ne traži bosanski drugim slovima nego svoj jezik.
    • Jezici zavise od adrese. Na .ba adresama su bosanski i engleski, na .rs adresama biće srpski i engleski. Srpski se ne može napraviti iz bosanskog onako kako je ćirilica mogla: pismo je preslikavanje i mašini se smije prepustiti, a ijekavica u ekavicu nije. Pravilo koje "prije" pretvori u "pre" pretvori i "nije" u "ne", a to je druga riječ i rečenica koja onda znači suprotno. Srpski katalog piše neko ko ga govori, a prekidač ga nudi onog dana kad postoji; do tada .rs nudi bosanski, što je ono što ta adresa i danas prikazuje.

    0.76.68

    25. septembar 2026.

    Ispravljeno

    • "Dodavanje firme nije uspjelo" nad firmom koja je bila napravljena. Dovođenje firme iz banke napravi firmu, njenu poslovnicu, račun vlasnika i vezu s bankom, pa pošalje vlasniku pozivnicu na e-mail i čeka da pošta potvrdi. Ovaj server nema obrnuti DNS zapis, pa mail.xpay.ba odgovara tek nakon dvadeset sekundi i nešto, izmjereno 20,8 sekundi iz kontejnera, a pretraživač odustaje na dvadeset. Ekran je javljao neuspjeh nad poslom koji je u cijelosti prošao, a operater bi pokušao ponovo. Sada se na poštu čeka najviše pet sekundi: slanje se nastavi svojim tempom, a zahtjev se vrati.
    • Isto je padalo i "zaboravio sam lozinku", što je gore, jer je to put natrag kad ništa drugo ne radi.
    • Da li je poruka otišla se i dalje javlja, jer pozivnica koja nije otišla je razlog zbog kojeg operater dobije link da ga preda rukom. Poruka koja stigne poslije petog sekunda se prijavi kao neposlana, što košta jedan link koji nije trebao, i to je bolja strana za pogriješiti.
    • Slanje fakture i računa e-mailom se i dalje čeka do kraja, jer je tamo pošta sama radnja a ne posljedica.

    0.76.67

    25. septembar 2026.

    Novo

    • Stranica "Šta je šta", u bočnoj traci ispod sekcija. Svaka sekcija kontrolnog centra, grupisana po modulu, sa rečenicom koja kaže čemu služi. Sekcija koju vaša rola ne koristi, ili koju ugovor banke ne nosi, je navedena i označena a ne sakrivena: pitanje "zašto ovo ne vidim" se odgovara na stranici umjesto pozivom podršci. Objašnjenja nisu pisana zasebno nego su ona ista koja već stoje na vrhu svake sekcije, pa ne mogu zastariti odvojeno od nje. Otvorena je svakoj roli, jer vodič koji traži pravu rolu objašnjava sekcije samo onima koji ih ionako vide.

    Ispravljeno

    • Ekrani banke koriste cijelu širinu. Sadržaj je bio ograničen na 1152 piksela i centriran, unutar prostora koji već daje bočnoj traci svoje, pa je na širokom ekranu stajao kao kolona u sredini sa prazninom sa obje strane. Na ekranu od 1760 piksela to je 1152 umjesto 1505, i sadržaj koji počinje 177 piksela desno od trake. Ove stranice su tabele, grafovi i mreže kartica i imaju gdje da stave prostor.

    0.76.66

    25. septembar 2026.

    Ispravljeno

    • Zapis revizije koji izgubi utrku se sada upisuje iza onoga ko je pobijedio, umjesto da se izgubi. Ograda dodana u 0.76.65 sprečava da se lanac račva, ali odbijeni upis je i dalje odbijen, a greška u reviziji se zapisuje u log i nikad ne obori zahtjev koji je bilježila. To znači da bi se red revizije tiho izgubio, što nije bolje od račvanja nego samo drugačije loše. Odbijanje se sada čita kao "vrh lanca se pomjerio" i upis se ponovi iza novog vrha, do tri puta, jer petlja koja ne može stati je gora od jednog reda koji nedostaje.

    0.76.65

    25. septembar 2026.

    Ispravljeno

    • Izuzeće od drugog faktora u jednoj banci više ne briše ga svugdje. Autentikator stoji na osobi, jer osoba ima jedan telefon, a izuzeće na članstvu, jer je to odluka jedne banke. Poštovanje drugog brisanjem prvog je doticalo sve u šta se ta osoba prijavljuje: konzolu njene firme i svaku drugu banku u kojoj radi. Administrator jedne banke je mogao skinuti drugi faktor osobi koja je administrator u drugoj banci ili vlasnik firme, i nijedna to ne bi saznala. Ostaje mogućnost za člana koji radi samo tu, jer je to onda stvarno stvar te banke, i to je jedini put natrag za nekoga ko je izgubio telefon. Gdje nije, izuzeće i dalje vrijedi a telefon ostaje.
    • E-mail koji sistem banke nije potvrdio više ne dohvata postojeći račun. E-mail tu nije oznaka nego ključ: dohvata postojeće članstvo i veže identitet na njega, i dohvata postojeći račun na platformi i dodaje mu bankarsko članstvo. To drugo izlazi iz banke, jer račun može pripadati vlasniku firme ili administratoru druge banke. OpenID Connect ima tvrdnju baš za to pitanje i odsustvo je odgovor, a odsustvo se prije čitalo kao potvrda.
    • Rolu iz grupa sada određuje redoslijed banke, ne redoslijed direktorijuma. Uzimala se prva grupa koju sistem banke pošalje, pa je ista osoba iz istih grupa mogla doći kao revizor jedan dan i kao operater naplate drugi, bez da se bilo gdje šta promijenilo. Sada odlučuje redoslijed koji je banka napisala. Ako su dvije grupe pogodile, to se zapisuje u reviziju, jer je to direktorijum koji je prerastao svoje pravilo.
    • Banka koja imenuje svoj atribut za e-mail i grupe čita samo njega. Uz imenovani atribut su se i dalje dodavala podrazumijevana imena, pa je suženje postajalo proširenje: kad imenovanog atributa nema u tvrdnji, identitet bi došao iz atributa koji banka nikad nije navela. Ime za prikaz i dalje zna uobičajena imena, jer tu rezerva ne kupuje ništa osim manje poziva podršci.
    • Lanac revizije banke je dobio ogradu u bazi koju su trgovački imali. Postgres NULL-ove u jedinstvenom indeksu smatra različitima, pa ograničenje nad kolonom trgovca nije pokrivalo redove banke ni platforme. Dva upisa u isti lanac u istom trenutku bi uzela isti broj i lanac bi se račvao, a red na napuštenoj grani se onda može dodati ili skloniti bez da pokvari hash grane koju neko provjerava. Revizija se i dalje zapisuje redom unutar procesa, što je i razlog da se to nije desilo, ali ta zaštita vrijedi tačno dok postoji jedan proces.

    0.76.64

    25. septembar 2026.

    Ispravljeno

    • Izmjena u instalacionoj skripti je tražila dva update-a da proradi. Skripta sama povlači novu verziju sebe, a onda nastavi po starom: kad se fajl zamijeni pod njom, pokrenuti shell i dalje čita stari, dovrši ga do kraja, a nova verzija ostane na disku neiskorištena. Verzija na status stranici bi skočila, rezultat bi rekao da je uspjelo, a ponašanje bi ostalo staro. Danas je to dvaput izgledalo kao da popravka ne radi. Sada skripta primijeti da se promijenila i pokrene novu verziju, jednom, sa istim argumentima koje je dobila.

    0.76.63

    25. septembar 2026.

    Ispravljeno

    • Instalacija koja je uspjela prijavljivala se kao neuspjela. U zadnjem koraku je stajala naredba koja pripada funkciji, van funkcije. Sve prije nje je prošlo: certifikati zakačeni, nginx napisan i ponovo učitan, aplikacije pokrenute. Onda je skripta stala na toj liniji i vratila grešku, pa bi vlasnik u konzoli vidio "update nije uspio" iznad servera na kojem je update uspio.
    • Provjera na GitHubu sada hvata tu vrstu greške. Dosadašnja provjera skripti prevodi ih bez pokretanja, a ovakva greška nije u sintaksi nego se javlja tek pri izvršavanju, pa je prolazila. Prva verzija nove provjere je brojala zagrade i nikad se nije oglasila, jer skripta ima zagrade i u navodnicima i u drugim naredbama. Provjera koja ne može pasti je gora nego da je nema, pa se sada oslanja na granice funkcija i testirana je na grešci zbog koje postoji.

    0.76.62

    25. septembar 2026.

    Ispravljeno

    • Naslovnica je dvadesetak minuta vodila na prijavu. Popravka iz 0.76.61 je naučila instalaciju da je app.xpay.ba iza Cloudflarea i dalje naša adresa, ali samo za konzolu. Istu provjeru koriste i www, bankarska aplikacija i certifikati, pa su te i dalje otpadale: www je ispao iz certifikata, bankarska aplikacija je ostala bez svog bloka, a naslovnica bez HTTPS-a. HTTPS na xpay.ba je onda pao na prvi blok koji ga još ima, a to je konzola, koja svakog posjetioca šalje na prijavu. Sada sve adrese odgovaraju na isto pitanje.
    • Zaštita koja je to trebala spriječiti se nije oglasila. Pitala je postoji li u konfiguraciji ijedan HTTPS blok. Jedan je preostao, pa je zaključila da je sve uredu. Sada broji: ako HTTPS pokriva manje adresa nego prije, vraća prethodnu konfiguraciju i kaže koliko ih je izgubljeno.

    0.76.61

    25. septembar 2026.

    Ispravljeno

    • Konzola se ponovo otvara. Stranica za prijavu je treperila između dvije adrese i nikad se nije otvorila. Konzola je zvala API na adresi sajta umjesto na svojoj, pa je pretraživač odbijao svaki njen poziv kao poziv prema tuđoj adresi. Nije mogla saznati ni da li ste prijavljeni, i vrtjela je u krug.
    • Dugme Prijava na sajtu više ne vodi na 404. Bilo je sastavljeno od iste pogrešne adrese.
    • Uzrok je bilo prepoznavanje imena iza Cloudflarea. Instalacija provjerava da li app.xpay.ba pokazuje na ovaj server tako što uporedi adrese, a ime iza Cloudflarea odgovara adresama Cloudflarea, pa poređenje nikad nije prošlo. Skripta je zato zaključila da konzola nema svoju adresu i vratila svaku javnu adresu na xpay.ba. Nginx i konzola su na app.xpay.ba cijelo vrijeme radili, pa ništa nije izgledalo pokvareno dok neko ne klikne link. Ime iza Cloudflarea se sada priznaje kao naše.
    • Iz iste vrijednosti se grade i linkovi na fakturama, QR kodovi za stolove, linkovi za rezervacije i link za reset lozinke. Svi su pokazivali na sajt umjesto na konzolu i svi su ovim popravljeni.
    • Certifikati i dalje postavljaju strože pitanje, jer za njih proxy ispred servera jeste razlika. Ovo je samo o tome koju adresu proizvod smatra svojom.

    0.76.60

    24. septembar 2026.

    Novo

    • Ćirilica u konzoli i u bankarskoj aplikaciji. Isti bosanski, drugo pismo. Bira se uz jezik, BS ili ЋИР ili EN, i niko u nju ne upadne sam: telefon podešen na bilo koji jezik i dalje dobije latinicu. Nije prijevod nego isti tekst drugim slovima, pa se ćirilični katalog piše iz latiničnog i ne ispravlja se rukom. Provjera na GitHubu padne ako neko pokuša, jer dva kataloga koja se održavaju odvojeno vremenom počnu govoriti različito.
    • Bankarska aplikacija je dobila biranje jezika, na stranici Račun. Izbor jezika je čitala iz kolačića od prvog dana, a taj kolačić nije imao ko postaviti, pa su ekrani ostajali na bosanskom šta god ko volio.

    0.76.59

    23. septembar 2026.

    Ispravljeno

    • Spora gradnja slika više ne guta provjere. Provjera na GitHubu je imala jedan red za cijeli posao, a taj red drži i najsporiji korak u njemu: gradnja kontejnerskih slika zna trajati dvadeset pet minuta. Dok ona traje, svaki novi commit čeka, a red pušta samo jedan na čekanju, pa svaki sljedeći push otkaže onaj prije sebe. Tri commita zaredom su tako otkazana a da nisu ni provjerena. Sada svaki posao ima svoj red: provjera čeka provjeru, slike čekaju slike, i dokaz koji ništa ne propušta ne može zaustaviti provjeru koja propušta sve.

    0.76.58

    23. septembar 2026.

    Novo

    • xpay.rs poslužuje isti sajt, sa svojim certifikatom i preusmjerenjem sa HTTP-a. Srbija još nije otvorena za posao, pa je to zasad sajt i ništa više.

    Ispravljeno

    • Adresa na kojoj se sajt otvori više ne odlučuje da li radi. Skripte sajta zovu API na adresi koja se ugradi pri buildu, bez obzira ko je stranicu poslužio, pa svako ime na kojem sajt odgovara mora biti dozvoljeno. Nije bilo: posjetilac koji ukuca www ispred imena imao je status stranicu i formu za probu koje ne rade, a greška se vidjela samo u konzoli pretraživača. Popravljeno za www i za dodatne domene, koje se sada čitaju iz XPAY_ALT_DOMAINS pa ih ponovno pokretanje instalacije ne briše.

    0.76.57

    23. septembar 2026.

    Novo

    • Srbija na sajtu, u budućem vremenu. Naslovna, stranica za ugostiteljstvo i cijene kažu da XPay stiže u Srbiju i pozivaju prve lokale da se jave. Namjerno nije sadašnje vrijeme: dinar, računi od osamnaest cifara, PIB, stope od 20 i 10 posto i kod koji čitaju aplikacije banaka u Srbiji su napravljeni, ali lokala u Srbiji još nema, a tvrdnju koju posjetilac iz Beograda provjeri i ne nađe ne vrijedi napisati.
    • Cijene za Srbiju u dinarima, isti planovi i isti iznosi: Flex uz 3 RSD po transakciji, Start 2.900, Business 5.900, Pro 11.900 RSD mjesečno, i ugostiteljski paket 2.900 RSD po poslovnici. Stoje uz tabelu a ne u njoj, dok se tržište ne otvori.
    • Fiskalizacija se sada objašnjava po zemlji, jer nije ista stvar. U BiH zakon dolazi do avgusta 2027 i XPay već vodi evidenciju koju nabraja. U Srbiji je fiskalizacija na snazi i XPay nije sistem koji je zadovoljava: lokal zadrži uređaj koji ima, a XPay stoji pored njega isto kao pored kase u Bosni. To piše otvoreno, jer ko to mora da zaključuje, zaključiće ono što mu odgovara.
    • Stranici za banke dodano šta Srbija znači njima: IPS QR kod Narodne banke Srbije je javno objavljen, za razliku od profila za BiH. Profil koji banka u BiH potvrdi nije jednokratan posao nego podešavanje u sistemu koji radi u dvije zemlje.

    0.76.56

    23. septembar 2026.

    Novo

    • Link koji radi i nakon što je plaćen. Račun je jedno plaćanje: izda se, plati i gotov je. Link je ono drugo što firmi treba, a nije imala: jedna adresa koja i dalje radi. Upisnina na stranici škole, donacija, „platite ovdje" u podnožju fakture, kartica koju majstor ostavi. Svako otvaranje diže svoj račun sa svojom referencom, pa četrdeset ljudi koji plate jedan link budu četrdeset priliva koje uparivanje razlikuje, a ne jedan na koji se gleda ručno.
    • Fiksni ili otvoreni. Kod fiksnog je iznos izjava firme, ne prijedlog: šta god platilac pošalje, ignoriše se, jer bi inače svaki odštampani link bio formular koji svako popuni sam sebi. Kod otvorenog platilac upisuje iznos, unutar granica koje je firma postavila; bez granica je zatipkanih 7480 umjesto 74,80 nalog za sedam hiljada, a čovjek to sazna tek u svojoj banci.
    • Iznos se ne može mijenjati na postojećem linku, namjerno. Link koji je već odštampan, poslan ili zalijepljen na izlog je obećanje koliko košta. Nova cijena je novi link.
    • Račun se može poslati na telefon. Kupcu koji nije u prostoriji ode poruka s iznosom i adresom stranice koju taj račun već ima, pa plati iz svoje bankarske aplikacije. Ništa novo se ne izdaje, pa je račun poslan dvaput i dalje jedan račun.
    • Kanal za poruke, bez imena provajdera u kodu. Pošta ima SMTP koji svi govore; SMS nema ništa slično, pa je gateway opisan u postavkama: adresa, jedno zaglavlje s kredencijalom i kako taj gateway zove svoja tri polja. Promjena provajdera je promjena postavki, ne izdanje. Podrazumijevano je isključen i tada odbija i kaže zašto, jer poruka koja tiho nestane je gore od poruke koja nije poslana.
    • Broj telefona se čita onako kako ga ljudi pišu, svih šest načina, a fiksni se odbija: gateway bi ga uzeo i naplatio, a niko ga ne bi pročitao.

    Sigurnost

    • Šezdeset četiri napada na svakoj gradnji. Nova provjera vrti prave pokušaje zloupotrebe protiv žive aplikacije i svaka prolazi samo kad je napad odbijen: rute bez kredencijala, tokeni koji nisu ono što tvrde, kredencijal jedne firme nad tuđim računom, poseg iznad svoje uloge, ulaz koji treba pročitati kao kod, šta nikad ne smije nazad, gdje platforma odbija da bude uperena, opterećenje koje nije upotreba, i pogađanje na vratima.
    • Prvi nalaz istog dana: jedan NUL bajt u parametru stizao je do upita i vraćao grešku servera. Sada se odbija uredno, s imenom polja.
    • Ovo nije nezavisan pen test i nigdje se tako ne predstavlja. Ko je pisao pravila, pisao je i napade, pa ne može naći slučaj kojeg se niko nije sjetio. To piše i u dokumentu za banke, odmah do popisa.

    Za programere

    • Platforma sada pita u kojoj je državi firma umjesto da pretpostavlja: novac, sat, jezik, QR dijalekt, oblik broja računa, poreski broj, stope PDV-a i odnos prema zakonu o fiskalizaciji na jednom mjestu. BA je podrazumijevano i ponaša se tačno kao do sada; država bez napisanog profila se odbija po imenu umjesto da tiho dobije bosanska pravila.
    • docs/en/MARKETS.md kaže šta od svega pripada kojem tržištu i šta namjerno nedostaje.
    • scripts/pentest.mjs u CI-ju, poslije pregledača, jer namjerno prazni korpu prijava za svoju adresu.

    0.76.55

    23. septembar 2026.

    Ispravljeno

    • Odsječen odgovor više ne prolazi kao lista. Provjera oblika je prihvatala odgovor u kojem je valjan makar jedan red, pa bi prenos prekinut na pola bio upisan kao uža lista Cloudflareovih raspona; posjetioci izvan tog užeg dijela bi opet svi računali kao jedna adresa. Uz to je i sam neuspjeh curl-a bio progutan, pa se prekinut prenos nije ni primjećivao. Sada se čita izlazni status, i traži se najmanje deset IPv4 i pet IPv6 raspona: dovoljno ispod onoga što Cloudflare objavljuje da povlačenje jednog raspona ne bude kvar, i dovoljno iznad onoga što ostane od odsječenog odgovora.

    0.76.54

    23. septembar 2026.

    Ispravljeno

    • Lista Cloudflare raspona se više ne zakucava. Server prepoznaje pravu adresu gosta po tome što veza dolazi s nekog od Cloudflareovih raspona, a ta lista je bila prepisana jednom i ostala takva. Kad Cloudflare doda novi raspon, posjetioci koji stignu kroz njega bi svi računali kao jedna adresa, ograničavanje zahtjeva bi za njih prestalo vrijediti, a u dnevnik bi se umjesto čovjeka upisivao Cloudflare. Ništa ne bi prijavilo grešku. Instalacija sada listu povuče s Cloudflarea, a zakucana ostaje kao rezerva ako mreže nema, pa mašina bez interneta dobije ono što bi i inače imala.
    • doctor.sh sada tu listu poredi s Cloudflareovom i imenuje šta fali, pa je zastarjelost nešto što se vidi umjesto da se sumnja.
    • Pri pisanju te provjere nađena je greška koja bi je učinila beskorisnom: Cloudflareov odgovor ne završava prelomom reda, pa se zadnji IPv4 i prvi IPv6 raspon spoje u jedan red i oba ispadnu. Provjera bi svaki put javljala da su dva raspona zastarjela, a nisu. Sada se svaka lista čita zasebno; provjereno na serveru, javlja aktuelnih 22.

    0.76.53

    23. septembar 2026.

    Promijenjeno

    • Stranica, konzola i bankarska aplikacija idu kroz Cloudflare. IP servera više ne stoji javno u DNS-u, saobraćaj prolazi kroz rubnu mrežu, i telefon na slaboj vezi dobija HTTP/3.
    • Pošta i cPanel ostaju van toga, namjerno. Cloudflare ne proxya SMTP ni FTP, a cPanelove servise drži na portovima koje dijelom i ne proxya, pa bi ih narandžasti oblak ili oborio ili im tiho prekinuo obnovu certifikata. Skripta za podešavanje sada odbija da upali proxy na tim imenima čak i kad joj se izričito kaže, zajedno s hostom za bankarske sisteme: tamo nginx traži klijentski certifikat, a kroz proxy koji prekida TLS taj certifikat nikad ne bi stigao.
    • Provjereno da adresa gosta i dalje stiže. U dnevniku servera su stvarne adrese posjetilaca, 41 različita u zadnjih 300 zahtjeva, a ne šačica Cloudflareovih. Ograničavanje zahtjeva i revizijski dnevnik i dalje znače ono što su značili.

    0.76.52

    23. septembar 2026.

    Ispravljeno

    • Skripta za Cloudflare je odbijenicu prijavljivala kao nedostatak plana. Kada token nema pravo na neko podešavanje, Cloudflare vrati 403; skripta je to gutala i pisala "nije dostupno na ovom planu", što čovjeka šalje na stranicu za naplatu zbog kvačice koju je zaboravio. Sada razlikuje odbijeno od nepostojećeg, na kraju nabroji šta je odbijeno i kaže koje pravo dodati.
    • Zone ID se više ne mora držati u fajlu: token koji smije čitati zonu nađe je po imenu.
    • --skip-dns odradi podešavanja i pravila keša, a zapise ostavi sive. To je redoslijed koji se i koristi: dok se ne zna da je SSL na "Full (strict)", paljenje narandžastog oblaka može napraviti beskonačni redirect, jer bi Cloudflare origin zvao preko HTTP-a a nginx ga vraćao na HTTPS.
    • Popravljeno i čitanje --hosts, koje je bez te zastavice čitalo putanju do node-a umjesto imena.

    0.76.51

    23. septembar 2026.

    Promijenjeno

    • Adresa gosta preživi Cloudflare. Ako se domena jednom pusti kroz Cloudflare, svaki zahtjev bi inače na server stizao s adrese Cloudflareovog rubnog servera. Ograničavanje zahtjeva na javnim rutama gosta ide po adresi, a i revizijski dnevnik je bilježi: oboje bi tiho prestalo nešto značiti, i cijela zemlja bi dijelila jednu kantu. Nginx sada uzima pravu adresu iz Cloudflareovog zaglavlja, ali vjeruje samo vezama koje stvarno dolaze s njegovih raspona, pa je posjetilac koji dođe direktno ne može falsifikovati.
    • Postavljeno je i na serveru i u deploy/install.sh, pa ga ima i sljedeća mašina. Ne mijenja ništa dok se Cloudflare ne uključi.

    Za programere

    • scripts/cloudflare-setup.mjs podesi zonu preko Cloudflare API-ja: proxy na zapisima koje mu se kaže (nikad na mail imenima), SSL "Full (strict)", Always Use HTTPS, HSTS na šest mjeseci bez preloada, HTTP/3, i dva pravila keša - /v1/* se ne kešira nikad, a slike jela i statika se keširaju na rubu.
    • Bez argumenata samo ispiše šta bi promijenio; mijenja tek uz --apply, i pokretanje dvaput ne uradi ništa drugi put.
    • Token čita iz Claudflare_data.txt (van gita) ili iz CLOUDFLARE_API_TOKEN, nikad ga ne ispisuje. Treba token uskog opsega samo za zonu xpay.ba: Zone:Read, DNS:Edit, Zone Settings:Edit, Cache Rules:Edit.

    0.76.50

    23. septembar 2026.

    Popravljeno

    • Pečat koji čuva svaku zapečaćenu tajnu sada ima imenovanu dužinu. Enkripcija u mirovanju je AES-256-GCM, a uz šifrat stoji pečat koji dokazuje da ga niko nije dirao. Pečat je oduvijek bio šesnaest bajtova, ali dužina nije bila napisana, a node bez toga prihvata i pečat od četiri bajta. Ko bi imao bazu i mogao pisati u nju mogao je odsjeći pečat i time spustiti posao krivotvorenja sa dva na sto dvadeset osmu na dva na trideset drugu, a ponovljeni pokušaji s kratkim pečatom otkrivaju i sam ključ za provjeru. Sada je dužina napisana na obje strane, pa se pečat koji nije te dužine odbija prije nego što se uopšte izračuna. Ništa što je do sada zapečaćeno nije promijenjeno niti se drugačije čita.

    Za programere

    • crypto.service.ts: authTagLength na createCipheriv i createDecipheriv. Našao ga je korak koji od 0.76.49 čita izvorni kod pri svakoj gradnji, pravilo javascript.node-crypto.security.gcm-no-tag-length, prvi put kad se vrtio.

    0.76.49

    23. septembar 2026.

    Novo

    • Fiskalni spool kao izvor računa. Kasa u BiH ne štampa sama fiskalni račun: to radi drajver proizvođača uređaja, a kasa mu ostavi fajl u folder. Taj folder postoji u svakom lokalu, bez obzira na to koju kasu ima i bez ičega od proizvođača kase. Konektor ga sada prati i za račun koji je uređaj zabilježio kao međuzbir ili kao plaćanje virmanom traži kod.
    • Samo čitanje, i to provjereno u kodu. Adapter neće ni startovati ako bi njegov izlaz završio unutar foldera koji prati. XPay ne štampa, ne fiskalizira i ne upisuje ništa u tok fiskalnog uređaja.
    • Račun plaćen gotovinom ili karticom se preskače. Taj je već naplaćen, pa bi kod uz njega bio poziv da se plati dvaput.
    • Broj računa s uređaja postaje broj naloga, kad ga drajver vrati, pa lokal i gost gledaju isti broj.
    • Na stranici konektora stoji "Prati fiskalni spool", a kad pretraga nađe fiskalni folder, dugme uz njega sada nudi taj adapter umjesto običnog praćenja foldera, koje bi pisalo u drajverov folder.

    Format više nije pretpostavka

    • Komandni dijalekt (.inp) provjeren je red po red uz F-Link ME uputstvo Mikroelektronike, uz SC-Link dokumentaciju od ranije: servisno polje 6,1,2, "Ok" i "Er", prodaja s poljem rabata, T bez parametara kao zatvaranje za gotovinu, i J linija kojom drajver vraća broj računa.
    • Zbog tog polja rabata konektor nikad ne sabira stavke da dobije ukupno: uzima samo iznos koji fajl sam navede, a račun bez navedenog iznosa preskače.
    • XML dijalekt (Tring) čita se po nazivima elemenata, jer se sami nazivi ne objavljuju: traži "ukupno" prije "iznos", da se jedna stavka ne zamijeni s cijelim računom.
    • Fajl koji konektor ne razumije kopira se u zaseban folder i u dnevnik se upiše gdje je kopija. Ništa se nigdje ne šalje. Taj jedan fajl je sve što treba da se dijalekt dopiše kako treba, pa lokal ne mora čekati da neko unaprijed pogodi format njegovog drajvera.

    0.76.48

    23. septembar 2026.

    Novo

    • Izvorni kod se pregleda pri svakoj gradnji. Do sada su se čitale zavisnosti koje se isporučuju, historija zbog tajni i stablo zbog poznatih propusta i pogrešno postavljenih fajlova za isporuku. Sam kod nije čitao niko. Sada ga čitaju otvorena Semgrep pravila, ista ona koja traže oblike koji postanu propust: nepouzdan ulaz u upit, u naredbu, u putanju. Prijavljuje se a ne obara gradnju, kao i puni pregled zavisnosti: pravilo koje odjednom počne prijavljivati obrazac star nekoliko mjeseci vrijedi pročitati prije nego što zaustavi popravku naplate.
    • CodeQL se ne vrti i pisali smo zašto. Traži GitHub Advanced Security na privatnom repozitoriju. Semgrep čita iste oblike bez toga, pa upitnik za banku sada kaže šta se stvarno radi umjesto šta je planirano.

    Za programere

    • Korak Patterns that become vulnerabilities, over the source u poslu security, nad apps/*/src, packages i scripts, paketi pravila p/javascript, p/typescript i p/owasp-top-ten.
    • BANK_SECURITY_THREAT_MODEL.md i STATUS.md više ne nose red koji čeka Advanced Security.

    0.76.47

    23. septembar 2026.

    Popravljeno

    • Povrat kroz banku se upisuje jednom, koliko god puta se potvrdi. Svaki korak zahtjeva se prije upisa pročita i provjeri, a između ta dva trenutka drugi poziv može uraditi isto. Dva poziva u istom času, dvoklik ili klijent koji ponavlja spor prvi pokušaj, prolazila su oba i oba su upisivala povrat u knjige firme: banka vrati pet, a knjige kažu deset. Sada korak upiše samo onaj poziv koji je zatekao zahtjev u stanju u kojem ga je pročitao, dovršenje se zauzme prije nego što se novac pomjeri, a drugi poziv dobije jasan odgovor da se zahtjev već pomjerio.
    • Vraćanje na spisak osoblja vraća i drugi faktor. Osoba izuzeta od koda s telefona, pa skinuta sa spiska, vraćala se i dalje izuzeta. Niko ko nekoga dodaje ne očekuje da dodaje osobu koja se prijavljuje samom lozinkom, pa se sada pri vraćanju pravilo uključuje.
    • Izvoz cijelog stanara ne puca na datum koji to nije. ?to=2026-13-01 ima oblik dana a nije dan; umjesto uredne greške izlazila je greška servera. Sada se odbija istim riječima kojima to rade i ostali datirani izvozi.
    • Prijava preko identiteta banke podnosi dolazak dvaput. Osvježena stranica ili ponovljeni povratak od pružaoca identiteta znali su završiti greškom servera. Sada je potrošena prijava jednostavno nepoznata prijava, a karta za sesiju se troši tačno jednom.
    • Iz izvoza ne izlazi ništa što se zove ključ. Pravilo je imenovalo oblike (apiKey, privateKey), pa su hmacKey i signingKey prolazili. Sada je dovoljno da se polje zove ključem, potpisom ili hmac-om; javni certifikat zadržan bez potrebe košta jedno pitanje, a izvezen ključ za potpisivanje košta kredencijal.
    • Opis rute za izvoz kaže šta ruta radi: bez raspona su datirani fajlovi posljednja godina, ili od dolaska banke ako je to manje, a duža historija ide kao jedan arhiv po godini.

    Za programere

    • bank-refunds.service.ts: svaki prelazak stanja je sada uslovni upis (updateMany s pročitanim stanjem u uslovu) i vraća 409 already_moved kad ne pogodi nijedan red; complete zauzme dovršenje stampanjem completedAt prije poziva payments.refund i vrati zauzeće ako upis povrata ne uspije, tako da ponovni pokušaj koji ruta obećava i dalje radi.
    • bank-sso.service.ts: jednokratnost prijave i karte nosi brisanje (deleteMany s provjerom broja), a ne čitanje prije brisanja.
    • bank-tenant-export.ts: SECRET_LOOKING hvata riječ umjesto oblika.
    • smoke-bank.mjs ima provjeru koja dvije potvrde istog povrata šalje istovremeno i traži jedan upisan povrat, jedan COMPLETED i jedan odbijen poziv. Bankarski smoke: 245 prošlo, 0 palo.

    0.76.46

    23. septembar 2026.

    Novo

    • Kartica "Vaše uobičajeno" na prvom ekranu gosta. Telefonu koji je kod vas već naručivao piše tačno ona narudžba koju kod vas pravi, s cijenama od danas. Naruči isto je pošalje odmah, Izmijeni je otvori u korpi da gost doda, oduzme ili promijeni količinu.
    • Bira se prava narudžba, ne mješavina omiljenih stavki. Ako je istu napravio više puta, piše "Ovo naručujete najčešće"; ako se nijedna ne ponavlja, nudi se zadnja i tako i piše. Gost prepozna "dvije kafe i baklava" jer je to stvarno naručio; korpa složena od stavki koje najčešće uzima bila bi kombinacija koju niko nije jeo.
    • Gleda se zadnjih četrdeset narudžbi u toj poslovnici, pa navika od prije dvije godine ne nadglasa ono što gost pije sada, a uobičajeno iz druge poslovnice se ne nudi kuhinji koja to nikad nije spremala.

    Detalji koji se vide tek kad zatreba

    • Ako je nešto iz te narudžbe rasprodano, kartica se i dalje vidi, ta stavka je precrtana, i ostaje samo Izmijeni. Dugme koje bi server ionako odbio ne treba ni nuditi, pogotovo u bučnoj sali.
    • Ako je jelo iz te narudžbe obrisano iz menija, kartice nema uopšte.
    • Slanje ide istim putem kao svaka druga narudžba: cijene se čitaju iznova u tom trenutku, rasprodano se odbija, a dvostruki dodir se veže na isti pokušaj i ne pravi dvije runde.

    Za programere

    • GET /v1/t/:slug/usual uz X-Guest-Key, vraća lines (id, količina, opcije, napomena), times i basis. Cijene i nazivi se ne vraćaju: telefon ih crta iz menija koji već drži, pa kartica ne može pokazati cijenu s kojom se ostatak ekrana ne slaže.
    • Izbor runde je usualOrder() u apps/api/src/modules/orders/usual.ts: iste stavke, iste opcije i iste količine su ista runda bez obzira na redoslijed; napomena ne razdvaja naviku; neriješiva runda (obrisano jelo, opcije bez ids) nije kandidat.

    0.76.45

    23. septembar 2026.

    Novo

    • "Vaša 3. posjeta" na ekranu gosta. Telefon koji prvi put otvori račun kod vas dobije slučajan broj i sam ga čuva. Kad isti telefon opet skenira kod za stolom, gost vidi malu oznaku koliko je puta bio, a lokal taj račun broji kao povratnu posjetu.
    • Stopa povratnih gostiju u izvještaju po stolovima, iznad tabele, uz broj računa na kojima se to uopšte moglo vidjeti. Pokazuje se tek od dvadeset takvih računa naviše: prije toga jedan gost pomjeri broj za trideset posto, a to nije podatak nego šum.

    Kako se broji

    • Posjeta se upiše tek kad se račun zatvori i plati. Skeniranje menija nije posjeta, otvoren račun nije posjeta, a sto koji je otišao bez plaćanja se ne broji.
    • Telefon koji ne dozvoljava čuvanje podataka izgleda kao prvi put svaki put. Takvi računi se ne broje ni u jednu stranu, pa zato uz stopu i piše na koliko računa se moglo vidjeti: stopa koja pada zato što gosti koriste privatni prozor bila bi podatak o pretraživačima, a ne o lokalu.
    • Ako se za istim stolom desilo da je jedan gost i domaćin i gost, broji se jedna posjeta po telefonu, ne po sjedenju.

    Šta taj broj nije

      Za programere

      • VenueGuest (migracija 20261109000000_venue_guest) i visitNumber na SessionGuest (20261110000000_session_guest_visit_number). Broj posjete se upisuje na sjedenje u trenutku kad gost sjedne, jer brojač poslije toga raste i izvještaj za mart bi inače čitao kao veče puno stalnih gostiju.
      • POST /v1/t/:slug/session prima X-Guest-Key i vraća venueKey telefonu koji ga nema, uz visit. GET /v1/t/:slug/visit je čitanje bez upisa, za pozdrav prije nego što se išta naruči.
      • GET /v1/analytics/tables nosi i guests: { known, returning, rate }.

      0.76.44

      23. septembar 2026.

      Novo

      • Banka čiji ljudi izlaze na internet kroz jednu adresu više ne udara u zid. Prijava na bankarsku aplikaciju dopuštala je dvadeset pokušaja u minuti po adresi, što je tačno za ljude koji rade sa svojih računara, a pretijesno za banku čije cijelo osoblje dijeli jedan izlaz. Sada je to BANK_SIGN_IN_PER_MINUTE, s istom podrazumijevanom vrijednošću.

      Popravljeno

      • Browser provjera koja se nije mogla oporaviti. Pomoćna funkcija za prijavu čekala je minutu i jednu sekundu kad limiter kaže "previše pokušaja", a sam test traje najviše minutu: test je umirao u toj pauzi, nasumično, i blokirao izlazak na produkciju. Sada prvo pomjeri vlastiti sat pa čeka u koracima, a CI diže limit tako da do toga ionako ne dolazi.

      0.76.43

      23. septembar 2026.

      Novo

      • Rezervacija, stranica gostove rezervacije i stranica za plaćanje sada govore jezikom gosta. Meni je to radio od ranije, ostale stranice su govorile jezikom lokala: turista koji rezerviše sto sa svog telefona, ili plaća račun iz webshopa koji prodaje vani, dobijao je bosanski. Jezik se sada čita iz samog zahtjeva, prije nego što se išta iscrta, pa stranica nikada ne trepne iz jednog jezika u drugi.
      • Telefon iz Zagreba, Beograda ili Podgorice dobije bosanski. Telefon koji ne govori nijedan naš jezik dobije engleski, jer je to bolja od dvije moguće pretpostavke. Kada zahtjev ne kaže ništa, ostaje jezik lokala.
      • Dugme za jezik na svakoj od tih stranica, dvije oznake u uglu preko slike. Izbor se pamti godinu dana i vrijedi na svim gostinjskim stranicama: ko ispravi našu pretpostavku u meniju, ne mora je ispravljati ponovo kod rezervacije.
      • Naslov u kartici pretraživača i ono što se otvori kad se link proslijedi prate istog čitaoca. To je prvo što vidi onaj kome je link poslan, a često nije onaj ko ga je dobio od lokala.

      Za programere

      • parseAcceptLanguage() i guestLocale() u apps/dashboard/src/i18n/accept-language.ts, iznad postojećeg negotiateLocale(). Izbor gosta živi u kolačiću xpay-guest-locale i u localStorage, pa ga čitaju i stranice iscrtane na serveru i meni.
      • GET /v1/payments/checkout/:token nosi i locale, jezik trgovca, kao rezervu kada pretraživač ne traži ništa.
      • Račun na /r/:token ostaje u jeziku dokumenta. To nije pretpostavka o čitaocu nego svojstvo samog računa.

      0.76.42

      22. septembar 2026.

      Novo

      • Drugi faktor se može isključiti za jednu osobu. Bankarsko osoblje se prijavljuje lozinkom i kodom, i prva prijava upisuje telefon; to ostaje pravilo. Operater sada može izuzeti pojedinu osobu, i tada njena lozinka odmah otvara sesiju. Napravljeno je za probni nalog, jer je pri testiranju kucanje koda svakih trideset sekundi naporno.
      • Ništa u tome nije tiho. Isključivanje zaboravi telefon koji je ta osoba imala, pa sljedeća prijava stvarno bude samo lozinka. I izuzetak i svaka prijava koju je omogućio stoje na revizijskom lancu. Operaterov ekran pokazuje ko je izuzet. Izvještaj o spremnosti okruženja imenuje svakog izuzetog: ispod produkcije kao napomenu, a u produkcijskom okruženju kao grešku, jer produkcija ne trpi nijedan izuzetak.
      • Vraćanje je jedan klik: kad se drugi faktor opet uključi, ta osoba pri sljedećoj prijavi ponovo upisuje telefon.

      Za programere

      • BankMembership.mfaRequired (migracija 20261108000000_bank_membership_mfa_required, podrazumijevano true za sve postojeće redove). PATCH /v1/admin/banks/:id/members/:memberId prima mfaRequired; odgovor kaže i da li je telefon zaboravljen. POST /v1/bank-auth/login za izuzetu osobu vraća par tokena umjesto koraka, a na lancu stoji bank.auth.password_ok s step: "none".
      • Scenario staff_second_factor u izvještaju o spremnosti; scripts/smoke-bank.mjs prolazi kroz sve: izuzimanje, prijavu bez koda, izvještaj koji to imenuje, vraćanje pravila i oba zapisa na lancu.

      0.76.41

      22. septembar 2026.

      Ispravljeno

      • Status stranica je danas pola dana kazivala staru verziju. Nije bila u krivu: ona ispisuje popis verzija iz izdanja koje zaista radi, a na server je izlazilo samo ono što prethodno prođe punu provjeru na GitHubu. Provjeru je svaki novi commit prekidao, pa kad se radi u dvije linije odjednom nijedna nije stizala do kraja i ništa nije izlazilo: server je ostao jedanaest verzija iza. Provjera se sada prekida samo na pull requestu, a svaki commit na glavnoj grani ide do kraja i može biti pušten.

      0.76.40

      22. septembar 2026.

      Ispravljeno

      • XPay Light je bio napola taman. Kartice u konzoli crtale su se iz stare tamne palete, pa su na kremastoj podlozi bile skoro crne; sada svaka tema crta svoje kartice. Isto je popravljeno za najdublju podlogu i pritisnuto stanje dugmeta.
      • Prelazak mišem preko reda se vidi u svakoj temi. Bio je napisan kao bijela boja na 5 posto, što na svijetloj podlozi ne postoji; sada je to jedna vrijednost koju svaka tema postavi po sebi (57 mjesta u konzoli).
      • Naš logo na svijetloj temi više nije blijed: postoji verzija za svijetlu podlogu i tema bira koju vidite, prije prvog iscrtavanja.
      • Meni gosta preuzme novu temu odmah. Stranica se kešira pet minuta, pa je vlasnik koji promijeni temu i odmah otvori svoj meni vidio staru; stranica sada ispravi podlogu iz živog odgovora.

      0.76.39

      22. septembar 2026.

      Novo

      • Scenario demonstracije. U prvoj sobi sjede četiri osobe koje ne žele isto: sponzor pita zašto je ovo važno, šef platnog prometa da li radi, CIO koliko će koštati njegov tim, a neko iz rizika čeka jednu tvrdnju koju može oboriti. Napisan je red kojim se svima odgovara bez čekanja: gost plaća na telefonu, pa pregled banke, pa jedno plaćanje s kraja na kraj i red za sravnjivanje, pa njihovi sistemi i portal, pa portfolio i izvještaj za upravu, pa pitanja rizika.
      • I ono što se u toj sobi nikad ne kaže: da neko već koristi ovo u produkciji, da je išta certificirano ili testirano probojem, bilo koji broj o dostupnosti ili propusnosti koji niko nije izmjerio, i bilo šta o drugoj banci. Obećanje bez dokaza kupi sastanak, a izgubi posao tri sedmice kasnije kad procurement zatraži dokaz.

      Za programere

      • docs/en/bank-platform/BANK_DEMO_SCRIPT.md; indeks pokazuje na njega, a svaki ekran koji scenario imenuje postoji i radi na demo banci iz seeda.

      0.76.38

      22. septembar 2026.

      Popravljeno

      • Red u tabeli za provjeru dobavljača. Stavka 29 stajala je prije stavke 28. Tabela u kojoj brojevi nisu po redu pojede povjerenje u ono što u njoj piše.
      • Putevi do susjednih dokumenata u bankarskim dokumentima sada su jednaki svuda (../08-bank-partner-api.md, ../06-deployment.md), pa onaj ko ih čita s diska zaista dođe do fajla.

      0.76.37

      22. septembar 2026.

      Novo

      • Izaberite kako vaš XPay izgleda. Konzola → Postavke → Izgled. Pet tema: XPay Dark (kao do sada), XPay Light (topla svijetla podloga), XPay Green (tamno zelena s cyan dugmadima), XPay Red (topla crna s crvenom) i XPay Blue (tamno plava s azurnom). Svaka kartica je naslikana u svojoj temi, klik je odmah pokaže na cijelom ekranu, a Sačuvaj je primijeni.
      • Tema važi za cijeli vaš lokal, i samo za vaš. Konzola, kasa, ekran sale, kuhinja, šank, zidni ekran, meni koji gost otvori skeniranjem, stranica za rezervacije i stranica na kojoj kupac plaća račun iz webshopa. Uređaji preuzmu novu temu čim se osvježe. Drugim lokalima se ništa ne mijenja.
      • Naljepnica za sto se štampa u boji vaše teme, a sam QR ostaje crn na bijelom: skener nema temu, a naljepnica koju kamera ne čita ne vrijedi ništa.
      • Ako ste postavili svoju boju, ona i dalje daje naglasak na gostinjskim stranicama: tema daje podlogu, vaša boja dugmad. Teme nisu vezane za paket.

      Promijenjeno

      • Status stranica više ne javlja "degraded" kad mail server odgovori sporo, nego tek preko 30 sekundi. Kašnjenje se i dalje mjeri i piše u detalju.

      Za programere

      • Merchant.theme (migracija 20261107000000_merchant_theme), lista imena u packages/shared/src/themes.ts, uz themeOf() koji svaku nepoznatu vrijednost vraća na podrazumijevanu. PATCH /v1/merchant {theme}; vrijednost putuje u GET /v1/merchant, GET /v1/t/:slug, GET /v1/reserve/:slug, /status/:token, POST /v1/terminals/pair i GET /v1/payments/checkout/:token.
      • CSS: :root[data-xpay-theme=...] u packages/design-tokens/src/tokens.css i #xpay-guest[data-xpay-theme=...] u guest.css; boja lokala se sada piše kao #xpay-guest[data-brand='1'] da nadjača temu samo za naglasak. Skripta u <head> vrati zapamćenu temu prije prvog iscrtavanja.

      0.76.36

      22. septembar 2026.

      Novo

      • Indeks bankarske dokumentacije. Predati banci dvadeset dokumenata odjednom znači da niko neće pročitati nijedan. Sada na jednom mjestu piše šta pročitati za dvadeset minuta, a šta ako ste onaj ko ocjenjuje proizvod, ko radi integraciju, ko gleda sigurnost, ko kupuje ili ko vodi infrastrukturu. Na kraju stoji i ono što nijedan od njih neće reći: da neko drugi ovo već koristi u produkciji.

      Popravljeno

      • Browser provjera specifikacije je pala u CI-ju, i to s pravom: svaka provjera se prijavljuje, a prijava banke dozvoljava dvadeset pokušaja u minuti s jedne adrese. Deveta prijava je prevršila mjeru. Provjera je sada dio postojećeg prolaza koji je ionako prijavljen, a pomoćna funkcija za prijavu sačeka minutu i pokuša ponovo kad ekran kaže da je pokušaja bilo previše, umjesto da padne na poruci koja je tačna.

      Za programere

      • docs/en/bank-platform/README.md, i 08-bank-partner-api.md sada pokazuje na njega s prvog ekrana.
      • Provjera portala i specifikacije živi u apps/bank/e2e/demo.e2e.ts, u prolazu CIO-a; studio.e2e.ts je obrisan. Osam browser tokova prolazi.

      0.76.35

      22. septembar 2026.

      Novo

      • U portalu za developere stoji dugme koje preuzima specifikaciju onog dijela API-ja koji je bankin, kao fajl koji generator odmah čita. Do sada je adresa postojala, ali ju je inženjer morao znati napamet; sada je na istom ekranu gdje su i adrese, zaglavlja i uzorak izvoda.

      Za programere

      • apps/bank/e2e/studio.e2e.ts: nova browser provjera koja se prijavi, otvori portal, klikne preuzimanje i onda otvori preuzeti fajl: naslov nosi ime banke, svaka putanja u njemu je bankina, i konzolinih putanja nema. Devet browser tokova prolazi.

      0.76.34

      22. septembar 2026.

      Novo

      • Četiri sedmice, napisane. Evaluacija banke obično stane na istom mjestu: svi su vidjeli demonstraciju, niko ne zna šta je sljedeći korak. Sada je napisan: šta se dešava koje sedmice, ko šta radi na obje strane, šta banka treba da obezbijedi, i šta se na kraju svake sedmice ima u ruci. Prva sedmica je sandbox, druga su bankini sistemi i izvještaj o spremnosti, treća je pravi lokal i pravo plaćanje, četvrta je paket za odluku.
      • Upitnik unaprijed odgovoren. Sto pitanja koja banke ionako šalju, s odgovorom i s putokazom na dokaz: arhitektura, zaštita podataka, sigurnost, rad, integracija, komercijala. Gdje je odgovor "još ne", tako i piše. Gdje odgovor zavisi od instalacije, piše ko ga popunjava, umjesto da se pogađa umjesto operatera.
      • Gdje sve ovo radi. Tri načina: kod nas, na zasebnoj instalaciji koju vodimo mi, ili unutar banke. Za svaki piše šta banka daje, šta je isto u sva tri, i, za instalaciju unutar banke, tabela onoga što bankin tim traži a u repozitoriju ne postoji: Helm, vlastiti registar slika, ažuriranje bez interneta, objektno skladište za slike, više API procesa, vanjski čuvar ključeva, otpremanje logova. Svako od toga je stavka u ugovoru, a ne iznenađenje u trećem mjesecu.
      • Dva reda u tabeli stanja bila su zastarjela i ispravljena su: dvofazna prijava za operatera i konzolu je gotova od 0.76.20, a paket za provjeru dobavljača postoji od 0.76.18 i popunjen je od 0.76.31. Tabela koja za gotovo kaže "planirano" pojede povjerenje u sve ostalo u njoj.

      Za programere

      • docs/en/bank-platform/BANK_EVALUATION_GUIDE.md, BANK_QUESTIONNAIRE.md i BANK_DEPLOYMENT_MODES.md; VENDOR_ASSURANCE.md sada pokazuje na njih. U tabeli stanja je ostala jedna planirana stavka i ona traži šemu koja ne postoji (IPS potvrda).

      0.76.33

      22. septembar 2026.

      Novo

      • Specifikacija onog dijela API-ja koji je bankin. Inženjer banke na jednoj adresi dobije OpenAPI dokument iz kojeg se generiše klijent u bilo kojem jeziku. Dokument se pravi iz aplikacije koja radi, pa je to što ona odgovara danas, a ne što je neki dokument jednom rekao.
      • U njemu je samo ono što banka zove: bankini pozivi, prijava njenih ljudi, adresa na koju stižu obavijesti o prilivu i stranice koje ugrađuje. Konzola, operater i gost nisu unutra. Naslov nosi ime banke koja je pitala, a adresa servera je ova instalacija, pa generisani klijent ne traži nikakvo dodatno podešavanje.
      • Puni /docs i dalje je ugašen u produkciji. On je mapa cijele površine i tu ostaje kako jeste; ovo je dio koji je bankin, iza bankine sesije.

      Za programere

      • GET /v1/bank/openapi.json za integracijsku ulogu i sistemski ključ. Pravila su čista funkcija u apps/api/src/modules/bank/bank-openapi.ts (BANK_PATH_PREFIXES, bankSurface) s devet testova: svaka bankina putanja ostaje, konzola i operater i gost nestaju, putanja koja samo počinje istim slovima se ne zamijeni s bankinom, šeme ostaju cijele da generator može razriješiti svaku referencu, a dokument koji je dobijen ostaje nepromijenjen.
      • scripts/smoke-bank.mjs traži specifikaciju kao inženjer, provjeri naslov i da je svaka putanja bankina, i da analitičara odbije.

      0.76.32

      22. septembar 2026.

      Novo

      • Alat koji mjeri, a ne tvrdnja. Banka u tehničkoj provjeri pita koliko sistem podnosi. Broj je osobina mašine, baze i mreže, a ne repozitorija, pa u dokumentaciji nema nijednog. Umjesto toga tu je alat koji mjeri instalaciju koja se kupuje: izdavanje naloga za plaćanje, primanje potpisane obavijesti o prilivu, projekciju iz koje banka čita, i same bankarske ekrane. Za svaki korak izvještava koliko poziva u sekundi, p50, p95 i p99, najsporiji poziv, i koliko ih je odbijeno i zašto.
      • Odbijanje s razlogom je dio odgovora. Ograničenje broja poziva koje radi svoj posao nije kvar, i alat kaže koje je od to dvoje bilo.
      • Ne laska razvojnom steku. Pokrenut protiv lokalnog servera, alat sam kaže da mjeri Postgres preveden u WebAssembly na jednom laptopu i da to o serveru ne govori ništa.
      • Dvadeset deveta stavka u paketu za provjeru dobavljača je kapacitet: šta u platformi utiče na njega (bankarski ekrani nikad ne sjede na putu pisanja, obavijesti su idempotentne po identifikatoru poruke, ograničenja su po kredencijalu i adresi, izvozi su omeđeni), šta rezultat ne dokazuje, i prazna tabela rezultata koja ostaje prazna dok neko ne izmjeri.

      Za programere

      • node scripts/load-bank.mjs --url <adresa> --payments 500 --concurrency 16 --key <systems key> --json rezultat.json. Namjerno nije u CI-ju: broj sa zajedničkog build servera mjeri taj server. Prvi put napravi jedan dovod i ispiše dvije zastavice kojima se isti dovod koristi ponovo, jer se tajna dovoda pokazuje jednom i ovaj alat nema izuzetak od tog pravila.
      • docs/en/bank-platform/BANK_CAPACITY.md objašnjava kako se rezultat čita (p95, ne prosjek; odbijanja prije latencije; projekcija je svoj broj) i šta raditi ako brojevi nisu dovoljni, uključujući ono što u repozitoriju ne postoji: više API procesa nad istom bazom, replike za analitiku, red ispred prijema obavijesti.

      0.76.31

      22. septembar 2026.

      Novo

      • Sve što banka ima kod nas, u jednom fajlu. Nova adresa za izvoz daje arhivu s konfiguracijom kakva jeste (banka, njen paket i moduli, okruženja sa sposobnostima i dovodima, kredencijali po vrsti i otisku a nikad po vrijednosti, ljudi s ulogama, poslovanja povezana s bankom i šta je koje dozvolilo, politike dokumenata, domene, brendiranje), s datiranim zapisima (plaćanja, revizijski lanac, slučajevi, incidenti i red izmjena), s popisom koji uz svaki fajl nosi veličinu i SHA-256, i s bilješkom koja kaže kako se to provjeri, kako se lanac verifikuje i šta namjerno nije unutra. Godina po arhivi, kao i svaki drugi datirani izvoz; duža historija dolazi kao jedna arhiva po godini, a konfiguracija je cijela u svakoj.
      • Izlaz se ne naplaćuje i ne traži razgovor. Adresa nije iza licence za modul. Put van nije funkcija koja se prodaje.
      • Nijedna tajna ne izlazi. Kredencijal je u arhivi po vrsti i otisku, s jasnom porukom umjesto vrijednosti. Test to provjerava tako što u cijeloj arhivi traži tajne koje je sam napravio.
      • Paket za provjeru dobavljača više nije spisak rupa. Napisani su: dijagram konteksta (ko s kim priča i gdje su granice), registar podobrađivača (šta softver uopšte traži od onoga ko ga vodi, i predložak koji se popunjava po instalaciji), kontinuitet i oporavak (šta se čuva i koliko često, put nazad korak po korak, i prazna tabela vježbe koja ostaje prazna dok se vježba ne uradi), odgovor na incident, upravljanje ranjivostima s procesom za test proboja, predložak nivoa usluge i plan izlaska. Od dvadeset osam stavki koje procurement pita, otvorena je ostala jedna, i to komercijalna.
      • Ono što nije izmjereno i dalje tako piše. Nema izmišljenog vremena oporavka, nema procenta dostupnosti, nema tvrdnje da je neko izvana provjerio. Gdje broj nije mjeren, stoji kako se mjeri i gdje se upisuje.

      Popravljeno

      • Revizijski lanac se sada čita u stranicama, i kod provjere i kod izvoza. Lanac raste svaki dan dok instalacija radi; tražiti ga cijelog odjednom bio je skok u memoriji koji je svakim danom gori, a na razvojnoj bazi je rušio zahtjev otprilike jednom u deset puta. Redovi, redoslijed i ograničenje su isti.

      Za programere

      • GET /v1/bank/exports/tenant.zip?from&to za izvršne, revizijske i compliance uloge; cijeli izvoz je stavka na lancu (bank.export, meta tenant) s rasponom, brojem fajlova, bajtima i svakim fajlom koji je ograničenje redova skratilo. Pravila su čiste funkcije u apps/api/src/modules/bank/bank-tenant-export.ts s deset testova, a scripts/smoke-bank.mjs otvara arhivu, poredi svaki kontrolni zbir s bajtovima i provjerava izolaciju i uloge.
      • docs/en/bank-platform/ je dobio BANK_CONTEXT_DIAGRAM.md, BANK_SUB_PROCESSORS.md, BANK_CONTINUITY.md, BANK_INCIDENT_RESPONSE.md, BANK_VULNERABILITY_MANAGEMENT.md, BANK_SERVICE_LEVELS.md i BANK_EXIT_PLAN.md; VENDOR_ASSURANCE.md pokazuje gdje je koji odgovor.
      • Razvojni stek: API, migracije i seed dobijaju istu veličinu heapa koju je build već dobio. Bez toga V8 ubije proces usred rada ("Check failed: index < size()"), što izgleda kao greška u kodu a nije.

      0.76.30

      22. septembar 2026.

      Novo

      • Banka koja svoje ljude vodi u Active Directoryju sada ih tako i prijavljuje. U verziji 0.74.3 pisalo je da SAML dolazi onog dana kad ga banka zatraži i s bibliotekom koja provjerava potpis; došao je. Prijava ide preko ADFS-a ili Entra ID-a, na istoj politici i kroz ista vrata kao i do sada: osoba izabere prijavu preko banke, ode kod svog providera i vrati se prijavljena.
      • Šta okruženje kaže. Da je provider SAML i gdje se ide na prijavu, a po potrebi i ko je provider (tada potvrda od nekog drugog ne prolazi, makar bila ispravno potpisana), mora li i odgovor biti potpisan, koliko satovi smiju biti razmaknuti, i pod kojim imenima taj provider nosi e-mail, ime i grupe. Ako ne kaže ništa od toga, čitaju se imena s kojima ADFS i Entra ID dolaze iz kutije.
      • Certifikat providera je kredencijal kao i svaki drugi. Prihvata se PEM, goli sadržaj koji se kopira s ekrana providera, ili cijeli metadata dokument koji administrator izveze, jer tražiti od administratora da zna razliku znači poziv podršci na dan pilota. Ako provider usred zamjene certifikata objavi dva, čitaju se oba, da dan zamjene ne bude ispad.
      • Šta banka uveze kod sebe. Adresa s metapodacima objavljuje ovu stranu: ko smo i gdje se potvrda šalje. Administrator to uveze i prijava radi. Adresa je bankina vlastita, pa ista potvrda poslana na adresu druge banke ne prolazi.
      • Uloga i dalje dolazi sa servera. Ko je već vezan za taj identitet ulazi kakav jeste, ko je poznat po e-mailu se veže, a ko je nov dobije ulogu koju mapiranje daje njegovoj grupi ili podrazumijevanu, ako je banka tako podesila. Mapiranje je bankino i na serveru; iz preglednika uloga ne dolazi nikad. Odbijanje uvijek ima razlog koji ekran zna reći.
      • Na lancu. Identitet, član kojeg je politika napravila i sesija, svaki put, uz ime providera preko kojeg je osoba ušla.
      • U portalu za programere stoji primjer politike i za SAML, s adresama ove instalacije i imenima kredencijala, pored onog za OpenID Connect.

      Za programere

      • GET /v1/bank-auth/sso/saml/:bank/metadata objavljuje metapodatke ove strane, POST /v1/bank-auth/sso/saml/:bank/acs prima potvrdu. Identitet ove strane je {API_BASE_URL}/v1/bank-auth/sso/saml/<oznaka>, a adresa za potvrdu ista ta i /acs. Zahtjev ide preglednikom preko preusmjerenja, potvrda se vraća POST-om.
      • Prijava u toku veže se za potvrdu preko RelayState: mora biti prijava koju je ovaj server započeo, za ovu banku, nepotrošena i neistekla. Potpis, primaoca, publiku i vremenski prozor provjerava @node-saml/node-saml; izdavaoca provjerava XPay, jer biblioteka to radi samo za odjavu, a banka koja imenuje svoj federacijski servis očekuje da potvrda od nekog drugog bude odbijena i kad je certifikat poznat. Kanonizacija XML-a i provjera potpisa ostaju bibliotekine, namjerno.
      • Politika, certifikati, čitanje tvrdnji i izdavalac su čiste funkcije u apps/api/src/modules/bank/bank-sso-saml.ts, sa četrnaest testova. scripts/smoke-bank.mjs igra providera: napravi ključ, potpiše pravu potvrdu i prijavi se njome, pa provjeri da ista osoba zadrži ulogu i da pogrešan ključ, pogrešna publika, pogrešan izdavalac, potvrda bez RelayState i potrošen RelayState budu odbijeni.
      • Izvještaj o spremnosti okruženja provjerava i SAML politiku: da kredencijal postoji i da u njemu ima bar jedan certifikat.

      0.76.29

      22. septembar 2026.

      Novo

      • Admin, Problemi. Jedna stranica koja pokazuje svaki lokal kod kojeg nešto ne radi, najglasnije prvo: istekla licenca, poslovnica bez bankovnog računa, veza s bankom koja ne radi ili ćuti duže od dvanaest sati, uplate koje nisu uparene, kodovi koji vise duže od šest sati, webhook koji pada ili je ugašen, konektor koji se ne javlja pola sata, štampač koji prijavljuje grešku, fiskalni dokument koji je Porezna odbila, poslovnica kojoj fiskalna oznaka nikad nije postavljena, dan koji nije zaključen, lokal koji je otvoren a nikad korišten, i lokal koji je utihnuo. Uz svaki problem piše šta znači, šta uraditi, koliko ih je i od kada.
      • Klik na lokal otvara njegov dosije: svi problemi u cijelosti, paket i stanje, kontakt mail i telefon (odmah pozivni), i zadnjih trideset stvari koje su se tamo desile iz revizijskog dnevnika. To je odgovor na drugo pitanje svakog poziva, "a šta se dešavalo".
      • Brojači na vrhu: koliko lokala ne može raditi, koliko škripi, koliko je za znati i koliko ih je uredno. Stranica se sama osvježava svakih minut.

      Za programere

      • GET /v1/admin/health (?only=problems) i GET /v1/admin/merchants/:id/health, oboje samo za operatera. Pravila su čista funkcija u apps/api/src/modules/admin/merchant-health.ts s dvanaest testova; pragovi su jedan blok na vrhu tog fajla. Novi problem traži kod ondje i tri riječi u katalogu (admin.health.problem, .fix, .amount), što check-i18n provjerava.
      • Runbook: docs/en/01-operator-runbook.md, sekcija "Who has a problem".

      0.76.28

      22. septembar 2026.

      Ispravljeno

      • Grafikon prometa i pločica "naplaćeno" razilazili su se za svaki povrat na zaokruženom ili manje plaćenom računu. Gost zaokruži 48,00 na 50,00, lokal mu vrati 2,00: pločica je to odbila (kao i fajl za knjigovođu), a kriva ispod nje nije, pa su dva broja pod istim natpisom bila različita. Kriva sada odbija povrate na sva tri stanja koja ulaze u promet, isto kao pločica. Račun vraćen u cijelosti se, kao i prije, ne odbija dvaput.

      Za programere

      • GET /v1/analytics/timeseries: noga povrata sada je vezana za PAID, UNDERPAID, OVERPAID (lista COUNTED_IN_TAKINGS iz refund-period.ts), ne samo za PAID.
      • Smoke: smoke-ordering sam napravi zaokružen račun s djelimičnim povratom prije poređenja krive i pločice, pa ovo hvata CI. Tri provjere koje su mjerile ukupno stanje umjesto razlike (printeri konektora, podsjetnici, lista najvećih dužnika) sada mjere razliku, pa lokalna baza koja se nikad ne prazni više ne obara ispravan kod.

      0.76.27

      22. septembar 2026.

      Za programere

      • dev-up je prestao da gradi API na laptopu. Kod API-ja je prerastao zadanu veličinu hrpe koju node daje tsc-u, pa je build padao sa "JavaScript heap out of memory" i izlazom 134, što izgleda kao pad kompajlera i šalje čovjeka da traži grešku u kodu koje nema. Skripta sada gradi sa podignutom hrpom, kao što se i typecheck odavno pokreće ručno. Na CI-ju ništa se ne mijenja: tamo mašina ima memorije i bez toga.

      0.76.26

      22. septembar 2026.

      Novo

      • Karantin za brojeve zatvorenih firmi. Svaka firma nosi četverocifreni broj koji ulazi u svaki poziv na broj koji ikad odštampa, a ima ih 9000. Zatvaranje firme sada upisuje i dan zatvaranja, pa broj firme koja nikad nije izdala nijedno plaćanje ide u karantin i vraća se u opticaj nakon 90 dana: ništa s tim brojem nije nikad odštampano ni poslano, pa ništa ne može ni stići. Firma koja je izdala makar jedno plaćanje zadržava svoj broj zauvijek, jer zakašnjela uplata ne smije sletjeti na tuđi račun. Tako se prostor brojeva vraća od napuštenih prijava i probnih naloga, a ne od onih koji su radili.
      • Pregled operatera kaže koliko ih čeka. Pločica "Brojevi firmi" uz zauzeto i slobodno sada broji i koliko brojeva čeka karantin i koliko se vraća pri sljedećoj prijavi.
      • Stranica za probni nalog prvo pita. Ako su probni nalozi zatvoreni zbog popunjenosti prostora brojeva, posjetilac to vidi odmah, a ne nakon što ispuni cijeli formular.

      Za programere

      • Merchant.closedAt i Merchant.retiredMerchantNo (migracija 20261106000000_merchant_number_quarantine, aditivna). PATCH /v1/admin/merchants/:id/status upisuje i briše closedAt; otpuštanje broja premješta red iznad opsega formata (100000+), upisuje stari broj u retiredMerchantNo, poništava licencni ključ izdat na taj broj (ključ je jedinstven i potpisan nad brojem, planom i danom isteka, pa bi se inače sudario sa sljedećim vlasnikom broja) i piše merchant.number_recycled na lanac. Radi prije svake dodjele i svaki dan u 4.
      • Provjere: sedam provjera u merchant-number.test.ts i jedna u scripts/smoke.mjs.

      0.76.25

      22. septembar 2026.

      Ispravljeno

      • Stranica za rezervaciju kad lokal ne prima rezervacije. Do sada je davala golo "404 This page could not be found", pa je gostu koji je link dobio s Instagrama lokala izgledalo da je stranica lokala pokvarena. Sada otvara stranicu tog lokala, s njegovom slikom, logom i bojama, i kaže da se sto ovdje dogovara telefonom, s dugmetom za poziv kad lokal ima upisan broj. Link i dalje ne prima zahtjeve dok se rezervacije ne uključe.
      • Pogrešan link (nepotpuna adresa, lokal promijenio naziv) kaže da link ne vodi nigdje, umjesto 404 ekrana.
      • Stranica rezervacije s nepoznatim kodom kaže da rezervaciju ne nalazimo i šta da gost uradi, umjesto 404 ekrana.

      Za programere

      • GET /v1/reserve/:slug i dalje vraća 404, ali s razlogom: reason: 'reservations_off' (uz venue: naziv, jezik, telefon, logo, paleta, naslovna slika) ili reason: 'unknown_venue'. GET /v1/reserve/status/:token nosi reason: 'unknown_reservation'.

      0.76.24

      22. septembar 2026.

      Promijenjeno

      • Naslovna slika ide od ivice do ivice. Fotografija s menija (ili boja lokala) više nije kartica s okvirom nego cijeli vrh ekrana, s logom lokala u uglu i imenom preko nje. Na telefonu je to cijela širina ekrana, na računaru cijela širina prozora.
      • Kategorije odmah ispod slike. Red kružića s nazivom i slikom kategorije stoji prije pozdrava i svega ostalog, pa gost koji je došao na kafu ne skrola kroz jela da bi našao piće. Jedan dodir i tu je.
      • Tri jela u redu na velikom ekranu. Na telefonu je jedno jelo po redu kao i do sada, na tabletu dva, na računaru tri; kategorije su dvije u redu na telefonu i tri na širem ekranu. Ekran se razlaže po širini prozora, od malog telefona (360 px) do monitora, bez horizontalnog skrolanja.
      • Miš dobija odgovor. Kartica se malo podigne kad pređete preko nje; na dodir ostaje kako je bilo.
      • Korpa, račun i plaćanje ostaju u širini telefona i na monitoru: spisak od dvije stavke razvučen preko cijelog ekrana ne pomaže nikome.

      Za programere

      • Gostinjska podloga ima .g-shell (širina ekrana) i .g-bleed-inner (mjera sadržaja); #xpay-guest[data-wide] odlučuje koja je koja, a postavlja ga sama stranica prema ekranu na kojem je gost. Naslovna slika je .g-hero[data-full].

      0.76.23

      22. septembar 2026.

      Popravljeno

      • Skener tajni u CI-ju prijavio je dvije lažne uzbune iz prethodnog izdanja. Prva je fiksna so kojom se lozinka razvlači u ključ: ona nije tajna nego razdvajač namjene, pa je sada imenovana konstanta koja to i kaže. Druga je bio primjer u runbooku koji je izgledao kao upisan ključ; sada se ključ u primjeru generiše, a gdje se upisuje piše u rečenici. Nijedna prava tajna nije bila u kodu ni u dokumentaciji.

      0.76.22

      22. septembar 2026.

      Novo

      • Stolovi: rezervisan sto. Sto koji rezervacija drži (pola sata prije termina) na ekranu sale stoji kao Rezervisan, s vremenom, imenom i brojem osoba, i ima dugme Otvori sto. Konobar ili šanker tako pušta naljepnicu s mjesta na kojem ionako radi, bez otvaranja knjige rezervacija. Sto na kojem je račun već otvoren ostaje kako je bio: otvoren račun je preča informacija za salu.

      0.76.21

      22. septembar 2026.

      Novo

      • Rotacija ključa za enkripciju. Svaka zapečaćena vrijednost sada nosi oznaku ključa kojim je zapečaćena, a instalacija može čitati sa više ključeva dok piše jednim. Stari ključ ide u ENCRYPTION_KEYS_OLD, novi u ENCRYPTION_KEY, i nakon restarta operater u Administraciji pokrene prepakivanje: kredencijali integracija banaka, tajne webhookova, tajne i konfiguracije izvora izvoda i tajne telefona za prijavu u dva koraka prelaze na novi ključ. Postupak se može ponoviti; vrijednost koju nijedan ključ na instalaciji ne otvara se prebroji i ostavi, ne obriše. Do sada je promjena ključa značila gubitak svih pohranjenih tajni, pa se u praksi nije ni radila.

      Za programere

      • Omot šifrata je v2.<id ključa>.<iv>.<tag>.<šifrat>; stari v1. se i dalje čita. GET /v1/admin/encryption vraća trenutni ključ, sve ključeve kojima se čita i broj redova po vrsti (telefoni, webhookovi, izvori, kredencijali banaka) na trenutnom ključu, na starom i nečitljivih; POST /v1/admin/encryption/rewrap prepakuje i piše platform.encryption_rewrapped na revizijski lanac. Oboje samo super admin.
      • Provjere: crypto.service.test.ts i jedna provjera u scripts/smoke.mjs.

      0.76.20

      22. septembar 2026.

      Novo

      • Prijava u dva koraka. U Postavkama (firma) i pod Moj nalog (operater) nova kartica: uz lozinku, upisanu ponovo, telefon se upisuje aplikacijom za kodove (QR ili ključ ručno), kod se potvrdi, i deset kodova za oporavak se prikaže jednom. Uključena, prijava poslije lozinke traži kod s telefona ili kod za oporavak; sama lozinka ne otvara ništa. Pogrešan kod se broji u zaključavanje kao pogrešna lozinka. Isključivanje traži lozinku i kod i odjavljuje sve prijave.
      • Operater zaboravlja izgubljeni telefon. Za dan kad nema ni telefona ni kodova za oporavak: operater briše telefon s naloga, sve prijave te osobe prestaju, a zapis je na revizijskom lancu. Niko drugi to ne može.
      • Nalog je jedan: ko je telefon upisao u banci, ima ga i u konzoli.

      Za programere

      • POST /v1/auth/login vraća { step: "verify", stepToken } za nalog s telefonom; POST /v1/auth/mfa/verify sa stepToken i kodom vraća isto što i prijava. GET /v1/auth/mfa, POST /v1/auth/mfa/enrol (lozinka), /confirm (kod, vraća kodove za oporavak), /disable (lozinka i kod), POST /v1/auth/mfa/reset (super admin, e-mail). Revizija: auth.password_ok, auth.login s factor, auth.mfa_enrolled, auth.mfa_disabled, auth.mfa_reset.
      • Provjere: tri provjere u scripts/smoke-bank.mjs na vlasniku Želje, koji na kraju ostaje samo s lozinkom.

      0.76.19

      22. septembar 2026.

      Novo

      • Rezervacija može imenovati sto. U knjizi rezervacija uz potvrdu (ili poslije, u koloni Sto) izaberete sto koji rezervacija drži. Pola sata prije termina naljepnica tog stola gostu kaže "Sto je rezervisan od 17:00" i ne prima narudžbe: ko sjedne u 16:40 ne može otvoriti račun na stolu koji samo što nije zauzet. Kad termin prođe (17:01), meni radi sam od sebe, ko god skenirao. Ako gosti dođu ranije, Otvori sto u knjizi odmah pušta naljepnicu; rezervacija ostaje. Stranica na telefonu sama primijeti i otvaranje i sat, bez osvježavanja.
      • QR kod i kod za sajt. Uz link stranice za rezervacije sada su i QR (PNG za vrata i šank, SVG za štampu) i gotov red HTML-a za sajt lokala: skeniranje ili klik otvaraju stranicu za rezervaciju.

      Za programere

      • Reservation.terminalId i seatedAt, migracija 20261105020000_reservation_table. POST /v1/reservations i .../confirm primaju terminalId; POST /v1/reservations/:id/table {terminalId|null}, POST /v1/reservations/:id/seat. Odgovor knjige nosi terminalId, table, seatedAt, holding, holdMinutes.
      • GET /v1/t/:slug vraća reserved: {at, from} | null; POST /v1/t/:slug/session i /orders odbijaju s 409 conflict, reason: table_reserved, dok sto drži rezervacija (pravilo u reservation-hold.ts: 30 minuta prije termina do termina, dok lokal ne otvori sto).
      • GET /v1/reserve/:slug/qr.png|qr.svg, javno, keširano.

      0.76.18

      22. septembar 2026.

      Novo

      • Vendor assurance pack. docs/en/bank-platform/VENDOR_ASSURANCE.md odgovara na pitanja koja nabavka banke postavlja dobavljaču: arhitektura, tok podataka, sigurnost, RBAC, izolacija, klasifikacija, privatnost, podobrađivači, rezidencija, enkripcija, ključevi, sigurnost API-ja, SDLC, ovisnosti, SBOM, backup i restore, RTO/RPO, BCP/DR, incidenti, ranjivosti, penetracioni test, revizija, promjene i izdanja, SLA, izlazni plan, izvoz podataka, escrow. Svaka stavka nosi oznaku PLANNED, IMPLEMENTED ili TESTED i putanju do dokaza u repozitoriju; ništa nije INDEPENDENTLY VERIFIED ni PRODUCTION-PROVEN, jer vanjske revizije nema i nijedna banka ne radi u produkciji. Što nema dokaza, piše PLANNED.

      0.76.17

      22. septembar 2026.

      Novo

      • Moduli u ugovoru. Operater u konzoli, Banke, Ljudi i ugovor, bira module koje ugovor daje: Kontrolni centar je osnova svakog ugovora, a Integracije, Građani i zahtjevi, Korporativno te Portfolio i izvještaji banka kupuje ili ne. Nema brojanja transakcija, nema kvote i nema cijene: banka se ne naplaćuje po transakciji.
      • Ruta bez modula odgovara imenom modula. Ono što ugovor ne daje odbija se prije nego što ruta krene, i za ljude banke i za njene sisteme, i za ugrađene stranice iza bankinog tokena; osnova i kupljeni moduli rade dalje. Banka čiji ugovor još nije upisan ne gubi ništa.
      • Licenca u aplikaciji za banke. Navigacija pokazuje samo ono što ugovor daje; kartica Licenca u Podešavanjima ispisuje module, period i stanje ugovora (nije upisan, još nije počeo, važi, istekao), nivo podrške, način instalacije i čije je ime na ekranima. Istekao ugovor se kaže, ne gasi ništa sam od sebe.

      Za programere

      • PUT /v1/admin/banks/:id/entitlement prima modules samo iz control_center, integration_factory, retail, corporate, intelligence (nepoznat je invalid_request); odgovor i GET /v1/bank-auth/me nose licensed i state. Ruta modula kojeg nema odgovara permission_denied s module_not_licensed i imenom modula (@BankModule na kontrolerima, provjera u BankRolesGuard, moduli na principalu iz ugovora pri svakom pozivu). Seed upisuje oba demo ugovora sa svim modulima.
      • Provjere: bank-entitlement.test.ts, nav.test.ts, dvije provjere u scripts/smoke-bank.mjs (smoke vraća puni ugovor na kraju, pa tokovi iza njega nalaze sve module).

      0.76.16

      22. septembar 2026.

      Promijenjeno

      • Rezervacija stola izgleda kao meni. Javna stranica za rezervaciju, i stranica na kojoj gost prati odgovor, više nisu bijeli obrazac. Otvaraju se na najboljoj fotografiji s menija (ili u boji lokala kad slika nema), s logom lokala u uglu, imenom preko cijele širine i jednim dugmetom u boji lokala: isto pismo i isti ton kao stranica koju gost skenira za stolom. Broj osoba se bira jednim dodirom (1 do 6, ili više uz brojač), polja nemaju okvire, a stranica prati tamni režim telefona. Logo i boje prate paket, kao na meniju.
      • Odgovor gostu. Potvrđena rezervacija nudi "Dodaj u kalendar" (.ics fajl s vremenom, adresom i porukom lokala) i "Nazovite" s brojem lokala; otkazivanje traži potvrdu. Dan u sedmici je ispisan na bosanskom.
      • Kartica u pregledniku i podijeljeni link (Instagram, WhatsApp) nose ime i logo lokala, ne XPay.

      Ispravljeno

      • Tanke linije na gostinjskim ekranima bile su crne umjesto blijede: konzolino pravilo za boju okvira nadjačavalo je svaku klasu. Sada je u osnovnom sloju, pa klase rade.

      Za programere

      • GET /v1/reserve/:slug i GET /v1/reserve/status/:token vraćaju logoUrl i palette (po paketu, kao /v1/t/:slug) i coverUrl (prva slika s menija po redoslijedu kategorija).
      • Gostinjska podloga (pismo, paleta, #xpay-guest) je izdvojena u components/guest/ground.tsx; dijele je meni i rezervacije.

      0.76.15

      22. septembar 2026.

      Novo

      • Osjetljive poslovnice. U Postavkama, pod Uvid za banku, firma označava poslovnicu čiju djelatnost banka ne treba čitati u detalje iako vrsta posla to ne kaže: apoteka pod trgovinom, advokat pod uslugama. Označena, banka o njoj vidi samo činjenice o plaćanju (iznos, stanje, vrijeme), nikad sažetak ni stavke, ni u detalju, ni u listi, ni uz stavku izvoda. Oznaka djeluje odmah na svaku banku koja firmu čita; snimak konteksta uzet dok je oznaka uključena i sam kaže da je osjetljiv, a oznaka nikad ne proširuje ono što je snimak rekao. Usluge i freelanceri su osjetljivi i bez oznake, kao i do sada.
      • Vidljivost konteksta u banci. Nova kartica u Podešavanjima aplikacije za banke: matrica po ulogama (bez razloga, s razlogom, osjetljivo bez i s razlogom), plafon i ono što se stvarno čita. Administrator predlaže suženje za jednu ulogu, drugi odobrava, kao svaka promjena; nivo iznad plafona odbija se po imenu prije nego što uđe u red. Vraćanje na plafon je dozvoljeno, iznad plafona nikad. Suženje je na lancu revizije.

      Za programere

      • PATCH /v1/locations/:id prima sensitive; GET /v1/locations ga vraća. Kolona locations.sensitive (migracija 20261105000000_location_sensitive, aditivna). Kad se oznaka promijeni, redovi svake banke u bank_payment_views za tu poslovnicu odmah prate.
      • GET /v1/bank/visibility vraća po ulozi ceiling, narrowing i effective. Red čekanja, predmet PRIVACY, prima i { role, general?, generalWithPurpose?, sensitiveWithPurpose? }; proširenje je invalid_request s razlogom widening; odobrenje piše bank.visibility_narrowed. Uskladišten nivo iznad plafona čita se kao plafon.
      • Provjere: bank-visibility.test.ts, payment-context.test.ts, dvije provjere u scripts/smoke-bank.mjs.

      0.76.14

      22. septembar 2026.

      Novo

      • Rezervacije. Konzola, Rezervacije: uključite po poslovnici i dobijete link (xpay.ba/rezervacija/vaš-naziv) za sajt, društvene mreže ili naljepnicu na vratima. Gost upiše datum, vrijeme, broj osoba, ime i telefon (e-mail po želji) i dobije svoju stranicu na kojoj vidi odgovor; zahtjev stiže u konzolu i mailom na adresu firme. Vi potvrdite ili odbijete, s porukom gostu ako hoćete; gost s e-mailom dobije odgovor i poštom. I gost i lokal mogu otkazati prije sata. Rezervacija telefonom ili na šanku se upiše i odmah je potvrđena. Ko sjedi gdje ostaje stvar sale te večeri: rezervacija se ne veže za sto ni za račun.

      Za programere

      • Javno: GET /v1/reserve/:slug, POST /v1/reserve/:slug, GET /v1/reserve/status/:token, POST /v1/reserve/status/:token/cancel (ograničeno po IP-u). Lokal: GET/POST /v1/reservations, POST /v1/reservations/:id/confirm|decline|cancel. Location.reservationsEnabled, model Reservation, migracija 20261104040000_reservations; događaji reservation.* na realtime kanalu.

      0.76.13

      22. septembar 2026.

      Novo

      • Izvještaj za upravu. Kartica na Pregledu u aplikaciji za banke, za direktore, analitičare i administratore: izbor mjeseca (zadnji puni mjesec je zadan; tekući do danas; dvije godine unazad), glavne brojke uz prethodni mjesec i dugme Preuzmi PDF. Paket na papiru: plaćanja i naplaćeno po načinu, potvrde banke i ručne, vrijeme do potvrde; firme povezane, aktivne, koje dijele, nove veze i pristanci, po segmentu, najveći promet; sravnjivanje (otvoreni, riješeni, odbačeni, otvoreni sada, sati do rješenja, udio automatski sravnjenih, prilivi po ishodu); potraživanja korporativnih klijenata (upisano, naplaćeno, otvoreno, kasni, preplaćeno, dani do naplate, računi kroz XPay); incidenti po ozbiljnosti i otvoreni na kraju. Ime i boja banke na vrhu, kad je banka postavila boju kojoj se može vjerovati.
      • Samo izmjereno. Izvještaj ne sadrži procjene, prognoze ni povrat ulaganja; ono što nije izmjereno nije na njemu, i to piše na dnu svake kopije. Svaki preuzeti fajl je na lancu revizije kao izvoz, s mjesecom.
      • Faza 7 zatvorena. Portfolio menadžera odnosa sa signalima i CRM linkom, Radar prilika s pravilima na ekranu i prekidačem banke, i mjesečni izvještaj za upravu: sve prolazi u smoke testu banke pri svakom prolazu CI-ja.

      Za programere

      • GET /v1/bank/reports/board?month= vraća month (granice i prethodni mjesec), bank, payments, business, reconciliation, corporate, incidents; GET /v1/bank/reports/board.pdf?month= vraća application/pdf sa zaglavljem X-Report-Month i upisuje bank.export (cilj board-report). Uloge: sistemi banke, direktor, analitičar, administratori. Mjesec koji nije počeo, dalji od 24 mjeseca ili pogrešno pisan je invalid_request.
      • Brojke dolaze iz BankAnalyticsService (isti pozivi kao ekrani), pa papir i ekran ne mogu reći različito.
      • Provjere: bank-board-report.test.ts, jedna provjera u scripts/smoke-bank.mjs.

      0.76.12

      22. septembar 2026.

      Novo

      • 0,350 kg na kasi. Mesnica, pijaca ili delikatesa prodaje po kilogramu, a kasa na ekranu je do sada prodavala samo cijele komade. Dodir na artikal čija jedinica nije komad (kg, g, l, dl, m) pita količinu s vage, u hiljaditim dijelovima; cijena je po jedinici, iznos zaokružen na fening kao i sve ostalo, svako vaganje je svoja stavka. Sa stanja se skida tačno toliko (jedan pokret od -0,35), na svakom ekranu piše 0,35 kg, na računu i u fiskalnoj evidenciji stoji 0,35 kg po cijeni za kilogram. Artikal u komadima se i dalje prodaje u cijelim komadima.

      Za programere

      • POST /v1/counter/sales prima quantity kao razlomak; jedinica artikla odlučuje da li je to dozvoljeno. OrderItem.quantityMilli i unitSnapshot (migracija 20261104030000_weight_lines), quantityText na stavkama narudžbe u API-ju.

      0.76.11

      22. septembar 2026.

      Novo

      • Račun kupcu mailom sa kase. Salon, servis ili ordinacija naplati na kasi na ekranu i kupac koji hoće potvrdu do sada nije imao šta dobiti. Na ekranu PRODANO (i na ekranu plaćenog koda) je polje za e-mail: kupac dobije PDF istog oblika kao faktura, iz zatvorenog računa, sa svim stavkama, PDV-om po stopi, načinom plaćanja i pečatom PLAĆENO, s napomenom da nije fiskalni račun i brojem pod kojim je zaveden u fiskalnoj evidenciji. Ništa se o kupcu ne pamti osim adrese u dnevniku. Isti dokument može se i preuzeti kao fajl.

      Za programere

      • POST /v1/sessions/:id/receipt {email} i GET /v1/sessions/:id/receipt.pdf (osoblje, i uređaj s tokenom). Odbija se s not_closed dok račun nije zatvoren; settlement_unavailable kad server nema podešen e-mail.

      0.76.10

      22. septembar 2026.

      Novo

      • Radar prilika. Panel na stranici Portfolio u aplikaciji za banke: šta banka može ponuditi firmi kroz ovu platformu, po četiri pravila. Čeka pristanak (veza koju je banka aktivirala prije dvije sedmice ili više, a firma još ne dijeli podatke), naplata kroz banku (firma izdaje račune izvan XPaya, a banka nije gurnula nijedan red knjige, pa ništa od potraživanja ne stiže do banke), feed izvoda banke (firma izdaje račune, a nijedan feed pod okruženjem banke ne radi) i QR umjesto gotovine (40 % ili više naplate u gotovini). Svaka prilika je nazvana po ponudi, ne po firmi, i nosi činjenice na kojima se upalila; pragovi pišu ispod. Ništa ne profiliše, ne boduje i ne govori o kreditu.
      • Isključen dok ga banka ne uključi. Radar ne računa ništa dok administrator banke ne uključi prekidač u Podešavanjima, kartica Funkcije, kroz red čekanja promjena: jedan predlaže, drugi odobrava. Isključen, panel to i kaže.

      Za programere

      • GET /v1/bank/rm/radar?rule= (iste uloge kao portfolio) vraća enabled, redove s opportunities (rule i facts), sharing, crmUrl, counts po pravilu i thresholds; isključen vraća enabled: false bez redova. Nepoznato pravilo je invalid_request.
      • Portfolio i radar čitaju istu knjigu (BankRmService.book), pa se činjenice računaju jednom.
      • Provjere: bank-radar.test.ts, jedna provjera u scripts/smoke-bank.mjs.

      0.76.9

      22. septembar 2026.

      Novo

      • Opomene po pravilu. Kupci, panel Opomene same: prekidač i tri broja, koliko dana poslije roka ide prva opomena (3), pa svakih koliko dana (14), i najviše koliko puta po računu (3). Svako jutro oko 9 XPay šalje istu opomenu koju šalje dugme na kupcu: svi dospjeli računi s linkovima, na jeziku kupca, u trail-u piše da je poslao sistem. Kupac bez e-mail adrese se preskače, opomenut u zadnja 24 sata takođe, a broj opomena se broji po računu pa treći put ostaje vama. Isključeno dok firma ne uključi: opomena je pismo u njeno ime. Dugme Pošalji dospjele sad radi po istom pravilu kad god hoćete.

      Za programere

      • POST /v1/customers/remind-due (menadžer) vraća {customers, sent, failed, skipped}. Pravilo u invoiceSettings (autoRemind, remindAfterDays 1 do 60, remindEveryDays 1 do 90, remindMaxTimes 1 do 10). Invoice.remindedCount i lastRemindedAt, migracija 20261104020000_invoice_reminders. Cron 0 7 * * *.

      0.76.8

      22. septembar 2026.

      Novo

      • Kupci iz fajla, prije prvog računa. Komunalno preduzeće i stanodavac imaju spisak korisnika prije nego što izdaju išta; do sada su kupci nastajali usput, iz uvoza računa. Kupci, dugme Uvoz iz fajla: CSV s nazivom i, po želji, šifrom, adresom, e-mailom, JIB-om, telefonom, jezikom i napomenom, kolone na bosanskom ili engleskom, isti čitač fajla kao za račune. Prvo pregled: koliko je novih, koliko već poznatih (po šifri, pa po JIB-u, pa po nazivu), i svaki red koji ne valja s razlogom. Poznatom kupcu se dopune kolone koje fajl nosi, ostalo mu ostaje; novi se doda. Fajl s ijednim problemom ne upisuje ništa, ni dobre redove, jer se za pola uvezen spisak ne zna koja je polovina.

      Za programere

      • POST /v1/customers/import {csv, preview?} (menadžer). Čitač u apps/api/src/modules/customers/customer-file.ts, do 5000 redova.

      0.76.7

      22. septembar 2026.

      Novo

      • Portfolio. Nova stranica u aplikaciji za banke, na kojoj menadžer odnosa sada i slijeće: svaka firma koja dijeli podatke s bankom u jednom redu, sa naplaćenim u zadnjih trideset dana prema trideset prije, udjelom gotovine, zadnjom naplatom, otvorenim i kasnim potraživanjima, otvorenim slučajevima, poslovnicama, feedom banke, referencom i proizvodima banke. Firma koja još nije pristala je broj, ne red.
      • Deset signala s pravilima na ekranu. Nova, raste, pada, tiha, kasne potraživanja, otvoreni slučajevi, puno gotovine, bez feeda, bez CRM reference, bez proizvoda. Svaki signal je pravilo s pragom koji piše na istoj stranici, i svaki nosi brojke na kojima se upalio: menadžer vidi zašto, ne to da je neki bod tako rekao. Ništa ne boduje, ne rangira i ne predviđa. Filter po jednom signalu, brojač po svakom.
      • Link na CRM banke. Banka u Podešavanjima, kartica Funkcije, upiše adresu svog CRM-a s oznakom mjesta za referencu firme; nakon toga svaki red portfolija s referencom banke ima dugme Otvori u CRM-u. Adresa se mijenja kao i sve drugo u banci: jedan administrator predlaže, drugi odobrava, a promjena je na lancu revizije. Tu je i prekidač Radara prilika, za sljedeću stavku.

      Za programere

      • GET /v1/bank/rm/portfolio?signal= (sistemi banke, menadžer odnosa, operativa, direktor, administratori) vraća redove s facts, signals (key i facts), crmUrl, counts, sharing, waitingForConsent, crmConfigured i rules. GET /v1/bank/features vraća crmUrlTemplate i opportunityRadar.
      • Red čekanja promjena primjenjuje predmet FEATURE: after nosi crmUrlTemplate (https adresa sa {ref}, ili null za brisanje) i/ili opportunityRadar; odobrenje je na lancu kao bank.features_changed. Nova kolona bank_partners.settings (migracija 20261104000000_bank_settings, aditivna).
      • Provjere: bank-rm.test.ts, dvije provjere u scripts/smoke-bank.mjs, navigacija u nav.test.ts.

      0.76.6

      22. septembar 2026.

      Novo

      • Izvod otvorenih stavki na engleskom. Kupac čiji računi idu na engleskom dobija i izvod na engleskom: riječi, datumi (22 Sep 2026) i format brojeva (1,250.00 KM) kao na računu, a fajl se zove Statement umjesto IOS. Jezik je onaj koji piše na kupcu; kad ga kupac nema, odlučuju njegovi računi, pa kupac kome je sve išlo na engleskom ne dobija izvod na bosanskom zato što niko nije popunio polje.
      • Svi PDF-ovi serije u jednom ZIP-u. Na seriji iz fajla (Fakture, Uvoz) dugme Preuzmi PDF-ove daje jednu arhivu sa svim izdatim računima serije, po redu iz fajla, za štampariju: komunalno ima stotine računa bez e-mail adrese koji se štampaju i nose. Nacrti i stornirani nisu unutra, iz istog razloga iz kojeg se ne šalju. Isti PDF kao onaj koji kupac preuzima s linka.

      Za programere

      • GET /v1/customers/:id/statement.pdf prati Customer.language, pa jezik računa. GET /v1/invoice-batches/:id/pdfs.zip (menadžer) vraća application/zip sa zaglavljem X-Bill-Count; arhiva je pisana bez biblioteke (apps/api/src/common/zip.ts, store, UTF-8 imena).

      0.76.5

      22. septembar 2026.

      Novo

      • Dnevno zaključenje. Konzola, Fiskalizacija, Dnevno zaključenje: na kraju smjene menadžer pritisne Zaključi dan i XPay zapečati sve od prethodnog zaključenja, po načinu plaćanja: preko banke (ono što je stiglo na račun, u trenutku kad je stiglo), gotovina i kartica kako ih je osoblje upisalo pri zatvaranju stola, napojnice posebno, pa povrati, neto, stolovi koji su otišli bez plaćanja, stolovi zatvoreni kao uplata na račun koju banka još nije vidjela, isplaćene napojnice, ko je zatvarao stolove i koje račune iz fiskalne evidencije period pokriva. Zaključenje ima broj u svojoj seriji po godini (Z-1, Z-2), pečat koji ga veže za prethodno, i PDF. Do sada se isto vidjelo na Pregledu, ali ništa se nije zatvaralo; knjigovođa je dobijao mjesec u komadu.
      • Obračunski dan počinje u 6:00. Zaključenje u jedan ujutro pripada večeri prije, kao što bi ga svaka kasa svrstala. Sto plaćen poslije zaključenja ide u sljedeće. Kad se od prošlog zaključenja ništa nije desilo, dugme to kaže umjesto da napravi prazan izvještaj i potroši broj.

      Za programere

      • GET /v1/day-closes, GET /v1/day-closes/preview?locationId=, POST /v1/day-closes {locationId, note?}, GET /v1/day-closes/:id, GET /v1/day-closes/:id.pdf; menadžer i vlasnik. Model DayClose, migracija 20261104000000_day_close je aditivna.

      0.76.4

      22. septembar 2026.

      Novo

      • Račun za svaki zatvoreni sto, onako kako ga traži Zakon o fiskalizaciji transakcija FBiH. Zakon (Sl. novine 9/26) se primjenjuje najkasnije do avgusta 2027, a podzakonski akti još nisu izašli. Ono što se već zna iz samog zakona ugrađeno je sada: kad se sto zatvori, XPay upiše račun sa svim elementima iz člana 18, nazivom i JIB-om firme, PDV brojem, adresom poslovnice, svakom stavkom sa šifrom, količinom i cijenom, PDV-om po stopi (osnovica i porez u bruto cijeni), načinom plaćanja kako ga zakon dijeli (kartica je gotovinsko, prenos bezgotovinsko, oboje kombinovano), kodom operatera i kodom mjesta poslovanja. Broj je u tri dijela bez praznina (član 19): redni broj po poslovnici i godini, kod mjesta poslovanja, broj ESET-a, npr. 12/1/1.
      • Narudžbenica za svaku narudžbu i korektivni račun za svaki povrat. U ugostiteljstvu zakon poznaje narudžbenicu (član 5) i traži da račun navede na osnovu kojih je izdat; XPay je upiše u trenutku kad sto naruči, u vlastitoj seriji (N-12/1/1). Povrat novca dobije korektivni račun (član 71) koji navodi broj računa i vraća PDV po njegovim stopama srazmjerno. Napojnica nije na računu, pa povrat koji vrati samo napojnicu ne pravi korektivni račun, isto kao u knjizi napojnica.
      • Arhiva koja pokazuje praznine. Svaki dokument je nepromjenjiv i lančano potpisan po poslovnici, kako član 26 traži od arhive. Nova stranica Fiskalizacija u konzoli ima listu dokumenata sa detaljima, dugme Provjeri lanac koje sve izračuna iznova i imenuje prvi dokument koji ne odgovara, i Preuzmi arhivu za knjigovođu ili inspektora. Tu su i spremnost (šta samo firma zna, a račun mora nositi) i polja za kod mjesta poslovanja, broj ESET-a i kod operatera za firmu i za svakog zaposlenog. Dokument bez nekog podatka se svejedno upiše i kaže šta nedostaje; ništa ne zaustavlja prodaju.
      • Šifra artikla i PDV po artiklu. U meniju svaki artikal može imati svoju šifru (bez nje na račun ide šifra iz sistema) i PDV stopu koja odstupa od firme; stopa i šifra se upisuju uz svaku stavku narudžbe u trenutku naručivanja, kao naziv i cijena. Isto i za zalihe.
      • Račun na papiru zna za PDV. Račun koji se štampa preko konektora nosi PDV po stopi čim firma kaže gdje stoji s PDV-om, a zatvoren sto se može štampati ponovo, bez koda i s brojem svog dokumenta. Dok Porezna uprava ne vrati VBR, na papiru i dalje piše da to nije fiskalni račun; kad ga vrati, isti papir nosi naslov FISKALNI RAČUN. Konektor 0.3.1 zna to štampati; stariji štampa kao do sada.

      Šta ne radi dok ne izađe pravilnik

        Za programere

        • GET /v1/fiscal/readiness, GET /v1/fiscal/documents, GET /v1/fiscal/documents/:id, GET /v1/fiscal/export.jsonl, GET /v1/fiscal/chain?locationId=; menadžer i vlasnik. Dokumenti se pišu iz apps/api/src/modules/fiscal/fiscal-draw.ts poslije zatvaranja stola, narudžbe i povrata, a svakih deset minuta prolaz dopiše što je promaklo u zadnja 24 sata. MenuItem.code, MenuItem.taxRatePermille, StockItem.taxRatePermille, OrderItem.taxRatePermille i codeSnapshot, Location.fiscalPlaceCode i fiscalEsetNo, Merchant.fiscalOperatorCode, StaffMember.fiscalOperatorCode. Migracija 20261103000000_fiscal_record je aditivna.

        0.76.3

        22. septembar 2026.

        Ispravke

        • Prepoznato je prepoznato. Priliv knjižen na očekivanje po referenci klijenta brojao se kao prepoznat samo kad ga je matcher sam zatvorio; priliv kojem je matcher zbog razlike u iznosu otvorio slučaj nije ulazio u "prepoznato po referenci klijenta" iako je stajao pod manje ili više. Sada se broji svaki priliv knjižen na očekivanje, kako i riječ govori. Provjera u CI-ju je to našla na svježoj bazi.

        0.76.2

        22. septembar 2026.

        Novo

        • Knjiga korporativnih klijenata u analitici. Kartica Korporativno čita račune i knjigu potraživanja kao jednu knjigu za period: upisano i koliko, naplaćeno, otvoreno i koliko od toga kasni, preplaćeno, prosjek dana od upisa do priliva. Tok novca po danu: šta je dospjelo i šta je stiglo. Iste brojke po povezanoj firmi, najotvorenije prvo; klik na firmu otvara entitet (naziv, ID broj) i njene poslovnice jednu po jednu.
        • Faza 6 zatvorena. Knjiga klijenta kroz banku bez XPay kodova, Smart Lockbox koji imenuje šta je svaki priliv ispao, i analitika potraživanja i toka novca po firmi i poslovnici: sve prolazi u smoke testu banke pri svakom prolazu CI-ja.

        Za programere

        • GET /v1/bank/analytics/corporate?from=&to=&merchantId= vraća uz dosadašnje i receivables, cashflow, perLink i, s merchantId, breakdown (entitet i poslovnice). Tuđa ili nedijeljena firma je not_found.
        • Provjere: jedna provjera u scripts/smoke-bank.mjs.

        0.76.1

        22. septembar 2026.

        Novo

        • Smart Lockbox izvještaj. Za jednog klijenta ili za sve klijente banke koji dijele, za period (zadano trideset dana do danas, najviše godina): svaki priliv koji su izvodi i feedovi donijeli stoji pod jednom od sedam riječi, upareno, na pregledu, manje, više, kasno (plaćeno u cijelosti nakon dospijeća), duplo (slučaj kaže da je udvostručio već uzet priliv) i nepoznato (nema šta da se upari, ili odbačeno). Novac je važniji od otvorenog slučaja: priliv koji je matcher knjižio i uputio osobi zbog razlike stoji pod manje ili više, ne na pregledu. Riječi se broje i sabiraju nad svim prilivima; do pet stotina se izlista s uparenim očekivanjem i slučajem. Pored priliva, očekivanja dospjela u periodu (računi i potraživanja) s naplaćenim i otvorenim, i koliko je priliva prepoznato po referenci klijenta, a koliko po XPayevoj: lockbox radi na referencama koje klijent već štampa.
        • Panel Smart Lockbox na ekranu Naplata. Period, sedam pločica koje filtriraju listu, sažetak očekivanja, CSV izvoz koji ide na revizijski lanac banke.

        Za programere

        • GET /v1/bank/collections/lockbox?merchantId=|bankBusinessRef=&from=&to= i GET /v1/bank/collections/lockbox.csv (isti parametri; X-Rows, bank.export s ciljem lockbox na lancu). Riječ se izvodi u bank-lockbox.ts iz matchStatus, uparenog plaćanja i slučajeva.
        • Provjere: bank-lockbox.test.ts, jedna provjera u scripts/smoke-bank.mjs.

        0.76.0

        22. septembar 2026.

        Novo

        • Knjiga potraživanja kroz banku. Sistemi banke, operativa, platni promet i menadžeri odnosa guraju knjigu korporativnog klijenta (firme koja dijeli s bankom) kroz API, do hiljadu redova odjednom, ili kao datoteku koju izvozi knjigovodstvo: zaglavlje s uobičajenim nazivima kolona na našem ili engleskom, tačka-zarezi ili zarezi, iznosi i datumi kako ih Excel piše ovdje ili vani; prvo se pročita i imenuju neispravni redovi, pa se upiše. Svaki red je potraživanje: plaćanje s referencom klijenta i XPayevom pored, bez izdanog dokumenta. Ista knjiga dva puta ne upisuje ništa dva puta. S brojem kupca red se vodi pod kupcem klijenta (napravljenim od imena kad ga nema), pa ga sanduče računa pokaže čim banka veže svog klijenta za taj zapis.
        • Šest riječi za potraživanje. Otvoreno, kasni, djelimično, plaćeno, preplaćeno, otkazano; uz svako šta je stiglo, šta ostaje i šta je preko. Pregled po klijentu broji i sabira po riječi. Sistemi klijenta i dalje čuju kroz vlastite webhookove, s referencom klijenta kao orderRef.
        • Samo sravnjivanje s bankine strane. Poslovnica prebačena na samo sravnjivanje ne izdaje ništa kroz XPay (računi, kodovi i naplate se odbijaju), a knjiga, sravnjivanje, izvodi i webhookovi ostaju. Upisano na oba lanca.
        • Podsjetnici kroz banku. Svako jutro u sedam i na klik: svako potraživanje koje dospijeva u tri dana ili kasni, još nije naplaćeno i nije podsjećano zadnjih sedam dana, javi se adapteru banke s referencom, iznosom i danom; red se obilježi, a prolaz upiše na lanac. Aplikacija banke podsjeća svog klijenta.
        • Ekran Naplata u aplikaciji za banke. Klijent, brojke po riječi, poslovnice i način rada s prekidačem, knjiga za zalijepiti s čitanjem i upisom, podsjeti sada, lista potraživanja po stanju.
        • Potraživanja i za firme kroz API. POST /v1/receivables prima customerRef (broj kupca) i vodi red pod kupcem.

        Za programere

        • GET /v1/bank/collections?merchantId=|bankBusinessRef=, GET /v1/bank/collections/receivables?state=, POST /v1/bank/collections/ingest (receivables[]), .../import (csv, preview), .../mode (locationId, reconciliationOnly), .../remind. Sanduče računa (/v1/bank/customers/:ref/bills, /v1/embed/bills) sada nosi i kind: "receivable" redove; predaja bez adaptera i bez stranice vraća url: null uz referencu i iznos.
        • Lanac banke: bank.receivables_ingested, bank.collections_mode_set, bank.receivables_reminded; lanac firme: receivables.recorded (sistem), location.reconciliation_only_set_by_bank.
        • Provjere: bank-collections.test.ts, šest provjera u scripts/smoke-bank.mjs.

        0.75.10

        22. septembar 2026.

        Novo

        • Zahtjev za povrat kroz banku. Klijent banke želi novac nazad s uplate koju je XPay vidio da je sjela. Sistemi banke, operativa, platni promet ili podrška građanima traže povrat po pozivu na broj s izvoda ili po uplati, najviše koliko je naplaćeno umanjeno za ono što je firma već vratila i za ono što drugi otvoreni zahtjevi traže. Firma je obaviještena na svom lancu i odlučuje u svojoj konzoli: da ili ne, s napomenom koju banka čita; odbiti može dok novac nije otišao.
        • Banka vraća i potvrđuje, XPay upisuje. Banka javi da je vratila novac sa svoje strane, s vlastitom referencom povrata, pa potvrdi transakcijom kojom potvrđuje povrat. XPay tada upiše firmin vlastiti zapis o povratu, isti kakav piše povrat s ekrana plaćanja, s referencom banke na sebi. Ako zapis ne može (firma je u međuvremenu sama vratila), zahtjev ostaje potvrđen i odgovor kaže zašto; završetak se ponavlja. Ništa ne ide unazad.
        • Sravnjenje se ne prepisuje. Priliv koji je sravnio uplatu i naplaćeni iznos ostaju tačno kakvi su bili; povrat stoji pored njih, kao i kad firma sama vrati. Provjera u smoke testu to tvrdi brojkama.
        • Ekrani. Panel Povrati kroz banku na ekranu Građani (zahtjev iz transakcije s izvoda, "banka je vratila", "potvrdi povrat") i stranica Povrati u konzoli firme (čeka vašu odluku, ranije).
        • Faza 5 zatvorena. Zahtjev za plaćanje, sanduče računa, pametne transakcije i računi, povrati: sve prolazi u smoke testu banke pri svakom prolazu CI-ja, a tokovi u pregledniku prolaze zahtjeve, sanduče i platiočev račun u kontrolnom centru.

        Za programere

        • Banka: POST /v1/bank/refunds (reference ili paymentId, amount, reason, requesterRef), GET /v1/bank/refunds?state=&merchantId=, GET /v1/bank/refunds/:id, POST .../:id/sent (bankReturnRef), .../confirm (confirmationTransactionId), .../complete. Firma: GET /v1/refund-requests, GET .../:id, POST .../:id/approve i .../reject (note).
        • Modeli RefundRequest i RefundRequestEvent (migracija 20261102000000_refund_requests, aditivna), prefiksi rfq_ i rfqe_; Refund.request vodi nazad na zahtjev. Stanja REQUESTED, APPROVED_BY_MERCHANT, SENT_TO_BANK, RETURN_CONFIRMED, COMPLETED, REJECTED.
        • Lanac banke: bank.refund_requested, bank.refund_approved_by_merchant ili bank.refund_rejected_by_merchant, bank.refund_sent, bank.refund_confirmed, bank.refund_completed; lanac firme: refund_request.received, refund_request.approved, refund_request.rejected.
        • Odbijanja: over_refundable (s brojkama), nothing_collected, wrong_state, payment_required.
        • Provjere: bank-refunds.test.ts, četiri provjere u scripts/smoke-bank.mjs.

        0.75.9

        22. septembar 2026.

        Ispravke

        • Firma koja je izdala račun u toku ostaje s dijeljenjem. Tok sandučeta računa je na kraju gasio dijeljenje Studija Vrbas, a lista plaćanja je projekcija koja firmu ispušta tek pri sljedećem prolazu: tok koji odmah zatim otvara najnovije plaćanje dobijao je 404 na detalju. Studio Vrbas sada dijeli od početka, kao i Mrkva i Željo, i ostaje tako.

        0.75.8

        22. septembar 2026.

        Novo

        • Obogaćenje stavke s izvoda. Sistemi banke i njeni ljudi pošalju pozive na broj kako stoje na izvodu (RF, numerički ili XP oblik, do stotinu odjednom) i za svaki dobiju da li je to XPay uplata firme koja dijeli s bankom, kome i gdje je plaćeno, iznose i kada, sažetak svrhe na nivou koji politika vidljivosti daje bez svrhe (sažetak općeg konteksta, ništa od osjetljivog, nikad stavke) i koji dokument je uplata ostavila i dokle ga kanal banke doseže.
        • Pametni računi. Uplata ostavlja dokument izveden iz vlastitog snimka: račun sa stavkama, plaćeni račun ili potvrdu plaćanja. Ništa se ne kopira, pa se ništa ne briše: politika banke po vrsti kaže koliko mjeseci nakon plaćanja kanal banke doseže dokument, i ko ga u banci smije otvoriti: samo platilac, podrška uz svrhu i slučaj, ili svaka uloga po politici vidljivosti (sažetak bez svrhe, cijeli dokument sa svrhom, upisano kao osjetljivo čitanje). PDF na jednoj strani, s napomenom da nije fiskalni dokument.
        • Platiočev račun u aplikaciji banke. Token ugrađenog prikaza dobio je tvrdnju t: stavke s izvoda za koje banka jamči da ih je klijent platio. Iza takvog tokena račun se otvara cijeli, kakva god bila kategorija, jer je platiočev; transakcija za koju token ne jamči nije nađena. Stranica /embed/receipt prikazuje račun i PDF.
        • Politika dokumenata u Podešavanjima. Kartica Dokumenti pokazuje zadržavanje i pristup po vrsti (zadano 24, 36 i 24 mjeseca, po politici vidljivosti; granice 12 do 120) i predlaže promjenu kroz red promjena: jedan predloži, drugi odobri, primijeni se odmah.
        • Transakcija s izvoda na ekranu Građani. Podrška upiše poziv na broj i vidi obogaćenje kako bi ga vidjela aplikacija banke, PDF za banku na svom nivou, i otvara račun kako ga platilac vidi.

        Za programere

        • POST /v1/bank/transactions/enrich (references, do 100), GET /v1/bank/transactions/:reference/document?purpose=&caseRef= i .../document.pdf, GET /v1/bank/documents/policy. Javno: GET /v1/embed/transactions/:reference?token= i .../document.pdf?token=. POST /v1/bank/customers/:ref/embed-token prima transactions.
        • Red promjena prima predmet PRIVACY s after: { documentType, retentionMonths?, staffAccess? }; odobrenje piše BankDocumentPolicy (migracija 20261101000000_bank_document_policies, aditivna, prefiks bdp_) i bank.document_policy_changed na lanac. Čitanje dokumenta sa svrhom piše bank.document_read.
        • Odbijanja: document_expired, not_paid, customer_only, not_support, support_case_required, transaction_not_vouched.
        • Provjere: bank-smart.test.ts, četiri provjere u scripts/smoke-bank.mjs, tok u pregledniku apps/bank/e2e/bills.e2e.ts proširen na plaćeni račun i platiočev prikaz.

        0.75.7

        22. septembar 2026.

        Novo

        • Preuzimanje dodataka. Stranica Integracije na sajtu dobila je dio "Dodaci za prodavnice": WooCommerce, PrestaShop i OpenCart, svaki sa arhivom za preuzimanje, verzijom platforme koju traži i koracima za instalaciju. Arhive se pakuju iz repozitorija pri svakom izdanju, pa su uvijek na verziji koja je na produkciji. Uz njih piše i ono što je istina: dodaci su novi, prije prve prave narudžbe javite se, pomažemo pri prvoj probi od 1 KM.

        Za programere

        • scripts/webshop-plugins.mjs --pack-only --out <dir> pakuje bez PHP-a; slika sajta ga zove prije next build i arhive završe u apps/web/public/downloads/ (git-ignored).

        0.75.6

        22. septembar 2026.

        Novo

        • Promotivni videi za kafiće i restorane i za banke. U promo/ su dva videa na bosanskom (72 i 84 sekunde): prvi prati jedan račun u Ćevabdžinici Željo od naljepnice na stolu, preko menija, kuhinje i konobarovog tableta, do koda za plaćanje i konzole; drugi vodi banku od instant plaćanja koje postoji a nema gdje da se plati, preko kontrolnog centra nad deset firmi iz svih djelatnosti, do pilota u tri koraka. Svaki kadar je snimak aplikacije kakva radi. Podaci koji se vide, snimanje ekrana i render su tri skripte koje se ponove kad se proizvod promijeni; kako, piše u promo/README.md.

        Za programere

        • scripts/dev-postgres.mjs: ponovno pokretanje slušača je ograničeno na deset sekundi. Slušač čiji start nikad ne završi do sada je ostavljao port mrtav bez ijedne poruke poslije "restarting the listener"; sada preda proces nadzorniku, koji podigne novi.

        0.75.5

        22. septembar 2026.

        Novo

        • Sanduče računa (Bills Inbox) za klijente banke. Banka vodi svog klijenta pod vlastitom referencom koju XPay ne tumači; sistemi banke ili podrška građanima vežu tu referencu za zapis kod izdavaoca po broju potrošača s računa (firma koja dijeli s bankom). Od tada je sanduče izdati računi tih zapisa, u četiri riječi: predstoji, uskoro (u roku od sedmice), dospjelo i plaćeno, dospjelo prvo, svaki s referencom, iznosom za platiti i vlastitom stranicom računa. Izdavalac koji prestane dijeliti nestaje iz sandučeta odmah; kad se ukloni posljednji izdavalac, ide i referenca.
        • Plati odabrano. Za svaki odabrani račun jedna predaja u aplikaciju banke: referenca, iznos i link koji gradi adapter banke kad okruženje tvrdi predaju u mobilnu aplikaciju, inače stranica računa. Račun koji je plaćen, nije klijentov ili nema referencu odbija se po imenu. Domaći trenutni prenos je jedan nalog, pa je jedan račun jedna predaja. XPay ne pomjera novac.
        • Ugrađeni prikaz s tokenom koji banka potpisuje. Aplikacija banke otvara sanduče kao web prikaz s tokenom koji imenuje banku i klijenta i traje minute: potpisan HMAC tajnom koju okruženje banke već drži, pod vlastitom namjenom, pa token nikad ne prolazi kao obavijest ni obavijest kao token; ili ga XPay iskuje na zahtjev. Izmijenjen, istekao ili tuđi token odbija se jednako. Iza tokena se čita sanduče i traži predaja, ništa drugo.
        • Ekran Građani u aplikaciji za banke. Za operativu i podršku građanima: klijent po referenci, njegovi izdavaoci, vezanje po broju potrošača, sanduče, plati odabrano kako bi to uradila aplikacija, i link koji aplikacija otvara. Podrška građanima sada slijeće ovdje.
        • Zahtjevi za plaćanje se čiste nakon dvije godine. Završeni zahtjevi (odbijeni, istekli, povučeni, plaćeni) brišu se dvije godine nakon kraja, kako je obećano u klasifikaciji podataka; plaćanje izdano za zahtjev ostaje firmino.

        Za programere

        • GET /v1/bank/customers/:ref, POST /v1/bank/customers/:ref/billers (merchantId ili bankBusinessRef, customerRef ili customerId), DELETE .../billers/:id, GET /v1/bank/customers/:ref/bills?state=, POST /v1/bank/bills/handoff (customerRef, billIds), POST /v1/bank/customers/:ref/embed-token (minutes). Javno: GET /v1/embed/bills?token= i POST /v1/embed/bills/handoff.
        • Token: xbe1.<base64url {b, r, iat, exp}>.<hex HMAC-SHA256 nad "xpay-embed:v1:" + claims> HMAC tajnom okruženja; provjera nad tajnama svih uključenih okruženja, pa rotacija s preklapanjem zadržava stare tokene do kraja preklapanja.
        • Model BankCustomerBiller (migracija 20261031000000_bank_customer_billers, aditivna), prefiks bcb_; BankCustomerReference se pravi pri prvom vezanju i briše s posljednjim. Stranica /embed/bills u apps/bank radi bez sesije.
        • Čišćenje: HousekeepingService.sweepPaymentRequests svaki dan u 5.
        • Provjere: bank-bills.test.ts, pet provjera u scripts/smoke-bank.mjs, tok u pregledniku apps/bank/e2e/bills.e2e.ts; pomoćnik signInAtApi u apps/bank/e2e/helpers.ts.

        0.75.4

        22. septembar 2026.

        Popravljeno

        • Napojnica je neto, svuda isto. Vlasnikova odluka: napojnica je neto. Pravilo je i do sada postojalo na stolu i u knjizi napojnica (povrat prvo ide iz napojnice), ali ga pregled i izvještaj po stolovima nisu primjenjivali, a knjigovodstveni izvoz je cijeli povrat knjižio na robu s nulom u koloni Napojnica. Sada pločica "od toga napojnice" na pregledu i kolona napojnica po stolu odbijaju vraćeno, izvoz u redu povrata upisuje dio koji je vraćen iz napojnice u kolonu Napojnica a ostatak na robu, i napojnica na računu koji je stigao kraći više se ne broji ni u izvozu, kao što se ne broji ni na pregledu. Iste brojke za istu večer, ko god ih čita.

        Za programere

        • tipNetOf i refundSplit u apps/api/src/modules/tips/tip-ledger.ts su to jedno pravilo; pregled, izvještaj po stolovima, izvoz i knjiga napojnica ga dijele.

        0.75.3

        22. septembar 2026.

        Novo

        • Štampaj račun. Konobar na tabletu i menadžer u konzoli imaju dugme koje pošalje račun za sto na štampač lokala: svaka stavka, ukupno, plaćeno i preostalo, i kad lokal prima kodove, QR kod i poziv na broj za plaćanje s telefona. Gost skenira s papira, uplata legne, sto se sam zatvori. Račun s kodom zauzme sto isto kao dugme "Pokaži kod"; ako je kod već živ, štampa se s njim, ne izdaje se drugi. Bez štampača dugme kaže da ga nema i gdje se podešava. Ovo nije fiskalni račun i tako piše na papiru: fiskalni izdaje kasa.
        • Štampač na konektoru. Stranica konektora dobila je "Štampač računa": adresa termalnog štampača na mreži, širina papira (58 ili 80 mm), kodna strana 852 za Č, Ć, Š, Ž i Đ (uključi se kad probna štampa pokaže da štampač zna) i QR kod. "Probna štampa" ispiše probni papir sa svim tim slovima. Konektor javlja štampač u otkucaju, pa konzola pod Kasa vidi "Štampač računa" uz ono što konektor prati. Ako je već podešen printer-tap s pravim štampačem, koristi se on.

        Za programere

        • POST /v1/sessions/:id/print (STAFF, payments:write, withCode po izboru) vraća queued, printers i reference; 409 no_printer kad nijedan konektor sa štampačem ne javlja za tu poslovnicu. Račun putuje kao realtime događaj print.requested s cijelim računom u data; print.* se tretira kao događaj o novcu (traži payments:read, ne stiže na kuhinjske ekrane). Konektor 0.3.0: printer u konfiguraciji, lokalne rute POST /printer, DELETE /printer, POST /printer/test, ESC/POS render u receipt.ts (12 testova), printer.ts za port 9100.

        0.75.2

        22. septembar 2026.

        Novo

        • Zahtjevi za plaćanje (Request-to-Pay) na platformi za banke. Firma koja dijeli s bankom zamoli građanina ili drugu firmu da plati (B2P, B2B, institucija građanina kao I2P), ili građanin zamoli građanina (P2P) bez ikakve firme na XPayu. Primalac je klijent banke po referenci koju banka vodi, ili e-mail odnosno telefon na koji banka isporučuje. Zahtjev ima iznos, svrhu, referencu tražioca, dospijeće i pravilo za djelimično plaćanje; živi do kraja dana dospijeća, sedmicu kad dospijeća nema, ili do trenutka koji je zatražen, najviše devedeset dana.
        • Život zahtjeva, korak po korak. Nacrt, poslan (adapter banke je obaviješten kad okruženje to tvrdi), isporučen i pogledan kako banka javi, samo naprijed; zatim prihvaćen, odbijen, istekao po satu, povučen ili plaćen. Svaki korak je događaj na zahtjevu, s imenom onoga ko ga je napravio; prihvatanje, plaćanje, odbijanje i povlačenje su na revizijskom lancu banke. Druga banka za zahtjev ne zna.
        • Prihvatanje izdaje plaćanje i predaju. Kad primalac prihvati, firmin zahtjev postaje obično XPay plaćanje s referencom, otvoreno sat vremena, a odgovor kaže gdje aplikacija banke vodi primaoca: link koji gradi adapter banke kad okruženje tvrdi predaju u mobilnu aplikaciju, inače stranica samog plaćanja. Priliv koji sravni to plaćanje, kroz isti cjevovod kao svaki drugi, čini zahtjev plaćenim; djelimičan priliv samo kad je zahtjev to dozvolio. Firmin zahtjev se ne plaća izvještajem. Građaninov zahtjev banka izvrši sama i javi s vlastitom referencom.
        • Podsjetnici. Ručno najviše tri po zahtjevu i ne dva u istom satu; zahtjev koji dospijeva sutra dobije jedan sam od sebe. Povlačenje prihvaćenog zahtjeva otkazuje i plaćanje izdano za njega; novac koji je već stigao ostaje sravnjivanju.
        • Ekran Zahtjevi za plaćanje u aplikaciji za banke. Lista po stanju s brojem po stanju, obrazac za novi zahtjev (firma koja dijeli, primalac, iznos, svrha, dospijeće, odmah ili nacrt), detalj sa cijelom pričom i radnjama koje su kome dozvoljene: operativa, platni promet i podrška prave, šalju, podsjećaju i povlače; operativa i podrška građanima bilježe šta je primalac uradio i prihvataju za njega. Sekcija je u navigaciji tih uloga; direktor, analitičar, inženjer i revizor je nemaju.

        Za programere

        • POST /v1/bank/requests, GET /v1/bank/requests (filter po stanju i firmi, kursor, brojanje po stanju), GET /v1/bank/requests/:id sa događajima, POST /v1/bank/requests/:id/send, .../remind, .../accept (odgovor nosi handoff), .../progress (DELIVERED, VIEWED, DECLINED, PAID samo za P2P uz bankReference), .../cancel. Sistemski ključ banke prolazi sve; uloge su na svakoj ruti.
        • Modeli PaymentRequest i PaymentRequestEvent (migracija 20261030000000_payment_requests, aditivna); prefiksi preq_ i prev_. Plaćanje izdano za zahtjev nosi metadata.paymentRequestId i orderRef jednak referenci tražioca.
        • Adapter: deepLink gradi predaju kad okruženje tvrdi mobileDeepLink; sendNotificationContext čuje slanje i podsjetnik kad ga okruženje tvrdi. Bez okruženja koje tvrdi, predaja je stranica plaćanja.
        • Sat: svake minute istekli zahtjevi prelaze u EXPIRED, zahtjevi s dospijećem sutra dobiju podsjetnik, a prihvaćeni s plaćenim plaćanjem se povežu; isto povezivanje se dešava i pri svakom čitanju.
        • Provjere: bank-requests.test.ts (primalac, život, podsjetnici, stanja, šta sravnjuje), deset provjera u scripts/smoke-bank.mjs, i tok u pregledniku apps/bank/e2e/requests.e2e.ts.

        0.75.1

        22. septembar 2026.

        Novo

        • Redoslijed u meniju bira vlasnik. Umjesto jednog prekidača "po traženosti", svaka poslovnica bira pravilo po kojem se jela u kategoriji ređaju na telefonu gosta: kako sam posložio, najviše naručivano, najveći promet, najveća marža po porciji ili najviše zarađeno (marža puta prodano). Pravilo gleda zadnjih 30 dana narudžbi; dok ih nema dovoljno, meni stoji kako je posložen. Jela bez nabavne cijene ne učestvuju u dva pravila koja je traže i ostaju u vašem redoslijedu ispod rangiranih; rasprodano i dalje ide na dno, a oznaka "najtraženije" ne zavisi od pravila. Nema formule koja miješa maržu i prodaju: koliko koja vrijedi je odluka lokala, ne koda.
        • Računi zatvoreni kao uplata na račun se vide. Kad menadžer zatvori sto na gostovu riječ da je prenos poslan, to se i dalje ne knjiži u promet (promet broji samo ono što je banka vidjela). Ali pregled sada uz "čeka potvrdu" kaže koliko je računa tako zatvoreno i koliko od njih banka još nije potvrdila, pa veče s tri takva stola više ne izgleda kao veče bez ičega. Konobar na tabletu zatvara samo gotovinu i karticu, kao i do sada; prenos potvrđuje banka ili konzola.

        Za programere

        • Poslovnica ima menuRanking (VENUE, POPULARITY, REVENUE, MARGIN, PROFIT) umjesto sortMenuByPopularity; migracija prenosi uključeni prekidač u POPULARITY. Pregled (/v1/analytics/overview) vraća closedAsTransfer (broj i iznos).

        0.75.0

        21. septembar 2026.

        Novo

        • XPay za PrestaShop (1.7.6 do 8.x). Kupac na kasi izabere XPay, narudžba se napravi u statusu "Čeka uplatu (XPay)", modul napravi račun i pošalje kupca na stranicu s kodom. Webhook s provjerom potpisa označi narudžbu plaćenom (Payment accepted, s upisanom uplatom i brojem računa), "Stiglo manje (XPay)" kad stigne manje, bilješka za ostalo. Stranica potvrde sama provjeri stanje kad se kupac vrati, a kad kod istekne nudi "Plati ponovo QR kodom" za istu narudžbu. Nudi se samo za korpu u KM i tek kad je ključ upisan.
        • XPay za OpenCart (4.0.2.x). Isti tok: račun na "Potvrdi narudžbu", stranica s kodom, webhook s potpisom, tri statusa narudžbe po izboru (dok čeka, kad stigne, kad stigne manje), komentar u historiji za svaki ishod, a stranica uspjeha sama provjeri stanje kad se kupac vrati i kaže da je uplata stigla.
        • Arhive za preuzimanje. pnpm run plugins provjeri sva tri dodatka harnessom bez instalirane prodavnice i spakuje ih u obliku koji svaka platforma očekuje: xpay-woocommerce.zip, xpay-prestashop.zip i xpay.ocmod.zip. Harnessi se od sada vrte i u CI-ju.

        Za programere

        • Zajednički dio dodataka (tri poziva i provjera potpisa) je jedna klasa bez ijedne zavisnosti od prodavnice, ista u PrestaShop i OpenCart paketu, pa se harnessom provjerava odvojeno od svake platforme.

        0.74.8

        21. septembar 2026.

        Novo

        • Brojevi firmi na ekranu operatera. Svaka firma dobije stalni četverocifreni broj koji ide u svaki poziv na broj, pa ih ima 9000 i format se ne može proširiti bez dogovora sa svakom bankom koja ga je usvojila. API je to odavno brojao i upozoravao u svom dnevniku na 80% i 95%, a dnevnik niko ne čita; sada pregled operatera ima pločicu sa postotkom, trakom i brojem slobodnih, koja mijenja boju kad bi dnevnik upozorio.

        0.74.7

        21. septembar 2026.

        Novo

        • Provjera spremnosti za UAT. Petnaest scenarija nad adapterom i podešavanjima okruženja, bez dodira s firmom ili plaćanjem: adapter postoji i smije voditi okruženje, tvrdnje su u dosegu adaptera, HMAC tajna se čuva, obavijest potpisana njome prolazi a lažna, stara ili nepotpisana se odbija, omotnica i lista se čitaju, mapa polja banke čita, verzije sheme su postavljene, produkcija ima listu adresa ili traži certifikat, adapter odgovara na očitavanje i provjeru zdravlja, politika prijave je cijela i njen provider odgovara, i kaže se šta čeka u mrtvom pismu. Svaki scenarij prođe, padne ili se ne odnosi na okruženje. Izvještaj ostaje na okruženju; sve prošlo vodi nacrt u "spremno za UAT", pad vraća u nacrt. Ništa nikad ne kaže "dokazano u produkciji": to kaže samo prihvatni test stvarne banke, a ovaj proizvod to ne kaže ni za jednu. Svaka provjera je na lancu s onim što je palo.
        • Dugme i izvještaj na kartici okruženja na ekranu Integracije.

        Provjereno

        • Bank smoke sa šest novih provjera: demo sandbox prolazi sve i postaje spreman za UAT, izvještaj ostaje revizorima, politika prijave bez tajne pada i vraća u nacrt, analitičar i druga banka odbijeni, generički webhook na UAT okruženju prolazi iste scenarije preskačući što ne radi, svaka provjera na lancu. Provjera prođena u pregledniku.

        0.74.6

        21. septembar 2026.

        Novo

        • Portal za developere. Za jedno okruženje, sve što bankin developer treba, izvedeno iz okruženja i ove instalacije: adrese na koje njeni sistemi šalju obavijesti (i host za klijentski certifikat kad ga instalacija ima), zaglavlja i potpis s rokom, oblici obavijesti (jedna, lista, omotnica) i mapa polja, šta se dobije nazad i kad je odbijeno, ugovor očitavanja, događaji koje bankina sesija čuje, primjer politike prijave preko banke s demo izdavaocem.
        • Studio: potpiši i pošalji. Inženjer zalijepi HMAC tajnu, koja ostaje u stranici i ide samo u potpis, uredi tijelo obavijesti, potpiše je i pošalje u okruženje odavde; vidi zaglavlje potpisa, istu poruku kao curl i odgovor. Put od bankinog sistema do naplaćenog računa prođe se prije nego što postoji ijedna linija bankinog koda.
        • Uzorak izvoda camt.053 s jednom uplatom na upisani poziv na broj, koji firma učita u konzolu: drugi put do naplaćenog računa, bez ikakve integracije.
        • Dnevnik prijema s ponavljanjem iz 0.74.1 je preglednik obavijesti.

        Popravljeno

        • Zaglavlja omotnice u CORS-u. Preglednik nije smio poslati X-Message-Id, X-Correlation-Id i X-XPay-Schema-Version, pa je slanje iz studija padalo bez traga na serveru; sada smije, a X-Correlation-Id i X-Rows se i čitaju iz odgovora.

        Provjereno

        • Bank smoke s tri nove provjere: portal imenuje adresu feeda, zaglavlja, oblike i demo izdavalac; analitičar i druga banka odbijeni; uzorak izvoda napravljen za račun firma učita i račun je plaćen. Studio prođen u pregledniku od potpisa do naplaćenog računa.

        0.74.5

        21. septembar 2026.

        Novo

        • Poveži konektor. U konzoli, pod Kasa, vlasnik klikne "Poveži konektor" i dobije kod od osam slova koji vrijedi 30 minuta i radi jednom. Na računaru pored kase konektor ima svoju stranicu (http://127.0.0.1:9110); kod se upiše tamo, konektor sam uzme svoj ključ, sačuva ga kod sebe i javi se konzoli. Vlasnik ključ nikad ne vidi. U konzoli se ključ zove "Konektor <ime računara>" i može se opozvati kao svaki drugi.
        • Pronađi kasu, na samom konektoru. Stranica konektora ima dugme koje pretraži računar (fiskalni servis, folderi sa računima, instalirani programi kasa) i uz svaki folder ponudi "Prati ovaj folder". Ko zna putanju ili adresu, upiše je ručno: folder, adresu kase preko HTTP-a ili štampač (kasa štampa na konektor, konektor proslijedi pravom štampaču). Sve što se izabere odmah radi i upiše se u fajl konektora, pa preživi ponovno pokretanje. Ono što se prati može se i ukloniti, s iste stranice.
        • Konektor krene bez ičega. Prije je odbijao da se pokrene bez fajla i bez ključa; sada krene, kaže da nije povezan i čeka kod. Poziv kase na lokalni /payments prije povezivanja dobije jasan odgovor, ne grešku mreže. Ručno napisan fajl, --config i XPAY_API_KEY iz okruženja rade kao i prije.
        • Instalacija na računar pored kase. Konektor se sada pakuje u jedan fajl (xpay-konektor.js, sve unutra) uz install.ps1 koji na Windows računaru nađe ili instalira Node.js, stavi konektor u C:\XPay\konektor, podesi da se sam pokreće pri svakom paljenju i sam diže ako padne, i otvori njegovu stranicu. Uklanjanje je uninstall.ps1. Tehničar više ne piše ništa rukom.

        Popravljeno

        • Uputstvo za servisera imalo je znakove koji liče na oznake. Tekst koji se kopira sa stranice Kasa sadržavao je "<ključ>" i "<broj računa>", što je konzola tumačila kao oznake i bilježila grešku pri svakom prikazu stranice; sada su u uglastim zagradama.

        Za programere

        • POST /v1/connectors/pairing-code (vlasnik) izdaje kod; POST /v1/connectors/pair (bez prijave, deset pokušaja u minuti po adresi) zamijeni kod za ključ s pravima payments:read i payments:write i vrati apiUrl, poslovnicu i ime firme. Nepoznat, iskorišten i istekao kod dobiju isti odgovor (404, reason code_spent). Konektor 0.3.0: lokalne rute GET /state, POST /pair, POST /detect, POST /adapters, DELETE /adapters/:index uz postojeće GET /health i POST /payments.

        0.74.4

        21. septembar 2026.

        Novo

        • Dovedi firmu. Jedan poziv od bankine reference napravi firmu, njenu prvu poslovnicu s računom na koji stiže novac, vlasnikov nalog u konzoli s pozivnicom koja ide vlasniku na e-mail i nikad banci, i bankinu vezu s referencom i proizvodima od prvog trenutka. Veza je predložena: uvid ostaje na vlasniku, a banka firmu čita onog dana kad vlasnik uključi dijeljenje. Ista referenca dva puta je ista firma, napravljena jednom. Što banka ne kaže, adapter njenog okruženja može naći po referenci; adapteru se i javi da firma postoji, kad okruženje to tvrdi. Račun koji druga firma već ima odbija se prije nego što se išta upiše. Sve je na lancu banke i na lancu firme.
        • Obrazac na ekranu Firme za operacije i menadžere odnosa.

        Popravljeno

        • CI ne pada na skladištu artefakata. Spremište artefakata na GitHubu odgovorilo je 403 kad je prostor naloga bio pun i time srušilo cijeli prolaz, iako je kod bio ispravan. Slanje popisa komponenti i tragova prolaza kroz preglednik više ne obara prolaz, a čuva se kraće.

        Provjereno

        • Bank smoke sa sedam novih provjera: firma napravljena s vezom i bez predane pozivnice, ista referenca ponovo, naziv koji je našao demo adapter, tuđi račun odbijen, firma nečitljiva do uvida, analitičar odbijen, zapis na lancu. Obrazac prođen u pregledniku.

        0.74.3

        21. septembar 2026.

        Novo

        • Prijava preko banke. Banka koja svoje ljude prijavljuje svojim sistemom upiše u okruženje gdje je njen provider i kakva je politika (izdavalac, klijent, mapiranje grupa na uloge, da li se novi ljudi dodaju pri prijavi i s kojom ulogom), a tajnu klijenta čuva kao kredencijal. Osoba na ekranu za prijavu izabere "Prijava preko banke", upiše oznaku banke i ode kod providera; nazad dolazi s kodom koji API zamijeni za identitet, provjeri potpis, izdavaoca, primaoca, rok i nonce, pita adapter šta identitet znači i primijeni politiku banke: ko je već vezan za taj identitet ulazi kakav jeste, ko je poznat po e-mailu se veže, ko je nov dobije ulogu koju mapiranje daje njegovoj grupi ili podrazumijevanu, a bez uloge ili bez politike se odbija, s razlogom koji ekran zna reći. Aplikacija dobije jednokratnu kartu i zamijeni je za sesiju. Uloge nikad ne dolaze iz preglednika ni direktno od providera; mapiranje je bankino, na serveru. Drugi faktor je providerov.
        • Demo provider. Za okruženje na demo adapteru API je i provider: stranica za prijavu koja pita e-mail, ime i grupu i ništa ne provjerava, dokument otkrivanja i izdavanje tokena. Odgovara samo za demo okruženje čija politika imenuje baš taj izdavalac, a demo adapter nikad ne vodi produkciju.
        • Na lancu. Identitet, član kojeg je politika napravila i sesija, svaki put.
        • SAML nije tu. Traži provjeru XML potpisa s kanonizacijom, za koju u kodu nema biblioteke; napisati je rukom bila bi najmanje sigurna stvar u proizvodu. Dolazi s bibliotekom onog dana kad je banka zatraži.

        Provjereno

        • Bank smoke s jedanaest novih provjera: ponuda, dokument otkrivanja, početak sa stanjem i PKCE izazovom, osoba napravljena politikom u mapiranoj ulozi, karta vrijedi jednom, isti identitet ponovo kao isti član, podrazumijevana uloga, poznati član vezan po e-mailu, politika isključena odbija stranca, tuđe stanje odbijeno, demo provider samo za sandbox, lanac. Tok prođen u pregledniku od /sso do pregleda.

        0.74.2

        21. septembar 2026.

        Novo

        • Feed koji banka očitava. Banka čiji adapter zna očitavati napravi feed za firmu koja dijeli s njom, pod svojim okruženjem od prvog trenutka; firma ga vidi među svojima, a može i sama povezati izvor vrste "očitavanje sa banke" u konzoli, gdje čeka dok ga banka ne stavi pod okruženje. Svake minute planer očita svaki dospjeli feed: adapter se pita od kursora feeda, što nađe ide u isti tok kao obavijest (ne knjiži se dvaput), kursor se pomjeri, a feed pamti kad je zadnje očitan i kad slijedi. Očitavanje koje padne označi feed greškom s razlogom i odgađa sljedeće, duplo svaki put do sat vremena; sljedeći uspjeh sve briše. Tri pada zaredom stave okruženje u radu na narušeno, sljedeći uspjeh ga vrati.
        • Očitaj sada. Inženjer očita sve feedove okruženja odmah, sa ekrana ili s POST /v1/bank/integrations/:id/poll, i vidi po feedu šta je očitano, novi kursor, grešku i odgodu.
        • Ekran Integracije pokazuje uz svaki očitavani feed kad je zadnje očitan, kad slijedi i grešku, i ima obrazac kojim banka napravi feed za firmu.

        Popravljeno

        • Provjera tipova u CI-ju. Pomoćna funkcija u testu adaptera sudarala se s imenom polja koje opisuje; CI 0.74.1 je pao na tome, kod je bio ispravan. Test je preimenovan.

        Provjereno

        • Bank smoke sa šest novih provjera: feed napravljen i viđen kod firme, očitavanje naplati račun i pomjeri kursor, drugo očitavanje ne nađe ništa novo, pad označi i odgodi, uspjeh očisti, analitičar i druga banka odbijeni. Ekran prođen u pregledniku.

        0.74.1

        21. septembar 2026.

        Novo

        • Dnevnik prijema. Svaka obavijest na feedu pod okruženjem banke je jedan red: id poruke koji banka pošalje (ili hash tijela kad ga ne pošalje), korelacijski id iz zaglavlja banke ili iskovan ovdje i vraćen u odgovoru, verzija sheme, stanje (prihvaćeno, odbijeno, mrtvo pismo) s razlogom, koji je kredencijal potvrdio potpis i šta je naplaćeno. Ista poruka dva puta se odgovara iz dnevnika i nikad ne knjiži dvaput. Potpisana poruka koju niko ne može pročitati čeka u mrtvom pismu; inženjer je ponovi kad ukloni uzrok, i to je zapis na lancu. Odbijene poruke se čiste poslije sedmice, ostale poslije devedeset dana.
        • Kapije okruženja. Lista dozvoljenih adresa i mreža (kredencijal ALLOWLIST, provjeren stavku po stavku pri upisu), verzije sheme koje okruženje prima, i klijentski certifikat: okruženje s mtls: required prima samo zahtjev čiji otisak certifikata, kako ga nginx javi, odgovara certifikatu koji okruženje čuva.
        • Rotacija ključeva s preklapanjem. Novi kredencijal iste vrste ne ruši stari: stari potpisuje još dan (ili koliko se kaže, nula gasi odmah), oba se vide po otisku, a odgovor kaže do kada.
        • Host za sisteme banaka. Instaler na zahtjev (--bank-mtls-domain) služi poseban host na kojem nginx traži klijentski certifikat i prosljeđuje otisak API-ju; sajt, konzola i aplikacija banke to zaglavlje brišu, pa se otisak ne može podmetnuti kroz njih.
        • Ekran Integracije pokazuje dnevnik prijema s filterima i dugmetom za ponavljanje mrtvog pisma, uređivanje podešavanja nacrta ili sandboxa, i do kada stari kredencijal još vrijedi. Zdravlje banke broji šta je svako okruženje poslalo u zadnjem danu i šta čeka u mrtvom pismu.

        Provjereno

        • Jedinični testovi omotnice, liste adresa, otiska certifikata i potpisa rotiranim ključem; bank smoke s devet novih provjera od ponovljene poruke do zahtijevanog certifikata; ekran prođen u pregledniku. nginx blok je napisan i lintovan, a isproban biva onog dana kad banka predoči certifikat.

        0.74.0

        21. septembar 2026.

        Novo

        • Adapteri i sposobnosti. Instalacija nosi dva adaptera: demo banku, koja ne postoji i može sve, uvijek isto, i nikad ne vodi produkciju; i generički potpisani webhook, koji zna potpisati obavijest i ništa više, i time dokazuje da apstrakcija drži. Deset imenovanih sposobnosti; okruženje tvrdi najviše ono što njegov adapter ima.
        • Okruženja integracije. Inženjer integracije otvara sandbox, UAT i produkciju, po jedno; svako radi na jednom adapteru, ima podešavanja bez tajni (tajna upisana u podešavanja se odbije i uputi na kredencijale) i kredencijale po vrsti koji se upišu i nikad više ne pročitaju: poslije se znaju po vrsti i otisku. HMAC tajna i API token se mogu iskovati ovdje i pokazati jednom. Adapter odgovara na provjeru zdravlja, odgovor ostaje na okruženju, a zdravlje banke od sada nabraja okruženja umjesto praznog spiska.
        • Feed firme pod okruženjem banke. Feed firme koja dijeli s bankom stavlja se pod okruženje čiji adapter nosi tu vrstu. Od tada obavijest na tom feedu provjerava adapter kredencijalom okruženja i čita je u obliku banke, a sve što pročita ide u isti tok sravnjivanja kao i do sada. Vlastita tajna feeda više ne potpisuje. Feed se može vratiti firmi.
        • Promjene okruženja s drugom osobom. Nacrt i sandbox inženjer uređuje direktno. Sve dalje ide kroz red promjena: inženjer predlaže podešavanja, tvrdnje ili promjenu stanja, administrator odobrava, a stanje se mijenja samo dozvoljenim koracima (isključenje odakle god, nazad u nacrt samo iz isključenog, u rad samo iz spremnog ili narušenog).
        • Ekran Integracije u aplikaciji banke: adapteri, okruženja s tvrdnjama, zdravljem, podešavanjima, kredencijalima i feedovima, i dugmad za sve gore navedeno.
        • Partnerski API. GET /v1/bank/adapters, GET, POST i PATCH /v1/bank/integrations, kredencijali i zdravlje okruženja, GET /v1/bank/feeds, stavljanje feeda pod okruženje i vraćanje.

        Provjereno

        • Jedinični testovi adaptera (tabela sposobnosti, registar, čitanje obavijesti, determinizam demo banke, provjera potpisa, otisci) i pravila promjena. Bank smoke: 17 novih provjera, od odbijene demo produkcije do obavijesti provjerene adapterom i odobrenja administratora. Ekran prođen u pregledniku.

        0.73.11

        21. septembar 2026.

        Novo

        • Zaboravljena lozinka i pozivnice, linkom. Na prijavi stoji "Zaboravili ste lozinku?": upišete adresu i, ako nalog postoji, stiže mail sa linkom koji vrijedi sat vremena i radi jednom. Odgovor je isti za adresu koja postoji i za onu koja ne postoji, pa ekran nikome ne odaje koje adrese imaju nalog. Isti ekran za postavljanje lozinke služi i pozivnici: nalog dobija link na sedam dana, osoba sama izabere lozinku i niko je nikad ne kuca umjesto nje. Postavljanje lozinke odjavi sve ostale prijave na taj nalog, a iskorišten ili istekao link kaže da zatražite novi.
        • Pristup konzoli, u Podešavanjima. Vlasnik vidi ko se prijavljuje u konzolu (vlasnici i menadžeri, sa zadnjom prijavom ili "poziv poslan"), dodaje osobu po imenu i adresi kao menadžera ili vlasnika, i uklanja je. Link iz pozivnice se pokaže i vlasniku, jednom, jer je nova osoba često u istoj prostoriji, a mail ponekad kasni ili ne ode. Sebe ne možete ukloniti, ni zadnjeg vlasnika. Osoblje u sali ostaje pod Osoblje sa PIN-om.
        • Operater više ne kuca lozinke. Pri otvaranju firme polje za lozinku vlasnika je prazno po pravilu: vlasnik dobija link mailom, a link stoji i u odgovoru operateru ako mail ne stigne. Upisana lozinka i dalje radi za onoga ko stoji pored vlasnika.

        Ispravljeno

        • Podešavanja su pri otvaranju javljala "Request validation failed": crtač računa slao je prazne napomene zaglavlja i podnožja kao "ništa", a server je tražio tekst. Sada prima oboje, i na uzorku i pri čuvanju.
        • "Prije 52 s" umjesto "-52 s": vrijeme "prije koliko" na bosanskom se sad piše ručno, jer neki preglednici nemaju te podatke za bosanski i ispisivali su minus.

        Za one koji razvijaju

        • POST /v1/auth/forgot (javno, 5 u minuti po adresi, uvijek 201), GET /v1/auth/link/:token (kome je i do kad), POST /v1/auth/link/:token (postavlja lozinku, troši link, odjavljuje sesije). Tabela password_links (migracija 20261024000000_password_links) čuva samo hash tokena. GET, POST i DELETE /v1/merchant/members za vlasnika; owner.password na POST /v1/admin/merchants je opcionalan, odgovor nosi owner.inviteUrl i owner.invited. Link vodi na DASHBOARD_BASE_URL/lozinka/<token>. Opšti smoke prolazi cijeli put: poziv, link, lozinka, prijava, uklanjanje.

        0.73.10

        21. septembar 2026.

        Popravljeno

        • API podrazumijevano odgovara i aplikaciji banke. Kad CORS_ORIGINS nije postavljen, API je dozvoljavao samo konzolu na portu 3000, pa je prijava iz aplikacije banke na 3003 padala u pregledniku porukom "Failed to fetch", a nijedan test na serveru to ne vidi. Podrazumijevana lista sada ima konzolu, sajt i aplikaciju banke; CI to postavlja i izričito. Prolazi kroz preglednik iz 0.73.9 su ovo našli na prvom prolazu u CI-ju.

        0.73.9

        21. septembar 2026.

        Novo

        • Prolazi kroz preglednik za aplikaciju banke. Playwright s Chromiumom vodi stvarne ekrane: prva prijava s upisom aplikacije za kodove i kodovima za oporavak, pogrešna lozinka odbijena jednom rečenicom, odjava; pretraga po pozivu na broj i po imenu firme iz palete, gdje pogodak otvara baš to plaćanje; detalj plaćanja s činjenicama, kontekstom, vremenskom linijom i isporukama, bez tehničkog dijela za operacije. Prolazi rade nad pravim API-jem sa seedom, jedan po jedan, i sami dovedu seed u poznato stanje: zaborave telefone seedovanih ljudi, uključe uvid dvjema firmama i pokrenu projekciju.
        • Demo iz tri perspektive. Direktor (analitičar) vidi banku u brojkama i analitiku iza njih; šef platnog prometa (operacije) radi plaćanja i red sravnjivanja; CIO (vlasnik) čita zdravlje, prijavi incident i provjeri lanac. Svaka uloga vidi ono što tabela uloga kaže i ništa više. To je izlazni kriterij faze 3 i od sada je dio CI-ja.

        Popravljeno

        • Pogodak iz pretrage otvara plaćanje i kad ste već na plaćanjima. Stranica plaćanja je adresu čitala samo pri otvaranju, pa je pogodak izabran s te iste stranice mijenjao samo adresu i ništa nije otvarao. Sada prati adresu: otvori plaćanje iz pogotka i primijeni filter po firmi kad pretraga tamo vodi. Prolaz kroz preglednik je ovo i našao.

        Provjereno

        • Šest prolaza zeleni lokalno nad dev serverom i u CI-ju nad izgrađenom aplikacijom; tragovi neuspjelog prolaza se čuvaju kao artefakt CI-ja.

        0.73.8

        21. septembar 2026.

        Novo

        • Zdravlje sistema. Stranica koja jednom riječju kaže kako je instalaciji za ovu banku, pa po dijelovima: svježina projekcije, izvodi firmi koje dijele s bankom po vrsti izvora (aktivni, pauzirani, u grešci, kad su zadnji put povučeni), isporuke sistemima firmi u zadnjem danu (neuspjele, napuštene, zakašnjele), otvoreni incidenti i trideset dana historije: neuspjele isporuke, otvoreni slučajevi i istekla plaćanja po danu. Integracije banke stižu s fazom 4 i stranica to kaže, umjesto da pokazuje zeleno svjetlo za nešto čega nema.
        • Incidenti. Osoba u banci prijavi šta ne valja: naslov, ozbiljnost, opis i broj iz service deska ako ga ima. Incident ide kroz stanja otvoren, praćenje i riješen, svaki korak s bilješkom i imenom onoga ko ju je napisao. Prijava i svaka promjena su zapis na revizijskom lancu banke. Prijavljuju i vode ih uloge integracije, operacija i platnog prometa; čitaju svi koji čitaju zdravlje. Sistemski ključ ne prijavljuje incidente, jer incident prijavljuje čovjek.
        • Revizija. Revizor i compliance čitaju lanac banke od najnovijeg zapisa: ko, šta, nad čim, s podacima i hashom, uz filter po radnji i danima. Dnevnik osjetljivog pristupa je isti lanac sužen na čitanja koja je svrha otvorila iznad uobičajenog nivoa uloge: ko, koje plaćanje, koja svrha i predmet. Dugme za provjeru prođe svaki zapis i potvrdi da se svaki poziva na prethodni i da zapečaćeni vrh još odgovara.
        • Izvozi. Tri CSV fajla za period do godinu dana: plaćanja iz pogleda banke (analitičar, uprava, operacije, platni promet, revizor i compliance), revizijski lanac s hashovima (revizor i compliance, da se može provjeriti i drugdje) i slučajevi sravnjivanja s uplatom, plaćanjem i odlukom banke (operacije, platni promet, revizor i compliance). Svaki izvoz je i sam zapis na lancu, s periodom i brojem redova.
        • Partnerski API. GET /v1/bank/health, incidenti (GET, POST i PATCH /v1/bank/incidents), GET /v1/bank/audit, /audit/access, /audit/verify i GET /v1/bank/exports/{payments,audit,cases}.csv. Sve je ograničeno na banku i firme koje smije čitati; tuđi incident je 404, a na tuđem lancu ničega od toga nema.

        Provjereno

        • Bank smoke: zdravlje s projekcijom, izvodima, isporukama i historijom; incident kroz sva tri stanja s bilješkama, a zdravlje s njim narušeno; druga banka ga ne vidi i ne može ga dirati; lanac s odlukama, incidentom i čitanjima po svrsi; dnevnik pristupa; provjera lanca; izvoz kao CSV sa zapisom na lancu; analitičar ne čita lanac; period duži od godine je odbijen. Obje stranice prođene u pregledniku.

        0.73.7

        21. septembar 2026.

        Novo

        • Pet pogleda, jedan period. Analitika ima pet tabova nad firmama koje dijele s bankom, za 30, 90 ili 365 dana. Plaćanja: naplaćeno po danu i načinu, broj uplata, prosječan račun, potvrde banke i ručne, brzina potvrde s medijanom i 95. i 99. percentilom kad ima dovoljno uzoraka, i ritam po satu i danu u sedmici. Građani: QR naplata po veličini računa i vrsti posla, s jasnom porukom da brojke o pojedinačnim ljudima dolaze tek kad banka dostavi reference kupaca. Firme: povezane, aktivne, s uvidom, nove veze i uključeni uvidi u periodu, aktivne firme po danu, deset s najviše naplate, segmenti. Korporativno: naplata korporativnih vrsta po danu i vrsti, izdavaoci računa, izdati, plaćeni i serijski računi i šta je otvoreno. Sravnjivanje: otvoreno i riješeno po danu, razlozi, vrijeme do rješenja, uplate po stanju sparivanja, firme s najviše otvorenih slučajeva. Svaka brojka je ograničena na banku i firme koje s njom dijele.

        0.73.6

        21. septembar 2026.

        Novo

        • Svaka firma s uvidom ima svoju stranicu. Ko je, kako je povezana (stanje veze, od kada predložena, od kada dijeli, ko ju je i kad označio), njena dva prekidača kako ih je sama postavila, naplata za 30 i 90 dana po načinu iz pogleda banke s grafikonom po danu, brzina potvrde, zadnja naplata, šta kod nje traži čovjeka (otvoreni slučajevi, nesparene uplate, plaćanja koja čekaju), poslovnice sa svime što primaju, kako joj stižu izvodi i koliko webhooka ima, i računi kupcima ako ih izdaje.
        • Banka označi vezu svojom referencom. Operativa i menadžer odnosa (ili bankin sistem) upišu na vezu referencu pod kojom bankini sistemi vode firmu i proizvode banke koje ima; referenca je jedinstvena po banci, upis ide na revizijski trag, a uvid ostaje firmin prekidač i ne mijenja se.
        • Izdavaoci računa kao poseban pogled. Firme koje kupcima šalju račune (komunalno, kirija, freelanceri, usluge, webshop, veleprodaja, trgovina) s brojem izdatih i plaćenih računa u zadnjih 30 dana i onim što je još otvoreno.

        0.73.5

        21. septembar 2026.

        Novo

        • Drugi prekidač prema banci. Uz "uvid za banku", u Postavkama firme stoji i "banka može odlučiti umjesto vas". Isključen je dok ga firma ne uključi, i može se uključiti tek uz uvid. Dok je isključen, bankina riječ o slučaju sravnjivanja ostaje preporuka uz slučaj; kad je uključen, bankina potvrda da uplata pripada računu zatvara slučaj i knjiži uplatu na račun istim putem kojim to radi menadžer u konzoli, "nije naša" označi uplatu kao zanemarenu, a "dupla" je zapiše uz račun bez dodavanja novca. Na vremenskoj liniji računa piše da je to uradila banka, u aplikaciji banke uz odluku piše "primijenjeno", a firma uz riješeni slučaj vidi da je odluka banke primijenjena.

        Ispravljeno

        • Ko je zatvorio pitanje piše na računu. Kad se slučaj "iznos se ne slaže" riješi potvrdom, uplata je već bila uknjižena kad je slučaj otvoren, pa se stanje računa ne mijenja, i do sada na vremenskoj liniji računa nije ostajao nikakav trag da je neko zatvorio slučaj. Sada ostaje zapis s istim stanjem, razlogom i onim ko je odlučio, bio to menadžer u konzoli ili banka.

        Za one koji razvijaju

        • Rješavanje slučaja i knjiženje uplate na račun izvučeni su iz kontrolera sravnjivanja u ReconciliationService, pa firma i banka prolaze kroz isti kod; kontroler samo delegira. Veze banaka i firmi su u vlastitom BankLinksModule, jer bi inače modul banke, sravnjivanja, plaćanja i realtime-a činili krug.

        0.73.4

        21. septembar 2026.

        Novo

        • Banka vidi slučajeve sravnjivanja firmi koje dijele s njom. Tri taba (otvoreni, riješeni, odbačeni) s brojevima, red po slučaju: razlog, uplata iz izvoda, plaćanje koje je matcher imenovao, broj kandidata i posljednja odluka banke. Detalj nosi uplatu kako ju je izvor donio (bez podataka o uplatiocu), plaćanje, svakog kandidata s bodovima i dokazima iza bodova (poziv na broj, iznos, račun, rok, minute od izdavanja) i sve što je banka o slučaju rekla.
        • Banka može reći šta je uplata. Operativa i platni promet (i administratori) biraju: uplata pripada ovom plaćanju, nije ove firme, dupla je, ili napomena. Svaka odluka se zapiše i ode na revizijski trag banke. Dok firma ne dozvoli banci da odlučuje umjesto nje, odluka je preporuka: firma je vidi uz slučaj u svojoj konzoli ("Banka X kaže: ...") i sama odlučuje kao i do sada. Primjena odluke uz dozvolu firme dolazi u drugom dijelu ove stavke.
        • Firma vidi šta je banka rekla. U konzoli, uz svaki slučaj sravnjivanja, stoji posljednja preporuka banke s napomenom, označena kao preporuka koja se ne primjenjuje sama.

        0.73.3

        21. septembar 2026.

        Novo

        • Jedna linija, odgovor u grupama. Ctrl K (Cmd K) sa svake stranice otvara pretragu: poziv na broj ili ime firme nalazi plaćanja iz pogleda banke, ime ili porezni broj nalazi firmu, id uplate iz bankovnog izvoda (vanjski ili end-to-end) nalazi uplatu i plaćanje na koje je sparena, id slučaja nalazi slučaj. Strelice biraju, Enter otvara plaćanje u ladici ili listu filtriranu po firmi. Server odgovara samo iz okvira banke i firmi koje s njom dijele, prije nego što se išta nacrta; osjetljivi sažeci se ne prikazuju ni ovdje.

        0.73.2

        21. septembar 2026.

        Novo

        • Detalj plaćanja kaže i šta su sistemi firme čuli. Uz vremensku liniju, uplate, slučajeve i povrate, ladica sada nosi i isporuke webhooka za to plaćanje: koji događaj, kojim krajem prošao (čeka, isporučeno, nije uspjelo, odustalo se), koliko pokušaja i kad je stiglo. Vidi ga svako ko vidi plaćanje; bez adresa i odgovora.
        • Tehnički dio, samo za one koji istražuju. Revizija, usklađenost i integracija dobijaju odjeljak s identifikatorima, podacima svakog događaja, referencama uplata (vanjski i end-to-end id, izvor, pouzdanost) i onim što su krajnje tačke odgovorile (host, kod, greška, sljedeći pokušaj). Server odlučuje po ulozi da li odjeljak uopšte postoji u odgovoru; ekran ga ne može zatražiti.
        • Filter po firmi i sačuvani filteri. Lista plaćanja ima izbor firme uz stanje, vrstu posla i pretragu; kombinaciju filtera preglednik pamti pod imenom koje joj date, jednim klikom se primijeni, jednim ukloni.

        Ispravljeno

        • Firma s više od dvije hiljade plaćanja u pogledu banke nije u jednom prolazu izlazila iz pogleda kad prestane dijeliti, pa se pri povratku vraćala s pola historije. Uklanjanje sada ide do kraja u istom prolazu.

        0.73.1

        21. septembar 2026.

        Novo

        • Biblioteka fotografija za meni. Kod svakog jela, pića i kategorije u konzoli stoji "Izaberi sliku": 118 fotografija onoga što se ovdje stvarno prodaje (burgeri i sendviči, pizze, roštilj, pite, salate i jela, deserti, kafa i čaj, bezalkoholna pića, pivo, vino i žestoka), izrezanih na providnoj pozadini, pa izgledaju isto na svakom telefonu. Dovoljno je upisati naziv jela: za "Pizza Quattro formaggi" birač se otvori na pizzama sa tom pizzom na prvom mjestu, za "kafa" na kafama. Pretraga po imenu na oba jezika, grupe sa naslovnom slikom, i pored toga "Dodaj svoju" za lokal koji ima svoje fotografije. Nacrtane sličice koje je demo lokal imao do sada su zamijenjene ovim fotografijama, i kod novih lokala i kod postojećih demo menija.
        • Kategorija ima svoju sliku. Kartica kategorije na telefonu gosta nosi sliku koju vlasnik izabere; bez izbora i dalje uzima prvo jelo sa slikom. Fotografija iz biblioteke stoji na tamnom tanjiru u boji jela, cijela, a vlastita fotografija i dalje ispunjava okvir.

        Ispravljeno

        • Novo jelo bez nabavne cijene nije moglo da se sačuva iz konzole: obrazac šalje praznu nabavnu cijenu kao "ništa", a server je to odbijao kao neispravan iznos. Sada prima i ništa i iznos.

        Za one koji razvijaju

        • GET /v1/menu/library vraća grupe i slike sa adresama; fajlovi se služe sa /media/library/<id>.webp iz apps/api/assets/menu-art, manifest je apps/api/src/modules/menu/menu-library.ts. MenuCategory.imageUrl (migracija 20261007000000_category_images), PATCH /v1/menu/categories/:id ga prima, meni za gosta ga vraća. Slikar dish-art.ts je uklonjen; sajt uzima svoje četiri sličice iz iste biblioteke (scripts/site-dishes.mjs). Smoke narudžbi provjerava biblioteku, sliku kategorije i jelo bez nabavne cijene.

        0.73.0

        21. septembar 2026.

        Novo

        • Pregled banke kaže šta traži čovjeka. Na vrhu ekrana su živi brojevi nad firmama koje dijele s bankom: otvoreni slučajevi sravnjivanja, nesparene uplate, propale isporuke webhooka u zadnja 24 sata, plaćanja istekla danas i ona koja još čekaju uplatu; svaki broj vodi tamo gdje se rješava. Ako projekcija nije prošla više od pet minuta, ekran to kaže umjesto da stare brojke prikazuje kao svježe.
        • Osam grafikona, iz projekcije i iz izvora. Naplaćeno i broj uplata po danu, udio po vrsti posla i po načinu plaćanja, usvajanje (firme predložene, aktivne i s uvidom, po danu), segmenti po vrsti posla, kvalitet sravnjivanja (slučajevi po razlogu i koliko je uplata sparila mašina bez čovjeka) i izuzeci po danu, s brzinom potvrde ispod njih. Nacrtani u aplikaciji, u boji banke, bez biblioteke.
        • Pregled prati sobu banke uživo. Kad firma koja dijeli s bankom izda ili naplati račun, ekran sam povuče nove brojke koji trenutak kasnije; u zaglavlju piše da li je veza uživo.

        0.72.2

        21. septembar 2026.

        Novo

        • Demo banka jednom naredbom na serveru. Instalacija bez ijedne banke dobija demo partnera sa servera: seed-demo-bank.js uzme bankovne kodove iz računa firmi koje mu se navedu, napravi banku, sistemski ključ, četvero ljudi (uprava, administrator, operativa, analitičar) s lozinkama koje se ispišu jednom, i predloži linkove tačno kako ih API predlaže pri startu. Prekidač dijeljenja ostaje firmin: dok ga firma ne uključi u svojoj konzoli, banka o njoj ne vidi ništa. Ponovljena naredba ništa ne briše i ne mijenja lozinke. Opisano u uputstvu za postavljanje.

        0.72.1

        21. septembar 2026.

        Popravke

        • Provjera spremnosti lokala čeka svoj red umjesto da padne. Prijava u konzolu dozvoljava dvadeset pokušaja u minuti s jedne adrese. Na CI serveru svi smoke paketi idu s jedne adrese i, s provjerom uvida za drugu firmu koju je donijela Faza 2, u istoj minuti naprave tačno dvadeset prijava; provjera spremnosti lokala koja ide poslije njih bila je dvadeset prva i padala je na odbijenoj prijavi, iako s lokalom nije bilo ništa. Skripta sada sačeka da prozor prođe i tek onda kaže šta je s lokalom; ograničenje prijave ostaje kakvo jeste.
        • Gornja granica zahtjeva po adresi može se podesiti. Ograničavač zahtjeva ima zaštitni plafon od 900 zahtjeva u minuti s jedne adrese, preko svih ruta, koji nijedan lokal iza jedne NAT adrese ne dosegne. Plafon se sada zadaje kroz THROTTLE_CEILING_PER_MINUTE; u produkciji ostaje 900, a test server koji sve pakete tjera kroz jednu adresu dobija više.

        0.72.0

        21. septembar 2026.

        Novo

        • Svako plaćanje nosi snimak onoga za šta je izdato. Pri izdavanju (narudžba za stolom, faktura, serija računa, naplata iz konzole, naljepnica, vanjska evidencija, API) XPay u istoj transakciji zapiše vrstu posla, sažetak, dokument, period, iznose i stavke, s otiskom koji se pri svakom čitanju ponovo izračuna. Snimak se ne mijenja kad se kasnije promijeni narudžba ili faktura: kaže šta je važilo u trenutku izdavanja. Postojeća plaćanja su dobila snimak pri prvom pokretanju. Firma svoj snimak čita na GET /v1/payments/:id/context.
        • Banka vidi onoliko koliko joj uloga dozvoljava, i razlog ostaje zapisan. Tri nivoa: samo činjenice o plaćanju, sažetak, ili sve stavke. Stavke se nikad ne daju bez razloga; razlog za podršku ili reklamaciju traži broj slučaja; za osjetljive djelatnosti (usluge, freelanceri) stavke vide samo revizija i usklađenost. Svako otvaranje iznad uobičajenog nivoa piše se u revizijski trag banke s razlogom i brojem slučaja, i ekran to kaže onome ko je otvorio.
        • Brojke za banku iz posebnih tabela, ne iz operativnih. Projekcija svake minute prepiše promijenjena plaćanja firmi koje su dozvolile uvid u pogled za banku i sabere dane koje su dotakla, po Sarajevu; firma koja povuče uvid nestane iz pogleda pri sljedećem prolazu, a pogled se može izgraditi ispočetka jednom naredbom. Pregled u aplikaciji banke sada radi iz te projekcije: period od 7, 30 ili 90 dana, poređenje s prethodnim, udio po načinu plaćanja i po vrsti posla, brzina potvrde, i vrijeme kad je projekcija zadnji put osvježena.
        • Ekran Plaćanja u aplikaciji banke. Lista s filterima po stanju i vrsti posla, pretraga po pozivu na broj ili firmi, učitavanje dalje; detalj s činjenicama, kontekstom na dozvoljenom nivou, vremenskom linijom, uplatama na račun, slučajevima sravnjivanja i povratima. Uloge koje smiju navesti razlog imaju polje za razlog i broj slučaja.

        0.71.2

        21. septembar 2026.

        Popravke

        • Konektor primijeti da je veza mrtva. Živi tok događaja iz oblaka nije imao rok: kad ruter u lokalu nestane bez zatvaranja veze, čitanje čeka koliko operativni sistem dozvoli, a to su minute do sati. Cijelo to vrijeme konektor je vjerovao da je spojen, kasa nije čula ni za jednu uplatu, i nije se pokrenulo ni sustizanje koje postoji baš za taj prekid. Server šalje otkucaj svakih 25 sekundi; tok koji šuti 75 sekundi sada se proglašava mrtvim, veza se prekine i petlja ponovnog spajanja radi svoje, s testom koji to dokazuje. Ni jedan poziv konektora prema oblaku više ne čeka bez roka.
        • Mjesec od 31. januara je 28. februar, ne 3. mart. Pretplata započeta 31. u mjesecu dobijala je rok do 3. u mjesecu iza sljedećeg, jer JavaScript nepostojeći dan prebacuje naprijed, i svako sljedeće produženje je ostajalo na 3. Rok sada pada na isti dan u mjesecu, ili na zadnji dan koji mjesec ima; 29. februar plus godina je 28. februar.
        • Predračun koji ne može postati račun ne ostavlja nacrt. Nacrt računa se pravio prije izdavanja, pa je odbijeno izdavanje (poslovnica bez računa u međuvremenu, i slično) ostavljalo račun koji niko nije tražio u listi nacrta, a svaki novi pokušaj još jedan. Nacrt se sada povuče prije nego odbijanje stigne do onoga ko je kliknuo.
        • Iznosi na izvodu kupca prolaze kroz isti parser kao svugdje. Množenje decimalnog iznosa sa sto u pokretnom zarezu (4,35 puta 100 je 434,99999999999994) zamijenjeno je parserom koji API koristi za svaki iznos; ispis je bio tačan zbog zaokruživanja, način nije bio.
        • Oznaka uvezene serije računa nosi datum kakav je u lokalu, ne datum kontejnera: pola sata poslije ponoći u Sarajevu server je još pisao jučerašnji.

        0.71.1

        21. septembar 2026.

        Novo

        • Promjena traži drugu osobu. Administrator banke predlaže promjenu uloge ili isključenje člana osoblja; drugi administrator je odobri, i ona se primijeni u istoj transakciji u kojoj je odluka zapisana, ili je odbije s razlogom; predlagač je može povući dok čeka. Ko je predložio, ne može odobriti, kolike god uloge imao. Promjena koja bi banku ostavila bez ikoga ko može odobriti sljedeću se odbija; iz banke s jednim administratorom izlaz je operater platforme. Osoba čija se uloga promijenila je odjavljena i vraća se u novoj ulozi. Svaki korak je na revizijskom lancu banke, s onim prije i poslije.
        • Ekran Pristup u aplikaciji banke. Red promjena koje čekaju s dugmadima koje predlagač nema i rečenicom zašto, ljudi banke s ulogom i stanjem telefona, prijedlog nove uloge, i historija odlučenog. Revizija i usklađenost isti ekran čitaju i ništa ne mogu pritisnuti.
        • Vrste promjena koje dolaze kasnije se odbijaju, ne stavljaju u red. Integracije, tajne, privatnost, funkcije i endpointi postoje u shemi i odgovaraju fazom koja ih donosi, umjesto da čekaju odobrenje koje ništa ne bi primijenilo.

        0.71.0

        21. septembar 2026.

        Novo

        • Aplikacija za banku. Zasebna aplikacija, apps/bank, na vlastitom hostu, koja razgovara samo s bankarskim rutama; ništa iz konzole firme nije u njoj i ništa u njoj se ne otvara sesijom konzole. Prijava u tri koraka: lozinka, pa upis aplikacije za kodove s QR-om i ključem pri prvoj prijavi ili kod s telefona pri svakoj sljedećoj, pa kodovi za oporavak prikazani jednom, s dugmetom koje ne ide dalje dok osoba ne kaže da ih je sačuvala.
        • Svaka uloga vidi svoje. Navigacija pokazuje odjeljke koji toj ulozi trebaju i vodi je na njen prvi: direktor na pregled, operativa na plaćanja, podrška na firme, integracije na zdravlje sistema, revizija na reviziju. Vlasnik i administrator vide sve. Odjeljci koje tek kasnije faze pune stoje u navigaciji i kažu, otvoreni, da nisu još u ovoj instalaciji i u kojoj fazi dolaze: proizvod se vidi kakav će biti, a ono što je danas piše kao danas.
        • Pregled i firme, iz stvarnih brojeva. Pregled pokazuje naplaćeno QR-om, koliko je toga potvrdila banka svojim izvodom, koliko firmi ima uvid i koliko ga nema, po danu i po načinu plaćanja, iz ista dva čitanja koja sistemski ključ ima od 0.68.0. Firme su tabela onih koje su dozvolile uvid, s mjesecom naplate; o onima koje nisu, samo broj.
        • Izgled po hostu. Jedna slika aplikacije služi više banaka: prije prvog iscrtavanja aplikacija pita API čija je banka host na kojem je stigla i postavi njene boje i ime; host koji niko nije registrovao dobija XPay izgled. Boje statusa nisu dio toga: plaćeno je zeleno kod svake banke. Svijetla i tamna tema, bosanski i engleski.
        • Instalacija. Slika za Docker, servis u compose fajlu i blok u instalacionoj skripti: aplikacija banke se služi na banka.<domena> (ili --bank-domain) čim taj zapis pokazuje na server, sa certifikatom; dok ne pokazuje, skripta to kaže i ništa drugo se ne mijenja.

        0.70.3

        21. septembar 2026.

        Sigurnost

        • Ime se razrješava prije nego se pozove. Čuvar webhook adresa čitao je samo ime iz adrese i odbijao privatne opsege koje u njemu vidi; ime koje se razrješava u privatnu adresu prolazilo je. Sada se ime razriješi pri registraciji i ponovo prije svake isporuke, a privatan odgovor odbija adresu ili trajno napušta isporuku. Ime koje se ne razrješava pri registraciji prolazi, jer je to greška u kucanju ili host koji još nije podignut, i prva isporuka će to reći.
        • Suspendovana firma je suspendovana i na živom kanalu. Prijava korisnika suspendovane firme na živi kanal se odbija, kao što je HTTP odbija od 0.55.6.
        • CI provjerava ono što se isporučuje. Poseban posao pored testova: poznate ranjivosti u zavisnostima koje idu u sliku ruše provjeru (visoke i kritične), pune provjere se izvještavaju, historija se pretražuje za tajnama, stablo se skenira, i za svaki prolaz se pravi popis komponenti (CycloneDX) koji se čuva 90 dana; to je ono što nabavka banke traži. CodeQL ne, jer traži Advanced Security na privatnom repozitoriju; piše u modelu prijetnji.
        • Tri prelazne ranjivosti zatvorene, u parseru upita ispod express-a, u multipart parseru ispod adaptera i u pomoćniku za spajanje ispod prisma konfiguracije, verzijama na istoj liniji; nodemailer podignut na 9.1.1. Ono što se isporučuje sada nema poznatih ranjivosti; ostaju dvije umjerene u alatu za testove, koji se ne isporučuje.

        0.70.2

        21. septembar 2026.

        Novo

        • Banka čuje kad novac sjedne, i ništa drugo. Prijava banke na živi kanal ulazi samo u sobu svoje banke, ni u jednu sobu ijedne firme, i ne može pratiti račun po broju. U tu sobu stiže bankarski pogled na novčane događaje firmi koje su s njom povezane i pristale: ishod, iznosi i vrijeme. Ne stiže poziv na broj, broj narudžbe, sto, gost ni bilo šta s kase; ne stižu narudžbe, stolovi ni pozivi osoblja. Događaj firme nikad ne završi u sobi banke ni po imenu sobe.
        • Provjera izolacije je ulaz za svaku sljedeću promjenu. Pravila nad kodom: nijedna bankarska ruta ne čita banku iz parametra, upita ni tijela; svaka je označena za banku ili javna; svako čitanje banke uzima banku s prijavljenog identiteta. I živi test s dvije banke na jednoj instalaciji, postavljen s obje strane: šta svaka vidi, šta svaka čuje, šta nijedna ne može. Ništa bankarsko se ne spaja dok to ne prođe.

        0.70.1

        21. septembar 2026.

        Novo

        • Osoblje banke se prijavljuje lozinkom i kodom s telefona, uvijek. Kolone za dvostruku prijavu postojale su od prve verzije baze i ništa ih nije čitalo. Sada se čitaju: prva prijava upisuje aplikaciju za kodove i daje deset kodova za oporavak, jednom; svaka sljedeća traži kod s telefona ili jedan od tih kodova, koji radi jednom. Između lozinke i koda osoba drži privremeni token koji otvara samo sljedeći korak, deset minuta. Pogrešan kod broji se kao pogrešna lozinka, prema istom zaključavanju, i dobija isti odgovor.
        • Sesija banke otvara banku i ništa drugo. Token aplikacije banke ne otvara ni konzolu firme ni operaterske rute, a token konzole ne otvara bankarske. Ista osoba može biti i u firmi i u banci: to su dvije prijave u dvije aplikacije, nikad jedan token. Osvježavanje sesije ostaje u aplikaciji koja ju je napravila i u banci za koju je napravljena.
        • Dvanaest uloga u banci, od vlasnika i administratora do operative, platnog prometa, podrške, analitike, revizije, usklađenosti, integracija, menadžera odnosa i direktora. Svaka bankarska ruta imenuje uloge kojima je namijenjena; vlasnik i administrator prolaze sve. Sistemski ključ banke prolazi samo gdje je imenovan.
        • Operater vodi ljude banke i ugovor. Na stranici Banke svaka banka se otvara: ko je u njoj i u kojoj ulozi, je li upisao telefon, dodavanje osobe (postojeći nalog se koristi, novi dobija lozinku prikazanu jednom), isključenje, zaborav telefona kad se izgubi, suspenzija banke koja odmah gasi sve njene prijave. Ugovor su moduli, datumi i nivo podrške; polja za cijenu i broj transakcija nema, namjerno.
        • Probne banke imaju osoblje u seed podacima i vlastiti smoke test, scripts/smoke-bank.mjs, koji u CI prolazi cijelu prijavu i provjerava da dvije banke na jednoj instalaciji ne vide jedna drugu.

        Popravke

        • Nalog bez mjesta u konzoli, kakav je osoblje banke, više se ne može prijaviti u konzolu; odgovor je isti kao za pogrešnu lozinku, pa se preko konzole ne može saznati ko radi u banci.

        0.70.0

        21. septembar 2026.

        Novo

        • Banka je od sada vlastiti prostor, a veza s firmom je zapis, ne šifra. Do sada je banka partner bila ključ i spisak šifri banke, a vidjela je koju god firmu ima tu šifru u broju računa; dvije banke s istom šifrom vidjele bi isto. Od sada šifra iz računa samo predlaže vezu banka-firma, a veza je ono što se čita: napravi se kad operater doda banku, kad joj promijeni šifre i kad firma unese broj računa, i nikad se ne briše. Prekidač Uvid za banku ostaje jedan, ali svaka veza pamti svoj pristanak i svoj datum. Postojeće banke dobile su veze pri prvom podizanju, a firma koja je već pristala pristala je i na njima, s datumom kad je prekidač okrenut.
        • Ono što banka smije čitati čita se samo kroz njen identitet. Banka se uzima s prijavljenog ključa i ni sa čega drugog; nema parametra kojim bi jedna banka imenovala drugu. Banka bez veza vidi praznu platformu, ne tuđu.
        • Temelj za osoblje banke i njenu aplikaciju. Tabele za članove banke i njihove uloge, integracije i njihove tajne, izgled, hostove, ono što ugovor daje (bez brojanja transakcija i bez cijena) i red promjena koje traže drugu osobu. Samo tabele: ništa ih još ne čita ni ne piše, i tabela stanja u docs/en/bank-platform/STATUS.md kaže tačno to.
        • Revizijski trag ima lanac po banci. Zapisi banke idu na njen lanac, odvojen od lanaca firmi i lanca platforme; nova verzija sažetka obavezuje se i na to čiji je lanac, pa se zapis ne može premjestiti.
        • Dvije probne banke u seed podacima, "Demo banka" i "Probna banka", namjerno ničije, da demonstracija ima jednu koju pokazuje i drugu kojom dokazuje da se ne vide.

        0.69.7

        21. septembar 2026.

        Dokumentacija

        • Bankarska platforma: plan i arhitektura. Prije nego se napiše ijedna linija koda za banke, pregledan je stvarni sistem i zapisano šta postoji, šta se proširuje, šta se gradi i šta čeka. Osam dokumenata u docs/en/bank-platform/: stanje sistema, analiza praznina, arhitektura (zasebna aplikacija za banku, banka kao vlastiti prostor od prvog dana, nepromjenjivi snimak sadržaja svakog plaćanja, jedan adapter po načinu spajanja), model prijetnji, klasifikacija podataka s pravilom ko od osoblja banke šta smije vidjeti, plan po fazama s 33 numerisana koraka, tabela stanja svake sposobnosti i izvještaj s 20 tačaka za pregled.
        • Šta je u izvještaju rečeno naglas. Dvije vrste izvora sravnjivanja (upit banci, potvrda šeme) postoje samo kao naziv u bazi, ne kao kod. Ključ banke iz 0.68.0 gleda po šifri banke iz IBAN-a, pa bi dvije banke s istom šifrom vidjele isto; veza banka-firma postaje granica. Dvostruka prijava ima kolone u bazi, ali je kod ne čita. Ni jedno od toga se ne smatra riješenim dok tabela stanja ne kaže drugačije.
        • Šta se ne mijenja. XPay i dalje ne drži i ne prenosi novac; postojeći proizvod za firme ostaje kakav jeste; javni sajt ne dobija ni riječ o bankama dok tabela stanja ne kaže šta je istina. Faza 1 ne počinje bez pregleda ovog izvještaja.

        0.69.6

        21. septembar 2026.

        Popravke

        • Pitanje koje nije postavljeno nije odgovor "u redu". Provjera reverznog DNS-a tražila je ime servera u podešavanju koje API kontejner nema, pa nije ni pitala, a to je izvještavala kao "reverzni DNS je u redu". Sada uzima prvo ime koje postoji (adresa API-ja), a bez ijednog kaže da ne zna i stranica ne tvrdi ništa o razlogu.

        0.69.5

        21. septembar 2026.

        Popravke

        • Reverzni DNS se pita javno, ne lokalno. Provjera iz 0.69.4 pitala je resolver samog servera, a on adresu servera zna iz privatnog pogleda hostinga, pa je stranica rekla da je reverzni DNS u redu i okrivila listu blokiranih. Pitanje je da li svijet može pronaći adresu, pa se sada pitaju javni resolveri (8.8.8.8, 1.1.1.1), i to PTR upitom koji zadržava pravi odgovor: zona koja ne odgovara (SERVFAIL) i zona koja kaže da zapisa nema više se ne miješaju.

        0.69.4

        21. septembar 2026.

        Popravke

        • Pošta: čekanje se plaća jednom, ne po pismu. Server pošte pušta ovaj server da čeka petnaestak sekundi prije pozdrava, i to čekanje se plaćalo na svakoj vezi, a svako pismo je otvaralo novu: serija od 25 računa čekala je šest minuta. Veza se sada drži otvorenom između pisama, pa se čeka jednom, a ostala idu odmah. Brzo pismo na već otvorenoj vezi ne briše upozorenje o sporom pozdravu; ono se skida tek kad nova veza dobije pozdrav na vrijeme.
        • Status stranica kaže koji od dva razloga. Spor pozdrav dolazi od reverznog DNS-a za adresu servera, a to su dva različita kvara i dva različita zahtjeva hostingu: zona koja uopšte ne odgovara (server pošte čeka istek vremena; popravlja se delegacija zone) ili zona koja odgovara da zapisa nema (traži se PTR zapis). Stranica je za oboje govorila "nema PTR zapisa", pa je od hostinga traženo pogrešno. API sada sam pita reverzni DNS za svoju adresu (u pozadini, jednom u pola sata) i stranica kaže koje je od to dvoje, ili da je reverzni DNS u redu pa je adresa vjerovatno na listi blokiranih.

        0.69.3

        21. septembar 2026.

        Popravke

        • Izvor koji čeka prvu uplatu nije izvor koji šuti. Poslije 0.69.1 status stranica je i dalje bila žuta: webhook banke povezan 18. 9., prije ikakvog dogovora s bankom, kroz koji nikad ništa nije stiglo, brojao se kao izvor koji je "utihnuo". Utihnuti sada može samo izvor koji je već donosio uplate pa stao na dan; izvor kroz koji još ništa nije stiglo je "povezan i čeka prvu uplatu", u zelenom, jer to čeka na banku, a stranica koja je mjesec dana žuta je stranica koju niko ne čita kad zatreba.

        0.69.2

        21. septembar 2026.

        Popravke

        • Kopija koja napušta server je zaključana. Noćna kopija je slala izvoz baze i slike na drugi server u čitljivom obliku, a samo tajne šifrovane. Izvoz baze su imena kupaca i svi računi, i mjesto s dovoljno prostora rijetko je i mjesto s najboljom bravom. Kad je lozinka za kopije postavljena, sve što odlazi se šifruje istom lozinkom (.sql.gz.enc, .tar.gz.enc), pa je kopija bez nje bezvrijedna; lokalne kopije ostaju kakve jesu, jer ih restore.sh čita. Uputstvo za vraćanje s druge mašine je u docs/en/06-deployment.md.

        0.69.1

        20. septembar 2026.

        Popravke

        • Status stranica je javljala "sravnjivanje otežano" bez razloga. Pravilo "izvor koji dan nije donio uplatu je utihnuo" brojalo je i ručne potvrde: svaka firma kod koje menadžer nije jučer pritisnuo "Plaćeno" bila je "izvor koji šuti", pa je stranica pisala "1 od 2 izvora šuti" u žutom, na sistemu koji još nema nijedan automatski izvor iz banke. Utihnuti sada može samo ono što samo donosi uplate (webhook banke, provjera banke, IPS potvrda, obavijest mailom); ručna potvrda i izvod iz fajla ne mogu. Bez automatskog izvora stranica kaže tačno to, u zelenom. Greška na bilo kojem izvoru se i dalje javlja.

        0.69.0

        20. septembar 2026.

        Novo

        • Račun na engleskom. Freelancer koji radi za klijenta u inostranstvu slao je račun koji klijent ne može pročitati. Nova faktura sada ima izbor jezika, Bosanski / Engleski: na engleskom su riječi na PDF-u (INVOICE, Bill to, Due date, Payment details, Scan to pay), datumi (5 Oct 2026), format brojeva (1,250.00 KM), sitna slova, pečati (PAID, OVERDUE), naziv fajla (Invoice-41-2026.pdf), mail koji nosi račun i stranica koju kupac otvara, na kojoj su i dugmad na engleskom. Brojevi, poziv na broj i kod su isti; mijenja se samo jezik. Predračun i storno takođe.
        • Kupac pamti jezik. Kupac napravljen iz engleskog računa ostaje na engleskom, pa idući račun za njega počinje na engleskom bez biranja; u Kupcima se jezik vidi i mijenja. Opomena za dospjele račune ide na jeziku kupca.
        • API: language: "bs" | "en" na POST /v1/invoices (podrazumijevano jezik kupca, inače bs), language u odgovoru i na stranici kupca, language na kupcu (POST/PATCH /v1/customers).

        0.68.0

        20. septembar 2026.

        Novo

        • Banka partner ima svoj ključ. Priprema za banku obećava banci ono što niko drugi nema: ko od njenih klijenata koristi XPay i koliko naplati. Operater sada u admin konzoli (Banke) dodaje banku po nazivu i šifri banke (tri cifre s početka domaćeg broja računa, 129 za UniCredit) i dobija ključ xpb_live_..., prikazan jednom; novi ključ jednim klikom, isključenje jednim prekidačem. Ko banka kod koje čita se iz IBAN-a poslovnice, niko ne vodi spisak.
        • Šta banka vidi. GET /v1/bank/merchants: firme koje bankaju kod nje i dozvolile uvid, s mjesecom QR naplate; koliko ih nije dozvolilo, samo kao broj. GET /v1/bank/volume: naplata po danu, QR s načinom potvrde (banka, ručno, simulator), kartica i gotovina radi udjela, najviše 92 dana po pozivu. GET /v1/bank/references/:poziv: šta je poziv na broj i da li je još otvoren, za trenutak kad klijent skenira kod u aplikaciji banke, pa aplikacija zna kome plaća i odbija već plaćen kod. Ključ banke ne otvara ništa trgovačko, a ključ trgovca ništa bankarsko.
        • Uvid daje firma, ne mi. Postavke imaju prekidač Uvid za banku, isključen dok ga vlasnik ne uključi; trenutak uključenja se čuva jer to traži ugovor o obradi podataka. Šta banka vidi piše na prekidaču: naziv, JIB, grad, djelatnost i broj i iznos uplata po danu; nikad pojedinačne račune, goste ni stavke.
        • Dokumentacija za IT banke: docs/en/08-bank-partner-api.md.

        Popravke

        • Primjer računa u Postavkama (izgled računa) je odbijao firmu s dvije poslovnice različite vrste, jer je tražio poslovnicu za dokument koji ništa ne izdaje. Više ne traži.

        0.67.0

        20. septembar 2026.

        Novo

        • Predračun. Freelancer, servis i radnja po narudžbi traže uplatu prije posla, a XPay je znao samo za račun. Nova faktura sada gore ima izbor Račun / Predračun. Predračun je isti dokument s vlastitom serijom (P-1/2026), vlastitim pozivom na broj i QR kodom, jer se ovdje predračun plaća; šalje se i naplaćuje kao i račun, i na PDF-u i na stranici kupca piše šta je. Nije potraživanje: ne ulazi u pregled, izvod kupca, opomene ni stanje, dok ne postane račun.
        • Pretvori u račun. Jedno dugme na izdatom predračunu: račun dobija broj iz serije računa, a uplata prelazi na njega. Plaćen predračun daje odmah plaćen račun s napomenom "Plaćeno po predračunu P-1/2026"; neplaćen daje račun na istom pozivu na broj, pa kupac plaća kako mu je već rečeno. Predračun ostaje označen kao pretvoren, s pečatom broja računa na PDF-u, a njegova stranica kaže koji je račun postao. Roba sa police silazi tek kad nastane račun, ne na predračunu.
        • Serija računa broji bez predračuna. Brojevi računa ostaju bez rupa gdje su bile ponude; mjesto u seriji se sada čuva uz broj, pa serija s prefiksom ostaje prebrojiva.
        • Pomoć ima vodič "Predračun pa račun".
        • Forma imenuje poslovnicu. Firma s restoranom i radnjom nije mogla iz konzole napraviti nacrt (server je odbijao pogoditi koja poslovnica izdaje), a greška se vidjela tek iza dijaloga. Forma sada šalje poslovnicu i pokazuje odbijanje u dijalogu.
        • API: kind: PROFORMA na POST /v1/invoices, POST /v1/invoices/:id/convert, stanje CONVERTED u listi i filteru, kind, proforma i convertedTo u odgovoru; stranica kupca nosi kind i convertedToNumber.

        0.66.0

        20. septembar 2026.

        Novo

        • Mjesec računa iz fajla. Komunalno preduzeće, kućni savjet ili stanodavac s tabelom imali su formu za jedan račun i API za programere, a njihov mjesec je hiljadu istih računa iz sistema koji ih je obračunao. Fakture sada imaju Uvoz iz fajla: CSV s jednim redom po računu (šifra korisnika, naziv, period, rok, iznos) ili više redova za isti račun (opis, količina, cijena, PDV stopa). Kolone se prepoznaju po nazivu na oba jezika i bez kvačica, razdvojnik i decimalni zarez kako ih Excel ovdje piše, datumi kao 15.10.2026. Fajl se prvo pročita i pokaže: koliko računa, koliki iznos, koliko novih kupaca, i tačno koji red i koja kolona ne valja. Ništa se ne upisuje do dugmeta Uvezi, a s greškom se ne uvozi ništa, da pola mjeseca ne uđe. Primjer fajla je u dijalogu.
        • Serija se izdaje i šalje kao jedna. Uvezeni računi su serija s dugmadima Izdaj sve i Pošalji sve: brojevi idu po redu iz fajla, brojač pokazuje dokle je stiglo, a što zapne se imenuje s razlogom i ostaje za idući pritisak, koji nastavlja gdje je stalo. Računi bez e-maila se preskaču i broje, ne padaju. Serija broji šta je nacrt, izdato, poslano, plaćeno, dospjelo. Račun pamti kad je zadnji put poslan.
        • Kupac po broju korisnika. Račun koji nosi šifru kupca (kod komunalnog broj korisnika) nalazi kupca po njoj prije JIB-a i imena, pa pogrešno napisano ime idući mjesec ne pravi drugog kupca; kupac napravljen iz računa je zadrži. Isti period za istog kupca drugi put se odbija, pa se fajl ne može uvesti dvaput. Račun odbijen iz bilo kojeg razloga više ne ostavlja kupca za sobom.
        • Broj korisnika na računu. PDF računa štampa referencu s riječju koju ta djelatnost koristi: Broj korisnika, Nekretnina, Broj narudžbe, Otpremnica, Termin. Do sada je referenca bila samo u sistemu.
        • Pomoć ima vodič "Mjesec računa iz fajla" za djelatnosti koje obračunavaju po periodima.
        • API: POST /v1/invoice-batches/import (csv, preview), GET /v1/invoice-batches, POST /v1/invoice-batches/:id/issue i /send (po sto odnosno dvadeset pet po pozivu, remaining kaže koliko je ostalo), GET /v1/invoices?batchId=, customerRef na računu, sentAt i batchId u odgovoru. Najviše 5.000 računa po fajlu.

        0.65.0

        20. septembar 2026.

        Novo

        • Račun za robu sa police. Veleprodaja je vodila zalihe i pisala račune, ali jedno nije znalo za drugo: račun je bio samo riječi i cijene, a stanje je trebalo skidati rukom, po sjećanju. Stavka računa sada može da imenuje artikal sa police: u opis se kuca naziv ili šifra, izabere se s liste, i stavka nosi njegov naziv i cijenu s kase (cijena se može prepisati, npr. za akciju; artikal bez cijene traži cijenu na stavci). Izdavanje računa skida količine sa stanja, jednom po stavci, s kretanjem koje nosi broj računa, pa se ni ponovljeno izdavanje ni ponovljena obrada ne skida dvaput. Nacrt ne dira stanje. Ponovi (za idući mjesec) nosi artikle dalje.
        • Otpremnica. Uz robu ide papir bez cijena, jer vozač i skladištar koji primaju robu nisu ti koji su cijenu ugovorili. Dugme Otpremnica (PDF) na računu koji ima stavke s police: šta i koliko, šifra i jedinica, tri mjesta za potpis (izdao, vozač, primio) i napomena da cijene stoje na računu. Štampa se i za nacrt, jer roba često krene prije broja računa, i tada na njoj piše da je nacrt.
        • Storno ne vraća robu. Namjerno: storniran račun ne zna da li se roba vratila. Ako jeste, povrat se upisuje u Zalihama, s razlogom, kao i svaki drugi.
        • Pomoć ima vodič "Roba koja ide sa police", samo za djelatnosti koje vode zalihe.
        • API: stavka fakture prima stockItemId (opis i cijena tada nisu obavezni), vraća ga u lines[], a GET /v1/invoices/:id/delivery-note.pdf daje otpremnicu. Artikal koji nije na polici te poslovnice se odbija (stock_item_unknown), artikal bez cijene bez cijene na stavci takođe (stock_item_unpriced).

        0.64.0

        20. septembar 2026.

        Novo

        • Kasa prodaje s police. Prodavnica je imala zalihe s brojem komada i bez cijene, a kasa na ekranu je prodavala samo jela s menija koji prodavnica nema, pa je jedini način bio slobodan iznos za koji stanje nikad nije čulo. Artikal u Zalihama sada ima cijenu na kasi i barkod; kasa u prodavnici otvara policu: artikli s cijenom i stanjem, polje za skener (barkod ili šifra pa Enter, ili dio naziva), i kad se prodaja zatvori, prodano silazi sa stanja, jednom, s vezom na red prodaje, pa uplata viđena dvaput ne skida dvaput. Artikal bez cijene se vodi, ali se ne nudi.
        • Gotovina i kartica na kasi. Kasa na ekranu je do sada znala samo za kod: prodaja za keš ili karticu nije postojala ni u prometu ni na stanju. Svaka prodaja na kasi je sada račun kao i svaki drugi, na vlastitom računu uređaja: gotovina i kartica ga zatvore odmah (ekran kaže PRODANO), kod ga ostavi da čeka i zatvori se sam kad uplata legne. Promet po načinu plaćanja, osoba prijavljena PIN-om, povrat, sve što izvještaji već znaju o računu važi i za kasu bez ijednog novog izvještaja. Kasa se ne može pozvati iz kancelarije: prodaja se kuca na uparenom uređaju.
        • Šanker ima izbore. Kasa na šanku je svako jelo prodavala u osnovnoj verziji jer nije imala kako pitati. Jelo s izborom sada pita isto kao na konobarovom telefonu: kafa s mlijekom, ćevapi po veličini, s cijenom koju izbor nosi.
        • API: POST /v1/counter/sales (linije s menija ili s police, način plaćanja, isti clientRef vraća istu prodaju), GET /v1/stock/sellable za uređaje, price i barcode na artiklu zaliha. Kod koji se ne može izdati ne ostavlja polovičnu prodaju; linija koja se odbije takođe.

        0.63.0

        20. septembar 2026.

        Novo

        • Webshop: stranica za plaćanje koju XPay drži. Prodavnica na internetu je imala API i webhook i ništa što bi stavila pred kupca: sama je morala crtati kod, ispisivati račun i pitati da li je stiglo. Sada račun napravljen preko API-ja ili iz konzole nosi link na stranicu (checkoutUrl): kod za bankovnu aplikaciju, broj računa i poziv na broj za one koji ne skeniraju, koliko kod još važi, i stanje koje se samo mijenja u PLAĆENO (ili „stiglo više", „stiglo manje", „kod istekao") kad banka javi. Uz returnUrl (samo https) stranica vrati kupca u prodavnicu s ishodom u upitu. Link je jedina ključ do stranice, kao kod fakture: bez prijave, bez ijednog podatka osim tog jednog računa. Račun podignut na tabletu ili kasi nema stranicu; uređaj je stranica.
        • Dodatak za WooCommerce. integrations/woocommerce: kupac na kasi bira XPay, prodavnica napravi račun, preusmjeri ga na stranicu, primi webhook s provjerom potpisa i označi narudžbu plaćenom; stiglo manje ide na čekanje uz bilješku koliko fali; kad se kupac vrati, stranica narudžbe i sama provjeri stanje, pa spor webhook ne ostavlja plaćenu narudžbu kao neplaćenu. Podešavanje je pet polja. Napisan po WooCommerce API-ju i provjeren harnessom bez WordPressa (14 provjera potpisa i ishoda); prva proba na živoj prodavnici je proba od 1 KM.
        • Uputstvo za webshop u tri poziva, docs/bs/07-webshop.md, i vodič pod Pomoć. Integracije na sajtu dobile četvrti način: webshop.

        Popravljeno

        • Loš iznos ili loša adresa vraćali su „Internal server error". Sheme koje dijele API i konzola žive u ES modulu i njihove greške validacije filter API-ja nije prepoznavao, pa je amount: "abc" ili returnUrl na http bio 500 umjesto 400 s imenom polja. Oba su sada 400 i kažu šta ne valja.

        0.62.0

        20. septembar 2026.

        Novo

        • Operater mijenja svoju lozinku na ekranu. Operater ne pripada nijednoj firmi, pa je Postavke, gdje lokal mijenja lozinku, ekran do kojeg operater ne može doći: konzola prvo pita koju firmu gleda. Jedini nalog koji je najviše bitan mogao je promijeniti lozinku samo komandom na serveru. Sada pod Administracija, Moj nalog: traži se trenutna lozinka, najmanje 12 znakova za operatera, i nakon promjene sve prijave se odjavljuju, i ta. Isti obrazac kao u konzoli lokala, jedan kod za oba.

        0.61.0

        20. septembar 2026.

        Novo

        • Kupci, klijenti, stanari, korisnici: svako jednom, sa saldom. Svaka faktura je nosila kupca kao ime i tri neobavezna polja, i ništa nije povezivalo jednu fakturu s drugom, pa je „šta mi duguje ovaj stanar" bilo listanje faktura s imenom u glavi. Sada je to jedan ekran, nazvan po djelatnosti (Klijenti, Stanari, Korisnici, Kupci): svako jednom, s ID brojem, šifrom (broj korisnika, ugovor, stan), e-mailom i adresom, i uz svakog koliko duguje, koliko od toga kasni i koliko dugo (nije dospjelo, do 30 dana, 31 do 60, 61 do 90, preko 90). Dodir na ime otvara sve njegove račune.
        • Izvod otvorenih stavki. Jedno dugme, jedan PDF: svaki otvoren račun s datumom, rokom, iznosom, uplaćenim i dugom, zbir na dnu, dospjelo crveno, na dan izrade, s napomenom da je stanje prema računima kroz XPay. Dokument koji knjigovođa šalje na kraju kvartala.
        • Podsjetnik jednim dodirom. E-mail kupcu sa spiskom dospjelih računa, iznosima i linkom na svaki (poziv na broj i kod). Šalje ga osoba, nikad automatika: podsjetnik je odnos, a zakupodavac zna ko je ovog mjeseca ostao bez posla. Najviše jednom dnevno po kupcu; odbijeno kad nema e-maila ili ništa nije dospjelo, s razlogom na ekranu. Vidi se kad je zadnji poslan.
        • API: GET/POST/PATCH /v1/customers, GET /v1/customers/:id sa saldom i starošću duga, GET /v1/customers/:id/statement.pdf, POST /v1/customers/:id/remind. Faktura prima customerId; odgovor nosi customer.id. Drugi kupac s istim ID brojem se odbija uz id postojećeg.

        0.60.0

        20. septembar 2026.

        Novo

        • Konzola zna čime se bavite. Server je oduvijek znao koje je vrste svaka poslovnica; konzola je čitala samo šta se smije, i samo za navigaciju. Pa je knjigovođa bio pošteđen ekrana Stolovi, a onda dobio pregled o gostima i gotovini za stolom, Poslovnice koje nude kodove za stolove i tablet konobara, i Osoblje čije su jedine uloge konobar, kuhar i šanker. Proizvod je bio restoran sa sakrivenim restoranskim ekranima.
        • Pregled za one koji šalju račune. Četiri broja i jedan spisak: izdato u periodu, naplaćeno u periodu, dospjelo a neplaćeno (danas), otvoreno a još nije dospjelo (danas), i ko duguje, po kupcu, najveći dug prvi, crveno što je prošlo rok, sa datumom od kada kasni. Dodir na ime otvara njegove račune. Ispod, naplaćeno po danu i zadnji računi. Isto pravilo za „kasni" kao na listi faktura, pa se dva ekrana ne mogu razići.
        • Salon, servis, ordinacija, teretana. Nova vrsta posla: naplata na licu mjesta po posjeti, prijava osoblja PIN-om da se vidi ko je naplatio, fakture kad trebaju (osiguranje, firma), bez stolova, menija i zaliha. Na prijavi i u konzoli operatera.
        • Osoblje po djelatnosti. Trgovina dodaje prodavača, blagajnika i skladištara; salon radnika i recepciju; restoran ostaje kod konobara, kuhara i šankera. Uloga je riječ, ne pravo: uređaj odlučuje ekran.
        • Pretraga faktura po kupcu. Polje na listi faktura, i cilj linka sa spiska dužnika.

        Popravljeno

        • Probni podaci više ne daju knjigovođi dvanaest naljepnica za stolove.

        0.59.0

        20. septembar 2026.

        Novo

        • Gosti se presele, račun ide s njima. Četvero sjedne za Sto 3, naruči, i pređe na terasu kad se oslobodi. Račun je do sada pripadao naljepnici s koje je otvoren, pa ga je konobar nosio u glavi, ili zatvarao kao gotovinu i otvarao ponovo, dok je kuhinja dozivala sto za kojim više nije bilo nikoga. Premjesti na stolu nosi cijeli račun, s narudžbama, na drugi slobodan sto: kuhinjski ekran i sala odmah pišu novi sto. Odbijeno dok se sto plaća ili gost drži živ kod, i odbijeno na sto koji već ima račun. Gosti ponovo skeniraju naljepnicu novog stola i nađu svoj račun tamo.
        • Otkazivanje narudžbe s telefona. Uz svaku narudžbu koja još nije spremna stoji Otkaži, s razlogom u jednom dodiru: gost odustao, greška, nema više. Račun pada tačno za tu rundu, kuhinja vidi razlog. Ono što je već na tacni ne može se otkazati: to je razgovor o povratu, ne dugme.

        0.58.0

        20. septembar 2026.

        Novo

        • Konobar uzima narudžbu sa menija, na svom telefonu. Sala je pokazivala stolove i šta je ko naručio, a jedino što nije mogla bilo je uzeti narudžbu: gost koji radije kaže „dvije kafe" nego da skenira naljepnicu upisivao se kao slobodan iznos, koji kuhinja nikad ne vidi i sto ne pamti. U lokalu s cjenovnikom konobar je kucao brojeve.
        • Telefon javlja šta se promijenilo u sali. Poziv sa stola, nova narudžba s gostovog telefona, zahtjev za račun (i kako), tanjiri koje je kuhinja završila i uplata kodom koja je zatvorila sto: svako svojim zvukom, vibracijom i porukom na vrhu ekrana koja otvara taj sto. Ne javlja ono što je konobar sam uradio. Poruke ne dolaze iz događaja nego iz razlike između dva pogleda na salu, pa ispadnuti wifi ne može progutati poziv: sljedeći pogled ga nađe.
        • Izneseno. Uz svaku narudžbu na stolu koja još nije iznesena stoji dugme. Konobar je taj koji je nosi, pa je konobar taj koji kaže da je stigla; gost na svom telefonu vidi da je stigla. Sto na kojem kuhinja ima gotove tanjire piše spremno za iznijeti, plavo, da se vidi preko sale.
        • Izvještaj o osoblju broji i uzete narudžbe. Nova kolona uz zatvorene račune, gotovinu i korake: koliko je narudžbi ta osoba uzela za stolom. Nula, ne prazno, za kuhara; nula i za sve što su gosti sami poslali.

        Popravljeno

        • Narudžba je morala biti „preuzeta" prije nego što se iznese. Pravilo je bilo da kuhinja prvo pritisne preuzeto, pa tek onda iko smije reći da je izneseno. U kafiću bez ekrana na zidu nema ko da pritisne preuzeto, pa su narudžbe stajale kao „poslano" zauvijek, a konobar koji je kafu napravio i donio bio je odbijen kada je to rekao. Izneseno se sada može reći odmah.
        • Slobodan iznos je jedan dodir dalje i zove se kako treba. Dugme na dnu sale sada piše Račun bez stola, za bocu na vratima i šank pri odlasku. Sve što se dešava za stolom ide preko stola.
        • Kuhinjski ekran ne može uzeti narudžbu. Narudžba dodaje dug na sto, pa traži isto što i naplata: ekran koji dijele tri kuhara u prostoriji u koju svako može ući ima pravo na narudžbe, ne na novac.

        0.57.0

        20. septembar 2026.

        Novo

        • Račun koji knjigovođa proknjiži bez telefoniranja. Račun iz XPay-a je imao broj, datum, stavke, PDV i ukupno, i to je bilo dovoljno gostu. Nije bilo dovoljno onome ko ga knjiži: nedostajali su PDV broj izdavaoca, mjesto izdavanja, datum prometa i način plaćanja, a PDV je bio jedan red bez stope, pa se iz njega nije vidjelo da li je 17% na sve ili je nešto oslobođeno. Svaki od tih redova je pitanje koje knjigovođa mora postaviti, i svaki račun bez njih je račun koji se vraća.
        • „Izdavalac nije u sistemu PDV-a." Firma koja nije u sistemu mora to reći na računu, i sada se ta rečenica ispisuje sama u podnožju kada je u postavkama rečeno „ne". Ali samo na računu bez poreza: firma koja je prešla u sistem i promijenila postavku, ili obrnuto, ima stare račune sa 17% i novu postavku „ne", i tu bi rečenica ispod redova sa PDV-om bila laž na dokumentu. Zato se ne štampa dok na računu ima poreza, a izdavanje računa sa stopom za firmu koja je rekla „ne" se odbija s objašnjenjem, prije nego što dobije broj.
        • QR kod na računu je manji i na desnoj strani. Bio je velik koliko i blok za plaćanje i gurao je podatke o banci u drugi plan. Sada stoji desno, centriran uz IBAN, iznos i poziv na broj, dovoljno velik da ga bankovna aplikacija pročita s papira, i ništa više.

        Uputstvo

        • Svakodnevni rad opisuje salu. Poglavlje o naplati je pisano za tastaturu i kod; sada opisuje stolove kakve konobar vidi na telefonu, šta otvara dodir na sto, četiri stvari koje se rade s novcem, i kada se koristi račun bez stola.

        0.56.0

        20. septembar 2026.

        Novo

        • Konobar na svom telefonu vidi salu. Terminal je bio tastatura i kod: upiši iznos, pokaži QR, uzmi novac. Sto, narudžbu i poziv sa stola nije vidio - to je stajalo na zidu u kuhinji i na laptopu u kancelariji, dva mjesta gdje konobar nije. Osoba čiji je posao sala bila je jedina u lokalu bez pogleda na nju.
        • Konobar može podići QR kod za cijeli sto. Za gosta koji ne može skenirati naljepnicu ili bi radije da konobar to obavi. Do sada je jedini odgovor bila tastatura, koja je pravila račun za koji sto nije znao: novac stigne, sto ostane otvoren, neko ga zatvori kao „neplaćeno" ili „gotovina" da oslobodi sto, i izvještaj broji veče dvaput ili nijednom. Kod se sada veže za sto pod istom bravom koju koristi gostov tok, pa dva koda za isti novac ne mogu proći, i kada novac legne sto se zatvara sam - put koji ga zatvara ne razlikuje ko je kod podigao. Odbijeno dok bilo koji gost drži živ kod, i odbijeno gdje je lokal isključio plaćanje kodom.

        Popravljeno

        • Poništen kod za sto ostavljao je sto zaključan. Podizanje koda parkira sto (bez narudžbi, bez novih telefona). Otkaži na terminalu je poništavao samo kod, pa je sto ostajao parkiran bez ičega na što čeka: dugovao 20,00, nije držao kod i nije mogao naručiti kafu. Otkaži sada ide preko stola, kao i gostovo dugme, pa se sto oslobodi. A sto parkiran isteklim kodom dobio je Oslobodi sto, jer istekao kod parkira sto još sat vremena, a dugme za to se pokazivalo samo dok je kod živ.
        • Telefon konobara sada smije čitati spisak stolova svog lokala. Opseg tables:read uveden uz zatezanje API ključeva nikad nije dat uređaju, pa bi telefon vidio svaki otvoren račun i nijedan sto. Čita svoj lokal; tuđi i dalje ne postoji za njega.
        • „Sto Sto 3" na ekranu čekanja. Oznaka s tastature je broj, pa joj se dodaje riječ; oznaka sa sale je već „Sto 3".

        0.55.34

        19. septembar 2026.

        Novo

        • Vlasnik bira šta gost može da plati preko telefona. Podešavanja → Načini plaćanja: za svaku poslovnicu prekidači za kod za plaćanje (bankovna aplikacija), karticu na vašem terminalu i gotovinu. Što je isključeno, gost ne vidi. Kafić koji prima samo gotovinu isključi prva dva: gostu dugme Plati odmah zove konobara, bez ekrana sa izborom. Kad je isključeno sve, gost nema dugme za plaćanje i na računu mu piše da se plaća kod osoblja; naljepnica za plaćanje bez menija kaže da lokal ne prima kod sa telefona. Isto vrijedi i na strani servera: kod ili zahtjev za način koji je isključen se odbije, pa zaobilaženje ekrana ne pomaže. Tablet konobara, kasa na ekranu i API ključevi i dalje izdaju kodove, jer to radi osoblje.

        Za one koji razvijaju

        • Location.acceptsQr, acceptsCard, acceptsCash (migracija 20261006000000_payment_methods, sve tri podrazumijevano uključene), PATCH /v1/locations/:id ih prima, GET /v1/t/:slug vraća payments { qr, card, cash }. Odbijanje je 409 payment_method_off na POST /v1/t/:slug/session/pay, .../session/request-payment i POST /v1/t/:slug/payments. Smoke narudžbi dobio je odjeljak koji lokal prebaci na gotovinu, provjeri sva tri odgovora i vrati ga.

        0.55.33

        19. septembar 2026.

        Novo

        • Zvuk za osoblje na svakom ekranu. Konzola, konobarski tablet i kasa na ekranu sada zvone kad se nešto desi, kao što kuhinjski ekran već zvoni: nova narudžba (dva tona nagore), gost zove konobara (tri tona nadolje, dva puta), gost hoće da plati (dva kratka pa jedan duži), uplata stigla (akord) i otkazana narudžba (nadolje). Svaki ekran ima dugme za zvuk u zaglavlju i izbor se pamti na tom uređaju. Preglednik ne pušta zvuk dok se ekran jednom ne dodirne, pa dotle pored dugmeta piše "Zvuk je blokiran, kliknite da ga uključite" umjesto da zvoni u prazno. Osam narudžbi sa jednog stola je jedan zvuk, ne osam.
        • Stranica Kasa sa dugmetom "Pretraži kasu". U konzoli, pod Kasa, vlasnik ili menadžer vidi kako je kasa povezana sa XPay-om i traži je jednim dugmetom. Konzola je web stranica i ne vidi uređaje u lokalu, pa pretraga nalazi ono što se javilo XPay-u: konektor na računaru pored kase (javlja se svakih pola minute, sa onim što prati i onim što je njegov detektor našao na tom računaru: fiskalni servis, foldere, instalirane programe) ili kasu koja sama zove XPay ključem (piše kad je zadnji put zvala i koji program). Pretraga sluša minut i stane čim se nešto javi. Kad ne nađe ništa, kaže da je to uobičajeno, ne greška, i daje tri načina: kasa koja može zvati internet (ključ pod Za programere plus uputstvo za servisera koje se kopira jednim klikom), računar pored kase (zahtjev za instalaciju konektora jednim klikom) i kasa koja ostaje kakva jeste (tablet, kasa na ekranu ili naljepnica rade već danas, a račun se na kasi zatvori kao za gotovinu). Ispod toga su uređaji XPay-a po vrsti i svi ključevi sa zadnjim pozivom.
        • Konektor se sam javlja. Konektor 0.2.0 šalje otkucaj svakih 30 sekundi i svakih 15 minuta ponavlja detekciju koju je dosad trebalo pokrenuti ručno sa --detect.

        Za one koji razvijaju

        • POST /v1/connectors/heartbeat (API ključ, opseg payments:read) upisuje red u pos_connectors, jedan po računaru po lokalu; GET /v1/pos-links (vlasnik ili menadžer) vraća konektore, ključeve sa lastUserAgent i broj uređaja po vrsti. Migracija 20261005000000_pos_connectors. Ključ uz lastUsedAt sada pamti i lastUserAgent.
        • Zvuk: apps/dashboard/src/lib/alert-sound.ts je jedan hook za sve ekrane sa tonovima sintetizovanim u pregledniku, components/sound-control.tsx je dugme, a konzola sluša događaje u components/console-alerts.tsx.

        0.55.32

        19. septembar 2026.

        Novo

        • Gost vidi kada mu stiže narudžba. Poslije slanja narudžbe na ekranu je prsten koji se puni i sat koji odbrojava: "Vaša narudžba stiže za 11:40", ispod toga "2 narudžbe ispred vas" i, kad narudžba ima i piće i hranu, posebno "Pića ~3 min" i "Hrana ~14 min". Isti sat stoji na svakoj otvorenoj narudžbi u kartici stola. Kad kuhinja označi spremno, piše "Spremno je, stiže za tren"; kad procjena istekne a kuhinja nije gotova, piše "Još malo, kuhinja završava", nikad nula.
        • Procjena je pametna, ne fiksna. Računa se iz tri stvari: koliko traje svako jelo (novo polje "Vrijeme pripreme" na artiklu; prazno znači uobičajeno za stanicu, kuhinja 12 min, šank 3 min), koliko je narudžbi ispred u redu iste stanice (kuhinja radi tri odjednom, šank četiri) i koliko ta kuhinja stvarno treba u odnosu na ono što meni tvrdi (srednja vrijednost zadnjih 60 gotovih narudžbi u dvije sedmice, između 0,6 i 1,8 puta). Vrijeme pripreme se pamti uz stavku narudžbe kao i naziv i cijena, pa izmjena menija sutra ne mijenja ono što je gost večeras vidio.
        • Red u kuhinji je po vremenu narudžbe i to piše. Na kuhinjskom ekranu svaka kartica nosi "1. u redu", "2. u redu" i "do 20:35" (vrijeme obećano gostu). Kartica koja probije obećano vrijeme postaje crvena i piše "kasni", bez obzira na sat. Isto na listi narudžbi u konzoli.
        • Na artiklu u meniju piše "Priprema oko 12 min" kad gost otvori jelo, da onaj kome se žuri izabere burek a ne lonac. Demo lokal ima vremena za svih 26 jela.
        • Povrat sa izvoda se evidentira sam. Kad banka platioca povuče uplatu a banka lokala je vrati, na izvodu lokala stoji zaduženje sa originalnim pozivom na broj. Uvoz izvoda ga sada prepozna i upiše kao povrat na tom računu (sa referencom banke, pa ponovni uvoz istog izvoda ne upisuje dva puta); račun više ne ostaje "plaćen" bez novca. Zaduženja bez naše reference su plaćanja lokala prema drugima i samo se prebroje.

        Za one koji razvijaju

        • apps/api/src/modules/orders/eta.ts: čista funkcija procjene sa 20 testova (red po placedAt, pozicija, paralelnost stanice, kalibracija, zastarjela procjena). Migracija 20261004000000_prep_minutes dodaje prepMinutes na menu_items i order_items. API vraća eta u pogledu stola za gosta (/v1/t/:slug/session) i na tabli (/v1/orders).
        • POST /v1/settlement/sources/:id/camt vraća i returned, returnsDuplicate, returnsUnmatched; parser camt fajlova daje returns uz credits, sa referencama iz RtrInf/OrgnlTxRef.

        0.55.31

        19. septembar 2026.

        Popravke

        • Uparivanje čita i broj dokumenta iz strukturirane doznake. Poruka instant plaćanja nosi referencu ili kao slobodni tekst (do 140 znakova) ili strukturirano, a u strukturiranom bloku banka može upisati broj računa ili fakture kao "referentni dokument" umjesto kao poziv na broj. Uvoz izvoda (camt.052/053/054) sada čita i to polje i identifikatore stavki ispod njega, pa se uplata sa referencom na tom mjestu upari po referenci, a ne tek po iznosu i vremenu.

        Za one koji razvijaju

        • Dokumentacija Centralne banke za sistem instant plaćanja (specifikacije, sheme poruka, primjeri, pitanja i odgovori) stigla je 19. septembra i čuva se u CBBH_docs/ izvan repozitorija (.gitignore). Šta iz nje slijedi za proizvod sažeto je u docs/go-live-bih-ips.md: KM ide kroz ne-euro shemu platforme, deset sekundi od prihvatanja naloga, referenca staje u oba polja (140 slobodno, 35 strukturirano), račun između banaka je uvijek IBAN, alias direktorijum i QR model su najavljeni a nisu objavljeni. Pitanja za banke dopunjena (u koje polje aplikacija upisuje referencu, da li EndToEndId i UETR stižu na izvod klijenta, alias plaćanja, kako izgleda povrat).

        0.55.30

        18. septembar 2026.

        Popravke

        • README govori o svim djelatnostima. Opis projekta na GitHubu je bio napisan za ugostiteljstvo ("gost", "restoran", "konobar"). Sada vodi sa fakturom, kasom i izvodom: trgovine, servisi i samostalne djelatnosti, komunalna preduzeća i zakup, webshopovi, veliki izdavaoci računa, i tek onda kafići i restorani. Dodane grupe "Fakture i naplata, za svaku djelatnost" i "Trgovina, veleprodaja i webshop" sa onim što već postoji u proizvodu; tok novca i pravna napomena govore o kupcu i firmi, ne o gostu i restoranu.

        0.55.29

        16. septembar 2026.

        Novo

        • Novi logo, svuda. Sajt, konzola, stranica gosta, naljepnice za stolove, QR kod (znak u sredini), faktura u PDF-u, slika koja ide uz podijeljeni link, README i sva tri dokumenta za štampu nose novi XPay logo: veliko X sa trakom pločica i riječ "Pay". Dvije verzije, jedna za tamnu podlogu sa svijetlim slovima, jedna za svijetlu podlogu sa tamnim slovima, i svaka površina nosi onu za koju je nacrtana. Ikona u kartici preglednika je X iz tog loga, u tri veličine (16, 32 i 48 piksela), a ikona za početni ekran telefona sjedi na crnoj podlozi sajta. Stari logo, i onaj ljubičasti i onaj plavi od prije septembra, nigdje se više ne prikazuje.

        Za one koji razvijaju

        • scripts/brand-logo.mjs prima dva fajla od dizajnera (za tamnu i za svijetlu podlogu), čuva ih pod assets/brand/ i iz njih generiše sve ostalo: lockup za oba app-a, znak, ikone, favicon.ico i modul sa slikom za OG stranicu. Granica između X-a i riječi se nalazi po obliku (stub slova P je prva kolona poslije križanja u kojoj neprekinuti trag tinte naglo poraste), pa nova verzija crteža ne traži nova mjerenja.

        0.55.28

        16. septembar 2026.

        Novo

        • Stranica za banke: "Vrijednost za banku" i "Zašto sada". Odmah ispod prvog ekrana stoje četiri kolone kako ih banka sama mjeri: volumen (više transakcija kroz IPS, veća frekvencija), novi prihodi (monetizacija SME segmenta, transakcioni ili pretplatni model), retencija (trgovac drži račun i priliv kod banke, manje odliva), diferencijacija (konkretan proizvod, prednost pred konkurencijom). Zatim "Zašto sada": IPS infrastruktura već postoji, tržište nema standardizovano rješenje, konkurencija nije pozicionirana, i ljubičasti blok "Prednost prvog". PDF za štampu obnovljen iz istog sadržaja (osam strana).

        0.55.27

        16. septembar 2026.

        Popravke

        • Stranica za banke govori jezikom koristi. Naslov je sada "Povećajte korištenje instant plaćanja na prodajnim mjestima, pod vašim brendom", a odmah ispod prvog ekrana stoji nova sekcija "Šta banka dobija, mjereno": četiri koristi (više instant transakcija, aktivniji klijenti u aplikaciji, trgovac vezan za banku, bez rizika i bez razvoja), svaka sa naslovom, dvije rečenice i redom "Rezultat:" koji kaže šta se mjeri. Tehnika i tok novca su ostali, ali ispod toga. PDF za štampu obnovljen iz istog sadržaja (šest strana).

        0.55.26

        16. septembar 2026.

        Popravke

        • Sajt: jela na telefonu imaju slike. Ilustracija menija na početnoj, na stranici za firme i na Hospitality stranici crtala je uz svako jelo dva smeđa prstena umjesto slike, što je izgledalo kao prazan krug. Sada su tu iste naslikane sličice koje vidi gost na stranici lokala (ćevapi, Begova čorba, burek, bosanska kafa), napravljene iz istog crtača (scripts/site-dishes.mjs), pa telefon na sajtu izgleda kao telefon u ruci gosta.

        0.55.25

        16. septembar 2026.

        Novo

        • Dvije stranice za slanje linkom: za banke i za firme. xpay.ba/banke je prijedlog partnerstva za banke i velike partnere (white-label): tok novca u pet stanica sa jasno označenim mjestom gdje XPay nikad ne dodiruje novac, šta banka dobija, sedam djelatnosti, tehnički okvir za inženjere, tri modela saradnje, pilot u tri koraka i iskren popis onoga što još nije napravljeno. xpay.ba/za-firme je za lokale i sve druge djelatnosti: tri toka (skeniraj-naruči-plati, skeniraj-vidi fakturu-plati, kod na kasi ili stranici), tabela po djelatnosti, cijene i pitanja koja svi postave. Obje su u glavnoj navigaciji i u podnožju.
        • Verzije za štampu. Svaka stranica ima dugme "Verzija za štampu (PDF)": pet strana A4 u istim bojama, napravljene iz istog sadržaja kao stranica (scripts/partner-docs.cjs), pa PDF u ruci i stranica na ekranu ne mogu reći različite stvari. Word verzije su pored, za uređivanje.

        0.55.24

        16. septembar 2026.

        Novo

        • Priprema za razgovor sa bankom (dokument za štampu). U docs/bs/prilozi stoji Word i PDF sa 14 strana: šta je XPay u tri rečenice, kako radi korak po korak, šta banka dobija od white-label saradnje, pitanja koja banka postavlja (poslovna, tehnička, pravna, o riziku) sa odgovorima, tehnički list sa brojevima, devet pitanja koja mi postavljamo banci, tri modela saradnje sa polaznim cijenama, lista onoga što se ne obećava i zašto, i plan sastanka od 30 minuta. Skripta koja ga pravi je pored, pa se dokument obnavlja jednom komandom kad se proizvod promijeni.

        0.55.23

        16. septembar 2026.

        Popravke

        • Korpa: dugme "Naruči" više ne bježi van ekrana. Dugme "Dodaj još" trebalo je da bude usko, uz široko ljubičasto "Naruči", a zauzimalo je cijeli red i gurnulo "Naruči" desno, van ekrana. Uzrok: osnovna klasa dugmeta uvijek je dodavala punu širinu, pa je zahtjev za uskim dugmetom gubio. Sada dugme koje traži svoju širinu i dobije svoju širinu.
        • Stranica gosta na laptopu izgleda kao na telefonu. Na širokom ekranu svaka kartica se razvlačila preko cijele širine (1900 piksela), a trake na dnu (korpa, narudžba, navigacija) i list sa detaljima jela isto. Sada je sadržaj ograničen na širinu telefona i centriran, boja lokala ostaje po cijeloj pozadini, a trake na dnu i list prate istu širinu. Na telefonu se ništa ne mijenja.

        0.55.22

        16. septembar 2026.

        Novo

        • Za malu raju: igrice na stranici gosta. Porodica sjedne, roditelji naruče sa telefona, i sljedećih dvadeset minuta dijete hoće telefon. Na početnoj stranici gosta sada stoji kartica "Za malu raju" sa tri male igre koje ne traže ni signal ni nalog: Memori (nađi parove), Iks-oks protiv telefona, i Slagalica od slike lokala. Ništa od toga ne razgovara sa serverom, pa dijete koje pritišće sve redom ne može ništa pokvariti.
        • Demo meni za lokal, jednom komandom. Nova komanda na serveru (seed-demo-venue) napuni lokal kompletnim menijem: doručak, predjela, roštilj, pite, glavna jela, pizze, salate i prilozi, "Za malu raju", deserti, topli napici i hladna pića, sa cijenama, opisima, opcijama (veličina ćevapa, prilog, šećer u kafi) i prijedlozima (piće poslije roštilja, kafa poslije deserta). Svako jelo dobije naslikanu sličicu u jednom stilu (tanjir, zdjela, čaša, pita, pizza, sladoled...), nacrtanu bez ijedne biblioteke, tako da meni na prvi pogled izgleda kao meni. Postojeće kategorije i jela lokala se čuvaju: "Jelo" postaje "Sa roštilja", "Pice" postaje "Hladna pića", ćevapi i Coca-Cola koje je lokal sam upisao ostaju sa svojim fotografijama, a jela bez slike dobiju sličicu. Ništa se ne briše.

        Provjere

        • Test za sličice (35 vrsta, ispravan PNG od 480 piksela, ista slika za isto jelo); typecheck API-ja i konzole; i18n paritet; lint. Komanda provjerena na lokalnoj bazi u probnom načinu (--dry) i stvarno.

        0.55.21

        16. septembar 2026.

        Popravke

        • Lista za dan testa zna za "Novo plaćanje" u konzoli. Korak za prvu uplatu od 1 KM sada kaže da se kod može napraviti i sa laptopa, bez tableta: Plaćanja, dugme "Novo plaćanje", iznos 1,00.

        0.55.20

        16. septembar 2026.

        Novo

        • Novi račun iz konzole. Konzola je mogla da pregleda, vrati i potvrdi uplate, a nije mogla da napravi nijednu: kod su izdavali samo upareni tablet i kasa, a prevod za dugme "Novo plaćanje" postojao je sedmicama bez dugmeta. Na ekranu Plaćanja sada stoji "Novo plaćanje": iznos, sto i broj računa na kasi (oba nisu obavezna), poslovnica ako ih ima više. Kod se prikaže na ekranu da ga gost skenira, uz poziv na broj i do kad važi, a stanje se osvježava samo dok je prozor otvoren ("Plaćeno", "Stiglo više", "Stiglo manje", "Kod je istekao"). Dupli klik ne pravi dva računa.
        • Sto koji predugo stoji neplaćen se vidi na rasporedu. Jedina granica do sada bilo je dvanaest sati, poslije kojih sto ne prima narudžbe, a ništa na ekranu nije reklo da sto devet od ručka sjedi na neplaćenom računu. Sto sa narudžbom, dugom i više od 90 minuta otvoren sada svijetli žuto sa natpisom "Otvoren predugo" i "N min bez plaćanja. Provjeri sto.", a zaglavlje rasporeda broji takve stolove. Prazan sto (bez narudžbe) nije ovo: njega API sam sklanja poslije pola sata.

        Provjere

        • Typecheck konzole, i18n paritet, lint. Dijalog šalje isti zahtjev kao tablet (POST /v1/payments sa ključem idempotencije), koji je pokriven postojećim testovima i smoke paketima.

        0.55.19

        16. septembar 2026.

        Popravke

        • Lista za dan testa zna za prekidač zapisa računa u QR kodu. U tabeli "Ako nešto ne radi" stoji šta uraditi kad bankovna aplikacija pročita kod, a odbije račun primaoca: na serveru uključiti QR_ACCOUNT_FORMAT="domestic" i podići API, bez nove verzije. Red o kodu koji se ne izdaje sada kaže "račun", ne "IBAN", jer lokal može upisati i broj računa od 16 cifara.

        0.55.18

        16. septembar 2026.

        Novo

        • Broj računa umjesto IBAN-a: lokal upisuje ono što zna. U BiH je IBAN uglavnom služio za plaćanja prema inostranstvu; na kartici, u e-bankarstvu i na izvodu stoji domaći broj računa od 16 cifara (pisan 3-3-8-2, npr. 129-007-94010284-94). To je isti račun: IBAN je BA, dvije kontrolne cifre i tih 16 cifara. Polje za račun u konzoli (nova poslovnica i izmjena računa) sada prima jedno ili drugo; iz broja računa se IBAN izračuna sam, a kontrolne cifre oba oblika se provjere prije spremanja i greška kaže koje cifre da se pogledaju. Operaterski unos lokala prolazi istim putem.
        • Broj računa svuda gdje neko plaća ručno. Stranica gosta ("Prepišite podatke u svoju banku"), PDF fakture i javna stranica fakture uz IBAN sada pokazuju i broj računa od 16 cifara, jer domaći nalog u bankovnoj aplikaciji traži "broj računa", a ne IBAN. Kopira se bez crtica, kako ga obrazac traži.
        • Prekidač za zapis računa u QR kodu. BiH profil koda upisuje IBAN, a niko još nije potvrdio da bankovna aplikacija iz koda čita baš njega, a ne 16 cifara. Nova postavka QR_ACCOUNT_FORMAT ("iban" ili "domestic") mijenja zapis u kodu na računu, na naljepnici i na fakturi bez nove verzije: samo postavka na serveru i ponovno podizanje API-ja. Prazno znači da odlučuje profil, kao i do sada.

        Provjere

        • Novi testovi za broj računa: pretvorba u oba smjera na stvarnom primjeru, kontrolne cifre, ispis 3-3-8-2, i šta polje prima (16 cifara sa crticama ili bez, IBAN sa razmacima) i šta odbija (zamijenjene cifre u oba oblika). Postojeći testovi IBAN-a, QR kodeka, faktura, lokala i plaćanja prolaze; typecheck API-ja i konzole; i18n paritet; lint.

        0.55.17

        16. septembar 2026.

        Popravke

        • PIN tastatura: tipka za brisanje je strelica. Znak za brisanje koji je stajao na tastaturi za prijavu osoblja nema svaki font na tabletu, pa se na provjeri u pregledniku vidio kao pogrešan znak. Sada je obična strelica ulijevo, koju ima svaki font.

        0.55.16

        16. septembar 2026.

        Novo

        • Osoblje po imenu: konobari, kuhari i šankeri se prijavljuju PIN-om. Konzola ima korisnike sa e-mail prijavom, a sala ima tablete, kase i kuhinjske ekrane koje drži više ljudi. Ništa nije spajalo to dvoje, pa je svaki zatvoren račun, svaka pomjerena narudžba i svaki odgovoren poziv nosio ime uređaja: izvještaj je mogao reći "tablet na šanku zatvorio 40 računa", a nikad "Amir". Sada vlasnik na novom ekranu "Osoblje" dodaje ljude po imenu, ulozi (konobar, kuhar, šanker) i PIN-u od četiri do šest cifara. Na tabletu, kasi i kuhinjskom ekranu gore stoji dugme "Prijava": osoba izabere svoje ime, upiše PIN, i od tada sve što uradi na tom uređaju nosi njeno ime. Prijava traje jednu smjenu (14 sati), važi samo na tom uređaju i ne daje uređaju nikakva nova prava; uređaj bez prijave radi tačno kao do sada. Osam pogrešnih PIN-ova zaključava osobu na petnaest minuta, isto kao i lozinku u konzoli. Deaktivirana osoba prestaje da se imenuje odmah, i nestaje sa uređaja u roku od pet minuta.
        • Izvještaj "Ko je radio" imenuje ljude, ne samo uređaje. Prijavljena osoba se u izvještaju vodi kao osoba sa ulogom, uz konzolne korisnike; zajednički ekrani na kojima niko nije bio prijavljen ostaju označeni kao uređaji, kao i do sada. Isti izvještaj stoji i na ekranu "Osoblje", pored imena o kojima govori.

        Provjere

        • Cijeli tok provjeren od početka do kraja na lokalnoj bazi: vlasnik doda kuhara, kuhinjski ekran ga vidi na spisku bez PIN-a, pogrešan PIN se odbija, tačan vraća potpisan token, konzolna prijava ne može tražiti token za osoblje, gost naruči, prijavljeni kuhar prihvati narudžbu, izvještaj imenuje kuhara sa ulogom i jednom prihvaćenom narudžbom, deaktiviran kuhar nestaje sa spiska i njegov stari token pada na uređaj. Testovi potpisa tokena (šest) i PIN-a (tri), i18n paritet uključujući nove uloge, typecheck API-ja i konzole.

        0.55.15

        16. septembar 2026.

        Novo

        • Nova naljepnica za sto i novi izgled QR koda. U sredini svakog koda stajao je stari zeleni znak iz augusta, ručno prepisan u API kao vektorske linije sa ikone koja je iz projekta obrisana kad je stigao novi logo. Sada je u sredini novi znak XPay (isti na naljepnici, na stranici gosta i na fakturi u PDF-u), a kod na naljepnici za sto ima zaobljene module i zaobljene uglove tri velika kvadrata, dok kodovi koji nose novac (račun, faktura, bankovna naljepnica) ostaju klasični kvadrati koje svaka bankovna aplikacija sigurno čita. Naljepnica je redizajnirana: ljubičasta traka sa imenom lokala i stolom, kod na bijeloj ploči, tri koraka (Skeniraj, Naruči, Plati; kod bankovnog koda Skeniraj, Upiši iznos, Plati), adresa za telefon bez kamere, šifra stola i znak XPay. Stalak za sto je tamno ljubičast, kartica velika. Tabak A4 sada nosi devet naljepnica (tri puta tri), jer dvanaest nikad nije stalo na jednu stranu pri veličini koda koji se čita sa telefona u ruci.
        • Pregled naljepnice prije štampe. Na ekranu "Kodovi za stolove" sada stoji jedna prava naljepnica (prvi sto, u odabranom formatu i vrsti koda) napravljena istom komponentom kojom se štampa, pa pregled ne može da laže.

        Provjere

        • Zaobljeni kod se u testu iscrtava u piksele onako kako ga kamera vidi, sa prekrivenom sredinom, i dekodira istom bibliotekom; svi postojeći testovi čitljivosti (dug URL, bankovni nalog, znak preko sredine) i dalje prolaze.

        0.55.14

        16. septembar 2026.

        Popravke

        • Adresa API-ja u uputstvima, SDK-u i konektoru je sada ona koja postoji. Uputstvo za spajanje kase, engleska POS dokumentacija, SDK za Node i lokalni konektor upućivali su na api.xpay.ba, adresu koja nikad nije podešena (nema DNS zapisa ni certifikata). Ko bi sutra pratio uputstvo, dobio bi grešku "host nije pronađen" prije prvog poziva. Sve sada pokazuje na xpay.ba, gdje API stvarno radi (ista adresa na kojoj je i dokumentacija /docs), a uputstvo za tablet vodi na app.xpay.ba/terminal umjesto na izmišljenu domenu. Ekran "Za programere" u konzoli sada ispisuje osnovnu adresu API-ja, uzetu iz iste postavke koju konzola sama koristi, pa se ne može razići sa stvarnošću. Uputstvo je i ispravljeno da dugme zove onako kako se zove ("Novi ključ").
        • Prazan sto se sam sklanja poslije pola sata. Skeniranje koda ne otvara ništa: sto se u sistemu otvara tek kad gost naruči ili pozove konobara. Ali gost koji pozove konobara pa se predomisli, ili ode prije prve narudžbe, ostavljao je otvoren sto bez ijedne stavke: na rasporedu stolova svijetlio je kao "Čeka narudžbu" sa 0,00 KM i brojačem minuta koji nikad ne staje, pregled ga je brojao među otvorenim računima, a zatvoriti ga mogao je samo konobar sa ekrana narudžbi, dugmetom koje postoji za novac. Sada se sto bez narudžbe, bez uplate, bez otvorenog poziva i sa svim telefonima tihim 30 minuta sam zatvara, svakih pet minuta, bez ikakvog knjiženja (ne ulazi ni u promet ni u izvještaj po osoblju), uz zapis u dnevniku i događaj koji osvježava ekrane.
        • Ikona konzole u tabu preglednika je novi znak. Konzola je za ikonu i dalje koristila stari logo iz augusta, jedino mjesto gdje je još bio u upotrebi.

        0.55.13

        16. septembar 2026.

        Popravke

        • Smoke provjera: izbor slučaja radi i na bazi koja se ne briše. Dvije provjere iz 0.55.12 tražile su svoj slučaj po iznosu i razlogu NO_REFERENCE. Na bazi koja se ne briše između pokretanja uparivač vidi i račun sa istim iznosom iz prošlog pokretanja, pa razlog postane AMBIGUOUS_CANDIDATES i provjera bi pala iako sistem radi kako treba. Oba razloga znače isto za ovu provjeru (kredit koji niko nije mogao da smjesti), pa se sada prihvataju oba. Ništa u proizvodu nije mijenjano.

        0.55.12

        16. septembar 2026.

        Popravke

        • Statusna stranica: "prije X s" i odbrojavanje mjere od trenutka kad je provjera stigla. Stranica je računala starost zadnje provjere od vremena koje je server upisao, a ne od trenutka kad ju je preglednik primio, pa je na sporoj vezi ili u uspavanom tabu odbrojavanje do sljedeće provjere preskakalo ili odmah stajalo na nuli. Svaka primljena provjera sada pamti i kad je stigla. Natpisi "zadnje 3 provjere", "zadnjih 5 provjera" i "od 2 adrese" dobili su ispravne bosanske množine, a poruka za komponentu bez vremena odgovora razlikuje pad od tišine.
        • Skripte gledaju svoje podatke, ne tuđe. Provjera spremnosti lokala (venue-ready) ispisivala je sve prijemnike izvoda kao da slušaju, i one ugašene; sada ih dijeli na aktivne i one koji trenutno ne slušaju. Smoke provjera je birala "bilo koji otvoreni slučaj bez računa", što je na bazi koja se ne briše između pokretanja često bio slučaj iz prošlog pokretanja; sada traži tačno svoj kredit po iznosu, najnovije prvo. Provjera povrata mjerila je ukupan broj povrata umjesto razlike koju napravi upravo taj povrat, pa bi prolazila i sa ugašenom funkcijom.
        • SDK za Node: tipovi govore istinu. Odgovor o računu dobio je polja settledAmount i creditedToClosedTab koja API već vraća. Događaji sa živog toka bili su deklarisani kao webhook omotač (id, createdAt, livemode), a tok nosi drugačiji okvir (paymentId, at, data koja zavisi od vrste događaja); novi tip StreamEvent i pomoćna funkcija isPaymentEvent opisuju ono što zaista stiže. Verzija paketa 0.1.1.
        • API: vremenska zona lokala se provjerava na ulazu. Lokal je mogao da sačuva "Europe/Sarajvo" kao vremensku zonu, a greška bi iskočila tek kasnije, u analitici ili pri računanju dospijeća fakture. Sada se prihvataju samo zone koje sistem poznaje, sa jasnom porukom šta se očekuje.

        0.55.11

        16. septembar 2026.

        Popravke

        • Konzola: lista uplata koja nije mogla da se učita to i kaže. Kad prvi upit za listu uplata padne (istek veze, wifi u lokalu), ekran je ostajao na sivim placeholderima zauvijek, jer je poruka o grešci stajala u dijelu koji se crta tek kad ima redova. Sada se prikazuje poruka i dugme za ponovni pokušaj. Dugme "Učitaj još" više ne ostaje zaključano na "Učitavanje" kad sljedeća stranica ne stigne.
        • Konzola: novac i datumi u bosanskom obliku svuda. Dijalog za povrat prikazivao je naplaćeno, vraćeno i preostalo kao "19.50" umjesto "19,50 KM", a birač računa u uparivanju isto; zaglavlje pregleda pisalo je period kao "2026-09-01 do 2026-09-07"; tri ekrana (izvodi, zalihe, licenca) formatirala su datume kroz preglednik, što daje "10. 9. 2026. u 16:05" na jednom računaru i nešto drugo na drugom. Sve sada ide kroz iste pomoćne funkcije kao ostatak konzole.
        • Konzola: bosanske množine. "Vrijedi još 1 dana" i "21 dana" postaju "1 dan" i "21 dan"; "1 uparivanja, 1 webhooka" postaje "1 uparivanje, 1 webhook". Prazan grafikon na pregledu više ne piše bosansku rečenicu i u engleskoj konzoli.
        • Konzola: dva ekrana koja su se trkala sama sa sobom. Raspored stolova je pri promjeni lokala slao dva zahtjeva i primao odgovore bilo kojim redom, pa je spor odgovor za stari lokal mogao prekriti novi; operaterska pretraga slala je zahtjev na svaki otkucaj tipke bez reda. Oba sada prihvataju samo najnoviji odgovor, a pretraga čeka četvrt sekunde poslije zadnje tipke.

        0.55.10

        16. septembar 2026.

        Popravke

        • QR slika se ne služi za preplaćen račun. Slika koda odbijala se za plaćen, otkazan i vraćen račun, ali ne i za preplaćen, koji je svugdje drugdje isto što i plaćen; stari otisak mogao se ponovo skenirati u drugi prenos. Lista stanja za koja se kod više ne daje sada je na jednom mjestu, sa testom, i uključuje preplaćen i neuspio račun. Djelimično plaćen i istekao račun se i dalje služe, jer je za njih kod još namijenjen.
        • Vrijeme plaćanja se bilježi i kad je račun odmah preplaćen. Račun zaokružen naviše prelazio je iz "čeka" pravo u "preplaćen", a vrijeme plaćanja upisivalo se samo pri prelazu u "plaćen": takav račun nije ulazio u mjeru vremena potvrde, webhook je nosio prazno vrijeme, konzola datum kreiranja.
        • Djelimično plaćen račun nema prelaz u "otkazan". Tabela prelaza ga je dozvoljavala, a zaštita novca ga je uvijek odbijala, dok su dva komentara taj prelaz opisivali kao put za otpis. Uklonjen je; račun sa dijelom novca izlazi iz tog stanja samo kroz još novca ili kroz povrat.
        • Kod za udio računa koji izgubi trku otkazuje se kroz redovan put. Kad su dva telefona za istim stolom u isti tren tražila kod za iste stavke, kod koji je izgubio upisivao se kao otkazan direktno u bazu, bez događaja, webhooka i zapisa u dnevniku, pa je vremenska linija u konzoli pokazivala "kreiran" na kodu koji je čitao "otkazan". Sada ide kroz isti put kao svako otkazivanje.
        • Bakšiš koji je vraćen gostu ne računa se kao zadržan za osoblje. Povrat ide prvo iz bakšiša, ali knjiga bakšiša je i dalje brojala vraćeni bakšiš kao prikupljen i zadržan. Sada se za svaki račun sa povratom oduzima ono što je vraćeno, najviše do iznosa bakšiša.
        • Poslovni planovi kažu da imaju izvoz izvještaja. Izvoz u CSV i PDF postoji i prodaje se na planovima Business i više, a odgovor API-ja o planu je za njih govorio da izvoza nema. Sada govori da ga ima. Sam izvoz i dalje radi za sve planove sa analitikom, dakle i Start i Flex; da li treba, odluka je vlasnika, ne koda.

        0.55.9

        16. septembar 2026.

        Popravke

        • Pošta na portu 465 bez izričitog SMTP_SECURE ide kroz TLS. Kontejner dobija SMTP_SECURE kao prazan tekst kad ga niko nije upisao, a prazan tekst se čitao kao "nije sigurno", pa se port 465, koji od prvog bajta govori TLS, otvarao bez TLS-a i čekao trideset sekundi na pozdrav koji nikad ne stigne, za svaku poruku. Baš to je podešavanje koje uputstvo preporučuje. Prazan tekst sada znači "nije rečeno", pa odlučuje port; izričito true ili false i dalje važe. Produkcija koristi 587 i nije bila pogođena.
        • Status stranica ne javlja "Ne radi" zbog tihog dana. Izvor uplata koji 24 sata nije donio uplatu brojao se kao zamro, i to od trenutka kad ga operater poveže, jer nov izvor nema ni jednu uplatu; sa jednim izvorom to je cijeli XPay na javnoj stranici pisalo "Ne radi". Tih dan je sada upozorenje, ne kvar, i broji se tek od dana poslije povezivanja. "Ne radi" ostaje za izvore koji javljaju grešku ili se ne mogu pročitati.
        • Provjera spremnosti servera ne objavljuje interne poruke. Javna ruta readyz ispisivala je tekst greške baze, sa imenom hosta i korisnika. Sada piše samo "error", a tekst ide u dnevnik servera.
        • Zahtjev za update bilježi pravu verziju. Poslije svakog ručnog restarta kontejner ne zna verziju ni commit (0.0.0, prazno), a zahtjev za update je to upisivao u dnevnik. Sada i on čita fajl koji install.sh ostavlja pri svakom deployu, isto kao status stranica.
        • restore.sh vraća kopiju. psql 17 odbija način rada koji je skripta tražila bez fajla ("-1 can only be used in non-interactive mode"), pa je svaki povrat padao prije prve naredbe i ispisivao poruku o vraćenoj bazi nad netaknutom bazom. Uz to, kopija napravljena prije migracije koja je dodala tabelu padala je na "drugi objekti zavise". Skripta sada prvo isprazni šemu pa učita kopiju u jednoj transakciji, a migracije je dovedu do tekuće verzije.
        • doctor.sh gleda pravi direktorij za slike. Testirao je putanju kakvu vidi kontejner (/data/media) na hostu, pa je na svakoj docker instalaciji javljao da direktorij ne postoji i nudio pogrešan popravak; provjera pisanja radila je kao root umjesto kao korisnik kontejnera. Sada preslika putanju na host i probu pisanja radi iz kontejnera kad je podignut.
        • install.sh ne pada u grani koja treba samo da upozori. Grana za "postoji drugi postgres volumen" zvala je nedefinisanu funkciju info, pa je pod set -e prekidala instalaciju umjesto da upozori i nastavi.
        • Updater ne traži certifikat za www koji niko nije objavio. Otkucaj updatera javljao je "Bez HTTPS-a" za www.<domena> i app.<domena> kad god nemaju certifikat, i kad install.sh nije ni trebao da ih traži. Sada traži domenu, host konzole kakav je install.sh zabilježio, a www samo ako postoji DNS zapis.

        0.55.8

        16. septembar 2026.

        Popravke

        • Faktura je dospjela tek kad prođe cijeli dan roka. Kod za plaćanje uz fakturu istjecao je u prvom trenutku dana roka, a posao koji svake minute gasi istekle kodove označavao je fakturu kao dospjelu u ponoć, cijeli dan prije nego što je kupac iskoristio dan koji mu pripada. Kod sada istječe na kraju dana roka, stanje fakture gleda dan a ne minutu, a lista faktura i stanje na svakoj od njih računaju dan isto.
        • Rok upisan kao dan piše se kao taj dan. "15.09." se čuvao kao kraj tog dana po svjetskom vremenu, što je u Sarajevu dva sata ujutro 16.09., pa su PDF, stranica za kupca i mail, koji datum pišu po zoni lokala, štampali "16.09.2026." za rok upisan kao petnaesti. Rok se sada čita u zoni lokala.
        • Storniranje fakture ne prolazi ako je novac u međuvremenu stigao. Provjera novca bila je izvan transakcije, pa je uplata uparena u tom trenutku ostavljala plaćenu fakturu označenu kao storniranu, sa lažnim zapisom o otkazivanju koda. Storniranje sada uslovljava da je kod još otvoren i odbija ako nije; ponovljeno storniranje kaže da je već stornirano.
        • Godišnja pretplata podrazumijevano naplaćuje dvanaest mjeseci. Podrazumijevani iznos za godišnji plan bio je deset mjesečnih cijena, što ugovor koji lokal potpisuje izričito isključuje. Konzola uvijek šalje iznos, pa je to pogađalo samo API poziv bez iznosa; sada je dvanaest.
        • Uključene transakcije se računaju po periodu koji se naplaćuje. Naknada za produženje množila je mjesečni uključeni broj brojem mjeseci koji se prodaju, a brojala je transakcije od zadnje fakture. Lokal produžen za tri perioda poslije mjesec dana rada dobijao je tri mjeseca uključenih transakcija za jedan mjesec korištenja, a lokal produžen za jedan period poslije četiri mjeseca rada plaćao je prekoračenje za volumen koji je plan već pokrivao. Sada se uključeni broj računa po mjesecima korištenja.
        • Probni nalog dobija ključ licence na 48 sati, kao i rok. Prijava sa sajta skraćivala je rok na 48 sati poslije kreiranja, a ključ licence ostajao je na 30 dana; konzola je prikazivala jedno pored drugog. Rok ide u kreiranje, pa ključ i rok nose isti datum.
        • Istekla licenca više ne piše "još 0 dana" prvog dana. Zaokruživanje je prvog dana po isteku davalo nulu, pa je pregled pretplata pokazivao "ističe uskoro" za licencu koja je već istekla, dok su ostali ekrani govorili isteklo. Stanje licence sada računa jedna funkcija, sa testovima.
        • Broj XPay fakture se uzima pod bravom i po godini lokala. Dva produženja u istom trenutku čitala su isti zadnji broj i drugo je padalo na jedinstvenom indeksu; godina se uzimala po satu servera pa je faktura izdata između 23 i 24 sata 31. decembra po svjetskom vremenu nosila staru godinu uz datum 01.01. Broj sada čeka na brave i računa najveći broj brojčano, a godina je sarajevska, kao na fakturama lokala.
        • Plaćena stara faktura ne vraća isteklu licencu u "aktivno". Oznaka kašnjenja postavlja se kad licenca istekne, ne kad faktura kasni; plaćanje stare fakture brisalo je oznaku i jutarnji posao je vraćao. Sada se briše samo dok licenca još važi, a komentari uz rok plaćanja opisuju ono što kod stvarno radi (rok osam dana, bez grejs perioda).

        0.55.7

        16. septembar 2026.

        Dokumentacija

        • README nabraja planove koji postoje. Pisalo je "Free, Pro, Enterprise i Flex" i jedna cijena po transakciji; planovi su Flex, Start, Business, Pro i Enterprise, svaki sa uključenim brojem transakcija, a cijena preko toga zavisi od plana. Sada piše tačno ono što stoji na sajtu i u kodu.
        • Vodič za prodaju više ne obećava promet po konobaru. Pisalo je da se u izvještaju vidi "ko je koliko naplatio"; izvještaj "Ko je radio" namjerno pokazuje broj zatvorenih računa i gotovinu kroz ruke, ne promet po konobaru. Vodič sada kaže to, i upućuje na uputstvo za ekrane osoblja gdje je objašnjeno zašto.
        • Vodič za kasu: opsezi API ključa. Changelog za 0.52.0 upućivao je na ovaj vodič za popis opsega, a popis je postojao samo u engleskom uputstvu. Sada je i ovdje: šta nosi ključ iz konzole, koje opsege treba tražiti posebno i šta odgovara ruta kad ključ nema opseg.
        • Vodič za kasu: naljepnica na stolu. Pregled na vrhu još je govorio da gost sam upisuje iznos, iz vremena kad je to bio jedini način; naljepnica danas radi i za naručivanje i za plaćanje, a uplata se sama veže za sto.
        • Primjer okruženja ne tvrdi verziju. .env.example je nosio "0.37.3" kao verziju, pa je razvojna kopija prijavljivala staro izdanje; sada je 0.0.0, isto što kod uzima kad build fajla nema, a install.sh upisuje pravu.
        • Vodič za proizvođače kasa: imena profila i vrste adaptera. Pisalo je da su četiri načina povezivanja implementirana, ali ne i da su imena profila jedno, a vrijednosti kind u xpay-connector.yaml drugo. Sada su nabrojane jedne uz druge.
        • Uputstvo za instalaciju: promjena lozinke operatera. Pisalo je da skripta traži novu lozinku dva puta; traži je jednom, bez prikaza na ekranu.

        0.55.6

        16. septembar 2026.

        Popravke

        • Suspendovan lokal je suspendovan i za svoje ljude. Kad operater suspenduje lokal, API ključevi i terminali su odmah odbijani, ali korisnici konzole istog lokala nisu: mogli su i dalje izdavati QR kodove i primati narudžbe. Sada i oni dobijaju odgovor da licenca nije aktivna; podrška i dalje može otvoriti pregled tog lokala.
        • Rute koje nisu rekle ko ih smije zvati. Lista lokacija i lista bankovnih izvora nisu tražile ni ulogu ni opseg, pa ih je mogao čitati i token kuhinjskog ekrana, koji stoji u pregledniku na zidu. PDF fakture, pregled, primjer i unos primaoca tražili su ulogu bez opsega, a API ključ sa bilo kojim opsegom za pisanje računa se kao menadžer, pa je ključ samo za narudžbe mogao preuzeti svaku fakturu sa imenom, adresom i ID brojem kupca; isto za izmjenu lokacije (isključivanje, promjena QR profila) i za mjesečnu potrošnju. Sve te rute sada traže opseg koji već nose svi obični ključevi i konzola; nov test prolazi kroz kontrolere i pada čim se pojavi ruta bez ugovora.
        • Zaključavanje prijave se resetuje kad istekne. Osam pogrešnih lozinki zaključa nalog na petnaest minuta, ali brojač se nije vraćao na nulu: prva pogrešna lozinka poslije isteka pravila je devetu i ponovo zaključavala, pa je jedan pogrešan pokušaj svakih petnaest minuta držao nalog zaključan zauvijek. Istekla brava je gotova; brojanje kreće iznova.
        • Zaključan nalog odgovara jednako sporo kao svaki drugi. Odgovor za zaključan nalog stizao je za milisekundu, dok provjera lozinke traje desetine milisekundi, pa se po satu moglo zaključiti da nalog postoji. Sada se troši isto vrijeme.
        • Webhook adresa sa IPv6 zapisom više ne prolazi zaštitu. Provjera je poredila "::1" sa vrijednošću koja u zagradama glasi "[::1]", pa nijedna IPv6 adresa privatne mreže nije bila odbijena, a ni "localhost." sa tačkom na kraju. Zagrade i tačka se skidaju, a IPv6 adrese se odbijaju u potpunosti: nijedan lokal ne treba webhook na golu adresu.
        • Izmjena lokacije ostavlja trag. Bila je jedina izmjena lokacije bez zapisa u dnevniku; sada piše ko je i šta mijenjao.

        0.55.5

        16. septembar 2026.

        Popravke

        • Uplata koja stigne kroz dva kanala više se ne knjiži dva puta. Kad isti prenos stigne i webhookom i u izvodu, sistem otvori slučaj "dupla uplata". Dugme Poravnaj na tom slučaju dodavalo je novac drugi put: račun od 60,00 KM na koji je stiglo 30,00 KM postajao je plaćen za 60,00 KM. Sada Poravnaj samo zabilježi da je i drugi kanal vidio isti prenos, bez novog novca. Ako se zaista radi o drugom prenosu istog iznosa, put je Odbaci pa Priključi iz liste neuparenih uplata, gdje se dodaje kao nov novac.
        • Jedna uplata ne može stajati na dva računa. Kredit koji je već zabilježen na jednom računu mogao se preko API-ja priključiti ili poravnati na drugi, pa je njegov novac ostajao na oba. Sada se odbija, uz ime računa koji ga drži.
        • Kredit u drugoj valuti ne ide na račun u KM. Ručno priključivanje i poravnanje nisu gledali valutu, pa je 1000 najmanjih jedinica eura moglo postati 10,00 KM. Sada se odbija.
        • Izvod bez vremena, samo sa datumom, uparuje se i po iznosu. Kad banka u izvodu da samo dan, uplata stiže kao ponoć tog dana, pa je račun napravljen u podne izgledao kao da je nastao poslije uplate i uparivanje po iznosu ga je preskakalo. Sada gleda cijeli dan, kao što je uparivanje po pozivu na broj već radilo.
        • Ručna potvrda druge rate više se ne prijavljuje kao dupla uplata. Kad je osoba ručno potvrdila drugu polovinu računa, jednaku prvoj koja je stigla iz banke, sistem ju je tretirao kao isti prenos viđen dva puta, javljao "nije potvrđeno" i ostavljao uplatu u provjeri bez slučaja koji se igdje vidi. Osoba koja imenuje račun nije drugi kanal.
        • Faktura plaćena trećeg dana nalazi svoj račun. Kandidati za uparivanje birali su se samo među računima napravljenim u zadnjih 24 sata, pa faktura plaćena kasnije, i sa tačnim pozivom na broj u opisu, završavala kao neuparena bez slučaja. Sada se gledaju i računi kojima još teče rok i svaki račun čiji poziv na broj stoji u opisu uplate, ma koliko star.
        • Webhook banke sa nepoznatom valutom dobija jasan odgovor. "GBP" ili brojčani kod "977" prolazili su provjeru i rušili obradu, pa je banka dobijala grešku 500 i ponavljala zauvijek. Sada dobija 400 sa razlogom i listom valuta koje se prihvataju.
        • Filter otvorenih potraživanja radi i za "false". Upit open=false vraćao je samo otvorene stavke, suprotno od traženog. Sada vraća sve, kao i bez filtera; prihvataju se samo riječi true i false.
        • Naljepnica stola: sumnja na duplu uplatu ide na provjeru, ne spaja se tiho. Kad isti prenos na naljepnicu stigne kroz dva kanala bez bankovnog identifikatora, prepoznavao se samo ako je vrijeme bilo do milisekunde isto, što webhook i izvod nikad nemaju, pa je nastajalo drugo plaćeno plaćanje i promet je bio dvostruk. Sada se gleda isti dan, a takav par ide osobi na provjeru, jer isti iznos istog dana može biti i drugi gost.
        • Uvoz izvoda više ne baca uplate. Identifikator uplate uzimao se i iz polja koje popunjava banka platioca, a ono kod više banaka na svakoj liniji glasi NOTPROVIDED. Prva takva uplata iz izvoda bila je upisana, svaka sljedeća tiho odbačena kao "već poznata". Sada se identifikator uzima samo iz oznaka koje daje naša banka.
        • Iznos kao broj podliježe istom pravilu kao iznos kao tekst. API je 12.345 poslano kao broj zaokruživao na 12,35, dok je iste cifre kao tekst odbijao; dokumentacija je obećavala odbijanje. Sada se i broj odbija ako ima više od dvije decimale.

        0.55.4

        16. septembar 2026.

        Popravke

        • Kuhinjski ekran zvoni i za prvi tiket dana. Ekran uključen prije početka smjene učitao je praznu listu, pa prvi tiket koji je stigao nije oglasio; drugi je. Sada zvoni za svaki tiket koji stigne poslije prvog učitavanja, a ne zvoni za one koji su već bili na ekranu kad je uključen, ni za otkaz stariji od ponovnog pokretanja.
        • Jelo koje je jučer prebrojano do nule može se naručiti danas. Meni ga je prikazivao kao dostupno, jer broj porcija vrijedi za dan kad je unesen, a narudžba ga je odbijala kao rasprodano jer je gledala u jučerašnji broj. Jučerašnji ostatak se uz to tiho smanjivao današnjim narudžbama. Narudžba sada gleda samo današnji broj, isto kao meni.
        • Narudžba koju je gost već platio ne može se otkazati. Kod "plaćam svoje" veže linije za uplatu, a otkazivanje te narudžbe je prolazilo jer je provjera gledala samo ukupne iznose stola. Gost bi platio jelo koje nikad nije napravljeno, bez traga o tome. Otkazivanje sada odbija i kaže da se novac vraća povratom uplate; konzola to ispisuje razumljivo.
        • Uplata na račun zatvoren kao "plaćeno prenosom" knjiži se kao uplata. Konobar zatvori sto kao prenos kad mu gost pokaže ekran banke. Kad je novac zatim stigao, sistem ga je označavao kao vjerovatno dvostruko plaćanje, a sto je u izvještaju imao nula prometa. Sada se takva uplata knjiži do iznosa računa; samo ono što bi prešlo iznos i dalje ide na provjeru.
        • Dvostruki tap na "Pošalji" više ne javlja narudžbu dva puta. Kad su dva ista zahtjeva stigla u isti tren, gubitnik je ponovo oglasio pobjednikovu narudžbu (zvono, webhook, dnevnik) ako je bila mlađa od sekunde i po, a prava nova narudžba koja je duže čekala na broj ostala je neoglašena. Sada se oglašava samo ona koja je stvarno upisana.
        • Stavka bez stanice (ni kuhinja ni šank) ne blokira tiket. Tiket sa vodom ili čipsom čekao je stanicu koju nijedan ekran ne može označiti kao gotovu, pa se mogao završiti samo iz konzole.
        • Stari kod stola ne može se vratiti dok je novi za isti sto aktivan. Vraćanje povučenog koda pored aktivnog ponovnog otiska pravilo je dva aktivna stola istog imena i dva odvojena računa. Sada se odbija, sa objašnjenjem u konzoli i u API-ju.
        • POS: "Očisti" zaboravlja ključ prodaje. Ispravljen skup stavki sa istim iznosom bio je odbijen kao ponovljen zahtjev sa drugim sadržajem, sve dok se iznos ne promijeni. Terminal je to radio ispravno; POS sada isto.
        • Gostova stranica: podjela računa se vraća na cijeli račun kad se kod napusti. Izabrani dijelovi, broj dijelova i bakšiš ostajali su u memoriji, pa je "Na 3", pa Nazad, pa dugme banke pravilo kod za trećinu dok je ekran pokazivao cijeli račun, a linije plaćene ranijim kodom slane su ponovo i odbijane. Uz to: kod se više ne zaboravlja zbog prekida veze ili preopterećenja, nego samo kad server kaže da ga nema; poslije kratke uplate glavno dugme je opet "Plati", a tekst kaže da se cijeli iznos ne plaća ponovo; odbijenica "neko već drži kod" ima svoju rečenicu; kopiranje IBAN-a i poziva na broj izgovara "Kopirano" čitačima ekrana; datum na traci o starom meniju piše se kao i svi ostali datumi.
        • Bosanski oblici. "5 stavki" umjesto "5 stavke" u opisu uplate koji gost vidi u aplikaciji banke (isto pravilo sada dijele svi ekrani), "2 stavke su skinute" i "5 stavki je skinuto" u poruci o promjeni menija, a svrha plaćanja u QR kodu više ne ponavlja ime stola.

        0.55.3

        16. septembar 2026.

        Popravke

        • Račun preko 5.000,00 KM izlazi bez QR koda, i kaže zašto. Instant plaćanje u BiH prima najviše 5.000,00 KM odjednom i samo u KM (IPS BiH, član 13). Račun za veći iznos je sasvim običan i kupac ga plaća običnim prenosom, pa se račun izdaje kao i do sada: broj, poziv na broj, račun primaoca, PDF i stranica za kupca. Ono što se više ne štampa je QR kod, jer bi ga svaka bankarska aplikacija odbila na ekranu na kojem nema ni riječi od XPay-a, a kupac ne bi znao zašto. Na mjestu koda, i u PDF-u i na stranici za kupca, stoji rečenica koja kaže granicu i upućuje na prenos uz poziv na broj. Isto važi za račun u valuti koju instant plaćanje ne prima. Naplata za stolom je ovu provjeru imala od ranije; računi je nisu imali. Važi i za račune preko granice izdate prije ove verzije: od sada se i oni prikazuju bez koda, sa istom rečenicom, jer se pitanje postavlja računu, a ne samo zabilješci uz njega. Mail kupcu više ne obećava QR kod kad ga nema, nego ponavlja tu rečenicu, a u konzoli uz poziv na broj piše da je račun izašao bez koda i zašto. Djelimično plaćen račun preko granice zadržava pravi razlog, umjesto rečenice o kodu koji nikad nije ni postojao.

        0.55.2

        13. septembar 2026.

        Popravke

        • Ključ za ponavljanje zahtjeva (Idempotency-Key) važi jedan dan, kako i piše, a ne zauvijek. Kasa koja pošalje isti zahtjev dva puta sa istim ključem dobije isti odgovor umjesto drugog plaćanja; to je svrha ključa. Svaki zapis se upisivao sa rokom od 24 sata, ali rok niko nije čitao niti brisao: tabela je samo rasla, a ključ koji je kasa upotrijebila jednom bio je "već iskorišten" i godinu dana kasnije. Kasa koja kao ključ koristi broj računa, što je najčešći način, dobila bi odbijenicu umjesto novog QR koda čim se brojevi računa ponove. Sada istekli zapis znači da je ključ opet slobodan, a server jednom dnevno briše sve istekle zapise.

        0.55.1

        13. septembar 2026.

        Popravke

        • Kontrolni broj u pozivu na broj sada je pravi kontrolni broj po modelu 97. Dvije cifre ispred poziva na broj računale su se po formuli koja je bila dosljedna sama sebi, ali nije bila model 97. Za primjer koji stoji u uputstvima svake banke, poziv 016 sa kontrolnim brojem 50, XPay je računao 48. Banka koja provjerava model 97 pri unosu naloga ili pri skeniranju koda mogla je odbiti svaki naš poziv na broj, a gost bi vidio samo da njegova aplikacija neće. Od sada se kontrolni broj računa onako kako ga banke provjeravaju: ISO 7064 MOD 97-10, ispisan ispred broja.
        • Stari pozivi na broj se i dalje prepoznaju. Uparivanje uplata prima i pozive na broj sa stare formule, pa novac koji stigne po ranije izdatom računu ili po staroj naljepnici i dalje nađe svoj račun. U pregledu uplate takav poziv je označen kao stari oblik, da se vidi kad ih više nema. Naljepnice za stolove odštampane prije ove verzije nose stari kontrolni broj, pa ih treba ponovo preuzeti iz konzole i zalijepiti čim bude prilike.

        0.55.0

        13. septembar 2026.

        Novo

        • Gost koji skenira naljepnicu otvara aplikaciju, ne web stranicu. Prvi ekran je fotografija preko cijelog telefona sa imenom lokala krupno preko nje, logom u uglu, stolom i jezikom na dohvat palca. Lokal koji nema naslovnu fotografiju dobije najbolje slikano jelo sa svog menija, jer je tanjir njihove hrane bolja naslovna od bilo koje boje. Ispod su pozdrav, dugme za poziv konobara, najtraženija jela kao velike kartice sa cijenom na fotografiji i kategorije kao pločice sa brojem jela.
        • Meni sa ljepljivim zaglavljem i kategorijama koje se čitaju bez čitanja. Dok se jela listaju, na vrhu ostaju ime lokala, sto i red kategorija, svaka sa okruglom fotografijom nečega iz nje; ona u kojoj se gost nalazi svijetli u boji lokala. Svako jelo je kartica sa fotografijom, imenom, opisom i cijenom, a dugme za dodavanje postaje brojač čim je jelo u korpi, pa druga porcija i predomišljanje ne traže otvaranje korpe.
        • Detalj jela, korpa, račun i plaćanje u istom duhu. Fotografija jela puni vrh panela sa imenom preko nje, dodaci su kartice sa oznakom "Obavezno", količina i napomena imaju svoje kartice, a dugme sa cijenom stoji na dnu ekrana. Korpa je traka preko cijele širine sa brojem, nazivom i iznosom. Narudžbe pokazuju dokle je stigao tiket kao liniju koja se puni: poslano, preuzeto, priprema, gotovo, na stolu. Načini plaćanja imaju ikone, a ekran sa QR kodom, iznosom i podacima za ručni prenos je bijela kartica sa dugmadima za kopiranje.
        • Jedan font za gosta. Plus Jakarta Sans, sa pravim težinama od običnog do najdebljeg i sa našim dijakritičkim znakovima, preuzet pri gradnji i posluživan sa našeg servera; telefon gosta nikad ne pita Google ni za šta. Konzola ostaje na svom fontu.

        0.54.3

        10. septembar 2026.

        Popravljeno

        • Uspješno slanje brisalo je upozorenje o sporom serveru pošte. Slanje otvara istu vezu i čeka isti pozdrav kao i provjera, ali je poslije uspjeha bilježilo samo "radi", pa je status stranica poslije svakog poslanog računa skakala sa "sporo" na "radi" i nazad na sljedećoj provjeri. Slanje se sada mjeri kao i provjera, pa upozorenje stoji dok kašnjenje traje.

        0.54.2

        10. septembar 2026.

        Popravljeno

        • Pošta nije išla jer je server pošte odgovarao tek nakon petnaest sekundi, a sistem je čekao deset. Server pošte tako dočekuje pošiljaoca čija adresa nema reverzni DNS zapis (PTR): veza se otvori, a pozdrav stigne kasno. Deset sekundi čekanja pretvaralo je to u "server nije odgovorio" na svakom računu, na vezi koja bi prošla. Sistem sada čeka pozdrav do trideset sekundi, pa pošta ide; a kad odgovor stigne sporo, status stranica to kaže kao upozorenje i imenuje ko šta popravlja: hosting provajder treba da postavi PTR zapis za adresu servera.
        • Jučerašnja dijagnoza "hosting provajder filtrira SMTP portove" bila je pogrešna. Provjera je gledala samo da li se veza otvori i da li stigne pozdrav u deset sekundi, pa je sporog domaćina pročitala kao zatvoren port. Ista provjera je ranije, sa još kraćim čekanjem, pisala isto. Provjera sada broji i sporog domaćina, a "nijedan port ne odgovara" kaže samo kad je zaista probala svaki port; ako je vrijeme isteklo prije toga, kaže da nije stigla.
        • Odbijeni certifikat se računao kao tišina. Port koji progovori TLS-om i pokaže certifikat je odgovorio, makar mu se ne vjerovalo; provjera ga je brojala kao da niko nije odgovorio i krivila hosting provajdera. Sada kaže da port radi, a certifikat glasi na drugo ime ili mu se ne vjeruje, i to razlikuje i u uputi operateru.
        • Neuspjelo slanje računa čitalo se po riječima, a ne po tome gdje je puklo. Server koji odbija pošiljaoca ili prenos često to kaže tek kod primaoca, i stranica bi to progutala kao "pogrešna adresa kupca". Sada se gleda faza SMTP razgovora koju server imenuje: odbijena prijava ili pošiljalac je kvar pošte, odbijen primalac je greška u adresi, a odbijena poruka (kao neželjena ili prevelika) je upozorenje, ne kvar. Prenešeni zaključak probe ne vraća sat unazad, pa se proba ponovo pokrene kad joj je vrijeme.
        • Operaterska konzola sada pokazuje šta je server pošte zadnje rekao, prije nego što se išta pritisne. Status stranica je za razlog upućivala na taj ekran, a on je pokazivao četiri podešavanja i dugme.

        0.54.1

        10. septembar 2026.

        Popravljeno

        • Status stranica je za svaki kvar pošte pisala da server pošte odbija slanje. Ista rečenica je stajala i kad server pošte uopšte nije odgovorio, jer hosting provajder filtrira SMTP portove, i kad ime servera ne postoji, i kad certifikat glasi na drugo ime. Nijedno od toga nije odbijanje, i svako popravlja neko drugi. Provjera sada razlikuje sedam stanja i stranica za svako kaže samo ono što je stvarno utvrđeno i ko treba šta da uradi: odbijena prijava ili adresa pošiljaoca, filtrirani portovi kod hosting provajdera, server koji se ne može dosegnuti ni na jednom portu, ime servera koje ne postoji u DNS-u, pogrešan port ili način šifriranja, certifikat na drugo ime, i certifikat kojem se ne vjeruje.
        • Pogrešno ukucana adresa kupca više ne gasi poštu na status stranici. Server pošte je primio prijavu i odbio jednu adresu; to je odgovor o toj adresi, ne o pošti, a stranica ga je pet minuta pokazivala kao kvar sa uputom da se provjere podešavanja koja su bila ispravna. Isto tako, račun koji ne ode jer je port filtriran više ne briše utvrđeni uzrok: status je i dalje "filtrirani portovi", a ne "nepoznato".
        • Probna poruka u konzoli je javljala grešku preglednika umjesto odgovora servera pošte. Kad podešeni port ne odgovara, sistem proba i ostale portove da bi rekao čija je greška, i to traje do minutu; dugme je odustajalo poslije dvadeset sekundi i ispisivalo "TimeoutError: signal timed out", rečenicu o pregledniku na ekranu čiji je jedini posao da pokaže šta je rekao server pošte. Dugme sada čeka odgovor, a uputa pored njega kaže da provjera može potrajati.
        • Veza koja se nikad ne otvori nije probala port 26. Provajder koji filtrira SMTP ne odbija paket nego ga proguta, i to se javlja kao istek vremena, a ne kao neuspjelo rukovanje; provjera je u tom slučaju odmah odustajala bez ikakvog objašnjenja umjesto da proba portove koje takav provajder obično ostavi otvorene. Sada proba, kaže koje je portove probala, i stane na vrijeme ako server ima više adresa pa svaka proba traje duže.

        0.54.0

        10. septembar 2026.

        Popravljeno

        • Korpa gosta ipak nije preživljavala izlazak sa stranice. Ono što je 0.50.0 obećalo, radilo je u testu i nije radilo u pretraživaču: prvi prikaz stranice ima praznu korpu, a kod koji korpu čuva pri svakoj promjeni zapisao je tu prazninu prije nego što je meni uopšte stigao - pa je korpu koju je trebao sačuvati brisao isti taj kod, svaki put, sekundu prije nego bi je vratio. Nađeno tako što je stranica napuštena i vraćena, što je jedino čemu ta funkcija služi. Sada se ništa ne zapisuje dok se stara korpa ne vrati.
        • „Osoblje je vidjelo vašu narudžbu i priprema je" pisalo je u trenutku pritiska na Pošalji. Tada je jedino tačno bilo da je server primio narudžbu; niko je još nije vidio. Ekran sada kaže „Stiže kuhinji" i mijenja se u „Osoblje je vidjelo" onog trenutka kada neko na ploči pritisne Prihvati - provjereno u obje kartice.
        • „Račun se zatvara čim banka potvrdi" na izboru plaćanja. Tačno gdje je banka povezana, netačno svugdje drugdje - a u pilotu je to običan slučaj. Lokal bez veze sa bankom sada kaže „Račun zatvara osoblje kada vidi uplatu".
        • Konzola je za kod za povezivanje pisala „važi još 525462 min". Pravi kod živi 30 minuta i tu je odbrojavanje bilo u redu; kod iz probnih podataka živi godinu i tekst je izgledao kao da je konzola poludjela. Ispod sata pišu minute, ispod dana sati, iznad toga datum. I zaokružuje se nadolje: kod sa 29:50 kaže 29, a ne 30.
        • Ploča koju niko nije dodirnuo sada to kaže prije prve narudžbe. Traka „Dodirnite ekran da uključite zvuk" dizala se tek kada zvono pokuša i ne uspije - dakle kada je narudžba već stigla u tišini, baš one večeri zbog koje traka postoji. Sada se pretraživač pita pri paljenju.

        0.53.0

        10. septembar 2026.

        Novo

        • Status stranica sada pokazuje put uplate kroz sistem, a ne samo spisak dijelova. Naslov je stanje, ispisano krupno i u boji stanja, a cijela stranica je osvijetljena tom bojom: onaj ko dođe usred incidenta vidi drugu sobu prije nego što pročita ijednu riječ. Ispod naslova su dijelovi sistema poredani onako kako ih uplata zaista prolazi: baza, sravnjivanje, ekrani uživo, obavijesti kasi, e-mail, slike i sigurnosne kopije. Sa svakim odgovorom svjetlo pređe tu liniju i stane na prvom dijelu koji ne radi; ono što je iza njega crta se isprekidano, jer dotle ništa ne stiže.
        • Odziv sistema se mjeri u tvom pregledniku. Jedini broj na stranici koji nije riječ sistema o samom sebi: koliko je odgovor trebao da stigne, sa linijom svih prethodnih, pa spor odgovor strši kao vrh a ne kao broj koji treba upamtiti. Prsten pored sata pokazuje koliko je ostalo do sljedeće provjere, umjesto da se to samo tvrdi u fusnoti.
        • Otisak izdanja stoji uz verziju, datum puštanja i broj izdanja u jednom pečatu, i mijenja se sa svakim puštanjem.

        Promijenjeno

        • Historija verzija otvara zadnjih šest. Na stranici je bilo svako izdanje ikad pušteno, što ju je učinilo dugom preko šezdeset hiljada piksela i smjestilo podnožje tamo gdje niko ne dođe. Starije verzije su iza jednog klika, na istoj liniji, bez ikakve skripte.

        0.52.0

        10. septembar 2026.

        Popravljeno

        • API ključ izdat samo za plaćanja mogao je mijenjati meni, stolove i zalihe. Te rute su bile zaštićene samo ulogom, a ključ koji drži bilo koji :write opseg rangira se kao menadžer - pa je ključ sa kase mogao preimenovati jelo, ukloniti sto i otpisati zalihe. Najgore od svega: označavanje jela kao rasprodanog je namjerno otvoreno osoblju, a ključ bez ijednog :write opsega rangira se kao osoblje - pa je ključ samo za čitanje mogao skinuti cijeli meni sa prodaje.

        0.51.1

        10. septembar 2026.

        Popravljeno

        • Datum isplate napojnica pisao je 2026-09-10 umjesto 10.09.2026. Jedini red u konzoli koji je datum pisao drugačije od svih ostalih.

        0.51.0

        10. septembar 2026.

        Novo

        • Napojnice: koliko je stiglo, koliko je isplaćeno, i koliko lokal još drži. Napojnica koju gost doda pri plaćanju QR-om stiže u istom prenosu sa iznosom računa. Na izvodu je jedan iznos, a XPay ga oduvijek drži razdvojen: Iznos i Napojnica su dvije kolone na plaćanju i dvije kolone u knjigovodstvenom izvozu, račun se zatvara iznosom naručenog, i faktura napojnicu nikada ne nosi.

        0.50.0

        9. septembar 2026.

        Popravljeno

        • Limit od 5.000 KM se gasio zajedno sa QR formatom. Provjera je gledala u koji je dijalekt kod napisan. A dokumentovani izlaz iz nepotvrđenog BIH_IPS profila je prebacivanje lokala na EMVCO_MPM - čime se gasio i limit, i pravilo da nalog glasi samo na KM. Društvo od dvadeset zatraži jedan kod za cijeli račun od 5.400,00 KM, XPay ga uredno nacrta, a odbijenica se desi unutar bankovne aplikacije, na ekranu na kojem ne piše XPay, iz razloga koji niko u sali ne može pročitati.
        • Povrat je tražio broj naloga iz banke, a račun na koji se vraća nije bio nigdje. Vlasnik otvori Naplatu, nađe račun, pritisne Povrat. Piše, tačno, da XPay ne prenosi novac i da povrat šalje iz svoje banke - pa mu treba broj računa, kojeg nema ni na plaćanju, ni u izvozu, ni na Usklađivanju, jer se ta uplata uredno uparila i nikada nije ni došla u red za pregled. Završi tako što gosta zamoli da mu IBAN napiše na salveti, pred vlasnikom lokala kojem je pokazivao kako je sve uredno.
        • gotovina, ručna potvrda - ne piše ništa, umjesto praznog polja.
        • Korpa gosta je živjela samo u memoriji stranice. Gost dodirne ćevape, otvori se list sa sastojcima, on povuče prstom sa ivice da ga zatvori - jer je to na Androidu način da se list zatvori - i pretraživač umjesto toga napusti stranicu. Kada se vrati, osam stvari koje je izabrao više nema, i ništa na ekranu ne pokazuje da ih je ikada bilo. Počinje ispočetka ili zove konobara.

        0.49.0

        9. septembar 2026.

        Popravljeno

        • Otkazana narudžba je nestajala sa kuhinjske ploče bez riječi. Kuhar je pritisnuo „U pripremi" za sto 9, meso je na roštilju, a vlasnik u međuvremenu otkaže tu narudžbu iz konzole na laptopu. Kartica nestane usred servisa. Kuhar podigne pogled, vidi da je nema, i zaključi da ju je sam obrisao - pa ili nastavi kuhati ono što niko neće platiti, ili prestane kuhati ono što neko i dalje čeka.
        • Gost koji pozove osoblje nije proizvodio nikakav zvuk. Vlasnik sjedne za svoj sto i pritisne „Pozovi osoblje" da pokaže kako radi. Njegov telefon kaže da neko dolazi. U kuhinji se u tišini pojavi mala crvena oznaka, dok je šanker okrenut aparatu za kafu a kuhar roštilju, i brojač na njoj raste. Poziv sada zvoni, svojim zvukom, i ponavlja se svake minute dok neko ne ode.
        • Ploča koju niko nije dodirnuo od paljenja bila je nijema, a ikona je govorila da je zvuk uključen. Tablet je na zidu i pretraživač se sam otvara na /display. Osoblje ujutro upali struju i niko ne dodirne staklo, jer nema šta pritisnuti. U 19:40 stigne prva narudžba - bez zvuka, na ekranu okrenutom leđima roštilju. Sada preko vrha stoji „Dodirnite ekran da uključite zvuk", a ikona je precrtana dok pretraživač drži zvuk. Otključavanje sluša i dodire na dugmadima kartica, koji ranije nisu dopirali do njega.
        • Ekran koji se ne može držati budnim to sada kaže. Web API za to postoji samo na HTTPS-u, a dokumentovana instalacija zna biti običan HTTP na lokalnoj mreži - pa je obećanje „ekran se ne gasi" baš tamo gdje treba ćutke ništa ne radilo. Sada stoji napomena da se u postavkama tableta stavi „Nikad".
        • Sa zidnog ekrana su nestali iznosi. Uputstvo koje vlasnik dobije kaže da se na tom ekranu ne vidi novac, a oznaka je pisala „Sto 4 - keš - 23,50 KM", čitljivo sa susjednog stola. Sada piše sto, način plaćanja i koliko čeka.
        • Konzola više ne nudi otkazivanje već otkazane narudžbe.
        • „Skenirajte kod" je pisalo ispod koda na telefonu koji gost drži u ruci. Gost dođe na taj ekran tako što je tim istim telefonom skenirao naljepnicu sa svog stola. Koraci sada opisuju prepisivanje podataka, a ispod piše da je QR kod za nekoga ko plaća sa drugog telefona. Naslov bloka sa podacima više ne počinje sa „Ili".
        • Ekran isteklog koda obećavao je da će se novac prepoznati sam. Tamo gdje ništa ne potvrđuje uplatu bez čovjeka - a to je u pilotu redovan slučaj, jer se potvrđuje izvodom sljedeće jutro - to nije tačno. Gost spremi telefon vjerujući da lokal zna, a konobar dođe naplatiti. Stranica gosta sada zna ima li ovaj lokal automatsku potvrdu i, ako nema, kaže da pokaže ekran osoblju.
        • Objašnjenje kako se uplata potvrđuje ručno briše se samo od sebe. Konzola je brojala sve izvore potvrde bilo koje vrste - a potvrda rukom se upisuje kao izvor vrste MANUAL, koji nastaje upravo time što uradite ono što poruka govori. Prva uspješna potvrda je zato obrisala objašnjenje, a sat kasnije je četiri računa stajalo nepotvrđeno pored prometa koji se ne slaže. Sada se broje samo izvori koji mogu potvrditi bez čovjeka.

        Novo

        • Uputstvo za provjeru potpisa na webhooku (docs/bs/05-webhook-potpis.md). Uputstvo za spajanje kase je na tom koraku podebljano tražilo provjeru potpisa i linkalo na dokument koji nije postojao. Serviser kase je dolazio do koraka koji se ne može izvršiti kako je napisan, a najvjerovatniji ishod je webhook bez provjere - adresa je javna, pa je to račun koji svako može zatvoriti. Sada postoji, sa primjerima za Node, PHP i C#.

        0.48.0

        9. septembar 2026.

        Popravljeno

        • Gost koji se vrati iz bankovne aplikacije više ne zatiče prazan račun. Gost pritisne Plati, prepiše IBAN i poziv na broj, pređe u banku. Devedeset sekundi kasnije telefon je odbacio karticu pretraživača i ona se ponovo učita - a plaćanje je živjelo samo u memoriji stranice. Vratio bi se na račun koji traži cijeli iznos, bez poziva na broj koji je upravo upisao i bez ekrana koji će reagovati kada uplata legne. Pored vlasnika, to zvuči kao „platio sam, a još mi traži novac".
        • Kopiranje IBAN-a je moglo ne uraditi baš ništa. U pretraživaču unutar druge aplikacije, na starijem Androidu ili gdje je dozvola odbijena, navigator.clipboard odbije - a ekran bi se vratio u stanje kao da niko ništa nije pritisnuo. Gost pritisne još četiri puta pa počne prepisivati dvadeset jedan znak sa ekrana. Sada postoji stariji način kopiranja, a ako ni on ne prođe, broj ostaje označen uz rečenicu da ga treba prepisati.
        • Prazan bijeli kvadrat umjesto QR koda. Ako se slika koda ne učita, ostane bijela ploča sa iznosom ispod i kucajućom tačkom - gost uperi bankovnu aplikaciju u ništa. Sva tri ekrana (gost, konobar, kasa) to sada kažu i nude ponovni pokušaj bez pravljenja novog računa.
        • Gost pod „Čekam potvrdu banke" nije mogao znati da mu je pukao internet. Telefon ispadne sa wifija dok je bio u banci, tačka kuca dalje, i poslije dva minuta gost zaključi da uplata nije prošla i ponudi gotovinu - pa isti račun stoji i na kasi i u banci. Poslije tri neuspjela provjeravanja ekran to sada kaže, uz napomenu da uplata i dalje važi.
        • Crveni natpis „Nema veze sa serverom" na tabletu konobara nije se gasio. Ručni ruteri i wifi sa prijavnom stranicom redovno blokišu websocket, pa je natpis stajao cijelo veče - dok je tablet, sasvim vidljivo, naplaćivao preko običnog provjeravanja svakih pet sekundi. Natpis sada prati da li tablet uopšte može doći do servera, a ne da li je websocket živ.
        • Kasa nije imala nikakav znak da je veza pukla. Wifi padne na minut i po, gost je već uplatio, a ekran cijelo vrijeme pokazuje istu živu tačku. Osoba na kasi zaključi da nije prošlo i posegne za „Odustani" - dugmetom koje na već plaćenom računu radi upravo pogrešnu stvar. Sada, poslije tri neuspjela provjeravanja, stoji crveno „Nema veze sa serverom" i rečenica da se ne otkazuje.
        • „Otkaži" na mrtvoj vezi nije radio ništa, i to bez riječi. Gost kaže da ipak plaća gotovinom, konobar pritisne Otkaži, ništa. Pritisne još pet puta pred vlasnikom. Dugme sada pokazuje da je pritisnuto i, kada odgovor ne stigne, kaže da je račun i dalje otvoren i da će se srediti sam.
        • Izgubljen odgovor pri povezivanju uređaja trošio je kod, a krivio kod. Vlasnik pročita kod sa laptopa, konobar ga upiše, odgovor se izgubi na wifiju - tablet kaže „kod nije ispravan ili je istekao", pa ga upišu ponovo, pažljivije, i tek tada je zaista potrošen. Sada se odgovor koji nije stigao razlikuje od odbijenog koda i upućuje na Novi kod u konzoli, na sva tri ekrana koja se povezuju.
        • Konzola je istekao kod za povezivanje pokazivala kao živ. Kod važi 30 minuta, a konzola ga je pokazivala u okviru sa dugmetom za kopiranje dok god je red postojao. Sada piše koliko mu je ostalo, precrta ga kada istekne, i upozorenje „ovo prekida vezu sa uređajem" se više ne pokazuje za uređaj koji nikada nije ni bio povezan.

        Tačnije

        • Uputstvo za naljepnice preskakalo je bankovni račun. Korak „Napravi kodove" se bez njega odbija, a IBAN u malom kafiću zna značiti telefon knjigovođi - dok vi stojite za šankom. Sada je to korak 0, stoji i na listi onoga što nosite sa sobom, i rečenica za prodaju više ne obećava da ne treba baš ništa.
        • Uputstvo za ekrane sada pravi kod tek kada je tablet spreman. Redoslijed je bio: napravi ekran u konzoli, pa montiraj tablet. Kod živi 30 minuta i obično istekne prije nego se dođe do njega.

        0.47.0

        9. septembar 2026.

        Popravljeno

        • Kuhinjska ploča je za pukao wifi krivila kolegu. Kada dodir na karticu ne prođe, ploča je ispisivala „neko je već pomjerio ovu narudžbu" - i za slučaj kada je to istina, i za slučaj kada server uopšte nije odgovorio. Kuhar tada vjeruje da je karticu preuzeo pass, a nije je preuzeo niko. Poruka je i ostajala na ekranu zauvijek.
        • Ploča koja je izgubila server javljala je to tačkom od osam piksela. Jedini znak je bio mali kružić u uglu, sa objašnjenjem koje se vidi tek kada se mišem stane na njega - na ekranu zavrnutom za zid, gdje ništa ne stoji mišem i niko nije dovoljno blizu. Ploča koja više ništa ne prima izgledala je isto kao ploča na kojoj nema posla.
        • Firma se mogla otvoriti bez ijedne poslovnice, a poslovnica se nije mogla dodati. Polje za prvu poslovnicu u otvaranju naloga bilo je neobavezno. Vlasnik takve firme završi na ekranu Poslovnice, pročita „Dodajte prvu poslovnicu da biste mogli izdavati QR kodove" - i nema gdje. Ruta za otvaranje poslovnice postoji od početka i konzola je nikada nije pozvala, a traži vlasnika, pa to nije mogao uraditi ni neko sa naše strane.
        • Kada ponestane mjesta za stolove, poruka nije rekla koliko ih paket dozvoljava. Odbijenica je stizala kao „kodovi se nisu mogli napraviti" - ista rečenica kao za pokvaren server, a potez vlasnika je sasvim drugi. Server je sve vrijeme slao brojeve; ekran ih nije čitao. Sada piše koliko paket dozvoljava, koliko stolova već postoji i koliko ih je traženo.
        • Jutarnja provjera je za nepotvrđen QR profil pisala „profil je potvrđen (DRAFT)". Dvije tvrdnje u jednoj rečenici, koje jedna drugu pobijaju, sa kvačicom pored - na listi čiji je jedini posao da joj se vjeruje u devet ujutro. To što server pristaje izdati kod nije isto što i to da je banka profil potvrdila, a samo drugo znači da novac stigne.

        Tačnije

        • Uputstvo za osoblje tvrdilo je da šank ne prikazuje hranu. Ne prikazuje je samo kuhinjski ekran; šank i ekran bez postavljene stanice namjerno vide cijelu narudžbu, jer u malom lokalu šank drži pass. Ista tvrdnja stajala je i u listi za provjeru prije puštanja u rad, kao stavka koja nikada nije mogla proći. Oboje ispravljeno.
        • Isto uputstvo je obećavalo promet po konobaru. Izvještaj Ko je radio to namjerno ne kaže i ne može reći: gost naručuje sa svog telefona, pa narudžba nosi sto i uređaj, a ne osobu. Uputstvo sada opisuje ono što izvještaj zaista mjeri i kaže da su redovi terminala označeni kao uređaj, ne kao osoba.
        • Limit od 5.000,00 KM po instant plaćanju više nije glasina iz medija. Odluka Centralne banke o pravilima rada instant plaćanja, usvojena 10. jula 2026., postavlja ga u članu 13, uz pravilo da je valuta isključivo KM. Dokument za razgovor sa bankom sada citira odluku umjesto novinskog teksta, i bilježi da specifikaciju QR koda tek treba objaviti Centralna banka - zbog čega BIH_IPS i dalje stoji kao nacrt.

        0.46.0

        9. septembar 2026.

        Popravljeno

        • Izgubljen odgovor na „Plati" zaključavao je sto od QR plaćanja preko sat vremena. Gost pritisne, odgovor se izgubi na wifiju, gost pritisne opet - a server, koji mu je već napravio kod, odgovori da je svaki dio računa već zauzet. Telefon pokaže „trenutno nije moguće napraviti kod", račun je u stanju „plaća se" pa se ne može ni naručiti, i ništa na ekranu ne može doći do koda koji postoji. Zaglavljen dok kod ne istekne, za stolom, pred vlasnikom.

        0.45.0

        9. septembar 2026.

        Popravljeno

        • Konobarski terminal je na plaćen račun ispisivao 0,00 KM. Ekran je čuvao kopiju plaćanja od trenutka kada je kod izdat i mijenjao joj samo status - a plaćanje koje još nije plaćeno nosi settledAmount „0.00", ne prazno. Pločica čita settledAmount ?? totalAmount, a ?? ne hvata nulu.
        • Nijedan zahtjev u pretraživaču nije imao vremensko ograničenje. Kafić s debelim zidovima ne prekida vezu čisto: pristupna tačka ostane spojena a prestane prosljeđivati, socket ostane otvoren i tih, i fetch čeka. Obećanje se nikada ne razriješi, finally se ne izvrši, i ekran ostane u pola koraka - dugme za slanje mrtvo, ispod natpisa da se šalje, do kraja sjedenja. Pažljivo napisan ekran „ne možemo se povezati, pokušaj ponovo" je pritom nedostižan, jer se pali samo kada fetch odbije.

        0.44.0

        9. septembar 2026.

        Popravljeno

        • Server instaliran po vlastitom uputstvu nije mogao izdati nijedan QR kod, a jutarnja provjera je javljala da je sve spremno. install.sh upisuje NODE_ENV="production" i nikada ne upiše ALLOW_UNPROVEN_QR, pa je podrazumijevano false; svaka nova poslovnica dobija BIH_IPS, a taj profil je DRAFT; i API u produkciji odbija svaki profil koji banka nije potvrdila.
        • Konobar je dobijao „pokušajte ponovo" na dvije greške koje ponovni pokušaj ne rješava. Nepotvrđen QR profil se neće riješiti kucanjem, a račun preko 5.000,00 KM traži naplatu u dijelovima. Oba sada imaju rečenicu koja kaže šta uraditi, na kasi i na konobarskom terminalu.
        • Gost je na račun preko limita dobijao samo „nije moguće napraviti kod". Dugme za dijeljenje računa je na tom istom ekranu. Sada poruka na njega i upućuje - kroz mehanizam koji taj ekran već ima za ovakve odbijenice.

        0.43.0

        9. septembar 2026.

        Popravljeno

        • Kod je izdavan i na iznose koje instant plaćanje ne može izvršiti. QR kod je samo način da se nalog otkuca u aplikaciju banke; aplikacija ga onda predaje shemi, a shema ima pravila koja kod ne može zaobići. Odluka o pravilima rada sistema instant plaćanja CBBiH kaže u članu 13 da nalozi glase isključivo na BAM i da je najveća pojedinačna transakcija 5.000,00 BAM.

        0.42.0

        9. septembar 2026.

        Popravljeno

        • Menadžer vezan za jednu poslovnicu mogao je čitati brojke druge. Četiri izvještajne rute gradile su filter kao locationId ? { locationId } : locationFilter(principal), što izgleda kao ograničavanje a radi suprotno: proslijeđen locationId ZAMJENJUJE opseg pozivaoca umjesto da se provjeri u odnosu na njega. Pet drugih mjesta u istom fajlu već je prosljeđivalo traženu poslovnicu u locationFilter, koji odbija onu do koje pozivalac ne smije. Reprodukovano: menadžer vezan za Mrkva Centar dobio je stolove, izvještaj o osoblju i knjigovodstveni CSV za Mrkva Ilidžu, sve sa 200. Tri od četiri mjesta su bila starija od danas; četvrto je preslikalo obrazac.
        • Licenca izdata prije jučer prestala je važiti pri unosu. Dvije promjene iz istog puštanja, razmaknute sat vremena: zaokruživanje isteka pomjerilo je NOVE ključeve naprijed, a pravilo o starijem ključu je onda svaki ranije izdat ključ čitalo kao zastario. Firma koja zalijepi ključ koji joj je poslan - a to je cijeli način na koji se paket aktivira - dobila je poruku da je ključ stariji od onoga koji već ima. Poređenje je bilo pogrešne vrste: ključ nosi dan, licenca nosi trenutak. Sada se porede dani.
        • Kolona „Gotovina" brojala je i karticu. Vlastiti POS terminal lokala nije gotovina: novac ide akvajreru i stiže u banku danima kasnije, nikada u kasu. Pregled u istoj konzoli te dvije stvari drži odvojeno („Gotovina za stolom" i „Kartica na terminalu"), a ovaj ekran ih je spojio pod gotovinom. Menadžer bi u subotu ujutro pročitao da je Ana imala 1.000 KM gotovine, izbrojao 600 u kasi, i pitao imenovanog radnika gdje je ostatak.
        • Narudžbe su se brojale po satu gosta, ne po satu osoblja. Izbor je išao po placedAt, a tri trenutka koja se broje - primljeno, spremno, izneseno - imaju svoje vlastito vrijeme. Narudžba primljena u 23:50 i iznesena u 00:10 cijela je knjižena na raniju smjenu. Upit pored njega o računima obrazlaže upravo suprotno, u toliko riječi.
        • Poslovi platforme pisali su se kao „Obrisan nalog". Ime se traži samo za osobu i uređaj, pa je red koji je zatvorila sama platforma - kada zadnja uplata stigne - izgledao kao da ga je zatvorio obrisani radnik.
        • Panel „Ko je radio" bio je na ekranu svakom konobaru, a ruta iza njega je samo za menadžera. Svaki član osoblja koji otvori Stolove dobio je crvenu poruku o zabrani, na ekranu koji najviše gleda. Isto i stavka „Zalihe" u navigaciji: sposobnost kaže da firma vodi zalihe, uloga kaže ko smije.
        • Jedan pritisak dugmeta mogao je napraviti dva poziva osoblja, a jedan odlazak zatvoriti sve otvorene. Provjera pa upis bez zaključavanja: dva dodira u istoj sekundi - što nestrpljiv sto i radi - oba su prošla. A potvrda je označavala svaki neodgovoren red na računu, ne onaj za koji je neko otišao.
        • Količina zalihe i red koji je objašnjava pisali su se odvojeno. Cijeli modul je složen tako da se broj ne može pomjeriti bez reda koji kaže zašto - a sam upis je mogao uraditi upravo to: pomjeriti broj, pasti na redu, i ostaviti stanje za koje niko ne može odgovarati. Sada je jedna transakcija.
        • Ekran zaliha se utrkivao sam sa sobom. Promjena poslovnice pokreće učitavanje i ne prekida prethodno, pa je polica jedne poslovnice mogla biti prikazana pod imenom druge. Uz to: neuspjelo učitavanje javljalo je „Još nema artikala. Dodajte prvi artikal", a neuspjelo čitanje historije „Nema zapisa." - na ekranu čije je cijelo obećanje da svaka promjena ostavlja red.
        • Upisan minus na prijemu je oduzimao. Znak je bio nametnut samo razlozima koji oduzimaju, pa je „-3" pod Prijem prošlo kao minus tri.
        • Poruka o pogrešnom ekranu stizala je na engleskom. Na tri ekrana koja gledaju konobar i kuhar, gdje je svaka druga riječ bosanska.
        • Migracija je ostavila dvije mrtve kolone. Kada je oblik zapisa poziva osoblja zamijenjen tabelom, shema je vraćena a SQL nije. Nova migracija ih briše - stara se ne dira, jer Prisma pamti njen kontrolni zbir.
        • Naredba za postavljanje lozinke nije ostavljala nikakav trag. Ona sada postavlja lozinku, diže zaključavanje i gasi sve druge sesije - a jedina radnja na koju dnevnik nije mogao odgovoriti bila je preuzimanje vlasnikovog naloga s pristupom serveru. To je red koji najviše vrijedi imati.
        • Trideset i jedan zapis u dnevniku upisivao je vrstu aktera rukom. Ranija provjera je gledala samo da li je akter imenovan, pa je red koji kaže „korisnik" uz principal.id prolazio - a četiri najprometnije radnje u lokalu radile su tačno to. Kuhinjski ekran i integratorov ključ vodili su se kao osoba. Provjera to sada hvata.
        • Tri provjere koje nisu mogle pasti. Provjera da uplata nije gotovina zatvarala je račun kao QR_TRANSFER, a takvo zatvaranje po definiciji ne knjiži ništa u kasu - pa je prolazila i kada se pravilo obriše. Test o dužini lozinke tvrdio je f(x) === f(x). I datum u provjeri osoblja tražio se po satu servera, pa bi dva sata svake noći tražila dan pod kojim posao nije zaveden.
        • Seed nije postavljao lozinke koje ispisuje. Postojećeg korisnika je ostavljao na miru, pa bi ko god upotrijebi naredbu za postavljanje lozinke i onda ponovo zasije bazu dobio bazu koja protivrječi vlastitom ispisu - i grešku „Invalid email or password" koja izgleda kao kvar proizvoda a nije. Sada postavlja ono što ispisuje i skida zaključavanje uz to.

        0.41.0

        9. septembar 2026.

        Novo

        • Zalihe - novi ekran za prodavnice i skladišta. Prodavnica i skladište su odavno vrste djelatnosti i odavno nose oznaku da vode zalihe, a tu oznaku ništa nije čitalo. Konzola im je ispravno sakrivala stolove i meni i ponudila ništa umjesto toga: prodavnica se mogla registrovati, dobiti potvrdu da je prodavnica, i naći proizvod bez ijednog mjesta da kaže šta ima na polici.

        Popravljeno

        • Provjera pred otvaranje pitala je i prodavnicu može li primiti gosta. Skripta koja se pokreće ujutro pred pilot prolazila je kroz sve poslovnice, a pitanja koja postavlja - ima li menija, jesu li naljepnice odštampane, je li naručivanje uključeno - za prodavnicu ili skladište nemaju odgovor. Firma koja uz restoran ima i prodavnicu bila bi obaviještena, pred vlasnikom, da nije spremna - za prostoriju na koju se ništa od toga ne odnosi. Nikada se nije pokazalo jer takva poslovnica dosad nije ni postojala. Sada se takve preskaču, a razlog preskakanja se ne miješa: prodavnica nije ugašena, ona je prodavnica.

        0.40.0

        9. septembar 2026.

        Novo

        • „Ko je radio" - novi izvještaj ispod izvještaja po stolovima. Koliko je računa ko zatvorio, koliko je gotovine kroz čije ruke prošlo, koliko je narudžbi primio, pripremio i iznio, i na koliko se poziva sa stola odazvao.

        Popravljeno

        • Poziv osoblja se sada pamti. Zastavica se ranije samo brisala, pa su minutu kasnije poziv na koji je neko otišao i poziv koji se nikada nije desio izgledali isto: nigdje se nije vidjelo je li iko otišao, koliko je sto čekao, ni ko je otišao. Sada se svaki pritisak zapisuje zasebno - sto u toku večeri pozove dvaput, još jedna tura pa račun, i brojanje po računu bi prijavilo jedan.
        • Narudžba pamti ko ju je pomjerio. Vrijeme prihvatanja, pripreme i iznošenja je odavno zapisano, osoba nije - to je znao samo revizijski trag, koji je ulančan hešom i pogrešna stvar za sabiranje: odgovoriti na „kako je prošla večer" značilo bi proći kroz svaki zapis koji lokal ima.

        0.39.5

        9. septembar 2026.

        Popravljeno

        • Postavljanje nove lozinke javljalo je da je gotovo, a vlasnik i dalje nije mogao ući. Prijava provjerava zaključavanje računa prije lozinke, i tako mora biti: zaključavanje postoji da neko ne bi redom probavao lozinke, pa ni pogođena ne smije proći dok traje. Ali razlog zbog kojeg nekome i treba nova lozinka najčešće je upravo to da ju je osam puta ukucao pogrešno, dakle račun je zaključan u trenutku kada se komanda pokreće. Komanda bi ispisala „Password set", vlasnik bi ukucao novu lozinku, a prijava bi odgovorila istim „Invalid email or password" kao i prije. Namjerno istom porukom, da se ne odaje koje adrese postoje - što vlasnika ostavlja s tačnom lozinkom i ekranom koji kaže da je pogrešna, petnaest minuta, one večeri kada je zvao u pomoć. Sada se zaključavanje diže zajedno s lozinkom. Isto i kod promjene lozinke iz konzole, gdje brojač neuspjelih pokušaja nije nulirao ništa osim uspješne prijave.
        • Vraćanje iz sigurnosne kopije javljalo je „Restored" i kada nije vratilo ništa. psql je vedar po pitanju grešaka: kada mu se da skripta, odradi šta može, greške ispiše na stderr i izađe s kodom 0. Kopija od koje se nije primila nijedna naredba izgledala je skripti isto kao ona koja je prošla u cijelosti, pa bi se pokrenule migracije, digao API i ispisalo „Restored from 20260903T032000Z" iznad prazne baze. U dva ujutro, na jedinoj komandi kojoj je cijeli posao da joj se vjeruje. Sada prva greška prekida posao i vraća sve unazad, API ostaje ugašen namjerno, a ispis kaže gdje je baza od prije vraćanja.
        • Konzola je pokazivala cijenu s cjenovnika umjesto dogovorene. Ugovor obećava da lokal u svojoj konzoli vidi broj transakcija i iznos koji iz njega slijedi, a taj iznos se gradi iz dogovorene cijene zapisane na firmi. Ekran je čitao cjenovnik. Lokal kojem su odobrena tri mjeseca po pola cijene svaki je dan gledao punu. Uz to je godišnja licenca, koja se plaća jednom za godinu, bila dodavana u svaki mjesec te godine.
        • Licenca je isticala i po jednu večer ranije nego što je plaćena. Ključ nosi dan, a pravo traje do trenutka, pa se nešto mora zaokružiti - i zaokruživalo se naniže, čime se vrijeme u danu gubi unazad. Pretplata započeta u devet ujutro obnavlja se na 07:00Z, to se spusti na taj dan, i ključ ističe u 02:00 po sarajevskom vremenu na danu koji je lokal platio. Konektor provjerava ključ lokalno, bez interneta, pa bi tu zadnju večer servisa jednostavno rekao da licenca ne važi. Sada se zaokružuje naviše: najviše dan gratis na nečemu što je već plaćeno, umjesto jedne izgubljene večeri.
        • Stariji licencni ključ tiho je poništavao nadogradnju. Ključevi se ne povlače - provjera je potpis i ništa drugo, upravo zato da radi bez interneta - pa je prošlogodišnji STARTER ključ i dalje ispravan i i dalje u sandučetu. Zalijepljen u konzolu, upisao bi STARTER preko žive PRO licence i povukao datum isteka godinu unazad, uz istu zelenu potvrdu koju dobije prava nadogradnja. Ono što bi vlasnik primijetio jeste da su mogućnosti nestale, dan nakon što mu je ekran rekao da je licenca prihvaćena. Sada se ključ koji ističe prije one licence koja već važi odbija, s objašnjenjem. Gleda se datum a ne paket, da dogovorena prelazak na manji paket i dalje prolazi.
        • Četiri zapisa u dnevniku nisu imenovala nikoga. Dnevnik je ulančan hešom da bi lokal mjesecima kasnije mogao odgovoriti ko je nešto uradio, a ovi su govorili samo da se dogodilo: postavljanje adrese na već izdatu fakturu, otvaranje i brisanje webhook tačke, i povezivanje izvora uplata. Uz to su se aktori upisivali ručno na tri različita načina, pa je sve što nije API ključ zavedeno kao „korisnik" - uključujući kuhinjski ekran i poslove koje platforma radi sama. Sada postoji jedno mjesto koje to čita iz onoga ko poziva, a provjera prolazi kroz sav izvorni kod i pada ako ijedan novi zapis zaboravi aktera.
        • Kod za uparivanje prolazio je na pogrešnom ekranu. Uparivanje nije gledalo koji je ekran otvoren, pa je kod kuhinjskog ekrana ukucan na konobarskom tabletu prošao: ekran za uparivanje bi nestao, što izgleda kao uspjeh, a ostao bi tablet koji vozi zidni ekran. Obrnuto je gore - kuhinjska ploča uparena na tablet nema stanicu, pa šankerski ekran pokazuje i hranu, što je tačno ono što stanica postoji da spriječi. Sada se odbija, i to prije nego se kod potroši, pa uređaj kojem kod pripada i dalje ima šta ukucati. Poruka kaže o čemu se radi umjesto „kod nije ispravan", jer je to kod koji je ispravan, samo na pogrešnom mjestu.

        0.39.4

        9. septembar 2026.

        Popravljeno

        • Uputstvo je davalo uzorak koji račun od 1.234,56 KM čita kao 1,23 KM. Kod je za to bio popravljen, uputstvo nije - a uzorak iz uputstva se upisuje u konfiguraciju i time gazi ispravan ugrađeni. Kraći oblik ne može obuhvatiti grupu hiljada pa uhvati samo početak. Društvo od dvanaest ljudi plati 1,23 KM, uplata se poklopi u fening, slučaj se nigdje ne otvori, na svakom ekranu piše da je plaćeno - a lokalu fali 1.233,33 KM i ništa ne javlja.
        • Primjer konfiguracije se nije mogao učitati. Tri regularna izraza su bila u dvostrukim navodnicima, gdje \s nije ispravan znak, pa YAML puca. README kaže da se taj fajl kopira, a blok za kasu je jedini razrađen primjer za slučaj koji pilot i cilja - kasu koja ne zna ništa osim štampanja. Kad ga instalater odkomentariše, konektor se ne pokrene i dobije jednu poruku o koloni u YAML-u koja ne spominje XPay.
        • Uputstvo nije spominjalo bindHost, a govorilo je da se kasa uperi na IP ovog računara. Konektor po pravilu sluša samo na loopbacku - tok štampe nije zaštićen lozinkom i nosi svaki iznos računa - pa je veza s kase bila odbijena i kasa je prestajala štampati, ni račun za gosta ni kopiju za kuhinju, bez ijedne poruke. Uputstvo i primjer sada to traže i objašnjavaju zašto, a konektor pri pokretanju kaže da sluša samo lokalno i šta podesiti.
        • Zauzet port lokalnog API-ja više ne ruši cijeli konektor. Slušanje nije imalo rukovanje greškom, pa je svako neuspjelo zauzimanje porta - obično druga kopija koju je pokrenuo raspoređivač zadataka - gasilo proces. S njim je odlazio i sloj između kase i štampača, pa bi kasa koja je uredno štampala prestala zbog slušača koji u lokalu niko ne koristi. Sada se zabilježi kao otkazan dio i vidi se na /health, a štampanje ide dalje.
        • Provjera pred puštanje sada čita taj primjer onako kako ga čita instalater: odkomentariše blok za kasu, učita ga, i provjeri da uzorak zaista pročita 1.234,56 kao 1.234,56.

        0.39.3

        9. septembar 2026.

        Popravljeno

        • Uparivanje drugog ekrana više ne preusmjerava prvi. Sva tri ekrana uređaja - konobarski, kasa i kuhinjski - držala su token na istom mjestu, a svaki je svoj kontekst čuvao posebno. Uparite kasu pa na istom tabletu kuhinjski ekran, i kasa i dalje piše „Šank" dok svaki njen zahtjev nosi token kuhinjskog ekrana. Taj token ima prava samo na narudžbe, pa naplata dođe odbijena zbog nedostajućeg prava - a to je 403, ne 401 koji klijent koristi da primijeti mrtav token i ponudi ponovno uparivanje. Osoblje ostane da pritiska dugme koje ne može raditi, bez puta nazad. Prolazak kroz cijeli proizvod na jednom tabletu - a tako se i pokazuje - udari u ovo na drugom ekranu. Svaki ekran sada ima svoje mjesto; uređaj koji je već bio uparen zadrži uparivanje na ekranu koji prvi otvorite.
        • Kasa više ne naplaćuje jučerašnje cijene. Meni je učitavala jednom pri otvaranju i nikad više, a uparena kasa nema prijavu i niko je ne osvježava - to je i smisao uparivanja. Kad happy hour počne u pet, gost za stolom plati sniženu cijenu a šank punu, za istu rundu; poslije sedam se obrne i lokal naplati manje. Sada se meni čita svake minute, i kad se ekran probudi, ali nikad usred kucanja računa.
        • Ponovni pokušaj na kasi više ne pravi drugi račun. Ključ se pravio iz sata unutar samog slanja, pa je ponovni pokušaj - jedini razlog zbog kojeg ključ i postoji - nosio drugi ključ. Konobarski terminal je za to bio popravljen i pravilo živi u zajedničkoj datoteci; kasa nikad nije prebačena na nju.
        • Zidni ekran sada može skinuti poziv osoblja. Prikazivao ga je i nije imao čime da ga skloni: jedini ekran koji to može je pregled stolova u administraciji, koji u kuhinji niko ne drži otvoren. Gore od zaglavljene oznake: poziv koji već stoji ne objavljuje ništa kad isti sto pritisne opet, pa je neskinuta oznaka gutala sljedeći poziv tog stola do kraja računa. Endpoint je za ovo i napravljen - u njegovom opisu piše da to smije uraditi i zidni ekran u kuhinji - samo ga ekran nikad nije nudio.
        • Pločica „otvoreni računi" na pregledu vlasnika se sada osvježava. Svaki drugi živi ekran ima tajmer iza veze - zidni na dvadeset sekundi, narudžbe na trideset, terminal na pet - a ovaj nije imao nijedan, i događaje o stolovima je ignorisao. U lokalu gdje se najviše plaća gotovinom to je cijela pločica: otvorite konzolu u šest s četiri računa i 84,50 KM, i u jedanaest i dalje piše četiri i 84,50.

        0.39.2

        9. septembar 2026.

        Popravljeno

        • Prekid veze na dvije sekunde više vas ne odjavljuje zauvijek. Osvježavanje prijave je svaku grešku tretiralo isto: i server koji kaže da token više ne vrijedi, i wifi koji je pao u zgradi s debelim zidovima, i 502 dok se API restartuje. A postupak je bio isti - obrisati jedini podatak za prijavu s uređaja. Vlasnik bi se onda, tri sekunde nakon što se wifi vrati, kucao lozinku pred ugostiteljem. To se dešava otprilike svakih petnaest minuta na svakom otvorenom ekranu, pa je kroz jednu smjenu na tri uređaja to na desetine prilika, ne rijetkost. Sada se briše samo kad server stvarno odbije token.
        • Dva otvorena taba se više ne odjavljuju međusobno. Dijele jedan token i svaki ga osvježava sam, pa oba mogu poslati isti. Server tada poštedi porodicu tokena i odbije onaj drugi - a taj drugi je brisao token koji je prvi upravo upisao. Sada se briše samo ako je u međuvremenu niko drugi nije zamijenio.
        • Živa veza više ne šalje istekao token. Rukovanje pri ponovnom spajanju je napisano baš zato da ne pošalje istekao token, a čitalo je token iz memorije koji se pri isteku nigdje ne briše - pa je uzimalo tačno onaj token zbog kojeg je i napisano. Svako ponovno spajanje poslije prvih petnaest minuta je zato bilo odbijeno, i to je ono što je gornju grešku pretvaralo iz rijetke u svakodnevnu. Sada se čita rok iz samog tokena.
        • Kuhinjski ekran na zidu se više ne isključi do kraja smjene. Uređaj s uparenim tokenom je na svako odbijanje odustajao zauvijek, uz obrazloženje da takav token ne ističe pa nema šta da se osvježava. Tačno za osvježavanje, netačno za ponovni pokušaj: server šalje to isto odbijanje za bilo koju grešku pri spajanju, uključujući i bazu koja je na trenutak zauzeta. Zasićen konekcijski bazen tokom uvoza izvoda bi tako skinuo ekran s prijenosa do kraja večeri, a jedini povratak je da neko otlijepi tablet sa zida. Sada pokuša ponovo, nekoliko puta, s razmakom.

        0.39.1

        9. septembar 2026.

        Novo

        • Boja lokala na meniju koji gost vidi. U postavkama, pored logotipa, bira se jedna boja. Dugmad i naglasci na gostovom meniju idu u toj boji.

        Popravljeno

        • Logotip i boja se sada prikazuju samo na paketu koji ih uključuje. customBranding postoji u tabeli paketa otkad postoje paketi i nije se provjeravao nigdje: logotip svakog lokala je stizao na gostov meni bez obzira šta lokal plaća. Odluka se donosi na izlazu, ne na upisu - lokal koji pređe na niži paket zadrži ono što je izabrao, samo se prestane prikazivati, a povratak na viši paket vrati njegove boje istog trena.

        0.39.0

        9. septembar 2026.

        Novo

        • Nabavna cijena po jelu, pa marža postaje stvaran broj. Uz cijenu jela stoji i koliko vas košta da izađe iz kuhinje. Iz toga se na spisku vidi marža po jelu, a u zaglavlju kategorije marža cijele kategorije.

        0.38.12

        8. septembar 2026.

        Popravljeno

        • Napojnica na zaokruženom računu se više ne gubi s pregleda. Podred „od toga bakšiš" brojao je samo račune plaćene tačno, iako promet iznad njega uključuje i kratke i prekoračene. Gost koji ostavi napojnicu pa prebaci malo više nego što kod traži vidio bi svoj novac u prometu, a napojnica bi nestala s jedinog reda koji je imenuje. Sada se broji na istom paru statusa na kojem se knjiži i sto i na kojem se broji kolona po stolovima: napojnica se računa kad je novac za nju stigao. Kratko plaćen račun se i dalje ne broji, jer nije pokrio ni robu, pa ništa ne govori da je išta od napojnice stiglo.
        • Taj podred sada kaže i koje napojnice imenuje. Pisalo je samo „bakšiš", pored „gotovina" u istom redu - a napojnica u gotovini se ne upisuje nigdje i ne može biti u toj brojci. Lokal koji je uzeo 400,00 gotovine i 60,00 QR-om čitao je red koji zvuči kao sve napojnice te večeri, a opisuje samo QR dio.
        • Knjigovodstveni PDF sada podvlači i napojnicu. Jedini zbir na stranici je kolona Uplaćeno, a to je bankovni priliv - dakle na običnom računu nosi i napojnicu, i to nigdje nije pisalo. Knjigovođa koji je htio zbir napojnica morao ga je sabrati rukom niz stranicu koja zna imati desetak listova. Sada ispod zbira stoji „od toga napojnica", i to samo kad je ima, da se na običnom mjesečnom izvozu ne pojavljuje red s nulom.

        0.38.11

        8. septembar 2026.

        Novo

        • Kolona s napojnicama, po stolovima. Pored Prometa stoji koliko je napojnice stiglo na taj sto u odabranom periodu. Broji se po istom pravilu kao i Promet: iste uplate, isti računi, isti period, prije povrata - jer dvije kolone s novcem u istom redu koje broje različite stvari su greška, ne mogućnost.

        Popravljeno

        • Kod izdat na stolu više se ne prikazuje veći od računa koji plaća. Red na spisku otvorenih stolova je sabirao ukupan iznos uplate, dakle s napojnicom, a preostali iznos pored njega je po prirodi bez nje: sto se knjiži iznosom naručenog. Sto od 20,00 KM na kojem gost drži kod za cijeli račun i 2,00 napojnice pisao je „1 kod izdat · 22,00 KM" pored preostalih 20,00 - a kad uplata stigne, konobar vidi kako s reda nestaje 22,00, a s preostalog se skine 20,00. Ta dva broja stoje jedan pored drugog baš zato da se porede.

        0.38.10

        8. septembar 2026.

        Popravljeno

        • „Ponovi isto" dvaput više ne znači dvije runde. Ta putanja nije nosila nikakvu oznaku pokušaja, a telefon ne razlikuje odbijanje od odgovora koji nije stigao - što je u bučnom lokalu s lošim wifijem obična stvar. Narudžba ode, šank je natoči, odgovor se izgubi, gost pritisne opet i šank natoči drugi put: dva piva naplaćena kao četiri. Isti pritisak sada nosi isto ime, pa drugi dodir slegne na rundu koja već postoji.
        • „Pokreni ponavljanje" sada kaže zašto je odbijeno. Poruka o grešci se ispisivala na stranici iza modala, ispod njegovog vlastitog neprozirnog pokrivača: modal ostane otvoren, dugme oživi, i ništa čitljivo se ne pojavi. Najobičniji unos od svih vodio je tačno u to stanje - prvi datum danas, koji API odbija svaki put jer datum čita kao ponoć u zoni lokala, a ponoć je prošla. Poruka je sada unutar modala, a birač datuma više ne nudi dan koji će sigurno biti odbijen.
        • Datum sljedećeg pokretanja više se ne čita dan ranije. Sprema se kao ponoć u zoni lokala, što je 22:00 dan prije po UTC-u, a konzola ga je formatirala u zoni pregledača - pa je svakom ko je na UTC-u ili zapadnije pisalo da faktura ide dan ranije, i preko granice mjeseca i preko granice godine. Server sada šalje i sam dan, a ekran ga samo prepiše.
        • Pregled zanemarenih uplata više ne nosi naslov reda za uparivanje. Oba su pisala „Nepovezane uplate", a jedina razlika je bila ljubičasti prsten na dugmetu. Brojač ispod naslova je bio gori: „Prikazano 50 od 63 nepovezanih" iznad spiska uplata koje je neko namjerno odložio, dok je sam red bio prazan. Dugme sada imenuje mjesto na koje vodi.
        • Knjigovodstveni izvoz ima gornju granicu i po broju redova. Ograničenje je bilo samo na dužinu perioda, a godina mirnog i godina prometnog lokala nisu ista količina memorije: svi redovi se učitaju u jedan niz, a crtanje PDF-a drži svaku stranicu do kraja pa gotov fajl napravi još dvaput - i to u istom procesu koji poslužuje kasu i kuhinjski ekran, bez ijednog ograničenja memorije. Kvar ne bi bio spor izvoz nego ugašen kontejner i prekinuta veza svakom terminalu usred smjene. Sada se odbija s brojem redova i prijedlogom užeg perioda, jer skraćen knjigovodstveni fajl izgleda tačno kao potpun.

        0.38.9

        8. septembar 2026.

        Popravljeno

        • Promet na ekranu i knjigovodstveni fajl više se ne razilaze za svaki povrat. Kratko plaćeni i zaokruženi računi ušli su u promet, ali se povrat oduzimao samo ako je račun i dalje pisao kao plaćen u cijelosti. Gost koji zaokruži 48,00 na 50,00 i dobije 2,00 nazad ostavljao je ekran na 50,00 - s redom „od toga vraćeno 2,00" tačno ispod - dok je fajl za isti dan davao 48,00. Vlasnikov ekran i papir iz kojeg knjigovođa knjiži razlikovali su se za svaki povrat na računu koji nije namiren u fening.
        • Stari stolovi zatvoreni gotovinom više se ne broje dvaput. Popuna kolone o naplaćenom za table upisala je cijeli iznos računa na svaki stari sto zatvoren gotovinom ili karticom, uz obrazloženje da se dio plaćen QR-om „više ne može odvojiti". Može: uplate nose oznaku stola i to je tačno taj iznos. Sto od 100,00 KM gdje je jedan gost poslao 40,00 QR-om, a konobar uzeo 60,00 u gotovini, brojao se kao 40,00 preko banke plus 100,00 gotovine: promet 140,00 KM na računu od 100,00. Ista greška išla je i kroz pregled po prostorijama i kroz satni grafikon, a kako je pogrešna vrijednost bila upisana u bazu a ne računata, preživjela bi svaku kasniju ispravku čitanja. Nova migracija oduzima bankovni dio; provjerena je na sva četiri oblika reda koja može zateći.
        • Nadogradnja više ne ostavlja server zaglavljen na staroj verziji. Migracije su se primjenjivale dok je prethodna verzija još posluživala promet, a kontejneri su se mijenjali tek poslije. U tom prozoru migracija koja kolonu čini obaveznom pukne: stari kod upiše red bez te vrijednosti, provjera padne na tom redu, i Prisma zapiše migraciju kao neuspjelu. Od tog trenutka svaka sljedeća nadogradnja odbija da primijeni bilo šta, uključujući migracije poslije te - pa server ostaje na staroj verziji, a dugme za nadogradnju u konzoli to ne može popraviti; treba neko na serveru s Prisma alatom. Dvije migracije u ovom repozitoriju već imaju taj oblik. Aplikacija se sada zaustavlja prije migracija, a provjera pred puštanje pazi da tako i ostane.

        0.38.8

        8. septembar 2026.

        Popravljeno

        • Isti mjesec se više ne može fakturisati dvaput. Kad se draft upiše pa odmah poslije toga pukne upis koji samo bilježi koji je draft nastao, stara obrada je vraćala mjesec kao nenaplaćen - a faktura je već postojala. Sutra ujutru bi posao podigao drugi identičan draft za isti mjesec: dvije kirije za oktobar, dva broja potrošena iz serije, i 1.300,00 KM traženo od stanara koji duguje 650,00. Vraćanje mjeseca sada pokriva samo upis fakture; sve poslije toga je bilježenje nečega što se već desilo.
        • Raspored se više ne može trajno zaustaviti. Mjesec se zauzimao jednim upisom, a datum sljedećeg pokretanja pomjerao drugim, i proces koji umre između njih - novi deploy, OOM, restart mašine - ostavljao je red u jedinom stanju iz kojeg nema izlaza: zauzeti mjesec je tačno mjesec datuma koji se nije pomjerio, a oba testa koja odlučuju hoće li se raspored pokrenuti porede baš to dvoje. Raspored ostaje aktivan, posao ga čita svako jutro i ne podiže ništa. Stanodavcu kirija prosto prestane da se fakturiše, bez ijedne greške, a ni "pokreni sada" ga ne može oživjeti: vrati 200 i broj prošlomjesečne fakture. Datum se sada pomjera istim upisom kojim se mjesec zauzima.
        • Jedna faktura može imati samo jedan živi raspored, i to sada čuva baza. Provjera je bila čitanje pa upis, bez brave i bez indeksa iza sebe, pa su dva zahtjeva dovoljno blizu jedan drugom oba prošla: dvoklik koji prestigne ponovno iscrtavanje, dva menadžera na istom nalogu, ili integracija koja ponovi zahtjev čiji je odgovor izgubljen. Rezultat je dva rasporeda na istoj fakturi, svaki sa svojim zauzimanjem mjeseca, pa se svakog mjeseca podižu dva identična drafta za istog kupca - zauvijek, i ništa u proizvodu to ne označava. Zaustavljanje rasporeda oslobađa fakturu, pa se može ponovo pokrenuti.
        • Raspored napravljen 29., 30. ili 31. više ne gubi svoj dan. Prvi termin se namjerno skraćuje na dužinu mjeseca - 31. pada na 28. u februaru - ali se dan sidra čitao nazad s tog skraćenog datuma i tako trajno upisivao. Stanodavac koji 31. januara pritisne ponavljanje dobio bi raspored sidren na 28., pa bi se kirija podizala 28. marta, aprila i maja do kraja najma. Skraćivanje traje jedan mjesec, ne cijelu knjigu.

        0.38.7

        8. septembar 2026.

        Popravljeno

        • Jedna uplata koja je račun podigla dvaput. Kad je jedan transfer stigao s viškom, matcher prvo namiri račun pa odmah kaže za koliko je preko: dva poteza za jedan novac. Oba su knjižila na sto, pa je sto pisao da je naplaćeno duplo više nego što je stiglo. Na kodu za dio računa gosti koji još sjede dobiju manji dio nego što duguju i veče se zatvori kraće za tačno jedan dio, bez ijednog traga na ekranu. Na kodu za cijeli račun prvi transfer zatvori sto, pa drugi padne na zatvoren sto i obilježi ga kao vjerovatno plaćen dvaput: optužba protiv gosta koji je platio jednom. Knjiži se sada na ulasku u namireno, ne na svakom potezu unutar njega.
        • Uplata koja nije upisana više se ne prijavljuje kao uparena. Kad dvije uplate za isti račun stignu istovremeno, druga se odbija jer je iznos iz kojeg je računata u međuvremenu promijenjen - i njen novac nije upisan nigdje. To se javljalo istom riječju kojom se javlja i "račun je već namiren" i "potez nije dozvoljen", a obje te riječi znače da se može dalje. Obje grane matchera su tako i radile: obilježile bi izvod kao uparen s računom koji tu uplatu nikad nije primio. Novac je u banci, nije ni na jednoj pločici, manjka u knjigovodstvenom fajlu, a iz reda za uparivanje je ispao jer piše da je uparen. Niko u lokalu ga ne može naći.
        • Otkazivanje koda ne odbacuje novac koji je stigao. Dugme kojim konobar obara kodove sa stola pobroji žive kodove pa ih otkazuje jedan po jedan, i uplata koja stigne između popisa i otkazivanja bila je otkazana zajedno s kodom. Otkazan račun je van kandidata za uparivanje, van onoga što sto računa kao zauzeto i van onoga što se može vratiti, a sto nikad nije knjižen - pa konobar naplati cijeli račun u gotovini stolu koji je već poslao dio, i ništa u proizvodu taj dio ne može vidjeti, prikačiti ni vratiti. Pravilo je sada na samim vratima kroz koja svaka promjena statusa prolazi, i čita se unutar iste transakcije.
        • Provjera da kodovi ne premašuju račun sada čita stanje pod bravom. Ponovo je brojala žive kodove pod bravom, ali ih je poredila s iznosom pročitanim prije nego što je kod uopšte napravljen - a upravo se to i mijenja u tom prozoru. Sto od 20,00 KM gdje šank otkaže rundu od 8,00 dok se kod pravi: račun padne na 12,00, a gost dobije QR na 20,00. Uplata se poklopi s kodom u fening pa se namiri kao plaćeno, bez slučaja i bez obavijesti, i lokal zadrži 8,00 KM koje niko nije dugovao.

        0.38.6

        8. septembar 2026.

        Interno

        • CI se sada vrti ovdje, po koracima pročitanim iz same CI datoteke. GitHub od 7. septembra ne pokreće nijedan posao na ovom repozitoriju. Svako pokretanje završi za dvije sekunde, bez ijednog koraka, s jednom jedinom porukom: posao nije pokrenut jer plaćanje na računu nije prošlo ili treba podići limit potrošnje. Nije riječ o grešci u kodu. Provjereno je svih dvadeset zadnjih crvenih pokretanja i sva nose tu istu poruku i nijednu drugu. Ali kvačica pored svakog commita je crvena, a na push se ne provjerava ništa.

        0.38.5

        8. septembar 2026.

        Interno

        • Provjera da image nosi ono što kod traži. Dva posla u CI-ju koja grade image i dižu produkcijski stack ne rade od 7. septembra, jer ih GitHub ne pokreće dok se ne riješi naplata, a Docker na razvojnoj mašini ne radi. Klasa greške koju ti poslovi hvataju - kod koji u radu poseže za putanjom koje u imageu nema - trenutno se nije hvatala nigdje. To je ovaj projekat već jednom koštalo, u drugom smjeru: devetnaest fotografija jela upisanih u stablo iz kojeg server ne servira, nevidljivo u svim setovima jer su se obje polovine testa slagale oko toga koji je to direktorij.

        0.38.4

        8. septembar 2026.

        Popravljeno

        • Sto sa izdatim kodom izgledao je isto kao svaki drugi otvoreni račun. Broj živih kodova stoji u odgovoru otkad je popravljeno da podijeljeni kod ne blokira naplatu gotovinom, a ekran ga je koristio samo da odluči hoće li nacrtati dugme - pa je sto sa tri izdata koda izgledao kao bilo koji drugi, uz jedno dugme više. Iznos koji ti kodovi drže vraćao se i nije ga koristio niko. Sada red piše koliko je kodova izdato i na koliko, prije nego što konobar krene do stola, a ne poslije.
        • Iznos je izlazio u feningima. Prvi ekran koji ga je prikazao proveo ga je kroz isti formatter kao ostatak reda, koji očekuje decimalni zapis, pa je konobaru pisalo da je 6,50 KM računa na tuđem telefonu kao 650,00 KM. Novac sada izlazi iz servisa već ispisan, kao i svaki drugi iznos u tom redu.

        0.38.3

        8. septembar 2026.

        Popravljeno

        • Zanemarena uplata je sa svakog ekrana i dalje bila izgubljena zauvijek. Ruta koja izlistava zanemarene i ruta koja ih vraća u red napravljene su prije nekoliko sedmica, i na ploči je pisalo da je rupa zatvorena. Konzola nijednu nije koristila: zanemarivalo se jednim klikom bez pitanja, nije bilo gdje pogledati šta je odloženo, i nije bilo dugmeta za povratak. Tri prevoda koja je taj isti commit dodao stajala su neiskorištena. Sada se pita prije, sa iznosom u pitanju, postoji prekidač „Zanemarene" i svaki takav red ima „Vrati u red".

        0.38.2

        8. septembar 2026.

        Popravljeno

        • „Ponovi isto" nije postojalo na telefonu gosta. Ruta, servis i oznaka po narudžbi koja kaže može li se runda vjerno ponoviti postojali su sedmicama, i na ploči je stajalo da je gotovo. Telefon dugme nikada nije prikazao, pa nijedan gost nikad nije mogao ponoviti ništa: prevod „Ponovi isto" je stajao u oba kataloga i niko ga nije tražio. Sada stoji ispod svake runde koju je taj telefon naručio, i samo kada server kaže da se može ponoviti vjerno: ako je jelo u međuvremenu skinuto sa menija, dugmeta nema, jer je u bučnom lokalu gore pritisnuti dugme koje odbije nego ga ne vidjeti.
        • Runda se ponovo cijeni po trenutnom cjenovniku, ne prepisuje: kafa koja je poskupila između dvije ture naplaćuje se po onome što košta sada.

        0.38.1

        8. septembar 2026.

        Dodano

        • Ekran za ponavljajuće račune, na listi faktura. Panel iznad liste pokazuje koje se fakture same podižu, koliko često, kada je sljedeća i koji je nacrt podignut zadnji put; zaustavljeni ostaju u listi, sivi, sa datumom umjesto dugmeta. Ponavljanje se uključuje sa same fakture, jer je ona predložak: tako postoji jedno mjesto na kojem je račun opisan umjesto druge forme koja se vremenom razmimoiđe sa njom. Panel se ne prikazuje lokalima koji nemaju šta ponavljati.

        0.38.0

        8. septembar 2026.

        Dodano

        • Račun koji se sam ponavlja, mjesec za mjesecom. Dugme „ponovi" je skinulo prekucavanje i ostavilo pamćenje: neko je i dalje morao znati da je prvi u mjesecu. Za stanodavca sa devet stanova to je bio cijeli posao. Sada se izabere jedna faktura, kaže se koliko često - mjesečno, kvartalno ili godišnje - i od kojeg datuma, a posao svako jutro podigne kopiju.
        • Ono što podigne je nacrt, nikad izdata faktura. Izdavanje uzima broj iz vlastite serije dokumenata i može poslati račun kupcu, a nijedno od toga nije stvar koju treba raditi dok niko ne gleda: pogrešan iznos izdat u četiri ujutro mora se poništiti, a broj ostaje potrošen. Nacrt čeka na ekranu i neko pritisne „Izdaj".
        • Datum se ne pomjera. Raspored zakačen za 31. sleti na zadnji dan februara i vrati se na 31. u martu, umjesto da se povuče na 28. i tu ostane do kraja najma. Kvartal je tri mjeseca a ne devedeset dana, i sve se računa po ponoći u vremenu lokala, ne po UTC-u.
        • Isti mjesec se ne može obračunati dvaput. Posao ide svaki dan, pa bi raspored koji kasni jedan dan inače podizao račun svako jutro dok neko ne primijeti da stanar ima četiri fakture za oktobar. Mjesec se zauzme prije nego što se račun napiše, uslovnim upisom, pa ni dvije instance ne mogu uzeti isti. Ako pisanje ne uspije, zauzeće se vraća da bi sutra bio novi pokušaj.
        • Može se podići i ranije, ali samo jedan mjesec unaprijed, za stanodavca koji hoće oktobarsku kiriju na stolu u septembru. Drugi pritisak se odbija i kaže kada je sljedeći na redu.
        • Zaustavljanje se pamti. Raspored se ne briše nego se gasi, sa tim ko ga je ugasio i kada: „zašto se kirija prestala fakturisati u martu" je pitanje koje neko postavi u junu.

        0.37.33

        8. septembar 2026.

        Dodano

        • Dugme za PDF pored dugmeta za CSV, na ekranu Plaćanja. Isti mjesec, isti redovi, dva oblika: CSV se uvozi u knjigovodstveni program, PDF se odlaže u registrator. Koji od ta dva neko želi nije nešto što ovaj ekran može znati, pa se nude oba umjesto da se pogađa.

        0.37.32

        8. septembar 2026.

        Popravljeno

        • Faktura duža od jedne stranice imala je praznu stranicu iza svake pune. Broj stranice se ispisuje ispod donje margine, a PDF alat za svaki tekst ispod margine otvori novu stranicu. Numerisanje je tako dodavalo praznu stranicu za svaku koju je numerisalo: faktura od dvije stranice odlazila je kupcu kao četiri, svaka druga prazna. Ništa nije prijavljivalo grešku, a jedina provjera koja je postojala tražila je "više od jedne stranice", što je i ovako bilo tačno.

        Dodano

        • Pregled naplaćenog kao PDF, uz postojeći CSV. Knjigovođa uvozi CSV a u registrator odlaže papir, pa sada postoji i papir: isti redovi, isti redoslijed, ista zaglavlja, položeno na A4 jer izvještaj ima petnaest kolona i nijedna nije višak. Zaglavlje tabele se ponavlja na svakoj stranici, a na kraju stoji zbir kolone Uplaćeno, koji se može provjeriti sabiranjem same stranice. Oba dokumenta se prave iz istog čitanja podataka, jer bi dva odvojena upita vremenom počela odgovarati na malo različita pitanja i lokal bi ostao da bira kojem svom dokumentu da vjeruje. Ni ovdje se ništa ne odbija i ni ovdje to nije bankovni izvod, isto kao u CSV-u.

        0.37.31

        8. septembar 2026.

        Popravljeno

        • Kada neko za stolom plati jednu od dvije kafe, onome ko ih je naručio je pisalo da ne duguje ništa. Iznos "moje" na telefonu preskakao je svaku stavku za koju je bilo ko držao kod. To je bilo tačno dok je zahtjev išao na cijelu stavku, i pogrešno od trenutka kada je postao broj komada: jedna plaćena kafa je izbacila obje iz iznosa. Gost koji ih je naručio vidio je 0,00, platio to, i sto je otišao kući kraći za dvije i po marke sa stavkom koja je i dalje na računu. Sada se broji ono što je ostalo, po komadu.
        • Poništena faktura je pisala "Poništeno: Poništeno iz dashboarda". Konzola je slala razlog kao konstantu, pa je svako poništenje ikad zabilježeno reklo istu stvar, a ekran ga je ispisivao kroz "Poništeno: {razlog}". Sada se pita zašto, prije nego što se išta uradi: broj fakture ostaje zauzet, kod za plaćanje se gasi i to se ne može vratiti, pa pitanje ide uz potvrdu uplate kao stvar oko koje se ne prolazi jednim klikom. Knjigovođa koji pita zašto je faktura povučena sada ima odgovor na samoj fakturi.

        0.37.30

        8. septembar 2026.

        Popravljeno

        • U noći kada se sat pomjeri unazad svaki sto je pokazivao upola manje računa dnevno. Posljednja nedjelja u oktobru u Sarajevu traje dvadeset pet sati: sat ide unazad u tri ujutro i lokal prođe kroz dva sata dvaput. Kolona "Računa dnevno" dijelila je proteklo vrijeme sa dvadeset četiri sata i zaokruživala naviše, pa je ta jedna subota ispala dva dana i svaki sto na najjačoj noći jeseni pokazao polovinu onoga što je stvarno okrenuo. Mjesec koji sadrži pomjeranje dijelio se sa trideset jedan umjesto trideset, što je tiše i jednako pogrešno. Sada se broje kalendarski dani u vremenu lokala.
        • Grafikon prometa je crtan po satu lokala a označavan po satu preglednika. Server siječe stupce po danu lokala, upravo zato da promet petka uveče ne pripadne četvrtku, a oblačić iznad tačke je vrijeme ispisivao bez ijedne zone, pa je čitao onu na kojoj je mašina. Na laptopu u lokalu se to poklapa i greška se ne vidi; vlasnik koji gleda iz Minhena vidio je svaki stupac pomjeren za sat, a sa mašine ostavljene na UTC za dva.
        • Na mjesečnom grafikonu je oblačić pisao 00:00 za svaku tačku. Stupac širok jedan dan i dalje se ispisivao kao sat i minuta, pa oblačić nije govorio ništa što iznos iznad njega već nije rekao. Sada piše datum.
        • Broj uplata u oblačiću je bio u istom obliku za sve brojeve. Obje grane su bile ista riječ, pa su jedna uplata i dvije uplate izgledale isto, u jeziku koji to ne kaže tako.

        0.37.29

        8. septembar 2026.

        Popravljeno

        • Dva telefona koja u istoj sekundi označe istu stavku dobijala su oba svoj kod. Plaćanje odabranih stavki radi se u dva koraka koja nisu jedan: prvo se pročita šta drugi kodovi već drže, pa se onda kod napravi. Provjera poslije toga gledala je samo iznos, a iznos ne odgovara na pitanje o stavkama: dvije kafe od 3,00 KM na računu od 33,00 daju 6,00, što je uredno ispod računa, pa su oba koda ostala živa. Jedna kafa je plaćena dvaput, biftek koji niko nije uzeo ostao je neplaćen, a račun je pokazivao 6,00 od 33,00 bez ijedne stavke na koju se može pokazati. Sada se i stavke provjeravaju, pod istom bravom, i kod koji je prešao preko onoga što sto ima povlači se prije nego što ga gost uopšte vidi.
        • Povrati se nisu vidjeli u fajlu za knjigovođu. Puni povrat je bar prebacivao račun u status vraćenog. Djelimični nije: 20,00 vraćeno na račun od 80,00 ostavljalo je red koji piše 80,00 i ništa drugo nigdje, pa je knjigovođa knjižio osamdeset maraka prihoda na šezdeset maraka novca, dok je pločica prometa u konzoli povrate oduzimala sedmicama. Povrat sada ima svoj red, negativan, sa datumom dana kada je novac vraćen a ne dana računa na koji se odnosi, pa račun iz prošlog mjeseca vraćen ovog mjeseca ulazi u ovaj fajl.
        • Negativan iznos u fajlu se otvarao kao tekst. Zaštita koja sprječava da ime jela pokrene formulu u Excelu stavljala je apostrof ispred svega što počinje minusom. Dok u fajlu nije bilo negativnih iznosa to nije smetalo; sada bi značilo da kolona koju knjigovođa sabere pokupi novac koji je ušao a preskoči onaj koji je vraćen. Običan broj prolazi bez apostrofa, sve ostalo i dalje ne prolazi.

        0.37.28

        8. septembar 2026.

        Popravljeno

        • Promet po stolu je brojao stolove koji još sjede i one koji su otišli bez plaćanja. Kolona je sabirala cijeli račun svakog stola na kojem je nešto naručeno, bez obzira na to da li je novac stigao. Sto koji je u pola jedanaest još uvijek zauzet, sa četiri hoda na računu, ulazio je punim iznosom, pa je izgledao najbolje dok gosti još biraju desert i padao kada plate. Sto koji je otišao bez plaćanja brojao se cijeli, tako da je jedini broj koji je trebao pasti dizao taj sto u poretku onih koji zarađuju. Sada se broji novac koji je stvarno stigao. Prosječan račun se računa po zatvorenim računima, jer račun koji još traje nema konačan iznos, a računi koji nisu plaćeni ostaju u prosjeku, jer je račun bio stvaran i kada novac nije stigao.
        • Pločica koja pokazuje da li banka sama potvrđuje uplate mjerila je nešto drugo. U imenilac je ulazio svaki izdati kod, pa je gost koji odabere plaćanje telefonom, predomisli se i plati gotovinom obarao broj: lokal kod kojeg je svaka uplata stigla i bila potvrđena i dalje je čitao 62,9 posto, a pločica je stajala žuta. U brojnik je ulazio svaki plaćen račun, uključujući i one koje je neko ručno potvrdio gledajući u bankovnu aplikaciju, a to je upravo ono što banka nije potvrdila: što je veza lošija, to je osoblje više radilo, a broj se manje micao. Sada se računa udio uplata koje je banka potvrdila sama, kodovi koje niko nije platio imaju svoj broj jer su problem za stolom a ne u banci, a pločica piše "Automatska potvrda".
        • Vrijeme potvrde je znalo biti negativno. Novac uplaćen direktno na naljepnicu sa stola nema račun koji ga čeka: račun se kreira kada uplata bude pročitana, a nosi vrijeme kada ga je banka proknjižila, dakle ranije. Oduzimanje je išlo unazad, pa je kafić koji većinu novca prima preko naljepnica čitao potvrdu koja je trajala minus jedan dan. Takve uplate nemaju vrijeme potvrde i više se ne mjere, a pločica kaže na koliko računa je mjerena.
        • Pregled zdravlja naplate je pratio dužinu izabranog perioda, ali ne i to gdje se nalazi. Konzola je slala samo broj dana, pa je izbor prošlog mjeseca značio zadnjih 31 dan do danas, što je gore od sedmice koja je prije toga bila fiksna, jer izgleda kao da prati izbor. Sada se šalju isti datumi kojima se čita sve ostalo na ekranu.

        0.37.27

        8. septembar 2026.

        Popravljeno

        • Gotovina naplaćena prije uvođenja jedne kolone brojala se kao nula. Kolona bilježi koliko je konobar uzeo za stolom, a čitanje je za starije račune trebalo uzeti ukupan iznos. To je napisano kao zbir cijele grupe, a SQL zbir preskoči prazne vrijednosti i vrati prazno samo ako su baš svi redovi prazni. Čim je u periodu postojao jedan noviji račun, zamjena se nije primjenjivala i svaki stariji je vrijedio nula. Lokal koji je u sedmici prije nadogradnje zatvorio 120 računa gotovinom, i jedan poslije nje, tih 120 nije vidio nigdje na prometu. Stare vrijednosti su dopunjene, kolona više ne može biti prazna, i dvosmislenog čitanja više nema.

        0.37.26

        8. septembar 2026.

        Popravljeno

        • Sto zatvoren gotovinom vraćao se na spisak otvorenih ako gost u istoj sekundi odustane od koda. Kada gost napusti ekran za plaćanje, sistem poništi kodove i vrati sto u otvoreno stanje, ali je odluku donosio na osnovu stanja pročitanog prije toga. Konobar koji u tom trenutku naplati gotovinu bio je nevidljiv: sto se vraćao kao otvoren, sa vremenom zatvaranja i naplaćenim iznosom koji su ostali na njemu. Takav sto se prikazuje na podu, telefoni mu se mogu pridružiti i narudžbe se primaju, pa lokal posluži još jednu rundu na račun koji je već naplaćen.
        • Isto i u drugom smjeru: gost koji zatraži plaćanje dok konobar naplaćuje gotovinu ostavljao je zatvoren sto na kuhinjskom ekranu, u redu „želi platiti“, dok ga neko ne zatvori po drugi put.
        • Uplata koja stigne u trenutku zatvaranja podizala je iznos na zatvorenom stolu, bez ijednog traga. Provjera je gledala stanje pročitano ranije, pa je uplata koja izgubi tu utrku povećala naplaćeni iznos i tišina. Nije se upisala oznaka na uplatu, nije bilo unosa u dnevnik ni upozorenja, a upravo to su tri stvari po kojima se dvostruka uplata uopšte može pronaći. Gost je bez novca dok neko ne pogleda.

        0.37.25

        8. septembar 2026.

        Popravljeno

        • Grafikon prometa crtao je samo uplate preko banke. Čitao je isključivo tabelu uplata, a naplata gotovinom ili na vlastitom POS terminalu upisuje se na sto i ne pravi uplatu. Ispod naslova „naplaćeno po satu“ stajala je kriva koja pokazuje koliko je gostiju poseglo za telefonom. Kafić koji u petak uzme 4.000 KM, od toga 2.800 u gotovini, dobio je krivu koja zbraja 1.200. Vlasnik koji poredi dva petka poredio je proširenost QR-a, ne promet. Sada grafikon broji i gotovinu i oduzima povrate, pa daje isti iznos kao pločica iznad njega.
        • Grafikon nije poštovao lokal kojem korisnik pripada. Upit je pisan direktno u SQL-u, koji ne može preuzeti Prisma filter, pa nije primjenjivao nikakvo ograničenje: osoblje vezano za jednu poslovnicu vidjelo je krivu cijelog lanca, dok je svaka druga brojka oko nje bila ograničena na njihovu poslovnicu.
        • Prozor grafikona bio je pomjeren za dva sata. Kolona sa vremenom čuva UTC zidni sat bez oznake zone, a sirovi upit ju je poređivao sa vezanim parametrom koji nosi zonu, pa je Postgres jedno pretvarao u drugo prije poređenja. Uplate pri rubu dana ispadale su iz grafikona iako su na svim ostalim brojkama tu. Nađeno tako što se grafikon i pločica nisu slagali ni nakon prve popravke.

        0.37.24

        8. septembar 2026.

        Dodano

        • Odštampan kod za sto sada se može povući, i vratiti u upotrebu. Mogućnost je postojala u API-ju otkad je modul napisan, gdje limit plana broji samo aktivne stolove i naziv se oslobodi tek kad se red povuče, a nijedan ekran je nije zvao. Spisak stolova je sa svakog ekrana bio samo za dodavanje. Lokal koji na dan pilota odštampa dvadeset kodova sa pogrešnim prefiksom nije imao šta da uradi: kodovi ostaju živi, troše dozvoljeni broj stolova, a naljepnica je jedina stvar kojom gost otvara račun. Sada red ima dugme, pita prije nego što povuče, i povučeni sto ostaje na spisku sa oznakom i dugmetom za povratak.

        0.37.23

        8. septembar 2026.

        Popravljeno

        • „Zanemari uplatu“ je bila konačna, bez pitanja i bez povratka. Zanemarena uplata je dobijala oznaku koju nijedan spisak nije prikazivao i nijedna ruta nije poništavala: stvarna uplata koja je stigla u banku nestajala je sa svakog ekrana i iz svakog odgovora, zauvijek. Dugme je stajalo pored „Zakači“, koje je isključeno dok se ne izabere račun, pa je na običnom redu bilo jedino što se moglo pritisnuti. Sada pita prije nego što uradi, postoji spisak zanemarenih i dugme koje ih vraća u red.

        0.37.22

        8. septembar 2026.

        Popravljeno

        • Kod za podijeljen račun blokirao je naplatu gotovine, a dugme iz poruke nije bilo na ekranu. Kada gosti dijele račun ili plaćaju svoje stavke, sto ostaje otvoren, jer samo kod za cijeli račun mijenja stanje stola. Spisak otvorenih računa nije nosio nikakvu informaciju o kodovima, a dugme „otkaži kod“ prikazivalo se prema stanju stola. Sto sa tri aktivna koda izgledao je kao svaki drugi otvoren sto: naplata gotovine je odbijena porukom „prvo otkažite kod“, a to dugme nije bilo nigdje. Jedino dugme koje nije odbijeno je „naplaćeno prenosom“, pa je gotovina iz konobarove ruke završavala zavedena kao bankovna uplata koja nikada nije stigla. Sada spisak kaže koliko je kodova aktivno, a dugme se pojavljuje kad ih ima.

        0.37.21

        8. septembar 2026.

        Popravljeno

        • Računi zatvoreni poslije ponoći naplaćivali su se u pogrešan mjesec. Mjesec po kojem se broji promet računao se u UTC-u, pa je za Sarajevo ljeti trajao od prvog u 02:00 do prvog idućeg u 01:59. Bar koji radi poslije ponoći zatvori zadnje račune 30. septembra između 00:10 i 01:40 prvog oktobra, i ti računi su ulazili u septembar: i na ekranu gdje lokal gleda svoju potrošnju, i na računu koji noćni obračun izda. Svaka druga granica dana u proizvodu je odavno bila po vremenu lokala; ova, koja odlučuje o novcu, nije. Sada jeste.
        • Faktura izdata poslije ponoći na Novu godinu dobijala je broj iz stare godine. Datum na dokumentu se piše po vremenu lokala, a godina u broju fakture uzimala se iz sata servera, koji radi u UTC-u. Ugostitelj koji izda fakturu u 00:30 prvog januara dobio je dokument sa datumom 01.01.2027. i brojem 418/2026, koji nastavlja zatvorenu godinu, a sljedeća faktura tog jutra dobila je broj 1/2027. Ostaje dokument iz jedne godine numerisan u drugu i serija sa jednim unosom više nego što knjige pokazuju.

        0.37.20

        8. septembar 2026.

        Popravljeno

        • Kasa na šanku je tvrdila da novac nije stigao, i prestajala gledati. Kada kod istekne, matcher još sat vremena prima uplatu koja je iz gostove banke krenula na vrijeme. Kasa je u tom trenutku pisala „Novac nije stigao“ i prestajala pitati server, pa uplata poslana nekoliko sekundi prije isteka nikada nije stigla na ekran. Konobarski terminal je namjerno napravljen suprotno i nastavlja gledati. Sada i kasa nastavlja, a tekst kaže ono što se zna: kod se više ne može platiti, a ako je gost poslao uplatu, još može stići.
        • Poruka je gosta slala da traži nešto što nijedan ekran ne može. Kada je za stolom previše telefona, pisalo je „Pozovite osoblje da vas doda“, a nigdje u proizvodu ne postoji dugme koje dodaje telefon na otvoren račun. Konobar dođe i nema šta da uradi. Sada piše šta se stvarno može: sačekati da neko završi, ili zamoliti osoblje da naruči.
        • Poruka o fakturama upućivala je na postavku koje nema. Pisala je da se „promijeni tip billera u postavkama lokacije“, a to je izraz iz baze i takve postavke nema ni na jednom ekranu koji lokal može otvoriti.
        • Brojevi na ekranu sa stolovima nisu bili u pravom padežu. Pisalo je „1 narudžbi“ i „3 narudžbi“, i „2 od 4 stolova zauzeto“. Ekran sa narudžbama je isti podatak oduvijek pisao ispravno. Sada je i ovdje: 1 narudžba, 3 narudžbe, 8 narudžbi, i 2 od 4 stola.

        0.37.19

        8. septembar 2026.

        Popravljeno

        • Izvoz za knjigovodstvo nije se sortirao po vlastitoj koloni datuma. Redovi se biraju i ređaju po danu kada je račun izdat, a kolona „Datum“ je pisala trenutak kada je priliv obrađen, a to je kod izvoda koji se učitava ručno jutro nekoliko dana kasnije. Račun naplaćen 31. avgusta u 21:40 završio je u avgustovskom fajlu sa datumom 1. septembra, a u septembarskom ga nije bilo uopšte. Knjigovođa koji knjiži po toj koloni upiše septembarski datum u avgustovsku knjigu i za njega ne nađe ništa u septembru. Sada je „Datum“ dan izdavanja računa, isti po kojem se fajl bira i sortira, a kada je novac stigao dobilo je svoju kolonu „Datum priliva“, iz datuma knjiženja same banke, koji se ranije nije čitao nigdje.
        • Povrat se oduzimao od dana kada je račun izdat, a ne od dana kada je vraćen. Obje stavke o povratima filtrirale su se po datumu računa i nikada po datumu samog povrata. Menadžer koji u ponedjeljak vrati 50,00 na subotnji račun mijenjao je subotu: dan koji je vlasnik već zapisao pao je za pedeset, sa objašnjenjem koje se pojavilo naknadno, dok ponedjeljak, dan kada je kasa stvarno bila kraća, nije pokazivao ništa.

        0.37.18

        7. septembar 2026.

        Popravljeno

        • Uplata koja nije tačna u fening nije bila ni na jednoj pločici. Gost koji u banci upiše 45,00 umjesto 50,00 ostavlja račun u stanju „plaćeno manje“, a ko zaokruži naviše u „plaćeno više“. Oba znače da je novac na računu lokala, a nijedno se nije brojalo: ni u promet, ni u čekanje, ni u neuspjele. Račun nije bio nigdje, dok ga je izvoz za knjigovodstvo za isti period uredno navodio, pa se konzola i izvoz nisu slagali za iznos svake takve uplate. Sada se broji ono što je stiglo, i posebno se prikazuje koliko je takvih uplata, jer iza svake stoji slučaj za uparivanje i neko kome se vraća ili ko još duguje.
        • Pregled po poslovnici nije se slagao sa pločicom iznad njega. Brojao je samo tačno plaćene račune u punom iznosu: bez uplata koje nisu tačne, bez oduzetih povrata i bez gotovine. Lokal sa jednom poslovnicom koji je vratio jedno jelo čitao je 900,00 u prometu i 1.000,00 u redu za istu poslovnicu istog dana, dva panela jedan ispod drugog. Lanac čiji najprometniji lokal naplaćuje uglavnom gotovinom vidio je taj lokal na dnu liste. Sada se sve tri stvari broje po sobi.

        0.37.17

        7. septembar 2026.

        Popravljeno

        • Kod koji je istekao držao je sto sat i po bez mogućnosti plaćanja preko QR-a. Istekli kod još sat vremena čuva svoj dio računa, da bi uplata koja je već krenula imala gdje stići. Kod za cijeli račun čuva cijeli račun, pa nakon isteka sto nije mogao platiti ništa preko koda: ni cijeli račun, ni podjelu, ni svoje stavke. Ništa to nije moglo osloboditi, jer poništavanje nije bilo dozvoljen potez iz stanja „isteklo“: ni konobarevo dugme, ni gost, ni API. Sedamdeset pet minuta gotovine ili čekanja, usred smjene. Sada konobarevo dugme skida i istekle kodove.
        • Poništavanje koda sada ostavlja trag. Pisalo se pravo u red, bez zapisa o promjeni stanja, bez unosa u dnevnik i bez poruke prema kasi. Kasa koja zatvara račun na poruku o poništenju nikada nije saznala da je gost odustao, a ko kasnije pogleda taj račun nije mogao vidjeti ko ga je i kada završio.

        0.37.16

        7. septembar 2026.

        Popravljeno

        • Ekran u kuhinji je znao zaćutati do kraja smjene poslije prekida veze. Prijava za živi kanal traje petnaest minuta, a nova se traži prekasno da stigne u pokušaj koji je već krenuo. Server odbije istekli token, a ekran je na to gasio vezu zauvijek, iako je svježa prijava ležala spremna pored njega. Sada se poslije odbijanja jednom uzme nova prijava i pokuša ponovo. Ako i ona bude odbijena, neko se odjavio ili je uređaj odvezan, pa je odustajanje tačan odgovor.
        • Dva pritiska na „napravi QR“ pravila su dva računa. Ključ koji sprečava dupliranje uzimao se iz sata u trenutku slanja, pa je ponovni pokušaj dobijao drugi ključ. A ponovo se pritiska samo kad veza pukne, kada je prvi zahtjev već stigao do servera: gost je imao dva aktivna koda, a onaj koji ne skenira ostajao je otvoren u dnevnom pregledu. Sada ključ pripada prodaji, a ne pritisku, i mijenja se tek kada konobar promijeni iznos ili sto.

        0.37.15

        7. septembar 2026.

        Popravljeno

        • Gost je plaćao stari iznos kada se račun promijeni dok mu je kod otvoren. QR nosi iznos za koji je izdat i ne mijenja se. Šank javi da nema piva, konobar skine tu stavku, račun padne sa 20,00 na 12,00, a gost u banci šalje 20,00 koje se poklapaju sa kodom u fening. Uplata se zavodi kao tačna, ne kao višak, pa se ne otvara nijedan slučaj, ne šalje nijedna poruka i nigdje ne piše da lokal ima 8,00 KM koje gost nije dugovao. Sada se stavka ne može skinuti dok je kod aktivan: odbijanje se imenuje isto kao kod naplate gotovinom, a konobar prvo poništi kod, pa promijeni račun.

        0.37.14

        7. septembar 2026.

        Popravljeno

        • Kada konobar otkaže račun u istoj sekundi kada uplata legne, novac je nestajao iz evidencije. Svaka promjena stanja računa je čitala red, provjerila da li je potez dozvoljen, pa upisala samo po broju računa. Dva učesnika u istoj sekundi su oba prošla provjeru i oba upisala, a onaj koji je upisao drugi vratio je natrag i ono što nije njegovo: račun je završavao kao otkazan, bez uplaćenog iznosa i bez vremena plaćanja, dok je novac bio na računu lokala. Sada upis imenuje stanje na osnovu kojeg je odlučeno, pa gubitnik ne upiše ništa i pogleda ponovo. Isto važi i za dvije uplate koje stignu u istom trenutku.
        • Ako se pitanje izgubi, ekran više ne tvrdi da je račun otkazan. Kada otkazivanje ne prođe, tablet pita server šta je zaista bilo. To pitanje je i samo moglo propasti, jer ide istom vezom koja je upravo pukla, a ekran se tada vraćao na tastaturu kao da je sve u redu. Sada ostaje na QR kodu dok se ne sazna istina. Uz to, prepoznaje i „plaćeno više“ i „plaćeno manje“, ne samo tačan iznos.
        • Račun na koji je novac stigao ne može se više otkazati. Ako je gost platio dio, otkazivanje je uspijevalo i taj novac je ostajao na računu koji sistem više ne gleda, pa mu se ostatak uplate nikada nije mogao pripojiti. Sada se odbija i odbijanje se imenuje, a otpis razlike ostaje odluka koju čovjek donosi u konzoli sa iznosom pred sobom.
        • Uplata preko iznosa računa sada piše da je plaćeno više. Gost koji je platio dio, pa greškom pošalje cijeli iznos, ostavljao je račun u stanju „plaćeno“ sa više novca nego što je račun bio, i niko nije saznao da treba vratiti razliku.

        0.37.12

        7. septembar 2026.

        Popravljeno

        • Kasa na šanku nije vidjela uplatu koja nije bila tačna u fening. Prepoznavala je samo stanje „plaćeno“. Gost koji u banci zaokruži 19,90 na 20,00 ostavlja račun u stanju „plaćeno više“, a ko upiše manje u „plaćeno manje“, i nijedno nije stizalo do ekrana: kasa je zauvijek prikazivala isti QR dok je novac već bio na računu lokala. Sada piše da je stiglo, koliko je stiglo i koliki je bio račun, a kad kod istekne ili bude otkazan ekran to kaže umjesto da nudi QR koji se ne može platiti.
        • Kasa na šanku naplaćivala je punu cijenu dok je akcija trajala. Učitavala je meni onakav kakav se uređuje: cijene bez akcije i sve što je ugašeno. Za stolom dva metra dalje gost je u isto vrijeme dobijao sniženu cijenu, a jelo skinuto sa menija tog jutra i dalje se moglo prodati sa kase. Sada kasa učitava isti meni koji vidi gost, sa cijenom koju server naplaćuje.
        • Biblioteka za POS partnere: dvostruki račun i čekanje bez potrebe. Ako pozivalac ne pošalje broj računa, zahtjev je išao bez ključa jedinstvenosti, pa je ponovni pokušaj nakon prekida veze pravio drugi račun za istog gosta. Sada ključ uvijek postoji. Uz to, čekanje na uplatu nije priznavalo „plaćeno više“ i „plaćeno manje“, pa je držalo kasu do isteka od petnaest minuta na računu koji je odavno plaćen.

        0.37.11

        7. septembar 2026.

        Popravljeno

        • Izvod bez datuma knjiženja dobijao je datum uvoza. U camt izvodu datum knjiženja nije obavezan i ima banaka koje šalju samo datum valute. Čitanje je za sve što nedostaje upisivalo trenutni čas, i to kao tačno poznat trenutak. Ko u ponedjeljak učita petkov izvod dobio je sve uplate zavedene kao da su stigle u ponedjeljak ujutro, pa ih sistem nije mogao spojiti ni sa jednim računom: uparivanje gleda račune otvorene u zadnja dvadeset četiri sata prije uplate. Sada se uzima datum knjiženja, pa datum valute, pa datum kada je banka napravila izvod. Ako izvod ne kaže nijedan, stavka se preskoči i to piše u izvještaju o uvozu, umjesto da se datum izmisli.

        0.37.9

        7. septembar 2026.

        Popravljeno

        • Dio webhookova sa spiska nije slao niko. Na stranici o API-ju stoji spisak događaja na koje se sistem lokala može prijaviti, i taj spisak je obećavao više nego što je slato. order.placed i reconciliation.review_required išli su samo na ekrane u lokalu, a ne i pretplatnicima; payment.manually_confirmed i invoice.sent postoje samo kao zapis u dnevniku i ne šalju se nikome. Ko se prijavio čekao je zauvijek, bez greške i bez traga igdje. Prva dva se sada šalju, druga dva su skinuta sa spiska, a provjera u izgradnji od sada ne da spisku i stvarnosti da se raziđu.
        • Skinuti terminal.online i terminal.offline. Bili su navedeni kao događaji, a ništa ih nikada nije proizvodilo: uređaj ima vrijeme posljednjeg javljanja i niko ga ne prati. Ime na spisku je obećanje, pa ostaju vani dok iza njih ne bude nešto stvarno.

        0.37.8

        7. septembar 2026.

        Popravljeno

        • Račun je pisao DOSPJELO već na dan kada dospijeva. Rok plaćanja je dan, a ne trenutak: ko na računu piše „Rok plaćanja: 20. septembar“ ima cijeli dvadeseti. Datum unesen na ekranu čuva se kao početak tog dana, pa je račun prešao u dospjelo u ponoć tog istog dana i kupac je bio u kašnjenju prije nego što je banka i otvorila. Isto je bilo i na našim računima prema lokalima, koji dospijevaju petnaest dana od minute izdavanja. Sada račun postaje dospio tek kada cijeli dan roka prođe.

        0.37.7

        7. septembar 2026.

        Sigurnost

        • Ekran u kuhinji mogao je pratiti naplaćivanje, iako mu se novac ne pokazuje. Kada se ekran ili tablet spoji na živi kanal, dobije tačno ono što mu pripada: kuhinjski ekran vidi narudžbe, ne i iznose, a osoblje vezano za jedan lokal vidi samo taj lokal. Postojao je i drugi ulaz, kojim klijent naknadno traži jedan račun po broju, a on je provjeravao samo da li račun pripada istoj firmi. Time je kuhinjski ekran mogao pratiti iznos, napojnicu i poziv na broj, a konobar vezan za jedan lokal račun sa stola u drugom. Sada oba ulaza traže isto.

        0.37.6

        7. septembar 2026.

        Sigurnost

        • Naljepnica za sto mogla je biti uparena kao kasa. Stolovi se čuvaju kao uređaji vrste „naljepnica“, a naljepnica je papir: nema ekran, niko se na nju ne prijavljuje i ne ulazi u limit uređaja po lokalu. Ekran za dodavanje uređaja je ipak primao tu vrstu i za nju izdavao kod za uparivanje, a taj kod daje token koji smije naplatiti. Takav red se ne vidi na spisku uređaja, ne broji se u limit i „novi kod“ ga odbija, pa se token nije mogao ni vidjeti ni povući. Sada se naljepnica ne može ni napraviti kao uređaj ni upariti, a nadogradnja briše kodove i tokene koji su ranije možda izdati na naljepnice. Stolovi se i dalje prave sa ekrana za stolove, kao i do sada.

        0.37.5

        7. septembar 2026.

        Popravljeno

        • Gost koji zaokruži iznos naviše platio je, a kasa to nije saznala. Ko u banci pretvori 47,30 u 50,00 zatvorio je račun, ali takva uplata ide pravo u stanje „plaćeno više“ i nikada ne prođe kroz „plaćeno“. Konektor je slušao samo ovo drugo, pa kasi nije javio ništa: račun ostaje otvoren, a konobar traži od gosta koji je platio da plati ponovo. Isti propust bio je i u nadoknadi propuštenog nakon prekida veze. Sada se obje vrste uplate javljaju kasi, a u logu piše koliko je stiglo i koliko je dugovano, da se vidi šta treba vratiti.
        • Konektor je zaboravljao račune koji još nisu plaćeni. Spisak računa na koje se čeka jedino je što preživi pad interneta: bez njega uplata koja stigne dok veza ne radi nikad ne bude isporučena kasi. Taj spisak se čistio na svaku poruku sa servera, a četiri vrste poruka ne znače kraj računa: djelimična uplata, poruka da je račun tek napravljen, povrat i neuspjeh. Sada se račun skida sa spiska tek kada je naplaćen, istekao ili otkazan.

        0.37.4

        7. septembar 2026.

        Popravljeno

        • Godišnja pretplata se obračunavala kao da traje mjesec dana. Dodatak za ugostiteljstvo (49 KM po lokalu koji prima narudžbe za stolom) i broj uključenih transakcija cijene su po mjesecu, a račun ih je množio brojem perioda, a kod godišnje pretplate period je godina. Lokal koji plaća godišnje dobijao je jedan mjesec dodatka naplaćen za cijelu godinu i jedan mjesec uključenih transakcija da pokrije dvanaest: na istom računu manje naplaćeno na jednoj stavci, više na drugoj. Sada se sve što je cijena po mjesecu množi brojem mjeseci. Dogovoreni iznos licence ostaje kakav jeste, jer ta kolona znači koliko se naplaćuje po jednom periodu.

        0.37.3

        7. septembar 2026.

        Popravljeno

        • Dvoje gostiju za istim stolom, isti iznos, jedna uplata se gubila. Naljepnica ima trajni poziv na broj, pa svaka uplata za taj sto nosi isti. Kada banka ne pošalje svoj identifikator uplate, sistem je dvije uplate razlikovao po stolu, iznosu i trenutku knjiženja, a camt izvod smije dati samo datum bez vremena, i to ovdje šalju. „Isti trenutak" je time postalo „isti dan": drugi gost je pripojen prvome i njegov novac nije nigdje zaveden.

        0.37.2

        7. septembar 2026.

        Popravljeno

        • Kod za plaćanje na svakoj PDF fakturi bio je štampan magentom. Boja je zapisana sa osam cifara, jer biblioteka koja crta QR sliku prihvata i prozirnost. Biblioteka koja pravi PDF ne prihvata: od osam cifara pročita četiri broja i za ovu boju vrati crveni kanal jedanaest puta izvan opsega. QR se čita po kontrastu, pa to nije kozmetika - to je kod koji telefon možda pročita a možda ne, odštampan na dokumentu koji kupac čuva.
        • Djelimično plaćena faktura je u PDF-u i dalje nosila kod na puni iznos. Web stranica je to prestala raditi jutros, PDF nije - pa su dvije kopije istog računa tvrdile različit iznos, što je gore nego da nijedna nije popravljena. Odluka nosi li račun kod uopšte sada je na jednom mjestu i obje kopije je čitaju, pa se više ne mogu raziću.

        0.37.0

        7. septembar 2026.

        Dodano

        • Slučaj se sada može naći, ne samo prebrojati. Red za sravnjivanje ide od najstarijeg i staje na dvjesta - što je tačno kako se raščišćava zaostatak, i tačno pogrešno kad zazvoni telefon. Slučaj o kojem vas pitaju je onaj koji je stigao prije pet minuta, a iza dužeg reda nije ni na jednoj stranici koju neko otvori. Prošli put smo napisali koliko ih ima; to je reklo da postoji i ostavilo ga van domašaja.

        0.36.7

        7. septembar 2026.

        Popravljeno

        • Natpis ispod grafikona je uvijek pisao "po satu, danas". Grafikon crta po danu čim se izabere period duži od dva dana - i to je ispravno, jer bi po satu za mjesec dana bilo sedam stotina tačaka na crtici od dva centimetra. Ali natpis se nije mijenjao, pa je vlasnik koji pritisne "30 dana" gledao trideset dnevnih stubića ispod rečenice koja kaže "po satu, danas". Sada se širina stubića odlučuje na jednom mjestu i natpis čita to isto.
        • Spisak nepovezanih uplata se tiho sjekao na pedeset. Pregled broji sve i vodi na tu stranicu: poslije sedmice odsustva zdravstvena ćelija je pisala 63, stranica pokazivala 50, i nigdje ni riječi o preostalih trinaest. Ograničenje je u redu; ograničenje o kojem se ćuti je ekran koji tiho laže da je posao gotov. Sada piše "prikazano 50 od 63", isto kao što red slučajeva već radi.

        0.36.6

        7. septembar 2026.

        Popravljeno

        • Kuhinja i šank koji završe u istoj sekundi pojeli su jedno drugom upis. Tiket sa supom i pivom stoji otvoren dok obje stanice ne završe. Svaki ekran je pročitao spisak gotovih stanica, dodao sebe i upisao nazad - pa kad se pritisne u istoj sekundi, drugi upis obriše prvi. Tiket onda čeka stanicu koja je već završila i ne može nikad sići sa ploče: kartica stoji, niko ne zna zašto, i pritisne se ponovo. Supa i pivo u petak navečer nije izmišljen slučaj.

        0.36.5

        7. septembar 2026.

        Popravljeno

        • Djelimično plaćena faktura nudila je QR kod na puni iznos. Kod se pravi kad se faktura izda i nosi cijeli iznos. Plati se pola prenosom, i stranica je i dalje pokazivala taj kod pored linije na kojoj piše ostatak - pa bi kupac koji ga skenira dobio u svojoj banci opet cijeli iznos, sa tačnim brojem ispisanim šest centimetara dalje. Jedno od ta dva bi bilo vjerovano, i to ono koje telefon sam popuni. Sada kod nestane i piše zašto; račun, poziv na broj i iznos sa strane su ionako tačni i njih treba prepisati.
        • Odbijanje zbog nedostajućeg bankovnog računa sada se prepoznaje po oznaci. Konzola je to prepoznavala tražeći riječi "bank account" u engleskoj poruci servera. Server je slobodan tu rečenicu promijeniti, i onog dana kad je neko promijeni ekran bi pao na "nije uspjelo pravljenje kodova" - tačno, beskorisno, i vlasnik ne zna šta da uradi. Uz to se pokazivala i sirova engleska poruka u drugoj crvenoj traci iznad bosanske.

        0.36.4

        7. septembar 2026.

        Popravljeno

        • Konobarski terminal je javljao da je kod istekao dok je novac bio u banci. Ekran je slušao dva od sedam ishoda uplate, a dva koja je propuštao su baš ona koja znače da je prenos prošao: gost koji u svojoj banci zaokruži iznos naviše napravi uplatu veću od računa, a onaj ko otkuca manje - manju. Nijedna nije stizala do ekrana, pa bi odbrojavanje isteklo i konobar bi vidio "Kod je istekao" dok novac stoji na računu lokala. Onda gosta pita da plati ponovo.
        • Provjera se više ne prekida kad kod istekne. Kod prestaje biti skenirljiv kad mu prođe prozor, ali prenos poslan minut prije toga i dalje stigne i i dalje se poveže sa tim računom. Ekran je prestajao pitati baš u tom trenutku, pa je jedini prenos oko kojeg postoji sumnja bio i jedini koji nije mogao potvrditi.

        0.36.3

        7. septembar 2026.

        Popravljeno

        • Račun preko hiljadu maraka izdavao je kod na hiljaditi dio iznosa. Kada XPay čita račun sa trake printera - način koji koristi kasa koja ne zna ništa osim štampati - iznos se prepoznavao obrascem koji ne može preći hiljadicu. Na "UKUPNO: 1.234,56" se zaustavljao na prvoj tački i čitao 1,23. To je sasvim uredan iznos, pa ništa nije prijavilo grešku: kod je izdat na 1,23 KM, gost ga je platio, uplata se poklopila sa računom u fening, sistem ga zatvorio bez ijednog slučaja za pregled - a lokalu je falilo 1.233,33 KM dok je svaki ekran pisao da je plaćeno.

        0.36.2

        7. septembar 2026.

        Popravljeno

        • Promjena paketa je skraćivala licencu koju je neko platio. Ako operater promijeni paket a ne navede datum, rok je postajao mjesec dana od danas - pa je lokal plaćen do sljedećeg septembra ostajao sa licencom do idućeg mjeseca, bez ijedne riječi o tome. Sada se rok pomjera samo kada operater to izričito kaže, i nikad unazad: probni period pred istek i dalje dobije mjesec kad se nadogradi, a plaćena godina ostaje plaćena godina.
        • Licencni ključ je i dalje pisao stari paket. Ključ je potpisan i sam sebe opisuje, da bi program u lokalu mogao provjeriti šta smije raditi i kada internet ne radi - znači u sebi nosi paket i rok. Promjena paketa ih je mijenjala u bazi, a ključ ostavljala kakav je bio, pa je lokal prebačen na Business imao ključ koji kaže Starter, i svaka provjera bez interneta je primjenjivala paket sa kojeg je prešao. Sada se ključ izdaje ponovo.

        0.36.1

        7. septembar 2026.

        Popravljeno

        • Kasa u jednoj poslovnici mogla je pročitati bankovni račun druge. Tablet ili kasa uparena u jednom lokalu ima pravo da pročita podatke o firmi - treba joj za vlastitu poslovnicu - a dobijala je nazad sve poslovnice, sa računom, nazivom vlasnika računa i bankom. Ista ruta je jednom već stegnuta, protiv ekrana u kuhinji; da uređaj vezan za jednu poslovnicu vidi samo nju je druga polovina iste ideje. Za vlasnika i menadžera se ne mijenja ništa.
        • Brisanje PDV broja ili telefona je javljalo "Sačuvano" a ostavljalo staro. Prazno polje se slalo kao "ne diraj", pa je onaj ko je obrisao svoj PDV broj bio obaviješten da je sačuvano i našao ga na sljedećoj fakturi. Sada se prazno polje šalje kao izričito brisanje. Naziv firme se i dalje ne može obrisati - firma mora imati ime - nego samo promijeniti.

        0.36.0

        7. septembar 2026.

        Dodano

        • XPay sada zna prepoznati fiskalnu kasu u lokalu. Kasa u Bosni ne štampa sama fiskalni račun - to radi uređaj ovlaštenog proizvođača, a kasa razgovara sa njegovim programom, i to tako što mu ostavi datoteku sa komandama u jednom folderu i pročita odgovor iz drugog. Kroz taj folder prođe iznos svakog računa koji se odštampa, bez obzira koja je kasa gore. Sada postoji xpay- connector --detect: pokrene se na računaru u lokalu i kaže šta je našao, gdje, i šta dalje. Ne piše ništa, ne pokreće ništa i ne dira fiskalni tok - samo gleda.
        • Profili za sve registrovane proizvođače fiskalnih uređaja u BiH. Tring (Gračanica), Config (Mostar), SK Trading (Sarajevo), Mikroelektronika (Banja Luka), ERP Consulting (Sarajevo), KIMTEC (Vitez) i Digit RS COM (Banja Luka). Za dva čiji je način povezivanja objavljen upisano je šta piše u njihovoj dokumentaciji; za ostale stoji ime i pitanja koja treba postaviti, označeno kao nepotvrđeno - jer profil napisan po nagađanju izgleda gotov i pukne prvi put kad se sretne sa pravom kasom.
        • Čitanje računa koji je uređaj već odštampao. Format je dokumentovan: jedna komanda po redu, S za prodatu stavku i T za kraj računa sa načinom plaćanja i iznosom. Iznos se prijavljuje samo kada ga datoteka stvarno kaže; izračunat iznos bio bi nagađanje tuđeg zaokruživanja i popusta. Račun plaćen kešom ili karticom se ne dira - taj je već naplaćen prije nego što datoteka postoji, pa bi nuditi kod za njega značilo nuditi da se plati dvaput.

        0.35.0

        7. septembar 2026.

        Popravljeno

        • Kuhinjski ekran nije mogao skinuti tiket sa dvije stanice. Narudžba sa supom i pivom ostaje otvorena dok obje stanice ne završe, što je ispravno. Ali ekran je pitao za sve narudžbe umjesto za svoje, pa se kuharu ista kartica vraćala čim pritisne Preuzeto i stajala tu dok šank ne završi - a to u kuhinji izgleda kao da dugme ne radi, pa se pritisne opet. Server prima taj podatak otkad je predaja između stanica napisana; jedini ekran zbog kojeg postoji ga nikad nije slao.
        • Gost koji je platio manje ili više ostajao je zauvijek na "Čekam potvrdu banke". Ekran je znao za četiri ishoda; uplata veća ili manja od računa nije bila među njima. Ko zaokruži iznos u svojoj banci - a to je ovdje običan petak - gledao je pulsirajuću tačku dok ne odustane i ne plati drugi put. Sada: veće od računa je plaćeno, a manje ima svoj ekran koji kaže da je uplata prošla i koliko je stiglo od koliko.
        • Promjena cijene je zaključavala korpu. Kad happy hour istekne dok gost bira, server odbije narudžbu jer je cijena druga - i to je ispravno. Meni se osvježio, korpa nije, pa je gost čitao "provjerite iznos i pošaljite ponovo" pored iznosa koji se ne može promijeniti, i svaki sljedeći pokušaj je odbijen isto tako. Sada se osvježi i korpa; šta je u međuvremenu skinuto sa menija, kaže se.
        • "Nazad na račun" je poništavalo kod za plaćanje. Ko je već poslao uplatu iz svoje banke pa se htio vratiti da vidi račun - najprirodnija sljedeća stvar - poništio bi kod, a poništen kod se ne povezuje sa uplatom kad ona stigne. Novac dođe, ne nađe svoj račun, i sto koji je platio biva zamoljen da plati opet. Sada ekran pita ko si: "Već sam platio" ne dira ništa, a "Odustani od plaćanja" piše šta radi.
        • Potpuno vraćen novac oduzimao se dvaput. Račun vraćen u cijelosti izlazi iz prometa sam od sebe, a oduzimao se i drugi put kao povrat - pa je stotina vraćena skidala dvjesta sa dana. Na mirno popodne to padne na nulu i ekran kaže da lokal nije uzeo ništa, dok novac stoji na računu. Iznos vraćenog novca koji se prikazuje ostaje isti: sve što je stvarno vraćeno.

        0.34.5

        7. septembar 2026.

        Popravljeno

        • Dva paketa su se u spisku zvala svojim ključem. U operaterskoj konzoli padajući spisak nudi svih šest paketa, a prevedena su bila četiri - Flex i Business su se ispisivali kao plans.FLEX i plans.BUSINESS, i u spisku i u redu svakog lokala koji je na njima.
        • U istoriji narudžbi status je bio prazan. Istorija traži samo servirane narudžbe, a ekran je znao imenovati samo one četiri koje su još u toku, pa je na svakoj kartici mjesto za status ostajalo prazno. Sada piše "Servirano", a i "Otkazano" ima svoju riječ prije nego što zatreba.
        • Provjera sada gleda i vrijednosti, ne samo tekstove. Oba gornja su ključevi koje ekran sastavi dok crta, pa ih jučerašnja provjera nije mogla vidjeti. Sada se svaki popis vrijednosti koji baza može vratiti poredi sa riječima koje za njih postoje, na oba jezika. Gdje ekran namjerno nema riječ za neku vrijednost, to je zapisano i obrazloženo, pa provjera ne pada na tuđoj odluci.

        0.34.4

        7. septembar 2026.

        Popravljeno

        • Dva dugmeta za brisanje pisala su svoje ime umjesto riječi. Na pravilima za happy hour i na pravilima za preporuke dugme je pisalo common.delete umjesto "Obriši". Prevod za tu riječ nije nikad napisan, a kada ga nema, sistem ispiše sam ključ - ne padne, ne javi grešku, samo ispiše. Sada je napisan, a uz njega i provjera koja prolazi kroz sve ekrane i traži isto to: svaki tekst koji ekran traži mora postojati na oba jezika, i to se sada gleda prije svakog objavljivanja. Provjera je pregledala 960 tekstova; ova dva su bila jedina koja nedostaju.

        0.34.3

        7. septembar 2026.

        Popravljeno

        • Adresa na naljepnici dobija veličinu i širinu formata na kojem se štampa. Bila je postavljena za naljepnicu koja ide dvanaest na tabak: sitna i uska. Na kartici preko cijele stranice to je bio najmanji red na papiru, a duži domen bi se i na kartici i na stonom stalku lomio u dva reda iako prostora ima. Sada svaki format daje toj liniji onoliko koliko ima.

        0.34.2

        7. septembar 2026.

        Popravljeno

        • Adresa na naljepnici se uzima odande odakle i QR kod. Uzimala se iz adrese na kojoj je vlasnik otvorio konzolu, a to je ista stvar samo dok jeste: u punoj instalaciji konzola ima svoje ime (app.domen), pa bi vlasnik koji uđe preko IP-a ili drugog zapisa odštampao šezdeset naljepnica sa adresom koju njegovi gosti ne mogu otvoriti. Sada se čita iz iste postavke koju nosi i sam QR kod, pa oba vode na isto mjesto.

        0.34.1

        7. septembar 2026.

        Popravljeno

        • Kod koji ne radi sada nudi da se ukuca ponovo. Ekran "Ovaj kod nije u upotrebi" je do sada značio samo jedno: naljepnicu koju je lokal povukao, pa je jedini savjet bio da se pita osoblje. Otkad naljepnica štampa i adresu za telefon koji ne može da skenira, isti ekran vidi i onaj ko je pogriješio jedan znak - a tome ne treba konobar, nego polje za kod, koje je sada tu.

        0.34.0

        7. septembar 2026.

        Dodano

        • Kod sa naljepnice sada ima gdje da se ukuca. Ispod QR koda na naljepnici stoji i kod od šest znakova, za telefon čija kamera neće da uhvati: napukao ekran, masna naljepnica, mrak u baru, stariji telefon bez skenera u kameri. Taj kod dosad nije vodio nigdje - nije postojala stranica na koju se unosi, a na papiru nije pisalo ni gdje da se ode. Sada naljepnica štampa i adresu, a na toj adresi je polje za kod. Polje prašta ono što ljudi zaista otkucaju: mala slova, crticu, razmak, cijeli link koji im je neko poslao, i slova koja se ne razlikuju od cifara (I i l čita kao jedinicu, O kao nulu - zbog toga ih u kodu i nema). Kod koji nije u upotrebi to i kaže, na mjestu, i ostavlja ostalih pet znakova u polju da se ispravi jedan.

        0.33.0

        7. septembar 2026.

        Popravljeno

        • Lokal se naplaćivao za goste koji nisu ništa platili. Jedna transakcija je jedan račun sa kojeg je naručeno i koji je zatvoren - svejedno da li kešom, karticom ili prenosom. Dvije stvari su se brojale a nisu to: račun zatvoren kao neplaćen (gost otišao bez plaćanja, ili se dug otpisao) i račun na kojem nema ničega (neko skenirao naljepnicu, predomislio se, konobar sklonio račun - u kafiću uveče to nije rijetkost). Prvo je i inače izuzeto iz prometa, pa se faktura nije slagala sa ekranom koji prati.
        • Preštampana naljepnica nije radila. Naljepnica se prolije ili joj kod vidi ko ne treba, lokal je povuče i odštampa ponovo - a sistem je vraćao povučeni red. Odgovor 201, u konzoli se pojavi sto, neko odštampa i zalijepi, i svaki gost koji skenira dobije 404, bez ijedne riječi zašto. Sada je ponovno štampanje nova naljepnica koja radi.
        • Povučena naljepnica više ne troši mjesto u paketu. Kod u kanti nije sto: ne može primiti nijednu uplatu i njegov link je mrtav. Brojao se, pa je limit postajao sve gori što se proizvod duže koristi - lokal koji jednom preštampa cijeli sprat biva odbijen zbog stropa kojem nije ni blizu. Broji se koliko ih radi u isto vrijeme, što je i ono što paket prodaje.

        0.32.0

        6. septembar 2026.

        Dodano

        • Isti račun ponovo, za sljedeći period. Stanodavac šalje istom podstanaru isti iznos svaki mjesec, a komunalno preduzeće cijeloj ulici. Do sada se sve to prekucavalo iz početka - kupac, njegov PDV broj, svaka stavka, rok plaćanja - što je upravo posao koji ovaj proizvod postoji da ukloni, i mjesto gdje se slučajno promijeni jedna cifra.

        Promijenjeno

        • Sposobnost recurring je do sada pisala „računi koji se ponavljaju po rasporedu", a raspored nije postojao nigdje - to je bila tvrdnja o proizvodu, ne opis. Sada piše šta stvarno radi. Pravi raspored vrijedi napraviti i nije napravljen.

        0.31.0

        6. septembar 2026.

        Popravljeno

        • Dvije djelatnosti se uopšte nisu mogle izabrati. Proizvod opisuje sedam vrsta posla, sa svojim mogućnostima i poljima na računu, a ruta koja poslovnici dodjeljuje vrstu imala je svoj prepisan spisak od pet. Prodavnica sa pultom i veleprodaja koja fakturiše šta izađe bile su opisane do kraja i nije ih se moglo postaviti. Spisak se sada izvodi iz registra, pa dodavanje nove vrste više ne traži da se neko sjeti i drugog mjesta.
        • Pogrešno ime polja na stavci računa se tiho gutalo. Količina se šalje u hiljaditim dijelovima, što se izvana ne može znati, pa je integrator koji pošalje obično quantity: 3 dobijao 201 i fakturu na jedan komad - kupac plati trećinu onoga što je uzeo, na dokumentu koji izgleda potpuno ispravno. Sada se takva stavka odbija i kaže se koje polje ne valja.

        0.30.3

        6. septembar 2026.

        Popravljeno

        • Svako dugme za dodavanje na meniju zvalo se isto. Naziv jela stoji na kartici, a ne na dugmetu, pa je gost koji koristi čitač ekrana dobijao meni od trideset jednakih dugmadi „Dodaj" bez ijednog podatka koje šta dodaje. Sada svako kaže i jelo.

        0.30.2

        6. septembar 2026.

        Popravljeno

        • Ekran za plaćanje je gostu obećavao dvije stvari koje XPay ne može garantovati. Pisalo je „Odmah dobijete potvrdu" - a kad će uplata biti potvrđena odlučuje banka, ne XPay, i to isto stoji u Uslovima korištenja. Sada piše da se račun zatvara čim banka potvrdi, isto što piše i na ekranu koji gost gleda dok čeka. Druga je bila značka „Bez naknade": banke mogu gostu naplatiti svoju naknadu i Uslovi to izričito kažu, pa značka sada kaže ono što jeste - „Direktno banci".

        0.30.1

        6. septembar 2026.

        Dodano

        • Provjera da li je lokal spreman za goste. Sve što lokalu treba prije nego prvi gost skenira naljepnicu razbacano je po pet ekrana, a red kojim se to radi ne piše nigdje: naljepnica se ne može odštampati prije nego postoji bankovni račun, meni bez ijednog pića izgleda kao pokvarena aplikacija, a naručivanje je prekidač kojeg se neko mora sjetiti uključiti. Nova provjera pita sistem isto ono što će za koji minut pitati gostov telefon, i odgovara redom kojim se stvari moraju popraviti - odvojeno šta zaustavlja lokal, a šta je samo napomena. Ništa ne mijenja.

        0.30.0

        6. septembar 2026.

        Dodano

        • Jelo i piće se sada mogu urediti. Do sada se artikal mogao samo dodati i obrisati - a svaki lokal mijenja cijenu. Jedini način je bio obrisati jelo i napraviti ga iznova, čime se gubi slika, izbori uz jelo i mjesto u kategoriji. Sada svaki red ima „Uredi": naziv, cijena, opis, slika i mjesto pripreme, u istoj formi u kojoj se jelo i dodaje.
        • Već poslana narudžba zadržava cijenu po kojoj je poslana. Promjena cijene važi od tog trenutka naprijed i ne dira račun koji gost gleda. To je bilo tako i prije - svaka stavka pamti svoju cijenu - ali sada to i provjeravamo, jer je sad prvi put moguće mijenjati cijenu usred servisa.
        • Gost može napisati napomenu uz svaku stavku u korpi. „Bez luka", „dobro pečeno". Polje je i ranije postojalo, ali samo na jelima koja imaju obavezan izbor - sve ostalo se dodaje jednim dodirom i polje se nikad nije pokazalo. Sada stoji na svakoj stavci u korpi, tamo gdje se narudžba i pregleda prije slanja. Kuhinja to već ispisuje.

        Popravljeno

        • Klik na kategoriju u meniju nije radio ništa. Trakа kategorija je označavala aktivnu po tome dokle je meni skrolan, a to prepoznaje samo uski pojas pri vrhu ekrana. Na meniju koji cijeli stane na telefon nema se gdje skrolati, taj pojas se nikad ne pređe, i druga kategorija se uopšte nije mogla izabrati: pritisneš i ekran se ne pomjeri i čip se ne promijeni. Lokal sa dvije kategorije prvog dana je tačno taj slučaj. Sada čip reaguje na pritisak.
        • Naslov kategorije je završavao ispod trake. Skok na kategoriju je dovodio njen naslov tačno pod ljepljivu traku, pa se stiglo na kategoriju čije se ime ne vidi.
        • Limit stolova je brojao i stolove koji već postoje. Naziv koji lokal već ima se ne pravi ponovo nego se vraća postojeći, ali se limit ipak naplaćivao za njega - pa je lokal na granici bio odbijen kad ponovo pošalje spisak stolova koje već ima, uz poruku da nema mjesta za stolove koji su već tu.

        Interno

        • Izmjena artikla se sada provjerava na serveru. Ranije je tijelo zahtjeva išlo neprovjereno u bazu: naziv je mogao stići kao broj, opis bilo koje dužine, a jedino je cijena bila provjerena i to slučajno.
        • Ordering suite više ne štampa novu naljepnicu na svakom prolazu i sam zatvara račun koji je zaostao, pa se može vrtjeti koliko god puta bez da udari u limit stolova.

        0.29.9

        6. septembar 2026.

        Sigurnost

        • Javna status stranica je objavljivala tuđe adrese. Provjere su na javni odgovor prosljeđivale ono u šta se greška pretvori, a te rečenice imenuju stvari koje javna stranica ne smije reći: Prisma javi „Can't reach database server at db.interni:5432", odbijena prijava na poštu nosi SMTP host i port koje je vlasnik upisao, a skripta za kopije nosi odredište na koje kopira. Niko to nije objavio namjerno - stizalo je kao „detalj", jedna biblioteka po jedna. Sada odgovor nosi samo rečenice koje smo mi napisali; pravi tekst ide u dnevnik, gdje ga čita onaj ko može nešto uraditi. Smoke provjerava da se ne vrati.

        Promijenjeno

        • Status stranica sada pokazuje i kako se sistem ponaša, ne samo kakav je ovog trenutka. Svaka provjera ostavlja crtu na traci, pa se za vrijeme kvara vidi oblik problema, a ne jedna tačka. Traka govori samo ono što je vidjela otkad je stranica otvorena - to nije zapis koji se negdje čuva, i tako i piše ispod nje.
        • Ako se nešto promijeni dok gledaš, stranica to i kaže. Ispod dijelova stoji spisak promjena viđenih u toj sesiji: vrijeme, dio, iz čega u šta.
        • Otisak izdanja. Uz naslov stoji mreža izvedena iz commita koji trenutno odgovara - ista slika za isto izdanje na svakom ekranu, druga čim se nešto pusti. Ukras, ne kod: nema šta da se skenira, i tako i piše ispod njega.
        • Historija verzija je dobila kičmu, sa trenutnom verzijom označenom na vrhu.

        Popravljeno

        • Provjera koja ne dobije odgovor sada ostavlja trag. Traka je pamtila samo odgovore, pa je kvar koji je preglednik gledao uživo nestajao iz nje čim se sistem vrati - ostajao je neprekinut niz zelenih crta preko baš onih minuta kad ništa nije radilo. To je jedina laž koju status stranica ne smije reći. Sada takva provjera ima svoju šuplju crtu i broji se posebno.
        • Jedan neuspio zahtjev više ne briše cijelu tablu. Prije je crveni okvir zamijenio sve, pa su traka i spisak promjena nestajali tačno onda kad su najpotrebniji. Sada stoji zadnji odgovor, jasno označen kao zadnji.
        • Sravnjivanje je javljalo „Radi" kad su svi izvori u kvaru. Izvor koji padne prelazi u stanje greške, a provjera je brojala samo ispravne - pa je lokal kojem je jedina veza sa bankom crkla vidio zeleno i rečenicu da nijedan izvor još nije povezan. Novac tog trenutka prestaje biti prepoznat.
        • Nepodešena adresa sistema se prikazivala kao kvar na XPay-u. Ako stranica nije građena sa adresom, nema koga pitati - to je propust u postavci, ne ispad, i sada tako i piše, bez crvenog.
        • Dva dijela sistema nisu imala ime na stranici. „Slike" i „Sigurnosne kopije" su se javljale, a stranica ih je ispisivala engleskim ključem, bez ijedne riječi šta su - baš onome ko je došao za vrijeme kvara.
        • Razlozi su bili na engleskom. Server je slao tehničku rečenicu, a stranica ju je prepisivala takvu kakva je. Sada razlog putuje kao kod sa brojevima uz njega, a stranica ga sama sroči na bosanskom. Poređenje po engleskom tekstu se namjerno ne radi: rečenica se jednom prepravi i podudaranje tiho prestane raditi, tačno onog dana kad neko čita ovu stranicu.
        • Odbijena pošta se javljala kao pošta koja ne odgovara. To su dvije različite kvarove: pogrešna lozinka odgovori, mrtav server ne.
        • Broj uz imenicu sada ima ispravan oblik („2 provjere", ne „2 provjera"), i glagol se slaže sa brojem.
        • Na telefonu je traka bila šira od ekrana i odsijecala najnovije provjere.
        • Sitna traka po dijelu razlikovala je „Otežano" od „Ne radi" samo bojom.

        Interno

        • Nova provjera hvata zalutale kontrolne znakove u skriptama. Dvaput je koštalo: jedan carriage return u CI fajlu oborio je cijeli prolaz bez ijednog posla i bez ijednog zapisa, a jedan backspace u regularnom izrazu pretvorio je provjeru curenja u provjeru koja može samo proći. Oba su nevidljiva u diffu i u editoru. Prvi takav znak je već bio u repozitoriju i ova provjera ga je našla.

        0.29.8

        6. septembar 2026.

        Popravljeno

        • Kolona „Poziv na broj" i izvještaj za knjigovođu pisali su dva različita broja pod istim naslovom. Lista plaćanja je pokazivala čitljivi oblik (XP-1042-0000-0091), a izvoz, faktura, QR i gostov dugme za kopiranje nose četrnaest cifara. Ko upoređuje jedno s drugim vidio je dva broja za istu stvar. Sada lista piše iste cifre - one koje kupac pročita preko telefona i koje stoje na izvodu iz banke.

        0.29.7

        6. septembar 2026.

        Popravljeno

        • Ista uplata na dva kanala se računala dva puta. Ponovo poslan izvod se prepoznaje po banci i njenom broju stavke, ali jedan te isti priliv koji stigne i preko live veze i preko noćnog fajla to su dva izvora, dva broja, dva reda - a jedan transfer. Račun koji je već zatvoren bio je zaštićen slučajno; onaj koji je djelimično plaćen nije, pa je druga kopija bila dodana na već upisani iznos. Lokal bi tada u svojoj evidenciji imao više novca nego što je banka pomjerila, a povrat se računa upravo po tom iznosu. Sada se takav priliv ne upisuje sam: ide čovjeku, kao slučaj „Dupla uplata". Ni ne broji dvaput, ni ne baca pravi novac.
        • Panel poslije učitavanja izvoda nije se slagao sam sa sobom. Uplata koja je djelimično platila račun nije bila ni u jednoj koloni, pa je zbir bio manji od ukupnog broja, a baš ta uplata je ona koja nekome još duguje odgovor. Sada ima svoju kolonu („Razlika u iznosu"), a stavka koja se ponovila broji se jednom - kao duplikat - umjesto u dvije kolone odjednom.

        0.29.6

        6. septembar 2026.

        Popravljeno

        • Uparivanje: „Poveži i naplati" nikada nije radilo na razlici u iznosu. Kada dođe manje ili više nego što račun traži, sistem sam upiše priliv na račun i onda pita čovjeka je li to u redu. Dugme je tražilo stanje u kojem je račun već bio, a to je čitano kao odbijanje - 409, slučaj ostaje otvoren. To je najčešći slučaj u redu za uparivanje, pa se red nije mogao očistiti. Sada se zatvara, a priliv se ne broji drugi put.
        • Neuspješan pokušaj je i dalje mijenjao datum priliva u izvještaju za knjigovođu. Upis u izvod se dešavao prije nego se zna hoće li naplata proći, pa je zahtjev koji je vratio grešku ipak pomjerio red u fajlu koji je neko već predao. Sada se upisuje tek kada je odluka prošla, a ponovni pritisak ne pomjera datum prvog uparivanja.
        • „Zanemari uplatu" je govorio da novac nije naš, a ostavljao ga na računu. Priliv koji je već upisan na račun sada se ne može proglasiti tuđim - isto pravilo koje ista datoteka već primjenjuje na nesparen priliv. Poruka kaže i na kojem je računu.
        • „Odbaci" je odbacivao i novac. Slučaj se zatvarao, a priliv je ostajao u stanju koje nijedan ekran ne prikazuje - pravi novac koji je stigao u banku nestajao je iz proizvoda. Odbacivanje znači „ovo nije taj račun", ne „ovo nije novac": priliv se vraća u listu nesparenih uplata, gdje se može povezati ili pošteno označiti kao tuđi.

        0.29.5

        6. septembar 2026.

        Popravljeno

        • Djelimično plaćen račun nije govorio koliko je stiglo. Lista plaćanja je pokazivala iznos računa i obojenu riječ: „Manje uplaćeno, 50,00 KM". To kaže da nešto nije u redu i ne kaže šta dalje - a duguje li gost pet ili četrdeset pet maraka je cijelo pitanje. Sada red piše i koliko je stiglo i koliko nedostaje, odnosno koliko je više uplaćeno. Podatak je server slao od ranije; ekran ga nije čitao.

        0.29.4

        6. septembar 2026.

        Popravljeno

        • Poziv na broj se nije mogao pretražiti. Gost nazove i pročita broj sa svoje uplate, a to je četrnaest cifara i ništa drugo. Konzola je sama pogađala šta je ukucano po obliku teksta: same cifre znače iznos. Tako je jedini broj koji gost sigurno ima uvijek završavao u filteru za iznos, i lista se vraćala prazna - a prazna lista izgleda kao odgovor „ta uplata ne postoji". Sada postoji jedno polje i jedan upit: server traži po svim oblicima odjednom.
        • Broj računa se nije nalazio onako kako je odštampan. Referenca se prije poređenja čisti od razmaka i crtica, a broj računa iz kase se čuva tačno kako ga je kasa napisala - sa crticama. „RN-2026-09-06-0042" prekucan sa računa nije nalazio ništa. Sada se traži i tačno tako, i bez razmaka, i potpuno očišćeno.
        • Referenca i iznos zajedno su tražili samo po iznosu. Oba filtera prave isti oblik upita i jedan je tiho brisao drugi, pa je pretraga izgledala kao da poštuje oba uslova. Sada se sužavaju međusobno, kako drugi filter i služi.
        • Prekratak unos - dva znaka - ne vraća više cijelu listu. Dva znaka se nalaze u skoro svakoj referenci izdatoj danas; puna lista izgleda kao pretraga koja je uspjela.

        0.29.3

        6. septembar 2026.

        Popravljeno

        • Tabla narudžbi je bila jedan ekran za sve poslovnice. Lanac je jedan trgovac, pa je kuhinja u jednom lokalu gledala i tikete drugog - a oba lokala stolove broje isto, tako da ih je razlikovao samo naziv stola. Sada tabla ima izbor poslovnice, kao što ga spratni plan već ima, i podrazumijevano pokazuje prvu.
        • Nema opcije „sve poslovnice", namjerno: ovo je ekran koji se gleda za vrijeme servisa u jednoj prostoriji, a „sve" je stanje koje je i pravilo zabunu.
        • Lokal sa jednom poslovnicom ne vidi birač i sve mu je isto kao prije.

        0.29.2

        6. septembar 2026.

        Popravljeno

        • Od papirne naljepnice za sto mogao se napraviti uređaj koji prima novac. Stolovi se čuvaju kao uređaji posebne vrste, i brojanje uređaja za paket to zna i izuzima ih - ali spisak i „Novi kod" nisu. Pritisak na naljepnicu je kovao kod za uparivanje, kod se uparivao, a dobijeni token može naplaćivati - izvan ograničenja paketa i izvan ičije pažnje. Sada se naljepnica ne može upariti, a spisak uređaja prikazuje uređaje.
        • Kutija „koliko stolova" nije dodavala, iako je ispod nje pisalo da dodaje. Uvijek je brojala od jedan, pa je vlasnik sa dvanaest stolova koji upiše 4 dobio nazive 1-4, koji već postoje - i poruku da su četiri stola napravljena, a nijedan nije. Sada broji dalje od onoga što je na podu i preskače zauzete brojeve.
        • Tablet kojem je token opozvan ostajao je na radnom ekranu zauvijek. Ekran je odlučivao po tome postoji li token, nikad radi li - pa je tablet koji je menadžer stao izgledao živ, a nijedan poziv nije prolazio. Sada se vraća na ekran za uparivanje, gdje osoblje može unijeti novi kod.

        0.29.1

        6. septembar 2026.

        Popravljeno

        • Narudžba poslana dok veza pada mogla je stići dvaput. Telefon ne može razlikovati „server je odbio" od „odgovor se izgubio", pa ekran zadrži korpu i pozove gosta da pošalje ponovo. To je tačno kad ništa nije stiglo, a druga tura u kuhinji kad jeste - a u prostoriji sa debelim zidovima drugo je uobičajeno.
        • Sada telefon imenuje svoj pokušaj, i ista oznaka na istom računu je ista narudžba. Ponovni dodir vrati onu koja već postoji; dva dodira u istoj sekundi takođe, jer o tome odlučuje baza.
        • Nova tura je i dalje nova tura - to je ono što nije smjelo puknuti.

        0.29.0

        6. septembar 2026.

        Popravljeno

        • „Odaberi stavke" nije dozvoljavalo da platite jedan komad. Dvije kole naručene zajedno su jedan red, pa je izbor bio „2x Coca Cola" ili ništa - a to je obična situacija: dvoje ljudi, jedna tura pića, svako plaća svoje.
        • Sada red od dva komada nudi dva izbora. Odaberete jedan, plaćate jedan, a drugi ostaje na računu za onoga ko ga je popio.
        • Račun pokazuje i cijenu jednog komada, jer to je ono što duguje neko ko plaća jedan.
        • Ako je neko već uzeo jedan komad, drugi je i dalje na raspolaganju - do sada je cijeli red nestajao sa liste čim ga neko dotakne.

        0.28.0

        6. septembar 2026.

        Popravljeno

        • Jedan tiket, dvije stanice: ko prvi završi, obriše onom drugom karticu. Narudžba sa jelom i pićem ima jedan status, a ekrani su po stanicama - kuhinja vidi čorbu i ne vidi piva, šank vidi piva i ne vidi čorbu. Dugme ispod bilo koje kartice pomjeralo je cijelu narudžbu, pa je šank, označivši svoja dva piva, označio i čorbu kao posluženu i skinuo kuhinjsku karticu sa svih ekrana. Čorba nikad nije skuhana.
        • Sada „gotovo" pripada paru narudžba i stanica. Šank završi svoje, tiket mu nestane sa table, a kuhinji ostane. Narudžba je poslužena tek kad završi posljednja stanica.
        • Lokal sa jednim ekranom, bez podešene stanice, radi kao i do sada: kad ništa nije sakriveno, „gotovo" znači gotovo.

        0.27.3

        6. septembar 2026.

        Popravljeno

        • Konobarski tablet je mogao stornirati cijeli plaćen račun. Nije mogao potvrditi da je uplata stigla - za to treba menadžer - ali je mogao skinuti naplaćen račun sa dnevnog prometa, jer storniranje nije tražilo nikakvu ulogu. Opasnija radnja je bila ona bez brave. Sada i ona traži menadžera.
        • Ključ koji ima samo narudžbe mogao je pretplatiti bilo koju adresu na sve događaje o plaćanju. Nije mogao ni pročitati listu pretplata, ali je mogao napraviti novu - trajan kanal kojim podaci o novcu odlaze na tuđu adresu. Sada kreiranje, brisanje i ponovno slanje traže isto pravo kao i čitanje.

        Šta se mijenja u praksi

          0.27.2

          6. septembar 2026.

          Popravljeno

          • Spratni plan jednog lokala prikazivao je račune drugog. Lanac je jedan trgovac, a lokali stolove broje isto - „Sto 1" postoji dva puta. Ekran je tražio sve otvorene račune i spajao ih sa stolovima po nazivu, pa je prazan sto u jednom lokalu svijetlio kao zauzet, sa tuđim novcem, a zbir u zaglavlju je bio oba lokala sabrana.
          • Lista otvorenih računa sada kaže u kojem je lokalu koji račun. Bez toga su „Sto 6" i „Sto 6" dva ista reda, svaki sa dugmetom za naplatu - a zatvaranje pogrešnog knjiži gotovinu tamo gdje je niko nije uzeo, i ništa je ne vraća. Lokal se prikazuje samo kad ih ima više od jednog.

          0.27.1

          6. septembar 2026.

          Popravljeno

          • Gost koji zatraži kod pa odustane zaključao je sto na petnaest minuta. Dok je kod živ, sto ne prima narudžbe i ne može se naplatiti - ni keš, ni kartica, ni „nije plaćeno". Konobar kojem gost pruža novac dobio je poruku da otkaže kod, a nigdje nije bilo dugmeta koje ga otkazuje.
          • Sada postoji: „Otkaži kod" stoji prvi u redu na računu koji čeka uplatu. Kod prestaje biti plativ, sto ponovo prima narudžbe i može se naplatiti kako god.
          • Poruka o toj odbijenici je do sada stizala na engleskom, na bosanskoj konzoli. Sada je na jeziku koji čitate, i konzola je tako naučila prevoditi i buduće odbijenice, jer ide po oznaci a ne po tekstu.

          0.27.0

          6. septembar 2026.

          Dodano

          • Ograničenje koliko jedan sto može poslati. Kod na stolu je odštampan i javan, pa je ograničenje na broj narudžbi do sada bilo vezano za telefon - a telefon je besplatan: ko pročita naljepnicu može otvoriti novu sesiju i dobiti novo pravo. Sada se broji po stolu, gdje novi token ne donosi ništa.
          • Najviše 12 telefona na jednom računu. Preko toga to više nije sto nego proslijeđen link, i odgovor je konobar, a ne trinaesto tiho pridruživanje.
          • Najviše 15 narudžbi u pet minuta po stolu. Osam telefona koji naruče u istoj sekundi prolazi normalno - to je obična petak večer.
          • Račun otvoren duže od 12 sati prestaje primati narudžbe i traži osoblje. Niko ne sjedi dvanaest sati; to se dešava kad niko ne zatvori sto uveče, pa kod fotografisan jučer naručuje doručak danas. Račun se ne zatvara sam, jer zatvaranje odlučuje o novcu.

          Šta je izbačeno, i zašto

            0.26.0

            6. septembar 2026.

            Dodano

            • Sto koji je otišao bez plaćanja može se tako i zatvoriti. Do sada su postojali samo načini naplate - keš, kartica, uplata na račun - a sto se svejedno mora zatvoriti, inače drži mjesto cijelu večer. Zato je odlazak bez plaćanja završavao u prometu kao da je neko platio. Dan je onda pokazivao više nego što je u kasi, i to u smjeru koji lokalu laska.
            • Dugme „Nije plaćeno" stoji zadnje u redu i traži potvrdu koja kaže šta to znači: iznos se neće voditi kao promet.
            • Ako je sto platio pola pa otišao, ta polovina ostaje uknjižena. Gubitak je samo ono što nije stiglo.
            • Na Pregledu se sada vidi „otišlo bez plaćanja", pored gotovine, bakšiša i povrata. Dan se tek tako sabere: naplaćeno, vraćeno, i ono što je otišlo.

            Napomena o provjeri

              0.25.11

              6. septembar 2026.

              Popravljeno

              • Na Pregledu je ispod naplaćenog pisalo „gotovina 90,00 KM KM" - valuta dvaput. Iznos je već nosio oznaku, a šablon ju je dodavao još jednom.
              • Grafikon prometa je iznose pisao na engleski način, 1,107.30 umjesto 1.107,30, odmah pored ispravno napisanih na istom ekranu. Koristio je sistemsko formatiranje, koje za bosanski daje pogrešne separatore.

              0.25.10

              6. septembar 2026.

              Popravljeno

              • Ograničenje broja prijava bilo je zajedničko za cijelu platformu, a ne po korisniku. API u kontejneru nije prepoznavao pravu adresu posjetioca nego je svaki zahtjev vidio kao da dolazi sa iste, pa je dvadeset pokušaja prijave u minuti bilo ograničenje za sve zajedno. Jutro sa tri lokala koja se otvaraju i par pogrešno ukucanih lozinki zaključa četvrti lokal koji nikoga nije ni dotakao. Isto je pogađalo i zapis u dnevniku, koji je bilježio adresu mreže umjesto korisnika.
              • Instalacija bez DNS zapisa za app.<domena> upisivala je https:// kao adresu konzole. Skripta ispravno ostavi konzolu na glavnoj adresi i to i kaže, ali je adresu svejedno sastavljala od praznog imena. Instalacija bi „uspjela uz upozorenje", a konzola bi se izgradila tako da gađa nepostojeću adresu. Sada koristi glavnu adresu, a upisivanje adrese bez imena se odbija sa objašnjenjem.

              0.25.9

              6. septembar 2026.

              Popravljeno

              • Povrat uplate koja je bila manja od tražene brisao je tuđi novac sa računa stola. Račun se zadužuje tek kad uplata bude potpuna; nedoplaćena ga ne dodiruje. Ali povrat je svejedno skidao sa računa - a skidao je ono što je tamo bilo, dakle plaćenu polovinu drugog gosta. Sto je onda ponovo tražio novac koji je jedan od njih već dao.
              • Sada se sa računa skida samo ono što je ta uplata na njega i stavila.

              0.25.8

              6. septembar 2026.

              Popravljeno

              • Otkazivanje jela koje je neko već platio guralo je račun u minus. Gost plati svoju stavku QR-om, kuhinja pokvari to jelo, konobar ga otkaže - i račun stola padne ispod onoga što je već naplaćeno. Ostatak stola je onda na svom telefonu gledao negativan iznos i nije mogao platiti ono što duguje.
              • Sada se takvo otkazivanje odbija sa objašnjenjem: za to ide povrat, ne otkazivanje. Obično otkazivanje neplaćene narudžbe radi kao i do sada.

              0.25.7

              6. septembar 2026.

              Popravljeno

              • Dok se račun plaća, drugi gost za stolom nije mogao ni naručiti ni pozvati konobara, a obje poruke su mu govorile da pokuša ponovo. Nijedno od toga nije moglo uspjeti: neko je za kasom, i dok to ne završi telefon bez svog računa ne može ništa. Sada piše šta se dešava i da će za koji trenutak moći dalje.
              • Poziv konobara je pao iz istog razloga: dugme prvo otvori račun za taj telefon, a to je upravo ono što server u tom trenutku odbija.

              Zašto je to ostalo neprimijećeno

                0.25.6

                6. septembar 2026.

                Popravljeno

                • Kad konobar zatvori račun, gostu na telefonu se ekran pretvarao u slijepu ulicu. Gost gleda račun, konobar uzme gotovinu i zatvori sto na tabletu, i osam sekundi kasnije telefon napiše „Za platiti 0,00 KM" i „Još niste ništa naručili" - čovjeku koji je upravo platio. Na ekranu nije ostalo nijedno dugme; jedini izlaz je bio ručno osvježavanje stranice.
                • Sada piše da je račun zatvoren i nudi povratak na meni. Naljepnica i dalje radi, pa sljedeća narudžba otvara novi račun, što je tačno ono što sto traži kad naruči još jednu turu.
                • Isto je popravljeno i na ekranu „Vaše narudžbe", koji je u istoj situaciji bez riječi prelazio u puni meni.

                0.25.5

                6. septembar 2026.

                Popravljeno

                • Zadnja porcija se mogla obećati dvama stolovima. Provjera zalihe je čitala stanje prije nego što transakcija počne, pa su dvije narudžbe u istoj sekundi obje vidjele „ostala jedna" i obje prošle. Umanjenje jeste bilo uslovno i drugom nije obrisalo ništa, ali se rezultat nije gledao, pa se narudžba svejedno upisala. Broj je izgledao ispravno, a kuhinja je imala dva stola za jednu porciju. Sada onaj ko izgubi trku dobije odbijenicu.
                • Svrha plaćanja je pisala „Sto Sto 1". Riječ „Sto" se dodavala na naziv koji je lokal već tako napisao. Sada se dodaje samo kad je naziv gol broj, pa „1" postane „Sto 1", a „Sto 1", „Terasa 3" i „Šank" prolaze kako su napisani. To je polje koje bankovna aplikacija pokaže gostu.

                Zna se, nije dirano

                  0.25.4

                  6. septembar 2026.

                  Dodano

                  • Generalna proba sada provjerava da svaka fotografija na meniju zaista stigne. Jučerašnja greška sa praznim kvadratima nije pala nijednom testu, i nije mogla: postojeće provjere šalju sliku kroz API pa je kroz API i pročitaju, a te dvije strane se po definiciji slažu bez obzira gdje je direktorij. Puklo je ono što upisuje neko drugi.
                  • Gleda se vrsta sadržaja, a ne samo status. Ona 404 se vraćala kao ispravan JSON, a pregledač takav odgovor odbije kao sliku bez ijedne poruke koju bi čovjek negdje vidio.

                  0.25.3

                  6. septembar 2026.

                  Popravljeno

                  • Meni je gostu prikazivao prazne kvadrate umjesto fotografija jela. Slike su se upisivale u jedan direktorij, a posluživale iz drugog, pa je svaka bila 404. Ništa u zapisima nije to prijavljivalo, jer fajl zaista nije postojao tamo gdje ga je server jedino i tražio. Od 20 fotografija u demo meniju učitavala se jedna.
                  • Uzrok: podrazumijevana putanja je bila ./data/media, što nije direktorij nego pitanje o tome ko pita. Seed pita iz korijena projekta, server iz svog foldera, i dobiju dva različita odgovora.
                  • Sada je podrazumijevana putanja stvarno mjesto, izračunato na jednom mjestu koje i seed i server koriste. Ko je ranije sam postavio putanju, njegova i dalje vrijedi.

                  0.25.2

                  6. septembar 2026.

                  Popravljeno

                  • Promet poslije ponoći se knjižio na pogrešan dan. Grafikon je dan sjekao po UTC-u, a ne po satu u lokalu, pa je sve što je naplaćeno poslije ponoći padalo na dan ranije. Za kafić koji radi do dva ujutro to znači da je najbolji dio petka bio upisan u četvrtak. Sada dan počinje u ponoć tamo gdje je lokal.
                  • Grafikon prometa se nije crtao. Prikazivali su se samo sati u kojima je bilo uplata, pa je dan sa svim uplatama u jednom satu davao jednu tačku i panel bi napisao „nema dovoljno podataka" iznad pločica koje su pokazivale promet. Sada se crtaju sva 24 sata, a prazni sat je nula.
                  • I krivulja je sada iskrena. Tačke su bile razmaknute po redoslijedu, a ne po vremenu, pa su uplata u devet ujutro i uplata u devet navečer izgledale kao dva susjedna sata. Ko je gledao oblik večeri, gledao je oblik broja uplata.

                  0.25.1

                  6. septembar 2026.

                  Dodano

                  • Generalna proba. Cijela večer u jednom sjedenju, na jednom stolu: naljepnica se odštampa, telefon je skenira, gosti naruče, narudžba se podijeli na kuhinju i šank, neko pozove konobara i konobar poziv zatvori, račun se podijeli po stavkama na dva telefona, plati se prenosom, ujutro se ubaci bankovni izvod i sto se zatvori. Vrti se na svakoj izmjeni koda.
                  • Dosad je svaki test izmišljao uplatu; sada prvi put kroz sistem prolazi pravi camt.053 XML fajl iz banke, od parsera do zatvaranja stola. To je spoj na kojem pilot stoji, a nije bio provjeren s kraja na kraj.
                  • Dugme za poziv konobara je prvi put pritisnuto u testu.

                  Vrijedi znati prije nego se sjedne za sto

                    0.25.0

                    5. septembar 2026.

                    Dodano

                    • Zaliha po jelu. Kuhinja ujutro upiše koliko ima porcija; kad odu, jelo se samo skine sa menija. Bez toga niko ne pritisne „rasprodano" dok gost već nije naručio dvadeset prvu porciju, pa se konobar vraća za sto da objasni.
                    • Narudžba veća od onoga što je ostalo se odbija, a ne skraćuje. Tri i izvinjenje je gore od odbijanja na koje gost još može reagovati.
                    • Broji se u istoj transakciji koja upisuje narudžbu, pa dva stola koja u istoj sekundi naruče zadnje dvije porcije ne mogu oba dobiti potvrdno.

                    Tri odluke koje su oblikovale ostalo

                    • Zaliha pripada danu. Broj upisan ujutro ništa ne znači sutra, pa nosi datum. Jučerašnja nula nije današnja nula nego *nema brojanja* - da je obrnuto, svako brojano jelo bilo bi rasprodano zauvijek prvo jutro nakon što je neko ovo uključio.
                    • Kad ponestane, ništa se ne upisuje. Zastavica „rasprodano" ostaje ono što je čovjek postavio, a zaliha se čita pored nje. Jelo koje je neko namjerno skinuo ostaje skinuto; jelo koje je juče nestalo se danas vraća samo od sebe. Da se zastavica upisuje, trebala bi druga zastavica da pamti ko ju je upisao.
                    • Nema broja znači nema ograničenja. Sva jela na svim menijima danas nemaju broj, a lokal koji zaboravi upisati prodaje jelo umjesto da ga sakrije. Meni koji tiho prestane nuditi hranu je gori kvar, jer ga niko ne primijeti.

                    0.24.0

                    5. septembar 2026.

                    Dodano

                    • „Šta ponuditi i kada", u Meniju. Meni je do sada znao samo da uz ćevape ide piće - pravilo o tome *šta je naručeno*. Ovo je pravilo o *sali*: nakon 45 minuta za stolom ponudi deserte, ili uvečer ponudi koktele.
                    • Oba uslova su neobavezna i oba moraju vrijediti. Restoran traži samo minute, bar traži samo sate; da su oba obavezna, oba česta slučaja bi se nezgrapno pisala.
                    • Pola prozora se odbija - i početak i kraj, ili nijedno. Pogađati koja je polovina mišljena je način da pravilo radi na pogrešnom kraju dana.
                    • Ista kategorija iz dva pravila se nudi jednom, i to nakon kraćeg čekanja.

                    Gdje se šta odlučuje

                    • Sat odlučuje server, u vremenu poslovnice. Jedini sat koji gostov telefon ima je gostov telefon, a on može biti podešen na drugu državu.
                    • Minute za stolom broji server, pa ih telefon samo poredi. Trajanje je isti broj u svakoj vremenskoj zoni, a meni se posluži jednom i gleda sat vremena - da telefon računa razliku od svog sata, gost sa pogrešno podešenim satom dobio bi desert sat ranije ili nikad.

                    Ostalo

                    • Računanje sata i prozora izdvojeno je iz happy houra u zajednički fajl, jer ga sada koriste dvije stvari. Svih 20 postojećih testova za happy hour prolazi nepromijenjeno, što je i bila svrha da se to provjeri tim putem.

                    0.23.4

                    5. septembar 2026.

                    Popravljeno - server se nije dizao

                    • API se nije mogao pokrenuti ako SMTP_SECURE nije postavljen. Docker ne može uslovno izostaviti ključ, pa se svaka neobavezna postavka u compose fajlu piše ${SMTP_SECURE:-} i stiže kao prazan string kad je niko nije postavio. Prazan string nije „nije postavljeno", pa ni .optional() ni .default() ne važe - enum ga odbije i API padne u petlju pri startu:
                    • SMTP_SECURE: Invalid enum value. Expected 'true' | 'false', received ''
                    • Ovo je čekalo svaku instalaciju koja SMTP nije podesila. install.sh ne piše SMTP_SECURE, a u compose je dodan tek nedavno - upravo zato da bi se mogao postaviti. Prvi sljedeći uspješan update bi ga aktivirao.
                    • Tiša polovina istog kvara: Number('') je 0, pa je prazan broj prolazio bez riječi. SMTP_PORT bi postao port 0, a PAYMENT_DEFAULT_TTL_SECONDS kod koji ističe u trenutku izdavanja.
                    • Prazne vrijednosti se sada odbacuju prije provjere, pa svaka zadana vrijednost dobije priliku. Razmaci se broje kao prazno: varijabla sa dva razmaka je omaška, ne namjera.

                    Kako je nađeno

                    • Poslom koji od jučer diže produkcijski stack u CI-ju. Migracije su prošle, kontejner se pokrenuo i nikad nije odgovorio na /readyz - a logovi su rekli zašto. Tri pokušaja da sam taj posao proradi, i onda je na prvom prolazu do API-ja našao pravi kvar.

                    0.23.3

                    5. septembar 2026.

                    Popravljeno - postavljanje

                    • Ažuriranje na serveru nije prolazilo. MAIL_REPLY_TO je u docker-compose.prod.yml bio naveden dva puta - jednom među ostalim mail postavkama, jednom u bloku dodanom kasnije za postavke koje nisu stizale do kontejnera. YAML sa dva ista ključa compose odbija, pa se stalo prije nego što je išta počelo da se gradi: line 131: mapping key "MAIL_REPLY_TO" already defined at line 97.

                    Dodano

                    • Provjera fajlova iz deploy/ u CI. Sve u tom folderu je jedini dio projekta koji nijedan test ne dotiče i nijedan build ne kompajlira - prvi put se pokrene na serveru, pred nekim ko čeka. Ovaj kvar je stajao iza više od dvadeset zelenih CI prolaza: svi testovi su prolazili, a proizvod se nije mogao postaviti.
                    • Provjerava se dvoje: da svaki YAML fajl prolazi parser, sa duplim ključem kao greškom - jer ga compose tako i tretira - i da svaka shell skripta prolazi bash -n, što uhvati nezatvoren navodnik ili fi koji fali. Ništa se ne pokreće; ovo su greške koje se mogu naći bez servera.
                    • Provjereno tako što je greška namjerno vraćena i potvrđeno da provjera pada, pa isto i za pokvarenu shell skriptu.

                    0.23.2

                    5. septembar 2026.

                    Dodano

                    • Oznaka „Stiglo na zatvoren račun" na ekranu Plaćanja. Gost uzme kod, ne iskoristi ga, kod istekne, konobar naplati gotovinu i zatvori račun - a transfer stigne sat kasnije ipak. Gost je platio dvaput.
                    • Blokirati zatvaranje cijeli sat nije rješenje: bankovni transfer stvarno može toliko da putuje, a kasa koja sat vremena neće da primi gotovinu je gori problem od onog koji rješava. Zato se sudar zabilježi, a ne sprječava: na samom plaćanju, u revizijskom tragu i kao oznaka u listi.
                    • Do sada je to bio jedan red u serverskom logu, a to nije mjesto sa kojeg gost koji je platio dvaput dobije novac nazad.

                    0.23.1

                    5. septembar 2026.

                    Popravljeno - novac

                    • Kod izdat u trenutku zatvaranja računa vezao se za već zatvoren račun. Zatvaranje na gotovinu odbija se dok je kod živ - ali kod se za račun veže tek na kraju procesa plaćanja, pa konobar koji zatvori u tom razmaku ne vidi ništa živo, zatvori, a kod poslije toga sleti na plaćen račun. Gost prebaci novac i lokal ga ima dvaput: u kasi i na računu u banci, a jedino što o tome negdje piše je jedan red u logu.
                    • Obje strane sada zaključavaju isti red u bazi, pa jedna čeka drugu. Ko izgubi dobije rečenicu: gost da je račun u međuvremenu zatvoren, konobar da je kod još živ. Kod koji je izgubio se poništi prije nego što ga gost uopšte vidi.
                    • Zatvaranje sada čita iznose iz zaključanog reda, a ne iz onog pročitanog ranije - uplata je mogla stići dok se čekalo, a uzeti gotovinu za novac koji je već stigao je upravo ono što se ovdje brani.

                    0.23.0

                    5. septembar 2026.

                    Dodano

                    • Happy hour i zakazane akcije. U Meniju se postavi pravilo: ovim danima, između ovih sati, toliko posto popusta - na cijeli meni ili na jednu kategoriju. Gost vidi novu cijenu, precrtanu staru i naziv akcije.
                    • Vrijeme je vrijeme u sali. Prozor postavljen na 17:00 je 17:00 u lokalu i ljeti i zimi; čuvaju se minute od ponoći u vremenskoj zoni poslovnice, a ne trenutak i ne pomak. Testovi prolaze i kad server radi u UTC, New Yorku, Tokiju i na UTC+14.
                    • Prozor preko ponoći, jer bar to i traži: 22:00 do 02:00. Sitni sati pripadaju danu u kojem je prozor počeo, pa petak pokriva ranu subotu, a ne rani petak.
                    • Ako se dva pravila preklapaju, važi ono sa većim popustom; ne sabiraju se. Dva puta po 20% koja se pomnože u 36% je broj koji niko nije postavio.
                    • Zaokruživanje ide u korist gosta: gdje postotak ne dijeli tačno, fening ide sa cijene, a ne na nju.

                    Šta ovo štiti

                    • Cijena na ekranu je cijena koja se naplaćuje. Telefon uz narudžbu šalje iznos koji je pokazivao; ako server izračuna drugi - akcija se u međuvremenu zatvorila, ili je neko promijenio cijenu - narudžba se odbija i gostu se kaže da se cijena promijenila, umjesto da se naplati iznos koji niko nije vidio. Meni se pritom osvježi.
                    • Popust ide na jelo, ne na dodatke. 20% na kafu je 20% na kafu; duplo je onoliko koliko je lokal odredio.
                    • Postotak je ograničen na 90. Pravilo koje skida sve nije popust nego besplatna hrana objavljena svakome ko ima naljepnicu sa stola, i mnogo je vjerovatnije greška u kucanju nego namjera.
                    • Pravilo bez ijednog dana, ili sa istim početkom i krajem, se odbija umjesto da se nagađa - takvo pravilo se nikad ne otvori, a vlasnik bi grešku tražio u popustu.

                    0.22.1

                    5. septembar 2026.

                    Popravljeno

                    • Provjera u smoke testu tražila je BOM u dekodiranom tekstu, a UTF-8 dekoder ga po standardu skida - pa ta provjera nikada nije mogla vidjeti oznaku, bila ona tu ili ne. Fajl je bio ispravan, provjera nije. Sada se gledaju bajtovi, jer je oznaka svojstvo bajtova, i isto je dodano u jedinični test.

                    0.22.0

                    5. septembar 2026.

                    Dodano

                    • Izvoz za knjigovođu, dugme na ekranu Plaćanja. CSV sa jednim redom po uplati koja je stvarno stigla: datum i vrijeme u vremenu poslovnice, poziv na broj, iznos, napojnica, uplaćeno, način i - kolona koju niko ne treba tražiti - da li je uplatu potvrdila banka ili je neko potvrdio ručno. To su dvije različite vrste činjenice i ko ih ne razlikuje ne može se osloniti ni na jednu.
                    • Fajl je napravljen da se otvori iz prve: tačka-zarez kao razdjelnik, zarez kao decimalni, i BOM na početku da Excel na Windowsu pročita naša slova. Bez toga svako č, ć, š, ž i đ u nazivima jela stigne kao nešto drugo, a knjigovođa zaključi da izvoz ne radi.
                    • Naziv koji počinje sa =, + ili @ se neutralizuje. Ime kupca nije nešto čime neko treba da može pokrenuti nešto u tuđem Excelu.

                    Šta ovaj fajl nije

                    • Nije bankovni izvod. Novac ide sa računa na račun i XPay ga nikad ne drži, pa su ovo XPay-evi zapisi o uplatama koje je prepoznao, a ne bankin zapis o njima. Banka ostaje mjerodavna i tako i piše u opisu.
                    • Ništa se ne odbija. Kartica ideje je tražila i „0,02 KM naknade" po transakciji - takve naknade nema. 0,02 KM je cijena transakcije preko uključenog broja na Business planu, i naplaćuje se na mjesečnoj XPay fakturi koja postoji zasebno. Oduzimati izmišljenu naknadu od ovih iznosa pogrešno bi prikazalo i prihod i trošak.
                    • PDF verzija nije napravljena. Knjigovođa uvozi CSV; PDF je za arhivu i može sačekati red iza stvari koje se koriste svaki dan.

                    0.21.0

                    5. septembar 2026.

                    Popravljeno - novac

                    • Ponovljeni zahtjev sa istim Idempotency-Key mogao je napraviti drugo plaćanje. Zapis o ključu upisivao se tek nakon što je odgovor već poslan, i to bez čekanja - pa je kasa koja je istekla i pokušala ponovo, a to je jedini razlog zbog kojeg to zaglavlje i postoji, mogla stići u taj razmak, ne naći ništa i naplatiti sto dva puta. Ključ se sada zauzima prije nego što se zahtjev obradi, a odgovor upisuje prije nego što se vrati.
                    • Time se zatvara i slučaj dva istovremena identična zahtjeva: onaj koji izgubi upis dobija odgovor da je prvi još u obradi, umjesto da napravi drugo plaćanje pored njega.
                    • Zahtjev koji ne uspije oslobađa svoj ključ, da plaćanje odbijeno zbog pogrešnog IBAN-a ne zaključa vlastiti ključ na 24 sata.
                    • Ovo je uhvatio smoke test koji pravi plaćanje pa ga odmah ponovi. Prolazio je mjesecima i pao na opterećenom CI serveru - tačno onako kako bi i pao u sali.
                    • Povrat je sa računa stola skidao i napojnicu. Na stol se knjiži samo hrana i piće - napojnica se namjerno ne knjiži - a povrat je skidao cijeli iznos, sa napojnicom. Kod stola koji plaća jedan gost to je sakrivalo ograničenje na nulu; kod stola koji plaćaju dvoje nije: gost A plati 20 uz 2 KM napojnice, gost B plati 30, i povrat gostu A ostavi račun na 28 od 50 - pa se sljedećem gostu naplati 2 KM koje je neko već platio.
                    • Pravilo je da povrat prvo ide iz napojnice. To je čitanje koje nikada ne traži od stola da ponovo plati hranu koju je već platio, i tačno se poklapa sa onim što je na stol i knjiženo.

                    0.20.3

                    5. septembar 2026.

                    Popravljeno

                    • Odlazak sa ekrana sa QR kodom bljesnuo bi meni. Ekran se crta dok postoje i pogled i plaćanje; kod se brisao prije nego što se čekao odgovor servera, pa je pogled ostajao na „čekanju" bez ičega da nacrta - i crtanje bi propalo do dna komponente, a to je meni. Trajalo je koliko i zahtjev. Isto se dešavalo i pri otkazivanju zahtjeva za gotovinu ili karticu.
                    • Sada se odredište i ono što se napušta mijenjaju zajedno, prije bilo kakvog čekanja, pa React nacrta jedan kadar i to onaj pravi.

                    0.20.2

                    5. septembar 2026.

                    Popravljeno

                    • „Biram stavke" je gostu nudio dugme za plaćanje 0,00 KM. Biranje unaprijed označi ono što je taj telefon naručio, a to je prazno kad je narudžbu ukucao konobar - pa je gost sa ukucanom narudžbom pritisnuo „Biram stavke" i dobio aktivno dugme za nula maraka. Sada na tom mjestu piše šta treba uraditi, umjesto da stoji ugašeno pored nule - isto kao što list jela kaže koju grupu opcija niste odabrali.

                    0.20.1

                    5. septembar 2026.

                    Popravljeno

                    • Ekran Izvodi je pokazivao ključ umjesto naziva za svaku vrstu izvora osim dvije koje trgovac može sam napraviti. Godinama nevidljivo, jer ništa u konzoli nije pravilo takav izvor - a onda je jučerašnje dugme „Plaćeno" napravilo prvi „Ručna potvrda" i naziv se pojavio kao statements.kind.MANUAL. Sada su prevedene sve vrste koje server uopšte može napraviti.
                    • Uz to test koji čita spisak vrsta iz Prisma šeme, ne iz kopije, i pada ako se doda vrsta bez naziva. Kopija bi se slagala sama sa sobom i ne bi rekla ništa o šemi.

                    0.20.0

                    5. septembar 2026.

                    Popravljeno - novac

                    • Ručna potvrda uplate knjižila je isti novac dva puta. 0.19.0 je popravio iznos, ali ne i put: potvrda se zavede kao priliv, matcher je odmah pripiše računu, a onda ju je kod pripisivao još jednom. Račun od 1000 KM sa 400 KM uplate, nakon potvrde preostalih 600, ispao je poravnat sa 1600 KM. Uslov je bio prenizak - gledao je samo da li je matcher rekao „poravnato", a matcher pripisuje priliv i kad ga ocijeni kao manjak ili višak. Sada se pita ono što je jedino pouzdano: kojem računu je priliv na kraju pripisan.
                    • Uhvatio ga je smoke test koji je uz to dugme i napisan. Prvi put je vratio 1400, drugi put 1600; obje brojke su bile pogrešne na različit način.

                    Dodano

                    • „Po stolovima" na ekranu Stolovi: promet, prosječan račun, koliko se puta sto dnevno okrene, koliko dugo račun stoji otvoren, i koliko skeniranja sa tog stola uopšte završi narudžbom.
                    • Vrijeme je sredina, ne prosjek. Jedan račun zaboravljen preko noći pomjeri prosjek za sat, a sredinu nimalo - a zaboravljen račun se dešava skoro svake sedmice.
                    • Prosječan račun se računa samo po računima na kojima je nešto naručeno. Skeniranje koje nije završilo narudžbom nije jeftin račun, nego nije račun; da se broji kao nula, najprometniji sto bi ispao najgori.
                    • Sto sa premalo računa se označi, a ne sakrije. Sto sa dva računa nema loše brojeve nego još nema brojeve, a da se izbaci iz tabele izgledalo bi kao da stola nema.

                    Šta ovaj broj nije

                    • Minute nisu koliko je gost sjedio. Mjere se od skeniranja koda do zatvaranja računa: gost često skenira usred obroka, a osoblje zatvori račun kad stigne. Dobro za poređenje stolova međusobno, loše kao stvarno vrijeme za stolom - i tako i piše ispod tabele, jer se po ovom broju premješta namještaj.

                    0.19.0

                    5. septembar 2026.

                    Popravljeno - novac

                    • Ručna potvrda uplate na djelimično plaćenom računu knjižila je novac koji nikad nije stigao. Potvrda se zavodi kao priliv, a priliv se dodaje na ono što je već uplaćeno - pa je račun od 1000 KM sa 400 KM uplate, nakon potvrde na puni iznos, ispao poravnat sa 1400 KM i prešao u PREPLAĆENO. Preplaćeno je iznos koji ekran za povrat rado ponudi da se vrati kupcu. Sada se potvrđuje ono što je preostalo, a ne cijeli račun.
                    • Ako na računu nema šta da se potvrdi, potvrda se odbija umjesto da se zavede kao priliv od nula.

                    Dodano

                    • Dugme „Plaćeno" na fakturi koja čeka uplatu. Ovo je vlasnikovo pitanje postavljeno naglas: firma izda račun sa QR kodom, kupac skenira svojom bankom i plati - hoće li XPay to primijetiti? Hoće, čim stigne izvod. Do tada je jedini put bio ručno slanje priliva kroz API, a sad je dugme.
                    • Zavodi se kao ručna potvrda, sa imenom onoga ko je potvrdio, i ostaje odvojivo od uplate koju je potvrdila banka. Pita se naglas prije nego što se zavede, jer se ovim novac knjiži kao stigao.
                    • Nudi se samo vlasniku i menadžeru, jer server i traži tu rolu. Dugme koje postoji samo da kaže ne gore je od dugmeta kojeg nema.
                    • Jedna rečenica na ekranu Fakture koja kaže kako se račun uopšte zatvara: uvezete izvod, XPay prepozna uplatu po pozivu na broj i zatvori ga sam. To je cijeli odgovor i nigdje nije pisao.

                    0.18.0

                    5. septembar 2026.

                    Dodano

                    • Dugme Štampaj, u Fakturama. Pregled je otvarao PDF u kartici, koju pretraživač zna odštampati - ako znate da je to ono što treba uraditi. Ko hoće papir traži riječ „štampaj", a ne karticu sa alatnom trakom.
                    • Nacrt se štampa kroz pregled i izlazi sa oznakom NACRT, što je tačno ono što treba da stoji na papiru koji još nije račun.

                    Promijenjeno

                    • Štampanje sada svuda znači štampanje PDF-a. Dugme na stranici koju kupac otvori zvalo je window.print() nad samom stranicom, a to je drugi prikaz istog računa - pa je kupčeva kopija na papiru bila složena drugim kodom nego ona koju firma arhivira. Stranica i PDF su se upravo usaglasili oko toga šta pišu; štampa se morala usaglasiti oko toga šta proizvodi.
                    • Ako pretraživač odbije da otvori dijalog za štampu nad fajlom, fajl se otvori u kartici. Ko gleda PDF uvijek ga može odštampati; dugme koje naizgled ne radi ništa je kvar koji vrijedi izbjeći.

                    0.17.1

                    5. septembar 2026.

                    Popravljeno

                    • Crtanje primjera računa vraćalo je 201 Created iako ništa ne stvara. POST je zato što postavke koje se isprobavaju idu u tijelo zahtjeva, a ne u adresu - ali odgovoriti „napravljeno" na zahtjev koji ništa nije napravio je laž na koju se klijent prije ili kasnije osloni. Sada 200.

                    0.17.0

                    5. septembar 2026.

                    Dodano

                    • Izgled računa, u Postavkama. Trgovac sada bira šta stoji na njegovom računu: svoja adresa, svoj ID broj, svoj kontakt, ID broj i adresa kupca, i QR kod. Uz to dvije vlastite linije - jedna u zaglavlju, jedna na dnu.
                    • Primjer računa koji se crta dok mijenjate, umjesto da se račun mora izdati da bi se vidio. Do sada je jedini način da se vidi kako račun izgleda bio da se izda - a to uzima broj iz vlastite serije dokumenata i ne poništava se brisanjem. Primjer nosi vaše zaglavlje i vaš logo, izmišljene stavke i izmišljenog kupca, oznaku PRIMJER na licu, i QR koji nije nalog za plaćanje.
                    • Primjer crta isti kod koji crta pravi račun. Pregled iz drugog renderera je pregled nečeg drugog - to je greška iz koje je ovaj dio upravo izvučen.
                    • Ništa se ne snima dok se ne pritisne Sačuvaj, i slanje jednog prekidača ne briše ostalih šest.

                    Šta se ne može isključiti

                    • Sitna slova na dnu. Ona kažu šta dokument jeste, a ne šta neko preferira, i račun koji se može natjerati da ih prestane pisati nije račun.
                    • ID broj i adresa kupca i dalje idu samo na PDF koji firma arhivira. Stranica koju kupac otvori ih nikad nije nosila i ne nosi ni sada - link se prosljeđuje knjigovođi, a proslijeđen račun ne treba nositi više od računa.

                    Zadano

                    • Sve uključeno, obje linije prazne. Trgovac koji nikad ne otvori ovaj ekran vidi tačno ono što je vidio i prije - jedino prihvatljivo zadano stanje za postavku koja mijenja pravni dokument.

                    0.16.0

                    5. septembar 2026.

                    Popravljeno

                    • Kupac i firma su gledali dvije različite verzije istog računa. PDF koji firma arhivira i stranica koju kupac otvori bile su dva ručno pisana prikaza istog dokumenta i razišle su se na četiri načina. Sada postoji jedno mjesto koje odlučuje šta račun kaže, a oba prikaza samo crtaju to.
                    • Sitna slova su govorila različite stvari. Na stranici je pisalo da je fiskalizacija obaveza izdavaoca, a na PDF-u da je račun izdat elektronski i punovažan bez potpisa i pečata. Jedan dokument ne može govoriti dvoje.
                    • Datum se računao po vremenskoj zoni čitaoca. Račun izdat u 01:30 ujutro u Sarajevu kupcu nekoliko sati zapadno prikazivao se sa datumom prethodnog dana
                    • na stranici sa koje se traži da plati. Datum na računu je činjenica o računu, ne o tome ko ga gleda. Sada se piše u vremenskoj zoni poslovnice, na obje kopije.
                    • „PDV 0,00" na računu firme koja nije u sistemu PDV-a. Stranica je uvijek štampala red za PDV, PDF samo kad ga ima. Nula na tom mjestu čita se kao tvrdnja da je izdavalac registrovan. Sad ga nema kad ga nema.
                    • Uplaćeni novac se vidio samo u jednom od četiri stanja. Stranica je prikazivala uplaćeno i preostalo samo dok je račun DJELIMIČNO plaćen, pa djelimično plaćen račun koji je u međuvremenu dospio nije kupcu govorio ništa o uplati koju je već poslao - a to je upravo slučaj kad mu to najviše treba.
                    • IBAN se grupisao u četvorke na dva mjesta, a QR kod se crtao u dvije različite boje. Po jedno mjesto za oboje.

                    Zašto ovo prije dizajnera računa

                    • Sljedeći korak je da trgovac bira šta stoji na njegovom računu. Da je to napravljeno prije ovoga, izbor polja bi se morao implementirati dva puta i razišao bi se na isti način - a to znači da kupac čita jedan dokument, a firma arhivira drugi.

                    0.15.0

                    5. septembar 2026.

                    Dodano

                    • Promjena vlastite lozinke iz konzole, u Postavkama. Endpoint postoji od početka i nijedan ekran ga nikad nije pozvao, pa je zaboravljena ili podijeljena lozinka značila da neko mora pokrenuti komandu na serveru - što je sasvim u redu kao zadnje rješenje i loše kao prvo. Račun je vlasnikov; promjena lozinke je njegova stvar.
                    • Traži se trenutna lozinka, da telefon ostavljen na šanku ne bude način da nekog zaključate iz vlastite konzole. Nakon promjene sve prijave se odjavljuju, i ova - pa ekran to i kaže i vodi na prijavu, umjesto da vas izbaci u nekom nepredvidivom trenutku kasnije.

                    Popravljeno

                    • Promjena lozinke je bila način da se zaobiđe pravilo za operatera. Pravilo o dužini živjelo je na pet mjesta i zbog toga je bilo tačno na četiri: forma za promjenu tražila je deset znakova od svih, pa je račun napravljen pod pravilom od dvanaest mogao sa ekrana preći na deset. Račun koji može doći do svakog trgovca na platformi završio bi sa najslabijom lozinkom na njoj. Sada postoji jedno mjesto koje kaže koliko, i svih pet ga čita.

                    0.14.0

                    5. septembar 2026.

                    Dodano

                    • Meni se čita i kad padne internet. Wifi u staroj kamenoj zgradi pada, a ekran koji iz toga ispadne je najgori kvar u proizvodu: gost skenira naljepnicu, dobije stranicu koja kaže da ne može ništa dohvatiti, i zaključi da naljepnica ne radi. Lokal onda čuje da XPay ne radi. Sve što treba da se meni pročita bilo je na telefonu minut ranije.
                    • Meni se čuva na telefonu pri svakom uspješnom otvaranju i vrijedi tri dana. Stariji se ne prikazuje - cjenovnik se u međuvremenu promijenio, a biti samouvjereno pogrešan pred nekim ko sprema novac je gore nego ne reći ništa.
                    • Traka na vrhu kaže kad je meni sačuvan i da su se cijene možda promijenile, sa dugmetom za ponovni pokušaj.
                    • Slika koja se ne može učitati sada pada na isti onaj crtani placeholder umjesto da ostane prazan okvir. Bez veze su sve slike takve.

                    Šta ovo namjerno ne radi

                    • Ne prima narudžbe u red čekanja. Narudžba koja piše „poslano" a nije poslana je najgori mogući ishod u sali: gost sjedi i čeka, kuhinja je nikad ne vidi, a dok se veza vrati možda je već otišao, ili se cijena promijenila, ili je jelo nestalo. Čitati meni bez veze je korisno. Naručivati u prazno nije, koliko god bolje izgledalo na spisku funkcija.
                    • Dok je meni sa telefona, dugmad za dodavanje i za poziv osoblja se ne prikazuju. Dugme koje ne može doći do servera gore je od dugmeta kojeg nema.
                    • Naljepnica koja stvarno ne postoji i dalje kaže da ne postoji. Keširani meni za sto kojeg nema primao bi narudžbe koje niko ne može donijeti.

                    0.13.0

                    5. septembar 2026.

                    Dodano

                    • Ekran za goste govori jezik telefona. Do sada je govorio jezik lokala, što je tačan odgovor za redovne goste i pogrešan za razlog zbog kojeg lokal u Sarajevu ovo i želi u augustu: turista sa telefonom koji nije na bosanskom dobijao je ekran koji mora pogađati, na mjestu gdje niko nema vremena da mu objašnjava.
                    • Telefon na hrvatskom, srpskom ili crnogorskom čita isti katalog kao bosanski. Poslati ih na engleski zato što oznaka nije tačno „bs" bilo bi besmisleno.
                    • Telefon koji ne govori nijedan od ta dva dobija engleski. Gost iz Njemačke je bolje uslužen engleskim nego bosanskim.
                    • BS / EN prekidač gore desno na naslovnoj strani, i njegov izbor se pamti. Nije zastava - zastava je država, a ovo je jezik, i to nije isto. Većina gostiju ga nikad neće ni pritisnuti jer je telefon već odgovorio.

                    Šta ovo ne radi

                    • Ne prevodi meni. „Ćevapi, 10 komada, somun, luk" je ono što je lokal napisao i tako i ostaje, na svakom jeziku. Dugmad i natpisi su naši i njih prevodimo; hrana nije. Turista dobije ekran kojim zna rukovati oko menija o kojem bi ionako pitao - to je pošten dio problema i dio koji vrijedi riješiti.

                    Ostalo

                    • Konzola je dobila svoj test runner. Do sada nije imala nijedan test, a jeste najveći dio koda u projektu.

                    0.12.0

                    5. septembar 2026.

                    Dodano

                    • Meni koji zna šta se prodaje. Do sada je meni bio ono što je neko utipkao u junu, u tom redoslijedu, sa rasprodanom ribom na trećem mjestu. XPay sada čita zadnjih 30 dana narudžbi u toj poslovnici i s tim radi tri stvari.
                    • Rasprodano pada na dno kategorije - i nikad se ne skriva. Gost koji je došao zbog ribe zaslužuje rečenicu „ne večeras". Meni koji se tiho smanjio tjera ga da traži, pa da ipak pita konobara - a to je razgovor zbog kojeg ekran za naručivanje i postoji.
                    • Oznaka „Najtraženije", na najviše tri jela po kategoriji i najviše na trećini nje. Oznaka na devet od jedanaest jela ne znači ništa. Kod izjednačenja na granici oznaka se ne dodjeljuje nikome: tri jela sa po osam narudžbi i mjesto za jedno nije izbor koji se može napraviti pošteno.
                    • Traka na naslovnoj strani sada vodi ono što se stvarno naručuje. Slika je i dalje ulaznica - ta traka je jedino mjesto gdje bi slika koje nema bila cijela pločica - ali među slikanim jelima prvo ide ono što gosti biraju.
                    • Poredaj meni po traženosti, prekidač po poslovnici u Meniju. Isključen dok ga neko ne uključi: vlasnik je svoj meni posložio, a mašina koja mu ga preko noći prerasporedi je bezobrazna. Uključen, diže jela koja se traže na vrh njihove kategorije, a sve ostalo ostaje gdje je i bilo.

                    Kako ovo ne laže

                    • Ispod praga se ništa ne pomjera. Traženost druge večeri je tri narudžbe i slučajnost, a poredati po tome znači tu slučajnost zamrznuti: jelo koje se zateklo na vrhu naručuje se više, pa ostaje na vrhu. Poslovnica mora imati najmanje 30 naručenih stavki, a jelo najmanje 5, prije nego što broj bilo šta uradi.
                    • Prozor se kotrlja. Jelo koje se prestalo prodavati prestaje biti traženo.
                    • Otkazane narudžbe se ne broje. Otkazana narudžba nije dokaz da je neko to htio - najčešće je dokaz da je kuhinji ponestalo.
                    • Broji se po poslovnici, ne po firmi. Ljetna bašta i gradski kafić istog vlasnika nemaju isto najtraženije jelo.
                    • Marža se ne dira. Ideja iz koje je ovo nastalo tražila je i da se guraju jela sa većom maržom. XPay ne zna koliko jelo košta da se napravi, samo po čemu se prodaje. Poredati po cijeni i to zvati maržom značilo bi gurati skupo jelo, a to nije isto jelo. Za to prvo treba nabavna cijena u meniju.

                    Popravljeno

                    • Test za „Ponovi isto" je držao svoju kopiju logike umjesto da je uveze - ista greška zbog koje je test za vremenske zone jednom prolazio dok je original bio pogrešan. Sada uvozi pravu stvar.

                    Uputstva

                    • Novo poglavlje u Pomoći: kako se pravi meni, šta radi Rasprodano i zašto se artikal ne briše.

                    0.11.0

                    5. septembar 2026.

                    Dodano

                    • „Ponovi isto" - jedan dodir za istu rundu. Za barove: runda je istih četiri pića, a mahati konobaru da to kaže je upravo ono što ovo zamjenjuje. Server je iznova sastavi iz onoga što je narudžba zapisala i pošalje je običnim putem - cijena se čita iz menija, a jelo koje je u međuvremenu rasprodano se odbija. Jedino što se ušteđuje je kucanje.
                    • Dugme se pojavljuje samo kad se runda može ponoviti vjerno. Narudžba čije je jelo obrisano iz menija, ili čije opcije potiču od prije nego što su im se pamtili ID-evi, ne nudi dugme - jer „isto ponovo" koje tiho izostavi duplu kafu koju je neko platio gore je od dugmeta kojeg nema.

                    Promijenjeno

                    • Izbor opcije se sada pamti i po ID-u, ne samo po nazivu i cijeni. Naziv i cijena su dovoljni da se sačuva šta je gost pristao platiti; da se runda ponovi treba znati i koja je opcija to bila.

                    0.10.6

                    5. septembar 2026.

                    Popravljeno

                    • Dva gosta koja u istoj sekundi zatraže kod dobijala su oba kod za isti novac. Koliko naplatiti se računa čitanjem tuđih živih kodova, pa se kod tek onda pravi - dva koraka bez ičega između. Sada se, pod zaključanim redom računa, prebroji sve živo uključujući i taj novi kod, i ako je sto prekoračen kod se poništava prije nego što ga gost uopšte vidi.
                    • „Zatraži novi kod" nije tražio novi kod, nego vraćao na prethodni ekran.
                    • Neuspjela narudžba je ostavljala gosta na ekranu preporuka bez izlaza - jedino dugme je bilo ono koje je upravo palo.
                    • Dugme za konobara ostajalo je zaključano do kraja obroka na početnom ekranu, jer se taj ekran nikad nije osvježavao.
                    • Lokal s dvije poslovnice nije mogao pogledati drugu: mapa stolova se vraćala na prvu čim se izbor promijeni, a na Poslovnicama je sklapanje jedne otvaralo prvu.

                    0.10.5

                    5. septembar 2026.

                    Sigurnost

                    • Ekran u kuhinji je preko WebSocketa dobijao tok plaćanja. Njegov token nosi samo dozvole za narudžbe, SSE mu plaćanja filtrira, a socket je svaki terminal stavljao u istu sobu - pa je zidni ekran, koji svako u prostoriji može pročitati, dobijao iznose, napojnice, reference i stolove. Soba za narudžbe je sada odvojena od sobe za novac.
                    • Tri rute nisu imale ni ulogu ni dozvolu, pa ih je dosezao svaki autentifikovan token uključujući isti taj zidni ekran: podaci firme s licencnim ključem i bankovnim računima, fakture koje XPay ispostavlja lokalu, i mjesečna potrošnja.

                    Popravljeno

                    • Firma s više poslovnica nije mogla ništa uraditi s fakturom. Šest ruta adresira fakturu po ID-u i ne spominje poslovnicu, a kapija je tražila da se poslovnica imenuje - na ruti koja za nju nema mjesta. Sada se izvodi iz same fakture.
                    • Povrat je bio nedostupan za potplaćene i preplaćene račune, a nudilo se „Potvrdi uplatu" - koje na njima knjiži drugu, izmišljenu uplatu na pun iznos.
                    • Uvoz izvoda je uvijek išao zadnjem izvoru u listi. Jedan ref dijeljen na više polja za odabir datoteke pokazuje na ono koje se zadnje montiralo, pa su stvarne uplate završavale pod pogrešnim bankovnim računom.

                    0.10.4

                    5. septembar 2026.

                    Popravljeno

                    • Sto se mogao naplatiti više nego što račun iznosi. Plaćanje odabranih stavki nije poredilo zbir s onim što je preostalo, niti je vidjelo kodove koji drže novac a ne imenuju stavke. Četvero gostiju za računom od 40,00 moglo je uzeti po četvrtinu, pa jedan od njih odabrati sve četiri stavke i biti zatražen za još 40,00.
                    • Plaćena stavka se vraćala u ponudu. Čim uplata sjedne, kod izlazi iz živih statusa i njegove stavke opet postaju izabirljive - pa je sljedeći telefon mogao izabrati ćevape koje je neko već platio.
                    • Uplata veća od iznosa nije knjižena na račun stola. Gost koji uzme dio od 5,00 i u banci zaokruži na 6,00 ide pravo u PREPLAĆENO, a račun se knjižio samo na tačno PLAĆENO - pa je novac stajao u banci, pripisan uplati, dok je sto i dalje dugovao cijeli iznos i nije se mogao zatvoriti.

                    0.10.3

                    5. septembar 2026.

                    Popravljeno

                    • Ista uplata se knjižila dvaput. Kada matcher nađe neslaganje iznosa, on već upiše novac i tek onda otvori slučaj koji pokazuje na tu istu uplatu - pa je pritisak na „Podmiri" dodavao isti iznos ponovo. Račun od 60,00 na koji je stiglo 30,00 završavao je kao plaćen u cijelosti: lokal prestane tražiti ostatak, promet je pogrešan, a povrat se odobrava do iznosa koji nikad nije stigao.
                    • Uplata manja od računa zatvarala je račun. Status je bio samo PLAĆENO ili PREPLAĆENO, nikad POTPLAĆENO. Zakačiti uplatu znači „ovaj novac pripada ovom računu", a to nije isto što i „ovaj račun je plaćen".
                    • Iznos se čitao van transakcije, pa su dvoje koji rješavaju u istom trenutku oboje čitali stari zbir i oboje dodavali svoje.
                    • Potvrda „vidio sam uplatu" nije bila zaštićena od dvostrukog pritiska. Vanjski ID nosi vrijeme u milisekundama, pa provjera duplikata nikad nije vidjela dvije potvrde kao istu - dva pritiska su knjižila dvostruki iznos.

                    0.10.2

                    5. septembar 2026.

                    Popravljeno

                    • Backup van servera nije radio ni jednom. Tri odvojene greške, sve moje od jučer: noćni timer nije učitavao .env, pa su BACKUP_REMOTE i BACKUP_PASSPHRASE bili prazni svake noći; rsync je uvijek dobijao putanju do šifrovanih tajni čak i kad taj fajl nije napravljen, pa je svaki backup sa podešenim odredištem padao; a status je javljao „degraded" s razlogom koji je bio tačan iz pogrešnog razloga.
                    • Obnova bez argumenta vraćala je snimak koji je napravila prethodna obnova. Sigurnosne kopije se zovu xpay-db-before-restore-..., glob ih je hvatao, a „before" sortira iza svake cifre - pa je „najnoviji backup" uvijek bio taj. Ko obnovi dvaput vratio bi baš onu bazu od koje bježi.
                    • SMTP_SECURE i ALLOW_UNPROVEN_QR nisu stizali do kontejnera. Postoje u .env.example i u shemi, a compose ih nije prosljeđivao - postavka koju operater upiše i koja ne radi ništa. Provjerio sam svih 34; fali još JWT_ACCESS_TTL i JWT_REFRESH_TTL_DAYS, i oni su dodani.
                    • Verzija se upisivala prije nego što su slike izgrađene, pa je status javljao novo izdanje dok su kontejneri vrtjeli staro - a ako bi build pao, javljao bi verziju koja nikad nije ni startala.
                    • install.sh je zvao nepostojeću funkciju na grani čiji je jedini posao upozoriti operatera; pod set -e to je rušilo instalaciju umjesto upozorenja.

                    0.10.1

                    5. septembar 2026.

                    Popravljeno

                    • Dan je na serveru počinjao sat ranije, dva puta godišnje. Granica dana se računala tako što se pomak zone uzme u podne i primijeni na ponoć - a na dan kada se sat pomjera to su dva različita pomaka. Radilo je na mom računaru jer on dijeli sarajevsko ljetno računanje vremena; na serveru, koji radi u UTC-u, nije.
                    • Kraj dana je bio fiksnih 24 sata. Dan kada se sat vraća traje 25 sati, pa se gubio zadnji sat večeri - onaj u kojem je lokal otvoren.

                    Testovi

                    • Test je do sada držao vlastitu kopiju te aritmetike umjesto da je uveze, pa je kopija prolazila dok je original bio pogrešan. Sada uvozi pravi kod i provjerava oba dana pomjeranja sata, u tri vremenske zone servera.

                    0.10.0

                    5. septembar 2026.

                    Dodano

                    • Postavljanje lozinke sa servera. Zaboravljena lozinka vlasnika je do sada značila ručno upisivanje argon2id hasha u bazu - postupak koji niko nije zapisao i koji se ne smišlja u osam uvečer dok lokal čeka. Odjavljuje i sve ostale sesije, jer je razlog za promjenu lozinke obično to što je neko drugi možda zna.
                    • Drugi operater se može napraviti. Komanda je to odbijala i upućivala na „Admin konzolu" i „password reset flow" - ni jedno ni drugo nije postojalo. Jedan operater je loše mjesto za biti: ode na godišnji, ode iz firme, a nalog koji može suspendovati svaku firmu je onaj u koji niko drugi ne može ući.

                    0.9.9

                    5. septembar 2026.

                    Dodano

                    • Pretraga plaćanja. Jedna kutija: upišete poziv na broj ili iznos. Do sada se moglo tražiti samo po tačnom broju računa iz kase - jedinom broju koji gost koji pita nema. Poziv na broj se traži u svim oblicima (sa izvoda, sa računa, RF), bez obzira na razmake i velika slova.

                    0.9.8

                    5. septembar 2026.

                    Dodano

                    • Forma za fakturu pita ono što ta djelatnost stvarno treba. Registar na serveru odavno deklariše koja polja koja vrsta posla ima i kako ih zove, a niko to nije čitao - pa su i zakupodavac i komunalno pitani za „Predmet", dok je server znao da jedan hoće mjesec a drugi obračunski period. Sada stanodavac vidi „Mjesec" i „Nekretnina", komunalno „Obračunski period" i „Broj korisnika", a skladište „Otpremnica".

                    0.9.7

                    5. septembar 2026.

                    Popravljeno

                    • „QR profile BIH_IPS has not been confirmed with a bank" pisalo je ugostitelju na engleskom. Poruka je tačna i napisana za onoga ko drži server, a stizala je pred onoga ko drži restoran - koji nije birao jezik i ne zna šta je QR profil. Sada se prevodi i kaže mu šta može uraditi.

                    0.9.6

                    5. septembar 2026.

                    Popravljeno

                    • Jedna greška je crtala dvije crvene trake. Ekrani koji sami prikazuju grešku nisu gasili opštu traku iz rasporeda, pa je isti neuspjeh izgledao kao dva - a onaj ko broji trake zaključi da su se pokvarile dvije stvari. Opcija za to postoji odavno i ovi ekrani je nisu koristili.

                    0.9.5

                    5. septembar 2026.

                    Popravljeno

                    • Pregled je pisao „Naplaćeno danas" i kad je izabran prošli mjesec. Sada natpis prati period.
                    • Povrati se konačno vide. Analitika ih vraća i oduzima od prometa otkako povrati postoje, a nijedan ekran ih nije spominjao - pa je menadžer koji vidi manji broj ostajao bez objašnjenja zašto je manji. Sada stoje ispod glavnog iznosa, i na svakom redu u Plaćanjima.
                    • Uspješnost uparivanja je bila zakovana na 7 dana bez obzira na izabrani period, pa je uz prošli mjesec stajao postotak za sedmicu koja s njim nema veze.

                    0.9.4

                    5. septembar 2026.

                    Popravljeno

                    • Prihvatanje ugovora se nije nigdje zapisivalo. Forma za registraciju šalje taj zapis otkako je napisana, a shema ga nije deklarisala - pa ga je zod odbacivao na svakoj prijavi. Ugovor sam kaže da se čuva zapis o tome koja je verzija prihvaćena. Sada se piše i na firmu i u lanac revizije, jer zapis o pristanku vrijedi tačno onoliko koliko se može dokazati da nije naknadno mijenjan.

                    0.9.3

                    4. septembar 2026.

                    Popravljeno

                    • Status stranica je javljala verziju 0.0.0. Verzija je stizala do kontejnera kao promjenljiva iz ljuske, koja postoji samo dok install.sh traje - pa ju je gubio svaki ručni docker compose up -d, tačno ono što se uradi nakon uređivanja .env. Sada se upisuje u datoteku koju API čita, i prepisuje se pri svakoj instalaciji.

                    0.9.2

                    4. septembar 2026.

                    Popravljeno

                    • Slučaj uparivanja s više mogućih računa nije se mogao riješiti. Slučaj pamti račun samo kada je tačno jedan bio uvjerljiv, a zatvaranje traži račun - pa je situacija u kojoj čovjek najviše treba, dva računa koja oba odgovaraju, bila ćorsokak na svakom ekranu. Sada se bira iz liste, istom onom koju već koristi lista neuparenih uplata.
                    • Kandidati se sada vraćaju s iznosom, referencom i stolom. Slučaj ih je čuvao samo kao paymentId i bod - sve što je matcheru trebalo i ništa od onoga po čemu čovjek bira.

                    0.9.1

                    4. septembar 2026.

                    Popravljeno

                    • Poziv konobara se nije vidio nigdje gdje osoblje gleda. Prikazivao se na mapi stolova u konzoli - jedinom mjestu gdje niko ne stoji tokom smjene. Sada stoji na vrhu ekrana u kuhinji i za šankom, iznad stolova koji čekaju naplatu, jer čovjek koji te gleda ima prednost pred čovjekom koji vadi novac.
                    • Gost koji još nije naručio nije mogao pozvati konobara. Dugme je živjelo samo unutar ekrana računa, iza računa koji već ima narudžbe - pa ga osoba kojoj najviše treba, ona koja je upravo sjela, jedina nije mogla pritisnuti.

                    0.9.0

                    4. septembar 2026.

                    Popravljeno

                    • Jedan gost je zaključavao cijeli sto. Kada bi neko zatražio QR za svoj dio, cijeli račun je prelazio u „čeka se uplata": niko drugi se nije mogao pridružiti, sto nije mogao naručiti ništa više, a izlaz je bio zvati konobara. Sada samo kod za cijeli račun zaključava sto; kod za dio ga ostavlja otvorenim, što je i smisao dijeljenja računa.
                    • Izlazak sa QR ekrana je poništavao tuđe kodove. Poništavali su se svi živi kodovi na stolu, uključujući onaj kojim je neko drugi upravo plaćao - a taj kod je već držao njihove stavke, pa bi novac stigao na poništenu uplatu. Sada se poništava samo taj gost, a sto se otvara tek kad nijedan kod nije živ.

                    Dodano

                    • Vidi se ko je za stolom i čija je koja narudžba. Server tu listu vraća otkako grupno naručivanje postoji i niko je nikad nije nacrtao, pa se drugi telefon priključivao računu u potpunoj tišini.

                    0.8.9

                    4. septembar 2026.

                    Dodano

                    • Firma konačno može sama unijeti svoj bankovni račun. Endpoint postoji od početka i nijedan ekran ga nije zvao, a konzola je poručivala „dodajte ga u postavkama lokacije" - ekran koji ne postoji. Bez računa se ne mogu izdati ni QR kodovi za stolove, ni naplata, ni fakture, pa firma koja se sama registrovala nije mogla uraditi ništa što donosi novac.
                    • IBAN se provjerava kontrolnim ciframa prije spremanja. Svaki QR kod koji ta firma ikad odštampa nosi taj broj, a zamijenjene dvije cifre ne padnu glasno - banka ili odbije uplatu danima kasnije ili je uplati na tuđi stvarni račun.

                    0.8.8

                    4. septembar 2026.

                    Popravljeno

                    • Provjera pošte sada proba i port 26. cPanel serveri slušaju na 26 baš zato što hosteri filtriraju uobičajene portove, a relay servisi nude 2525. Proba je gledala samo 465 i 587, pa je zaključivala „hosting blokira" u situaciji koja ima izlaz koji radi odmah.
                    • Odbijena lozinka se više ne prijavljuje kao zatvoren port. Proba se autentifikuje, a gutala je svaku grešku - pa je na serveru gdje su i način šifriranja i lozinka bili pogrešni ispadalo da nijedan port ne odgovara, i krivio se hosting. Ako server odgovori i odbije lozinku, to dokazuje da je port otvoren, i sada tako i piše.
                    • MAIL_REPLY_TO nije bio nigdje dokumentovan iako kod čita tu postavku - a ona odlučuje gdje stiže odgovor kupca.

                    0.8.7

                    4. septembar 2026.

                    Popravljeno

                    • Poruka o pošti sada kaže i ko je kriv. „Pitajte ih da otvore" ne kaže koga, pa tiket putuje između dva dobavljača sedmicu dana. Jedna TCP veza to rješava: ako port 443 na istom hostu radi a nijedan SMTP port ne, ruta je ispravna i adresa nije blokirana - filtriraju se SMTP portovi, a to je hosting. Ako ni 443 ne prolazi, mail host odbija ovaj server.
                    • Stari status backupa čitao se kao ispravan. Fajl bez novih polja pisala je starija skripta, što znači da kopija sigurno nije napustila mašinu i tajne sigurno nisu unutra - a odsutno polje se čitalo kao „nema problema". To je bila tačno ona laž zbog koje je provjera i dodana.

                    0.8.6

                    4. septembar 2026.

                    Dodano

                    • Backup ide i van servera. BACKUP_REMOTE je bilo šta što rsync prima. Do sada su sve kopije padale na isti disk na koji piše i baza, pa bi gubitak mašine odnio i podatke i svih četrnaest kopija odjednom.
                    • Tajne ulaze u backup, šifrovane. .env nosi ENCRYPTION_KEY, bez kojeg se nijedan webhook secret ni šifrovana konfiguracija u vraćenoj bazi ne mogu pročitati. Obnova na novom hardveru je izgledala uspješno dok neko ne otvori prvi zapis. Šifruje se lozinkom koju drži vlasnik, jer backup je datoteka koja završi na mjestima o kojima niko pažljivo ne razmišlja.
                    • Status stranica javlja kada backup ne bi pomogao. Ako kopija ne napušta mašinu ili tajne nisu unutra, stanje je „degraded" s razlogom - oboje su nevidljivi do dana kada niko ne može provjeriti.

                    Popravljeno

                    • Dokumentacija je i dalje slala operatera da sam napravi pg_dump cron, a automatika postoji i radi svaku noć. Monitoring je bio uperen u /readyz, koji javlja „ok" dok backup nikad nije prošao i pošta pada.

                    0.8.5

                    4. septembar 2026.

                    Dodano

                    • Period u pregledu poslovanja. Danas, jučer, 7 dana, 30 dana ili vlastiti raspon. Sve na tom ekranu bilo je zakovano za tekući dan jer pozivi nisu nosili nijedan parametar, a server prima raspon oduvijek - pa se „koliko smo uzeli prošle subote" nije moglo pitati nigdje u konzoli.

                    Popravljeno

                    • Datum se čitao kao UTC ponoć. „1. septembar" je u Sarajevu počinjao u dva ujutro, pa bi dan obuhvatio dva sata prethodne noći i izgubio zadnja dva sata večeri - a to je za restoran najprometniji dio. Sada se goli datum tumači u vremenskoj zoni lokala, i ljeti i zimi i na dan pomjeranja sata.

                    0.8.4

                    4. septembar 2026.

                    Dodano

                    • Povrat novca u konzoli. Backend je bio gotov i pažljiv od ranije, a nijedan ekran ga nije zvao - i još gore, dva druga toka odbijaju operaciju i poručuju menadžeru „umjesto toga napravite povrat", pokazujući na dugme kojeg nije bilo. Prozor pokazuje koliko je naplaćeno, koliko je već vraćeno i koliko ostaje, i traži broj naloga iz banke jer XPay ne prenosi novac.

                    Popravljeno

                    • Djelimičan povrat nije ostavljao trag. Zapis u historiji plaćanja pisao se samo kada povrat pokrije cijeli iznos, pa je račun vraćen u dvije rate imao jedan zapis za oboje i nijedan za prvi.
                    • Filter na Plaćanjima nije imao REFUNDED ni OVERPAID, pa se vraćen račun nije mogao naći na jedinom ekranu koji ih nabraja.

                    0.8.3

                    4. septembar 2026.

                    Popravljeno

                    • Uplata koja se ne uklopi ni sa čim sada se može zakačiti za račun. Gost zaokruži 19,50 na 20,00 i uplata ostane bez doma. Lista je bila samo za čitanje, pa je jedini način da se račun zatvori bio „Potvrdi uplatu" - a to ubaci drugu, izmišljenu uplatu na iznos računa. Lokal je ostajao sa izmišljenih 19,50 označenih kao uparenih, stvarnih 20,00 i dalje neuparenih, i onih 0,50 koje su zaista stigle nigdje zapisanih.
                    • Uplata se kači na iznos koji je stvarno stigao, pa račun može završiti kao preplaćen. To je istina, i ništa ne odlučuje umjesto čovjeka da je razlika napojnica.
                    • Uz to i Zanemari, za priljev koji nema veze s naplatom.

                    0.8.2

                    4. septembar 2026.

                    Dodano

                    • Izvodi. Novi ekran: povežete izvor, učitate izvod iz e-bankarstva i vidite šta je od toga zatvorilo račun. Do sada je jedini dokumentovani način bio curl sa XML-om ugniježđenim u JSON polje, a ovo je posao koji se radi svako jutro.
                    • Preskočene stavke se konačno vide. Parser ih vraća oduvijek i njegov komentar tvrdi da se prikazuju u dashboardu. Nisu se prikazivale nigdje.
                    • Zadnja greška izvora se vidi. Zapisivala se pri svakom neuspjelom uvozu i nije se prikazivala, pa lokal čiji izvodi tjedan dana padaju nije imao načina saznati zašto.

                    Testovi

                    • Parser bankovnih izvoda je konačno testiran. 281 linija koja čita pravi bankovni XML nije imala nijedan test ni jedan uzorak u repozitoriju. Osam testova, među njima i onaj za slučaj koji sam parser opisuje kao „pravi novac koji stigne i nikad ne bude evidentiran": dva stola koja isti dan plate isti okrugli iznos, kod banke koja ne popunjava nijedno polje reference.

                    0.8.1

                    4. septembar 2026.

                    Popravljeno

                    • Gost s jednim telefonom nije mogao platiti. Skenira naljepnicu sa stola telefonom koji drži, a mi mu na tom istom telefonu nacrtamo QR i kažemo mu da ga skenira bankom. Niko ne može skenirati vlastiti ekran. Sada ispod koda stoje primalac, IBAN, poziv na broj i iznos - svaki red se dodirom kopira.
                    • Gost čiji je kod istekao čekao je zauvijek. Provjera je gledala samo status PLAĆENO, pa je onaj ko nije dovršio ostajao pod natpisom „čeka se potvrda banke" koliko god je bio voljan gledati. Sada dobije jasnu poruku i dugme za novi kod, i piše mu da ne plaća dvaput ako je već uplatio.

                    0.8.0

                    4. septembar 2026.

                    Dodano

                    • Licenca se sada aktivira sama. Firma zalijepi ključ koji je dobila nakon uplate i paket radi odmah. Ključ se ne može izmisliti - potpisuje se tajnom koju ima samo server - i nosi broj firme kojoj je izdat, pa tuđi ključ ne radi ništa.
                    • Pomoć i uputstva u konzoli. Kako gost plaća telefonom, kako se upari tablet konobara, ekran u kuhinji, postojeća POS kasa, stara kasa koja samo štampa, ko šta vidi od osoblja, i kako se zna da je neko platio. Pisano za nekoga ko to nikad nije radio, i pokazuje se samo ono što ta djelatnost ima.
                    • Trgovina i skladište kao djelatnosti, sa vlastitom sposobnošću vođenja zaliha. Ekrani za zalihe još nisu napravljeni; vrsta postoji da se konzola već sada ponaša ispravno - prodavnica ne dobija stolove ni meni.

                    Napomena o fiskalizaciji

                      0.7.2

                      4. septembar 2026.

                      Popravljeno

                      • Račun napravljen u konzoli nije se mogao poslati mailom. Dugme „Pošalji" se prikazuje samo kad račun ima e-mail kupca, a forma za novi račun to polje nije imala - pa se nije prikazivalo nikada. Dodano je polje, i dodan način da se adresa upiše i naknadno, jer izdani račun se ne može poništiti pa je bez toga to bio ćorsokak. Upisuje se samo ako je prazna: adresa se ispisuje na računu, a izdani račun je zapis, ne formular.
                      • invoice.paid se nije slao kada je račun uredno plaćen. Obavijest se šalje iz prelaza stanja i čita iznos s reda koji je taj prelaz upravo upisao - a novac se upisivao tek poslije, običnim update-om. Radnja koja čeka invoice.paid da zatvori narudžbu nije čula ništa. Stizalo je samo za neuredna plaćanja, što je najteža verzija ovog buga za primijetiti.
                      • RAW_TEXT je tvrdio da je potvrđen s bankom. Kapija koja čuva neprovjereni domaći QR profil propušta sve što nosi status PRODUCTION, a RAW_TEXT ne tvrdi ništa o svojim bajtovima - to mu je cijeli opis. Jedan poziv sa qrFormat: 'RAW_TEXT', s tokenom terminala, prolazio je pored provjere.
                      • Dokumentacija je tvrdila da se račun šalje kao link bez priloga. Šalje se i link i PDF, i tako je već neko vrijeme.

                      0.7.1

                      4. septembar 2026.

                      Dodano

                      • Pregled računa prije izdavanja. Do sada se izgled računa mogao vidjeti jedino tako da se račun izda - a izdavanje uzme broj iz serije firme i to se brisanjem ne vraća. Pregled crta isti PDF koji se šalje, samo je nacrt pečatiran sa NACRT i nema ni broj ni referencu ni kod, jer ih zaista nema.
                      • PDV se konačno može unijeti iz konzole. Model ga nosi po stavci od početka, a forma za novi račun nije imala nijedno polje za njega - pa se račun s PDV-om nije mogao napraviti bez API-ja. Jedna stopa za cijeli račun, 17%, uključena po difoltu; firma van sistema PDV-a je isključi i tada se porez uopšte ne ispisuje.

                      0.7.0

                      4. septembar 2026.

                      Promijenjeno

                      • Konzola se sada prilagođava struci. Knjigovođa, advokat i slobodni profesionalac dobijali su Stolove i Meni. Struka se bira pri otvaranju firme i server je cijelo vrijeme znao šta koja može - registar, čuvari ruta i forma računa to čitaju - a navigacija je bila jedino mjesto koje nije, pa je konzola svima nudila restoran.

                      Dodano

                      • Postavke. Puni naziv, naziv u upotrebi, JIB/PDV broj, kontakt i logo - sve što se ispisuje na fakturi. API je to primao od početka, ekrana nije bilo, pa firma nije mogla ni ispraviti vlastito ime ni dodati porezni broj koji na fakturi u BiH mora stajati.
                      • Logo firme na fakturi, i u PDF-u i na stranici koju kupac otvori.

                      Popravljeno

                      • Paketi Flex i Business pisali su se kao admin.plans.FLEX. Nedostajali su prevodi, pa su se ispisivali sirovi ključevi.
                      • PDF je u svojstvima dokumenta pisao „XPay" kao tvorca. Sada piše firma koja je fakturu izdala.

                      0.6.9

                      4. septembar 2026.

                      Popravljeno

                      • Matcher je uzimao hiljadu kandidata bez sortiranja. Preko te granice baza je vraćala proizvoljnih hiljadu - najvjerovatnije najstarije račune, a svježa uplata pripada najnovijima. Gore od izgubljene uplate: rezervni mehanizam po iznosu ju je onda mogao zakačiti za drugi račun s istim ukupnim. Sada ide najnovije prvo.
                      • Zatvaranje računa iz liste otvorenih uvijek je knjižilo gotovinu. Sto koji je platio uplatom evidentiran je kao novac preko šanka, pa je dnevni zbir keša bio pogrešan za taj iznos. Dodano dugme za uplatu na račun.
                      • Poziv konobara se nije mogao potvrditi. Endpoint postoji od početka i nijedan ekran ga nije zvao, pa je sto ostajao crven cijelo sjedenje, brojač je rastao preko dva sata, a gostu je dugme ostajalo zaključano.

                      Promijenjeno

                      • Tri vrste settlement izvora se više ne mogu napraviti. BANK_API_POLL, EMAIL_NOTIFICATION i IPS_CONFIRMATION nemaju ni adapter ni posao koji ih poziva ni inbound secret - izvor te vrste stajao bi u listi kao aktivan i čekao nešto što ne može stići. Dokumentacija je prebačena u buduće vrijeme.
                      • reportExport je isključen na sva tri paketa koja su ga prodavala. API ga vraća direktno na kredencijal firme koja plaća, a endpointa nema nigdje.

                      0.6.8

                      3. septembar 2026.

                      Uklonjeno

                      • „Provizija 0,00 KM" sa nacrtanog računa. Isti argument kao i sekcija „0%", samo napisan kao stavka na računu - a stavka na računu se čita kao činjenica. Bez nje su „Iznos" i „Ukupno plaćeno" bili isti broj pod dva imena, pa je ostalo ono što račun stvarno kaže: broj računa, plaćeni iznos i vrijeme.

                      0.6.7

                      3. septembar 2026.

                      Uklonjeno

                      • Sekcija „0%" sa naslovnice. Naknada po transakciji kod Flex paketa i kod prekoračenja jeste fiksna, ne postotak - ali ogromna nula na ekranu je prvo što se pročita, a ostalo je sitno ispod nje. Restoran koji plati prekoračenje neće se sjetiti pasusa. Cijena je već jasno napisana u tabeli paketa i tamo joj je mjesto.

                      0.6.6

                      3. septembar 2026.

                      Popravljeno

                      • Provjera pošte sada proba i drugi port, ne samo drugi način šifriranja. Produkcija je javila „Greeting never received (mail.xpay.ba:587, STARTTLS)" - a taj host odgovara i na 465 i na 587 kada se pita izvana. Kada nijedan port ne odgovori, to nije postavka nego mreža, i sada tako i piše: server ne može doći do mail hosta, pa to treba otvoriti kod hostinga.

                      0.6.5

                      3. septembar 2026.

                      Popravljeno

                      • Status stranica je pisala da pošta radi dok nije radila. Zeleno je bilo vezano za to da su četiri postavke unesene, a ne za to da server odgovara - pa je ostajalo zeleno kroz svaki neuspjeli račun. Sada se prikazuje ono što je server zadnje rekao, uključujući razlog. Provjera se radi u pozadini, pa javna stranica nikada ne čeka na SMTP.

                      0.6.4

                      3. septembar 2026.

                      Popravljeno

                      • Ime se i dalje pisalo dvaput. Dostavljeni logo sadrži veliki ukrasni X, pa zatim riječ XPAY - a riječ već počinje na X, tako da cijeli fajl pročitan slijeva nadesno kaže XXPay. To nije lockup nego dvije varijante iste stvari, pa se sada razdvajaju: riječ ide svuda gdje stoji ime, a X samo tamo gdje ima mjesta jedino za kvadrat.

                      Dodano

                      • SMTP_SECURE. Do sada je način šifriranja zaključivan iz porta, što je tačno za 465 i 587 a netačno za sve ostalo. Sada se može reći izravno.
                      • Test pošte kaže šta ne valja. „Greeting never received" ne imenuje ni server ni postavku. Kada se to desi, XPay isproba suprotni način šifriranja i, ako server odgovori, napiše koju vrijednost treba postaviti. Greška uz to nosi host, port i način koji je pokušan.

                      0.6.3

                      3. septembar 2026.

                      Popravljeno

                      • Logo je bio u crnoj kutiji. Priprema logotipa je pretpostavila da je slika na bijeloj podlozi, jer je svaki preglednik tako prikazuje. Datoteka je već imala prozirnost, pa je obrada svaki prozirni piksel pretvorila u crni. Otuda crna pozadina, mutan znak i favicon sa kockom - sve tri stvari su bile ista greška.
                      • Ime se pisalo dvaput. Pored znaka X stajala je i riječ „xpay", pa je ispadalo XXPay. Logo već sadrži i znak i ime, pa se koristi cijeli.

                      0.6.2

                      3. septembar 2026.

                      Dodano

                      • Dugme za probnu poruku. Provjera e-mail podešavanja je sada u konzoli, na stranici za e-mail: unese se adresa i pošalje prava poruka. Ako mail server odbije, prikazuje se njegov odgovor, jer razlog je skoro uvijek u odbijanju.

                      0.6.1

                      3. septembar 2026.

                      Promijenjeno

                      • Novi logo. Znak je sada pravi logo umjesto ranije nacrtane zamjene, na sajtu, u konzoli i na prikazima proizvoda.
                      • Logo u kartici pregledača. Favicon u tri veličine i ikone za telefone, pa se XPay prepoznaje u nizu otvorenih kartica.

                      0.6.0

                      3. septembar 2026.

                      Dodano

                      • Objekat sam podešava račun na koji stiže novac. Ko se sam prijavi dobija lokaciju bez bankovnog računa, namjerno, da se ništa ne može naplatiti prije nego što neko kaže gdje novac ide. Do sada to nije imao gdje reći: račun se mogao dodati samo pri otvaranju nove lokacije ili preko operatera. Sada se postavlja i mijenja iz same konzole.
                      • IBAN se provjerava prije nego se upiše. Kontrolne cifre hvataju upravo ono što se stvarno kuca pogrešno: jednu pogrešnu cifru i dvije zamijenjene. Pogrešan IBAN je novac koji ode negdje drugdje, a onaj ko ga je ukucao to nikada ne sazna. Provjerava se i dužina po državi, a greška kaže šta je pogrešno umjesto da samo odbije.

                      Promijenjeno

                      • Jedna provjera IBAN-a umjesto dvije. Ista logika je postojala na dva mjesta. Dvije implementacije pravila o tome gdje novac slijeće je jedna previše.

                      0.5.0

                      3. septembar 2026.

                      Dodano

                      • Noćna sigurnosna kopija. Baza i sve postavljene slike se svake noći u 03:20 sami arhiviraju i čuvaju četrnaest dana. Do sada je jedina uputa bila da operater ručno pokrene pg_dump, što znači da kopije nije bilo.
                      • Kopija se provjerava, ne samo pravi. Arhiva manja od praga se odbacuje jer to nije baza nego poruka o grešci, a svaka arhiva mora proći vlastitu kontrolnu sumu. Prekinut zapis na punom disku izgleda ispravno po veličini i ne može se pročitati, a to bi se otkrilo tačno u trenutku kada zatreba.
                      • Vraćanje podataka. Skripta koja izlistava dostupne kopije i vraća odabranu. Prije vraćanja pravi kopiju trenutnog stanja, jer se dešava da vraćena kopija nije ona prava.
                      • Stanje kopija na status stranici. Ako kopije nema ili je stara, to se vidi pored ostalih komponenti. Kopija koja je tiho prestala raditi je gora od nikakve, jer se vjeruje da postoji.

                      Promijenjeno

                      • Doctor provjerava kopije. Da li je tajmer instaliran, da li je posljednja kopija uspjela i koliko ih ima.

                      0.4.1

                      3. septembar 2026.

                      Dodano

                      • Provjera e-mail podešavanja. Operater sada može poslati probnu poruku sa servera i vidjeti šta je mail server odgovorio. Do sada se znalo samo da li su podešavanja upisana, a ne i da li rade: pogrešna lozinka je i dalje izgledala ispravno, svaka faktura bi tiho pala, a prvo što bi se čulo bilo bi pitanje klijenta gdje mu je ugovor.

                      0.4.0

                      3. septembar 2026.

                      Dodano

                      • Povrat novca. Do sada se povrat nije mogao ni evidentirati: postojala je tabela i status, ali nijedna ruta koja bi ih napunila. Sada se povrat bilježi, djelimično ili u cijelosti, sa razlogom i sa referencom banke.
                      • Djelimični povrati se sabiraju. Jedno pogrešno jelo za stolom od šest ne poništava cijeli račun. Plaćanje ostaje PLAĆENO dok povrati ne pokriju sve što je stiglo, jer novac je i dalje najvećim dijelom objekta.

                      Promijenjeno

                      • Promet je ono što je objekat zadržao. Djelimičan povrat nije skidao ništa sa prometa: plaćanje je i dalje bilo PLAĆENO i cijeli iznos se brojao. Jedno vraćeno jelo je svaki dan uvećavalo prikazani promet za cijenu tog jela, bez ijednog traga na ekranu. Povrati se sada oduzimaju i posebno prikazuju.
                      • Vraća se ono što je stiglo, ne ono što je traženo. Račun koji je plaćen manje nego što glasi primio je manje; povrat punog iznosa bi vratio novac koji nikada nije ni uzet.
                      • Otvoren račun za stolom se umanjuje. Ako je račun još otvoren, vraćeni novac se skida sa plaćenog iznosa. Zatvoren račun se ne prepravlja - povrat stoji pored njega kao zaseban zapis.

                      Važno

                        0.3.0

                        3. septembar 2026.

                        Dodano

                        • Više telefona za jednim stolom. Do sada je sto pripadao onom ko prvi skenira; svi ostali su dobijali „račun je već otvoren, pitajte osoblje". Sada se svako ko skenira pridružuje istom računu, dobija svoj naziv (Gost 1, Gost 2) i svoja narudžba se vodi na njega.
                        • Plaćanje samo svojih stavki. Podjela na jednake dijelove nije poštena podjela kada je jedno jelo, a drugo kafa. Gost sada može odabrati stavke koje plaća; iznos se računa na serveru iz samih stavki. Kada se otvori odabir, stavke tog telefona su već označene, pa je najčešći slučaj bez ijednog dodira.
                        • Poziv osoblja. Dugme koje ne znači ništa osim „dođite". Ranije se konobar mogao pozvati jedino tako što gost kaže da plaća gotovinom, što je račun prebacivalo u stanje plaćanja i zaustavljalo dalje naručivanje. Poziv koji već stoji zadržava svoje vrijeme, pa sto koji najduže čeka ostaje prvi na ekranu.
                        • Stolovi koji zovu na tlocrtu. Poziv ima prednost nad svim ostalim stanjima, uključujući čekanje na plaćanje, i pokazuje koliko minuta traje.

                        Promijenjeno

                        • Račun koji se plaća ne prima nove goste. Jedina vrata koja ostaju zatvorena: dok neko poravnava račun, novi telefon se ne može pridružiti, jer račun koji naraste nakon što je dogovoren je gori od gosta koji čeka pola minute.
                        • Stavka koju neko već plaća ne može se platiti dvaput. Šta je zauzeto izvodi se iz živih kodova, istim pravilom i istim vremenskim prozorom koji već koristi podjela na jednake dijelove.

                        0.2.0

                        1. septembar 2026.

                        Dodano

                        • Fakture. Merchant izdaje račun svom kupcu: napravi nacrt, izda ga, pošalje kupcu link. Uplata koja ga plaća sravnjuje se istim putem kao i račun za stolom: kada stigne odgovarajuća potvrda o uplati, transakcija se povezuje sa fakturom.
                        • Link za kupca. Izdavanje pravi nepogodiv link na kojem stoji iznos, poziv na broj i QR koji čita bankovna aplikacija. Štampa se, jer tako račun stigne do knjigovođe.
                        • Potraživanja. Biller koji ima svoj billing može poslati šta mu se duguje, sa svojim brojem računa, i matcher ga prepozna u izvodu.
                        • Mod samo za sravnjivanje. Lokacija se može podesiti da uparuje uplate i ne izdaje ništa.
                        • Vrsta posla. Operater pri otvaranju bira je li firma restoran, freelancer ili agencija, kirija, komunalno ili webshop. To odlučuje šta nalog uopšte nudi.
                        • Javni sajt. Devet stranica, na istim dizajn tokenima kao konzola.
                        • Status stranica. Ova, sa stanjem sistema i historijom verzija.

                        Promijenjeno

                        • Jedna paleta. Konzola je prešla na paletu koju koristi sajt. Zelena sada znači jedno te isto na oba mjesta: ova uplata je sravnjena.
                        • QR profili nose status. Produkcija odbija svaki profil koji nije potvrđen s bankom. BIH_IPS je nacrt dok se to ne desi.
                        • Otvaranje firme pravi firmu koja može naplatiti. Ranije je merchant nastajao bez poslovnice i bez računa na koji novac stiže, pa je prva radnja padala.

                        Popravljeno

                        • Kucanje u dijalogu je pomjeralo kursor na dugme za zatvaranje. Svaka forma u konzoli je to radila nakon jednog slova.
                        • Slanje fotografije javljalo je "internal server error". Ograničenje veličine zahtjeva bilo je manje od bilo koje prave slike, pa je zahtjev odbijan prije nego što bi ruta koja bi ga prihvatila uopšte bila pokrenuta.
                        • Provjera merchanta nije granica. Osoblje vezano za jednu poslovnicu moglo je otkazati narudžbe, zatvarati račune i gasiti kodove za stolove u drugoj poslovnici istog lanca.
                        • Refresh tokeni. Ukraden token upotrijebljen nakon rotacije sada se primijeti i gasi sve tokene te sesije.
                        • Zapisnik sada pokriva ko i odakle, i kaže koliko je dug, pa brisanje zapisa s kraja više nije nevidljivo.
                        • Brojevi merchanata potrošeni neuspjelim otvaranjem vraćaju se u pool, a popunjenost se prijavljuje prije nego prostor nestane.
                        • Red za uparivanje kaže koliko slučajeva zaista ima. Prikazivao je pedeset najstarijih i ništa o ostatku, pa najnoviji slučaj nije bio dohvatljiv.