Istorija izmena
Kompletna istorija razvoja sajta
8. septembar 2026.
1U aplikaciji administrator kluba može da spoji novi zahtev sa bilo kojim igračem, uključujući i karticu bez naloga.
7. septembar 2026.
3Bez imena i prezimena molba za učlanjenje ne može da se pošalje — ranije je prijava preko Apple naloga sa skrivenom adresom pravila zapis bez imena.
U redu zahteva novi igrač se može ručno spojiti sa bilo kojim igračem kluba, a ne samo kada se imena tačno poklope.
Jezik se bira odmah na ekranu prijave; telefoni sa hrvatskim i bosanskim jezikom više ne otvaraju aplikaciju na ruskom.
6. septembar 2026.
5U aplikaciji: dugme «Kako doći» na treningu i utakmici, a kartica igrača se otvara i sa klupe.
Kartica igrača prikazuje tekuću sezonu, sa prekidačem na statistiku za sve vreme.
U aplikaciji je stigla kartica igrača: statistika, dolasci i kontakti za štab — otvara se iz sastava, statistike, treninga i utakmice.
Štab vidi sa kog uređaja se igrač prijavljuje — iPhone, Android ili sajt — i verziju aplikacije.
U aplikaciji: razumljive greške i ponovni pokušaj na ekranima zahteva i profila, potvrda odjave, osvežavanje spiskova povlačenjem, lakša prijava i pretraga sastava, jasnija prazna stanja, pristupačnija obaveštenja i podeliba sopstvenog reda u tabelama (od verzije 0.1.2).
5. septembar 2026.
6Štab na utakmici zadaje boju dresa i vreme okupljanja — vidljivo na sajtu, u aplikaciji i u podsetniku pre utakmice.
Sastav kluba u mobilnoj aplikaciji — svaki odobreni član vidi spisak igrača svog kluba; štabu su vidljivi i kontakti (telefon, e-mail). Stiže sa verzijom 0.1.2.
U aplikaciji: dugme „U kalendar” na treninzima i utakmicama i niz dolazaka u profilu (od verzije 0.1.2).
Mobilna aplikacija je do sada tražila sistemsku dozvolu za notifikacije samo na dodir kartice-objašnjenja na ekranu treninga — na iPhone-u je to izgledalo kao da dozvola uopšte nije tražena. Sada se sistemski dijalog automatski pojavljuje jednom pri prvoj prijavi; kartica ostaje kao rezerva ako dijalog ostane bez odgovora. Stiže sa verzijom 0.1.2.
Dijalog „Poveži” na `/admin/players` do sada je nudio kandidate za spajanje iz SVIH klubova, dok je samo spajanje (server) od 2026-09-03 klupsko — pa je štab mogao izabrati karticu koju bi server odbio sa 404. Lista kandidata sada koristi isti opseg kao spajanje: sopstveni klub plus sopstveni red čekanja. Operater platforme bez kluba vidi praznu listu.
Javna strana igrača (`/roster/[slug]`) do sada je prikazivala samo statistiku u sopstvenom klubu. Igrač koji je prešao iz drugog kluba sada dodatno vidi razbijenu statistiku po klubovima — utakmice, golove, asistencije i treninge posebno za svaki klub u kom ima podatke, sa sopstvenim klubom na prvom mestu. Ako igrač ima podatke samo u jednom klubu, strana izgleda kao pre.
3. septembar 2026.
5Igrač koji se registruje bez izbora kluba (npr. „tražim klub” ili je zatvorio prijavu pre tog koraka) do sada nije ulazio ni u jedan red čekanja i bio je potpuno nevidljiv za štab. Operater platforme sada na `/admin/players` vidi novu sekciju „Registracije bez kluba” — može poslati igrača u svoj klub jednim klikom ili obrisati registraciju. Bedž u zaglavlju admina broji i ove zahteve.
Bedž sa brojem zahteva u zaglavlju admina brojao je SVE neodobrene naloge na celoj platformi, a ne samo red sopstvenog kluba kao spisak na `/admin/players` — zato je ponekad pokazivao „1” dok je spisak bio prazan. Sada bedž koristi isti izvor kao spisak (red sopstvenog kluba) i sam se sakriva kad korisnik nije član štaba.
Kad se igrač ponovo prijavi sa druge poznate adrese (Google nalog, novi broj telefona pretvoren u imejl…), sistem sam prepoznaje da je reč o istoj osobi umesto da otvori dupli nalog. U redu čekanja `/admin/players` štab sada vidi podsetnik „Liči na …” i spaja dupli zahtev u jedan klik; u kartici igrača dodat je spisak „Imejlovi za prijavu” za ručno upravljanje.
Štab nije mogao da odbije kandidata iz reda kluba ako se prijavio preko Google-a i nije izabrao klub (bez izričite prijave) — dugme „Odbij” na `/admin/players` uopšte nije postojalo, a postojeće odbijanje je brisalo samo već praznu kolonu, pa je takav kandidat zauvek ostajao u redu iako je interfejs prikazivao uspeh. Odbijanje sada stvarno uklanja kandidata iz reda, a na sajtu se pojavilo dugme „Odbij” pored „Odobri”.
Sajt i mobilna aplikacija sada prijavljuju greške i padove u Sentry (besplatni plan, EU region). Do sada nismo imali nikakav uvid: ako bi se aplikacija nekom srušila, saznali bismo samo ako nam se sam javi. Šalje se samo tehnički trag i ID korisnika — bez e-pošte, imena ili telefona. Za aplikaciju je potrebna nova nativna verzija 0.1.2 kroz obe prodavnice.
2. septembar 2026.
13Kapiten/pomoćni kapiten na `/admin/players` do sada nije mogao da sačuva NIŠTA — svako čuvanje je slalo i polja rezervisana za admina kluba (uloga, odobrenje...), pa je server odbijao ceo zahtev. Forma sada te prekidače prikazuje zaključanim (sa objašnjenjem), umesto da ih sakriva ili šalje netaknute — dugme za izmenu na `/roster/...` (koje je ranije kriilo ceo blok admina) sada isto tako prikazuje ono što kapitan SME da menja. Na strani turnira, tabela grupe sada razdvaja timove izjednačene po bodovima I gol-razlici po rezultatu njihovog međusobnog susreta, pre nego što padne na ukupnu gol-razliku.
Dugme za izmenu igrača (`/roster/...`) je do sada pisalo profil direktno iz pregledača. Otkako klupski trigeri čuvaju ulogu/status po klubu reda, pokušaj kapitena da promeni ulogu se tiho vraćao na staru vrednost — interfejs je i dalje prikazivao „sačuvano“. Dugme sada ide kroz isti čuvani API (`PATCH /api/admin/players/[id]`) kao i lista `/admin/players`: kapitan dobija jasnu poruku da ulogu/status može da menja samo klupski admin. Avatar sada mora da dolazi iz sopstvenog storage-a kluba, ne sa proizvoljnog linka; prazan ili neispravan slug se sada odbija kao greška umesto da tiho ostane stari; adresa igračke stranice (/roster/<adresa>) se automatski preračunava kad se ime promeni kroz ovu formu ili kroz `/admin/players`. „Moj profil“ je prešao na isti obrazac — piše preko servera (`PATCH /api/v1/me`), ne direktno iz pregledača — a otpremanje avatara na `/admin/players` više ne zaobilazi tu proveru.
Paket manjih ispravki. Slobodna objava sa linkom sada vodi tamo i iz zvonca (ranije samo push nosio link). Dodat prekidač za puševe o promeni vremena/mesta treninga. Adresa igračke stranice (/roster/<adresa>) sada se ažurira kad igrač promeni ime, ne ostaje zaglavljena na staroj. U formi za utakmice sada je moguće postaviti golmana i terenskog igrača koji ume da brani (ranije je to radilo samo u jednom od dva uređivača utakmica). Dugme „Učini stalnim” za legionare više nije zakucano na ruskom.
Edge funkcije `send-training-notification` i `send-approval-email` su ranije bile dostupne bez ikakve provere — bilo ko ko je znao URL mogao je da pošalje proizvoljan push SVIM igračima i da upiše redove u zvonce. Sada obe funkcije prvo proveravaju da poziv nosi servisni token (poklapa se sa `SUPABASE_SERVICE_ROLE_KEY`), a gateway je podešen sa `verify_jwt=true`. Ni jedna postojeća ruta (admin broadcast, podsetnik za trening, poziv na utakmicu, odobravanje naloga) se nije promenila — sve već šalju servisni token.
Slobodna objava štaba (/admin/broadcast) sada ostavlja trag u zvoncu — igrač koji odbaci banner obaveštenja više ne gubi poruku zauvek. Objava dobija sopstveni tip (`admin_broadcast`) i ide SVAKOM članu kluba nezavisno od toga da li je push stigao (isto pravilo kao i svi ostali unosi u zvoncu — publika je iz profila, ne iz pretplata). Ruta takođe sada šalje `organisation_id` pošiljaoca, koji je pre nedostajao — bez njega je i sam push (ne samo zvonce) išao ka svim klubovima na platformi, ne samo pošiljaočevom.
Slobodna objava štaba (/admin/broadcast) sada ostavlja trag u zvoncu — igrač koji odbaci banner obaveštenja više ne gubi poruku zauvek. Objava dobija sopstveni tip (`admin_broadcast`) i ide SVAKOM članu kluba nezavisno od toga da li je push stigao (isto pravilo kao i svi ostali unosi u zvoncu — publika je iz profila, ne iz pretplata). Ruta takođe sada šalje `organisation_id` pošiljaoca, koji je pre nedostajao — bez njega je i sam push (ne samo zvonce) išao ka svim klubovima na platformi, ne samo pošiljaočevom.
Ekran Podešavanja u mobilnoj aplikaciji sada ima pun blok "Klub", isto kao veb profil. Igrač koji je već član kluba vidi "Tvoj klub" i dugme "Promeni klub" — bira novi klub, a do odobrenja štaba ostaje tačno tamo gde je bio, bez gubitka sastava i statistike. Poslata molba se vidi kao "Zahtev za <klub> je poslat" sa dugmetom za povlačenje. Ranije je ovaj blok postojao samo za nalog bez kluba i bez molbe.
Klub sada ulazi u KLJUČ keša stranica /schedule i /roster, ne samo u podatke koje one čitaju — do sada su te dve `unstable_cache` obmotnice čitale klub IZNUTRA keširane funkcije, nevidljivo za ključ, pa bi prvi posetilac zapečatio svoj klub u kešu za sve ostale (danas bez efekta — postoji samo jedan klub). `/stats` i `/training` su ranije popravljene istim obrascem. `lib/cache/tags.ts` dobio je klupsku dimenziju (`orgTag`/`tagsForOrg`/`TAG.forOrg`) bez lomljenja postojećih poziva — 18+ ruta za mutacije i dalje rade nepromenjeno, a `POST /api/revalidate` sada prima opcioni `org` za pražnjenje keša samo jednog kluba (operater ili sopstveni klub pozivaoca). Nova provera `pnpm check:cache-keys` sprečava da se ubuduće doda `unstable_cache` obmotnica bez oznaka ili sa klubom koji nedostaje u ključu.
Dve popravke. Tip sastava utakmice na sajtu je tvrdio da nosi CEO profil igrača (uključujući kontakte), iako je upit tražio samo javne kolone — `player.email` bi se kompajlirao i prikazao prazno umesto da build padne; sada tip tačno prati ono što se zaista čita. I: odobreni gost (vratar koji se sam pridružio, ili prihvaćen poziv) do sada nije mogao da se odjavi sa treninga, a ni štab nije mogao da ga skine — status je ostajao zauvek odobren, pa je broj vratara i kvorum brojao gosta koji se nije pojavio. Sada gost ima dugme „Otkaži prijavu”, a štab dugme „Skini” pored svakog gosta na sastavu; broj vratara i kvorum se automatski smanjuju, a druga strana dobija obaveštenje.
Tri manje popravke za štab, uglavnom oko rada sa telefona. Kolona akcija u tabeli "Upravljanje igračima" bila je potpuno skrivena na uskom ekranu (`hidden sm:table-cell`) — ispod te širine tabela sada postaje lista kartica sa istim dugmićima (prevod u klub, izmena, brisanje, poziv). Nova skripta `pnpm revalidate <entitet…|all>` zamenjuje ručno sastavljanje POST zahteva ka /api/revalidate posle ručne popravke podataka preko Management API-ja. I operater platforme BEZ sopstvenog kluba više ne dobija praznu stranu na /admin/clubs — GET /api/v1/roster/directory sada pušta i njega, ne samo štab klubova.
Tri popravke. Prekidač obaveštenja na vebu (/profile) više ne briše ceo `push_preferences` odjednom — sada menja samo dirnuti prekidač preko istog API-ja koji koristi aplikacija, pa uključivanje/isključivanje na jednoj strani više ne poništava tiho ono što je igrač podesio na drugoj (npr. „Pozivi na utakmicu“). Pozadinski sat koji podseća štab na neodobrenu prijavu (5 minuta posle ankete) sada šalje push samo štabu KLUBA kome se igrač prijavio — ranije je push (za razliku od zvonca) išao svim administratorima svih klubova. I: dovršen prelazak na jedinstven obrazac za tihe otkaze čitanja (posle prošle popravke): `/games/[slug]` i početna strana sada takođe bacaju grešku unutar keša umesto da je tiho progutaju (pa se odbijeni upit više ne konzervira u kešu na 24h), sitemap.xml sada vraća 500 umesto lažno prazne mape kad čitanje sastava ne uspe, a čuvar `check:profiles-errors` sada vidi i PostgREST ugnježdene upite (`player:profiles(...)`), ne samo direktne.
Odbijanje pristupa igračima (profiles) sada se vidi, umesto da se tiho pretvori u praznu stranu. Do sada je više od dve trećine mesta koja čitaju sastav igrača gledala samo podatke, a ne i grešku — kad baza odbije upit (nedozvoljena kolona, mrežni prekid), to je izgledalo tačno kao „ovde nema nikoga“. Tako je nestao ceo javni sastav 21.8, a stranice utakmica su mesecima tiho prikazivale prazan sastav i statistiku, a da to niko nije primetio. Sada /roster, /roster/[slug], /stats, /games/[slug] i početna strana prikazuju poruku „nije uspelo učitavanje“ umesto lažne praznine, svaka takva greška se beleži na serveru, a nova provera (`pnpm check:profiles-errors`) sprečava da se ubuduće doda čitanje koje grešku prećutkuje.
Pet sitnih ispravki. Mobilna anketa više ne može zauvek da visi na koraku izbora kluba — dodat je tajm-aut od 8 sekundi, posle kog se korak preskače kao i pri bilo kojoj drugoj grešci mreže. Web anketa više ne pita iznova onog ko je klub već izabrao u mobilnoj anketi (od kad ona pita za klub prvim korakom, popunjena anketa je ponovo pun odgovor). Promena imena ili nadimka kroz /api/v1/me sada odmah briše keš javnih stranica (sastav, statistika) — ranije je moglo da ostane staro ime do 24 sata. Kad operater promeni kapitena kluba, briše se keš i prethodnog kapitena, ne samo novog — inače je njegova strana i dalje pokazivala staru ulogu. I: prekidač „Pozivi na utakmicu“ iz veb profila stigao je i u aplikaciju, u podešavanjima pored ostalih obaveštenja.
1. septembar 2026.
16Zatvoren je poslednji veliki propust pre nego što drugi klub pridje platformi: administrator BILO KOG kluba je mogao da menja i briše karticu igrača BILO KOG DRUGOG kluba (uključujući odobrenje i „želi Propelere“), i tako ga tiho prebaci u red za odobrenje. Baza sada proverava klub kartice, ne samo ulogu (`profiles_update`/`profiles_delete_admin`/`guard_profile_role_elevation`). Ekran `/admin/players` sada pokazuje samo svoj klub i svoj red čekanja, umesto svih igrača platforme, a sva pisanja (odobri/obriši/sačuvaj) idu preko servera sa proverom kluba, ne direktno iz pregledača. Obaveštenje o novoj prijavi (i push i zvonce) sada budi štab kluba kome je igrač zaista pisao, a ne ceo štab platforme — isto pravilo koristi i sat rezervne provere u pozadini.
Kartice igara i tabele statistike u aplikaciji sada prate klub igrača koji je ulogovan, a ne klub sajta. Do sada su `/api/v1/games` i `/api/v1/stats` uvek vraćali klub domaćina bez obzira ko pita, a aplikacija uopšte nije slala token uz te zahteve — igrač drugog kluba je na kartici Igre i Statistika video Propelerijeve utakmice i tabele, iste kao anoniman posetilac. Sada oba API-ja prepoznaju ko pita (isti mehanizam kao raspored) i vraćaju klub tog igrača; anonimni posetilac i dalje vidi klub domaćina, bez promene.
Mobilna anketa za nove igrače sada pita i za klub — prvi korak, pre svega ostalog: bira se klub sa liste (ili „za sada bez kluba“), i taj izbor postaje molba za učlanjenje, isto kao na sajtu. Do sada aplikacija to uopšte nije pitala, pa je igrač koji se prijavi preko telefona ostajao mimo svake liste za odobrenje. Uz to, stranica /register?club=<slug> — pozivnica kluba — sada iznad forme jasno kaže da tu treba da se registruje osoba koju je klub pozvao (aplikacija još ne ume da pročita taj link), a ako link više ne odgovara nijednom klubu, to i piše umesto da se izbor kluba tiho izgubi.
Zatvorena su dva propusta oko kontakata na marketplace-u. Prvo: pravilo baze koje čuva otkrivanje kontakta (`contact_views`) sada traži isto što i sajt — potvrđenu e-poštu i da niko od dvoje učesnika nije blokirao drugog — ranije je to proveravao samo sajt, a neko ko bi upisao red mimo sajta (direktno u bazu) to je mogao da zaobiđe. Drugo: stranica usluge (`/shop/services/…`) do sada je davala telefon i ostale kontakte majstora SVAKOM ko je ulogovan, bez dugmeta „Prikaži kontakt“ koje oglasi imaju — sada usluge imaju isto dugme, isti zapis u `contact_views` i isto obaveštenje majstoru kad neko otkrije kontakt.
Obična registracija sada traži potvrdu e-pošte: posle upisa stiže pismo sa linkom, i tek klik na njega otvara nalog — dalje, kao i do sada, odobrava uprava kluba. Ekran posle upisa to i kaže („otvorite pismo koje smo poslali na …“) umesto ranijeg „čekajte odobrenje“, koje bi na ovom koraku bilo neistina. Usput je sajt dobio sopstvenu poštu: kod za ulazak, link za potvrdu i novu lozinku sada stižu sa noreply@propeleri.rs — do sada ih je slao ugrađeni servis sa plafonom od dva pisma na sat za ceo sajt, pa je treći igrač u istom satu ostajao bez koda. Klupska pisma (obaveštenje o odobrenju) takođe stižu sa adrese kluba, a ne sa tuđeg domena.
Ko uđe preko Google-a sada bira klub u anketi za nove — i time stiže u red za odobrenje tog kluba. Do sada ga anketa nije pitala ni za šta osim imena i telefona, pa je čovek ostajao bez molbe za klub, a red uprave prikazuje samo one koji su za taj klub i zamolili: nalog nije video niko, i klub je morao da se upiše ručno u bazi. „Za sada bez kluba“ je i dalje potpuno ispravan odgovor — klub se može navesti kasnije. Izbor kluba je molba, ne članstvo: prima i dalje uprava. Ko je već član nekog kluba, taj izbor ne vidi — promena kluba je posebna radnja u profilu, sa svojim objašnjenjem. Usput: anketa više ništa ne upisuje u profil iz pregledača, sve ide kroz server.
Upis više ništa ne dopisuje u profil iz pregledača. Nadimak i izabrani klub sada putuju zajedno sa samom prijavom, pa profil nastaje odmah sa njima. Do sada su se dopisivali posebnim korakom, već posle otvaranja naloga — a taj korak je radio samo zato što potvrda e-pošte nije uključena: sa uključenom potvrdom ne bi upisao ništa i ne bi prijavio nikakvu grešku, pa bi čovek video „uspeh“ i ostao bez kluba i bez nadimka. Time je uklonjena i prepreka da se potvrda e-pošte uključi. Klub u prijavi je i dalje samo molba — članstvo i dalje daje isključivo uprava pri odobrenju — a nepostojeći klub se sada jednostavno ne upisuje umesto da obori upis.
Isto pravo oduzeto je i oglasima na pijaci. Kontakt koji prodavac upiše u oglas do danas je mogao da pročita bilo ko prijavljen, zaobilazeći sajt — bez dugmeta „prikaži kontakt“, bez traga i bez obaveštenja prodavcu, pa je to otključavanje za takve oglase bilo samo ukras. Sada baza ta polja ne daje prijavljenom nalogu; kontakt stiže samo kroz otključavanje, koje kao i pre ostavlja trag i javi prodavcu da je neko pogledao. Usput je ispravljena i jedna nedoslednost: odgovor na otključavanje sada nosi Viber i poštuje kontakt upisan u sam oglas, kao što je stranica oglasa oduvek prikazivala.
Pravo čitanja tuđih kontakata sada je oduzeto u samoj bazi. Do danas je svaki prijavljeni nalog mogao, zaobilazeći sajt, da izvuče e-poštu, telefon i datum rođenja svih članova; od sada baza tih osam polja ne daje nikome ko je samo prijavljen. Ništa se ne menja na ekranu: svoje podatke i dalje vidite i menjate u profilu, uprava i dalje vidi kontakte igrača, prijava na sajt radi kao i pre. Kontakt prodavca na pijaci se i dalje otključava kao i do sada.
Poslednji ekrani kojima kontakti zaista trebaju prešli su na serverski put. Spisak igrača u upravi, prozor za izmenu igrača i spajanje novoprijavljenog sa postojećom karticom više ne čitaju telefone i e-pošte iz pregledača, nego traže od servera koji prvo proveri ko pita — po prijavljenom nalogu, nikad po onome što je poslato u zahtevu. Vaša sopstvena anketa (profil i upitnik pri upisu) čita se istim putem kao i u aplikaciji na telefonu. Spajanje kartica sada uopšte ne dobija adrese: pretraga po e-pošti radi na serveru, a u pregledač stižu samo ime, broj i link. Rođendani na stranici događaja od sada putuju BEZ GODINE — kartica ionako pokazuje samo dan i mesec, a godina rođenja je godine života. Ako neki od tih spiskova ne stigne, ekran to i kaže umesto da izgleda kao da je klub prazan.
Nastavak zatvaranja pristupa kontaktima. Stranice koje zaista prikazuju telefon ili e-poštu — vaša podešavanja prodavca, formular za oglas, otključani kontakt prodavca, kontakt majstora i spisak zahteva za odobrenje — od sada čitaju te podatke posebnim serverskim putem, a pravilo ko sme da ih vidi ispisano je u kodu iznad samog čitanja: sopstveni red se bira po prijavljenom nalogu, tuđi kontakt na oglasu i dalje traži da ste ga otključali, a spisak zahteva sada sam proverava da ste u upravi. Ništa se nije promenilo na ekranu; ovo je priprema da se sledećim korakom oduzme pravo čitanja tuđih kontakata svima ostalima.
Prijava za obaveštenja više ne pada kada se na istom telefonu prijavi drugi nalog. Token za push pripada TELEFONU, a ne osobi — isti je za svakoga ko se na tom uređaju prijavi — pa je zapis o uređaju i dalje stajao na prethodnom nalogu, a novi je na ekranu profila dobijao crvenu poruku „Server: 500“ koju dugme „Pokušaj ponovo“ nikada nije moglo da ukloni. Sada uređaj prelazi na onoga ko je trenutno prijavljen, u oba smera i koliko god puta zatreba, a prethodni vlasnik prestaje da dobija svoja obaveštenja na tuđem telefonu. Aplikaciju nije trebalo ažurirati — popravka je urađena na serveru.
U upravljanju igračima pojavila se kolona „Aplikacija“: uz svakog igrača stoji sa čega je viđen — iOS, Android, pregledač — i datum poslednje prijave. Prikazuju se sve platforme odjednom, jer aplikacija na telefonu i pregledač na računaru nisu izbor između dva, nego uobičajen par. Ko se nijednom nije prijavio jasno je označen, a onaj ko se prijavljivao dok trag uređaja nije sačuvan stoji kao „Nepoznato“ umesto da bude lažno upisan među one koji nisu dolazili. Sama oznaka uređaja nikada ne izlazi na ekran: server je čita, prevodi u platformu i dalje šalje samo nju.
Statistika u aplikaciji više nije prazna na novoj sezoni: obe tabele sada prikazuju ceo sastav kluba, a igrač bez statistike stoji sa nulama umesto da nestane — isto pravilo koje strana „Statistika“ na sajtu već ima. Brojke se nisu promenile, samo se više ne krije niko ko je u timu. Igrač koji je otišao iz kluba, a ima odigranih utakmica u sezoni, i dalje ostaje u tabeli. Aplikaciju nije trebalo ažurirati — promena je urađena na serveru.
Strana „Statistika“ na sajtu dobila je izbor sezone i obe tabele — i utakmice i treninge — računa za izabranu sezonu. Ranije su obe išle „svih vremena“. Podrazumevano je TEKUĆA sezona, bez zamene: ako je tek počela, brojke su nule, i to je tačan odgovor. Da strana ne bi bila prazna, obe tabele sada prikazuju ceo sastav kluba — igrač bez statistike stoji sa nulama umesto da nestane. Adresa pamti izbor (/stats?season=…), pa se link na određenu sezonu može poslati. Profil igrača ostaje karijerni, kao i do sada.
Tabela treninga u aplikaciji sada prati izabranu sezonu, kao i tabela utakmica pored nje. Ranije je ostajala „svih vremena“, pa je na novoj sezoni 2026/2027 pokazivala 44 igrača sa brojkama prošle sezone iako u njoj još nema nijednog upisanog dolaska. Sada je na novoj sezoni prazna dok ne bude prvog treninga — to je tačan odgovor, ne greška. Istog dana je i strana „Statistika“ na sajtu prešla na sezone (zapis iznad); profil igrača ostaje karijerni.
31. avgust 2026.
6Statistika se sada vezuje za klub za koji je utakmica ODIGRANA, a ne za klub u kome igrač trenutno jeste. Ranije bi prelazak u drugi klub odneo sve golove i asistencije sa sobom i obrisao ih iz tabela starog kluba. Zbog toga se brojke na tabelama strelaca i na profilu igrača mogu razlikovati od onoga što si video ranije — to je ispravka, ne gubitak podataka.
Sezona je jedna za celu platformu, pa njome sada upravlja samo operater platforme — klupski admini i kapiteni više ne vide ekran „Sezone“. Ranije je admin bilo kog kluba mogao da postavi svoju sezonu kao tekuću i time drugom klubu skine tekuću sezonu. Rad sa utakmicama i treninzima ostaje nepromenjen: sezona se i dalje bira pri unosu.
Operater platforme je dobio ekran „Klubovi“: novi klub se sada otvara kroz sajt (naziv, slug za adresu /c/<slug>, grad) umesto ručnim SQL-om, a uz njega se odmah pravi i klupski tim. Tu je i „Postavi kapitena“ — pretraga po svim igračima platforme; novi kapiten dobija klub i odobrenje, a prethodni se spušta u igrača. Bez toga sasvim nov klub ne bi imao ko da odobri prvog čoveka.
Pri registraciji sada biraš klub kome se prijavljuješ — zahtev ide u red baš tog kluba, a ne podrazumevano Propelerima. Ako nisi siguran, „za sada bez kluba“ je uredna opcija: nalog radi i klub se bira kasnije. Klub može da deli i svoj poziv — link /register?club=<slug> unapred izabere klub, pa se niko ne izgubi u tuđem redu za odobrenje.
Promena kluba sada ima ekrane. U profilu igrača stoji „Promeni klub“: biraš klub i šalješ zahtev, a dok ga štab tog kluba ne odobri ostaješ u svom klubu i ne gubiš ništa — zahtev možeš i da povučeš. Operater platforme u kartici igrača dobija „Prebaci u klub“; klupski admin i kapiten tu dugmad ne vide, jer je prelazak između klubova van njihovog kluba. Trenutni klub se ni na jednom ekranu ne nudi kao odredište.
Prijava preko Google naloga: korisnik marketplace-a (nalog otvoren u prodavnici, bez imena i prezimena) više se ne gura u klupsku anketu za nove igrače — ta anketa ne postoji na shop.propeleri.rs, pa je prijava završavala na 404. Uz to, preusmeravanje kupca sa glavnog sajta na prodavnicu sada mapira adresu umesto da je nosi doslovno: /shop/x vodi na /x, a stranica koja postoji samo na glavnom sajtu vodi na početnu prodavnice.
27. avgust 2026.
3Priprema za sezonu: podsetnici za trening (3h) više ne mogu da se izgube u celoj grupi ako jedan naiđe na privremenu grešku; nalog koji čeka odobrenje sada to jasno prikazuje u aplikaciji umesto nejasne greške; nove treninge i utakmice admin podrazumevano vezuje za TEKUĆU sezonu, ne za najnoviju po datumu.
Turniri: kreiranje meča i upis rezultata više ne pucaju u bazi (bili su potpuno pokvareni), turnir sa vezanim događajem se sada može obrisati, uklanjanje tima više ne ostavlja duha „?“ u tabeli, a admin greške pri izmeni (grupe, timovi, mečevi) se sada vide umesto lažnog „sačuvano“.
Ispravljena bezbednosna greška: tabele strelaca i statistika (početna strana, /stats, sezonski poredak) su ponekad prikazivale igrače drugih klubova pomešane sa tvojim — sada su striktno u okviru sopstvenog kluba.
26. avgust 2026.
1Novo zvonce sa istorijom obaveštenja, u aplikaciji i na sajtu: pozivi na trening, podsetnici, provera golmana, izmena termina, poziv na utakmicu i odobrenje naloga sada ostaju zabeleženi i posle što ih smakneš sa telefona — vidi ih svako koga se tiču, ne samo oni sa uključenim push obaveštenjima.
25. avgust 2026.
1Nalog sada možeš obrisati sam — na sajtu u Profilu ili u aplikaciji u Podešavanjima: prijava, kontakti i lični podaci se trajno brišu, aktivni oglasi se povlače, a statistika odigranih utakmica ostaje u istoriji kluba. Uputstvo: propeleri.rs/delete-account.
20. avgust 2026.
3Na stranici treninga sada i posetilac bez naloga vidi „Prijavljeno: N · Golmani: M" (samo brojevi, bez imena) — da na brzinu proceni da li se skuplja ekipa; ako je golman potreban a nijedan se nije prijavio, ističe se oznaka „Potreban golman". Broj golmana se vidi i u aplikaciji, pored broja prijavljenih.
U aplikaciji, u listi treninga, dodat je prekidač „Drugi klubovi" sa filterom po gradu: kada je uključen, ispod tvog rasporeda se pojavljuju otvoreni treninzi drugih klubova (samo broj prijavljenih, bez imena) sa dugmetom za prijavu — igraj i van svog kluba.
Višeklubska bezbednost: štabske akcije i vidljivost sastava sada su strogo u okviru sopstvenog kluba; anoniman posetilac na treningu vidi samo brojeve (imena i statusi su samo za članove, i posle početka), a rezultat i strelci na završenim utakmicama ostaju javni; rasporedi, brojači dolazaka i push-obaveštenja više ne mešaju klubove.
19. avgust 2026.
9U podešavanjima obaveštenja (sajt) dodat je zaseban prekidač za „Pozivi na utakmicu" — sada možeš da isključiš zazive na utakmicu bez gašenja ostalih podsetnika.
Mobilna aplikacija: novi igrač posle registracije prolazi kroz kratak upitnik — gde igra (HC Propeleri / drugi klub / traži tim), da li je golman, pozicija, broj, grad, telefon (uz napomenu da se nigde ne objavljuje) i nadimak. Namera se beleži za trenera; upitnik ne dodeljuje nikakva prava — u klub i dalje prima admin.
Sastav za utakmicu se pre početka meča više ne prikazuje anonimnim posetiocima ni na sajtu — vidljiv je samo članovima kluba (u aplikaciji i na sajtu), a svima ostalima tek kada meč počne. Do sada je stranica utakmice na sajtu otkrivala sastav i pre početka.
Mobilna aplikacija, stranica utakmice: na vrhu — kartica sa grbovima timova, rezultatom i ishodom (Pobeda/Poraz/Nerešeno), a ispod nje spisak golova po periodima — ko je postigao gol i ko je asistirao. Prikazuje se samo za utakmice kod kojih je trener već uneo događaje meča; ostale utakmice izgledaju kao i do sada.
Teren sastava (mobilna app): prevlačenje igrača sa klupe sada se vidi ispod prsta do samog kraja, ne samo na terenu. Prevlačenjem preko oznake druge petorke (drži ~250ms) teren se odmah prebacuje na nju, a spuštanje direktno na oznaku postavlja igrača na prvo slobodno mesto te petorke. Sastav se sada čuva sam, nekoliko sekundi posle poslednje izmene — dugme „Sačuvaj" je zamenjeno tihim statusom sa dugmetom za ponovni pokušaj ako sačuvavanje ne uspe.
Mobilna aplikacija: na karticama „Statistika" i „Utakmice" izbor sezone je sada preko padajuće liste — polje sa trenutnom sezonom, dodirom se otvara spisak sezona; nova sezona 2026/2027 se može pogledati odvojeno od tekuće 2025/2026, kao i od stare 2024/2025. U tabeli strelaca — veća okrugla fotografija igrača (ili inicijali), broj dresa je sada mala oznaka u uglu fotografije, a ne posebna kolona. Red sa nazivima kolona ostaje prikačen pri vrhu dok se tabela skroluje. Trening statistika i dalje ne zavisi od izabrane sezone — uvek je za sva vremena, i tabela to jasno piše.
Teren sastava (mobilna app): kvadratna pozadina je uklonjena — fotografija je sada veći krug direktno na ledu. Na terenu se prikazuje samo jedan golman; ostatak prijavljenog tima (uključujući rezervnog golmana i legionere) je u novoj traci ispod petorki — dodirom se postavlja ili uklanja iz prijave, prevlačenjem ide direktno na poziciju. Dugme „+" otvara ceo klupski spisak, uključujući legionere, za dodavanje u prijavu.
Mobilna aplikacija: na terenu sastava utakmice sada su okrugle fotografije igrača — kao na sajtu, sa obojenim prstenom po poziciji; prazna mesta su iscrtkan krug sa oznakom pozicije. Kapiten, trener i pomoćnici sada mogu da prevuku igrača prstom unutar jedne petorke (dugi pritisak pa prevlačenje) da zamene dvojicu ili postave nekog na prazno mesto — bez otvaranja menija.
Mobilna aplikacija je dobila karticu „Utakmice": naredne utakmice i rezultati, a na utakmici — teren sa petorkama uspravno (golman dole, par odbrane, napadačka trojka), sa brojem i prezimenom na svakoj poziciji i oznakom K/A. Prazna mesta su iscrtkana, petorke se menjaju prevlačenjem; postoji i kompaktan spisak. Kapiten, trener i pomoćnici sastavljaju postavu dodirima i čuvaju je dugmetom, i mogu push-om da pozovu ekipu na utakmicu. Teren se prikazuje kada je postava uneta.
18. avgust 2026.
7Mobilna aplikacija sada ima donje kartice: „Treninzi" i „Statistika". Na novoj kartici statistike su dve tabele — strelci za tekuću sezonu (utakmice, golovi, asistencije, bodovi; kaznene minute i +/- se otvaraju dodirom na red) i trening statistika svih vremena (broj treninga, golovi, asistencije). Period svake tabele je ispisan iznad nje, jer se ne poklapaju.
U admin panelu na stranici treninga: na kartici „Meč na treningu" sada se na vrhu vide prijave igrača (golovi/asistencije/napomena koje su sami uneli) — trener ih potvrđuje jednim klikom, čipovima ili dugmetom „Prihvati sve"/„Prihvati". Kartica push obaveštenja je podrazumevano skupljena u jedan red — otvara se klikom.
U mobilnoj aplikaciji, posle treninga svaki učesnik može sam da prijavi koliko je dao golova i asistencija i da doda napomenu. To je prijava treneru — brojke ulaze u zvaničnu statistiku tek kada ih trener proveri i prenese; u admin panelu se prikazuju odmah pored reda tog igrača.
Mobilna aplikacija: na završenom treningu više se ne prikazuje napredak prijavljivanja (kvorum, dugmad za odgovor, pozivanje i dopuna legionarima) — na tom mestu je sada, ako je trener uneo rezultat meča, rezultat trening meča sa golmanima i listom golova, a u spisku prošlih treninga stoji kompaktan rezultat. Premeštanje igrača između belih i tamnih i dalje radi i posle treninga.
Mobilna aplikacija (Android): pošto dugmad „Dolazim/Ne dolazim“ direktno na obaveštenju nisu pouzdana na Android telefonima, dodir na podsetnik o treningu sada uvek otvara baš taj trening, sa odgovorom na vrhu ekrana — bez skrolovanja. Ovo važi bilo da je aplikacija bila otvorena, u pozadini ili potpuno zatvorena.
U podešavanjima mobilne aplikacije dodat je izbor jezika: „Kao u sistemu“, Русский, Srpski ili English. Izbor se odmah primenjuje u celoj aplikaciji, pamti se i koristi se i za jezik push obaveštenja.
U mobilnoj aplikaciji sada možeš da povučeš svoj odgovor na trening: dodirni odgovor koji si već dao (Dolazim/Ne dolazim/Možda) i on nestaje, umesto da ostane zaglavljen bez mogućnosti da se ukloni.
17. avgust 2026.
9Bezbednosne ispravke na /api/v1 (trening i slotovi): prijava na termin sada zaista proverava da li je termin otvoren (status, datum u budućnosti, i needs_goalie/is_open_to_guests) umesto da se oslanja samo na strani ključ u bazi — privatni termini više ne mogu primiti prijave od bilo kog naloga. Javna ruta za detalje treninga dobila je ograničenje broja zahteva i proveru oblika slug-a. Ruta za odluku o prijavi sada validira UUID pre upita ka bazi. Zaštita od duplog slanja podsetnika sada proverava bazu (notification_log), ne samo memoriju jedne instance servera.
Mobilna aplikacija: ekran treninga sada ima tabove „Predstojeći“/„Odigrani“ — odigrani treninzi pokazuju da li si bio prisutan i koliko je igrača ukupno bilo. Na stranici treninga trener/kapiten sada vidi dugme „Podseti N igrača“ (šalje push podsetnik onima koji se još nisu izjasnili, sa potvrdom pre slanja), belešku trenera ako postoji, i sekciju „Gosti“ za prihvatanje/odbijanje prijava igrača iz drugih klubova.
Administratori sada mogu da uključe golmanski režim i „otvoreno za goste“ po treningu, i sa sajta i iz aplikacije: forma za trening dobila je dva prekidača i opciono polje za grad, a isti prekidači se pojavljuju na ekranu treninga u aplikaciji admin/kapitenima/pomoćnim kapitenima. Golmani u aplikaciji sada dobijaju pristup golmanskom režimu na osnovu stvarnog profila (pozicija ili „mogu na gol“), a ne lokalnog prekidača na uređaju — prekidač u podešavanjima sada zapisuje taj profil direktno.
Golmanski režim (native aplikacija): ekran „Treba golman“ prikazuje otvorene termine svih klubova na platformi, filter po gradu i dugme „Igram“ koje šalje prijavu klubu bez otkrivanja kontakata. Bekend (migracija, /api/v1/slots, /api/v1/slots/[id]/apply) je spreman; funkcija se uključuje po treningu preko kolone needs_goalie kada operater primeni migraciju.
Dodat oporavak zaboravljene lozinke. Na stranici za prijavu, ispod lozinke, sada postoji link „Zaboravljena lozinka?“ koji šalje email sa linkom za resetovanje — bez otkrivanja da li nalog uopšte postoji. Ista opcija je dodata i u profilu, u sekciji „Lozinka“, za slučaj kada nalog ima i Google i email/lozinku prijavu, ali vlasnik nikad nije saznao lozinku (uvek se prijavljivao preko Google-a) — dugme „Ne sećam se trenutne lozinke“ šalje isti email bez traženja stare lozinke.
Na stranici profila dodata sekcija „Lozinka“. Ko se prijavio preko Google-a i nema lozinku sada je može postaviti direktno na sajtu — to je bio uslov i za prijavu lozinkom u mobilnoj aplikaciji. Ko već ima lozinku može je promeniti (traži se trenutna lozinka radi potvrde). Nalozi bez email-a za prijavu (@no-login.local) tu sekciju ne vide.
Podsetnici za trening sada pokazuju koliko igrača je već prijavljeno („nas N, treba M — jesi li s nama?“), na sve tri obaveštenja pred trening (24h, 3h i za golmane).
Katalog se otvara osetno brže. Stranica više ne šalje kolačić jezika pri svakom otvaranju, pa je CDN ponovo može keširati; zaglavlje, uvod i filteri se prikazuju odmah, a kartice dolaze zasebno uz skelete iste veličine, tako da mreža ne poskakuje. Filter cene sada čeka da prestanete da kucate umesto da šalje upit na svaki pritisak, slike ispod prvog ekrana se učitavaju tek pri skrolovanju, a brojač rezultata koristi jeftiniju procenu.
Obaveštenja: isti telefon više ne dobija isto obaveštenje dvaput. Kada se uređaj ponovo prijavi na push, stara pretplata istog uređaja se sada gasi — ranije je ostajala aktivna jer je Apple nastavljao da je prihvata dok god je aplikacija instalirana. Dodato i beleženje „ugasi obaveštenje na drugim uređajima“, tako da se taj tok sada može proveriti iz podataka.
12. maj 2026.
18Marketplace Phase 5: admin moderacija (sakrivanje/vraćanje/istorija promena), filteri kataloga (samo sa slikama, otvoreno za ponude, dostava), draft oglasi sa preview-om za prodavca, životni ciklus dogovora (prihvaćena ponuda → rezervisano → prodato), trust signali na profilu prodavca, podešavanja obaveštenja po vrsti, health dashboard za admine, proširene help sekcije (bezbednost kupovine i prodaje, zabranjeni predmeti, privatnost kontakta, disclaimer).
Marketplace: dugme „Zanima me“ spojeno sa „Sačuvaj“ u jedan signal. Detalj oglasa sada ima samo jedno dugme, prodavac vidi javni broj i listu kupaca koji su sačuvali oglas (sa datumom) na istoj kartici. Stranica /shop/my/interested uklonjena, brojač na /shop/my/listings sada vodi direktno na listu sačuvanih kupaca. Help sekcija ažurirana.
Bug: na izmeni oglasa fotografije nisu mogle da se dodaju. Razlog: PhotoUploader je slao sirov fajl iz telefona (3-5 MB) na presign, koji je odbijao sve preko 500 KB → generička greška „upload error“. Dodato klijent-side smanjenje + konverzija u WebP (max 1600 px, ≈400 KB) pre upload-a, /shop/sell/<id>/edit sada prikazuje sve postojeće fotografije sa „X“ za brisanje, nova DELETE ruta /api/listings/<id>/photos/<photoId> briše DB red i čisti R2. Limit na serveru podignut na 1.5 MB kao bezbedna granica.
Zatvorena dyra u privatnosti: anon Supabase ključ je do sada dao bilo kome pristup contact_phone/contact_telegram/contact_whatsapp/contact_other svih odobrenih profila preko PostgREST direktnog upita (profiles_select USING true + table-level SELECT grant). Migracija revoke-uje table-level SELECT od anon-a i ponovo grant-uje samo bezbedne kolone — contact_* anon više ne vidi (vraća 42501). Adminski/marketplace tokovi prolaze kao authenticated i rade kao i pre. Bonus: usput sređena kupovina koja je padala kad se trogue filtersa kombinovala sa paginacijom.
Nova sekcija /shop/services — usluge (oštrenje, popravka, treninzi, iznajmljivanje leda) odvojene od kataloga oglasa. Provider podiže ponudu (naslov, opis, cena, jedinica, grad); kontakti se uzimaju iz profila. Veza u headeru shopa, sajt u sitemap-u sa Schema.org Service JSON-LD-om za rich rezultate. Anonimni vide opis i cenu, kontakti otkriveni samo prijavljenim korisnicima.
Marketplace, srpski jezik: zamenjeni ijekavski oblici na ekavske (sajt je na srpskom, ne hrvatskom/bosanskom). „Lijeva (LH)“ → „Leva (LH)“ (filter strane hvataljke kod štapova i vratarske opreme), „Krivulja“ → „Krivina“ (oznaka krivine štapa).
Detaljne stranice (/roster/<slug>, /games/<slug>, /events/<slug>, /tournaments/<slug>) više se ne pretplaćuju na kolekcijske tagove (TAG.roster/games/events/tournaments/stats/teams) — samo na svoj per-ID tag. Pre toga jedan admin save na bilo kog igrača flush-ovao je svih 45 stranica igrača × 3 lokala = 135 ISR Writes po izmeni. Sad — 3. ~50× redukcija na detail-page izlivima. Slug→entity lookup uklonjen iz unstable_cache: čitamo jedan red iz baze na svaki render (jeftino), ali stranica više nije gerojzakažena za invalidaciju kolekcijskim tagom.
Smanjeno potrošnje ISR Writes na Vercelu: tagsForEntity više ne flush-uje home tag iz profile/team/event/tournament/training/game_stats — daily revalidate je dovoljan za te widget-e. Lista pretplata home stranice istanjena (skinuti roster/teams/tournaments). Aggregate stranice (/stats, /gallery, /events) prebačene na 7-dnevni revalidate umesto dnevnog — on-demand flush preko revalidateTag i dalje radi. Očekivano: <1/3 dosadašnjih ISR Writes/dan.
Marketplace SEO pass: shop.propeleri.rs sada ima svoj sitemap.xml (kategorije + svi aktivni oglasi + javni prodavci, ~350 URL-ova) i robots.txt koji isključuje /shop/admin, /shop/my, /shop/login itd. JSON-LD na detalji oglasa: Product (cena, valuta, dostupnost, prodavac, stanje) + BreadcrumbList; LocalBusiness na /shop home. Sve javne stranice imaju canonical na shop.propeleri.rs, generateMetadata sa opisom i OG/Twitter card-ovima; sold oglasi → noindex; privatne stranice (admin/my/sell/settings/login/register/disabled/notifications) zatvorene metadata robots: noindex.
Marketplace: dodato sortiranje kataloga — Preporučeno (default), Prvo novi, Prvo stari, Prvo jeftiniji, Prvo skuplji. Sort radi i preko valuta: u bazi je generisana kolona `price_rsd` (RSD-ekvivalent koristeći 117 RSD/EUR), pa cene u evrima i dinarima sortiraju zajedno bez čudnih skokova. Promena sortiranja resetuje page=1.
Marketplace filter fix: hokejaške pantalone sada koriste prostu odeću S/M/L/XL/XXL skalu umesto strukova u inčima, a polje „Kroj“ (Regular/Tapered/Loose) je uklonjeno — kupci nisu filtrirali po njemu, a prodavci su pogađali. Postojeći oglasi se migriraju (28-30"→S, 32-34"→M, 36"→L, 38-40"→XL). Vratarska oprema: filter „Strana hvataljke“ (LH/RH) sada se vidi i pre nego što kupac odabere `kind` — ranije je bio sakriven sve dok se ne klikne pads/catcher/blocker.
Marketplace: toggle EUR/RSD u filtrima — svaki oglas se prikazuje u odabranoj valuti sa ≈ prevodom i originalnom cenom ispod. Tekst marketplace-a ažuriran: platforma je otvorena za hokejiste svih timova, ne samo HC Propeleri.
Marketplace: katalog se sada otvara osetno brže — lista kategorija je u unstable_cache (1h, deljen između /shop i /shop/[slug]), generateMetadata i page handler dele isti React `cache()` poziv, a auth/blocked/listing upiti idu paralelno umesto sekvencijalno. Dodata paginacija (?page=N) sa numerisanim UI-em u dnu kataloga (30 oglasa po strani). Filteri i pretraga resetuju page=1 da bi izbegli praznu stranicu, dugme „← Nazad“ na oglasu sada poziva router.back() pa se vraćaš na tačno isti broj strane i filter kombinaciju (uz scroll restore iz browser history-ja).
Marketplace (faza 5): obaveštenja end-to-end — emitNotification helper piše u notifications iz interest / contact / offer / report flow-ova; nova zvona u ShopHeader sa brojem nepročitanih, lista na /shop/notifications sa „označi pročitano“. Blokiranje sada zaista isključuje korisnika — interest/contact/offer/report vraćaju 403 ako jedna strana je blokirala drugu, a stranica oglasa skriva kontrole. Banned-words matcher na POST /api/listings (hard hit odbija, soft šalje na pending_review) + admin tabovi /shop/admin/moderation-queue i /shop/admin/banned-words. PriceDropDialog na mojim oglasima sa 7-dnevnim debounce-om i fan-out obaveštenjima. /shop/admin/listings sa featured toggle-om. /shop/help dokumentacija. Bug fix: login se sada deli između propeleri.rs ↔ shop.propeleri.rs (cookie domain `.propeleri.rs`), button „Login“ više ne vodi na glavni sajt, /shop/login poštuje ?next=. 24 nova testa (chromium), email-gate ponovljen na sve nove endpoint-e.
Marketplace (faza 4 — buyer flow II): kupci sada mogu predložiti svoju cenu (offers) na oglase sa „pregovaračka“ oznakom — prodavac vidi dolazne ponude u /shop/my/offers i prihvata ili odbija; prihvatanje automatski otvara prodavčev kontakt kupcu. Dodate i sačuvane pretrage: dugme „Sačuvaj pretragu“ na katalogu hvata aktivne filtere, /shop/my/saved-searches lista snimke sa povratkom na jedan klik. 15 novih Playwright testova (chromium).
Marketplace (faza 3 — buyer interactions): kupci sada mogu otkriti prodavčev kontakt (telefon, Telegram, WhatsApp) — klikom se piše u contact_views; pritisnuti „Zanima me“ (javni signal prodavcu sa brojačem) i „Sačuvaj“ (privatno omiljeno, niko ne vidi). Dodate i odvojene liste /shop/my/interested i /shop/my/favorites. Korisnik može da blokira prodavca (/shop/my/blocks) i da prijavi oglas — administrator obrađuje prijave na /shop/admin/reports. 35 novih Playwright testova (chromium).
Trening / RSVP: igraci koje je trener rucno oznacio kao prisutne (training_stats) sada se broje u badz „yes“ i „goalkeepers“, i vise ne sede u koloni „cekaju odgovor“. Service worker za detail stranice (training/games/roster/...) prebacen na NetworkFirst — kada trener azurira prisustvo, promene se vide na prvom ucitavanju umesto pri sledecem osvezavanju.
Admin / trening: legionari (is_match_only) sada su prikazani u editoru prisustva kao posebna grupa „Legionari“ (i na desktopu i na mobilnom), sa malim narandzastim badzom „Лег“ na kartici. Autosave debounce smanjen sa 900ms na 300ms — unos prisustva sad reaguje brze.
11. maj 2026.
2Marketplace (faza 2 — prodaja): prodavci mogu kreirati, uredivati i brisati oglase, ucitavati fotografije, postavljati kompleti opreme (bundle sa stavkama), editovati profil kontaktnih podataka (telefon, Telegram, WhatsApp). API blokira nepotvrdjene mejl adrese. 60+ novih Playwright testova (chromium/webkit/Mobile Chrome/Mobile Safari) zelena.
Marketplace (faza 1 — temelj): pokrenuli smo shop.propeleri.rs sa katalogom, filterima (sekcija/kategorija/brend/grad/komplet), stranama oglasa i profilima prodavaca. U bazi: 16 tabela sa RLS politikama, FTS pretraga, automatsko aggregiranje bundle stavki i okidači za R2 ciscenje. Glavni sajt i marketplace dele Supabase sesiju preko poddomena, a public_profiles view sakriva externalne/odbijene/match-only naloge od javnih lista. 33 testna oglasa pokrivaju sve hokej-kategorije (od stikova i klizaljki do golmanske opreme i kompleta). Cuvanje fotografija ide preko Cloudflare R2, sa direktnim URL-ovima za testne stock slike. Plejer/external/admin razgranicenje na nivou enuma i RLS-a. 33 Playwright testa (chromium) zelena.
30. april 2026.
1Sastav tima: igracke kartice sada nose oznaku trening tima (A — Beli, B — Tamni) u donjem levom uglu avatara, pored postojeceg broja dresa i kapitenske/trener oznake. Dodat treci nacin pregleda — „Po timovima“ — gde su zaglavlja oba tima jedno pored drugog, a ispod su zajednicki redovi po pozicijama (napadaci/odbrana/golmani) sa dve mrezice — leva za tim A, desna za tim B. Tako se grupe poravnavaju vertikalno i mogu da se uporede direktno. Igraci bez dodeljenog trening tima i treneri prikazuju se ispod kao zasebne sekcije.
25. april 2026.
5Admin/igraci: dialog „Dodaj novog igraca“ sada ima kvacicu „Legionar (samo za jedan mec)“ umesto „Gost“ — to je flag koji se najcesce postavlja na licu mesta kad se zove privremeni igrac za turnir/utakmicu. „Gost“ ostaje u edit-dialogu kao informativni tag, ali vise ne iskljucuje igraca iz tournament rostera, RSVP liste ili broja push-pretplatnika — jer „gost klubа“ moze potpuno da igra za nas. Edit-dialog dobija prekidac „Legionar“, tako da admin moze ručno da skine zastavu kad legionar predje u stalni roster.
/install: vizuelni vodic kroz instalaciju. Inline SVG mokapi koji prikazuju iOS Safari Share dugme, „Add to Home Screen“ akcioni list i ekran potvrde, kao i Android Chrome trotackasti meni i „Install app“ stavku — sistemska iOS/Android UI ne moze da se snimi Playwright-om (to je OS-level), pa su mokapi normalni industrijski standard. Iznad svega su pravi device-emulirani snimci same propeleri.rs/install stranice u iPhone 14 Pro Safari-ju i Pixel 7 Chrome-u, generisani novim skriptom npm run screenshots:install.
Auth refactor: requireAdmin() helper centralizovan na 5 admin API ruta, src/lib/auth/login.ts → email.ts (sa mrtvim username helperima izbacenim u prethodnom prolasku), middleware koristi locale-aware startsWith umesto includes (vise nije matchovao podstringove tipa /x/profile-info), magic-link mode iz PasswordlessBlock-a uklonjen — ostao samo OTP tab. profiles.username kolona i profiles_account_status view dropnuti — vise nista ne cita njih. Dodat tests/auth.spec.ts e2e set: prikaz formi, validacija, redirect-ovi za zasticene rute, ceo password sign-in flow + admin badge sanity.
Auth UI: prijava sada radi samo preko stvarne emaila (Google, magic link, OTP, email + lozinka). Polja za username/lozinku u admin formama za kreiranje i izmenu igraca su uklonjena — admin upisuje samo ime, sistem dodeljuje tehnicki @no-login.local marker; kasnije se igrac sam registruje preko mejla i biva povezan kroz „Poveži“. Pomocnici loginToEmail / extractLoginFromEmail / isSyntheticLoginEmail i njihove i18n stringe (sr/ru/en) su uklonjeni iz koda.
Auth: ukinuli smo prijavu preko username-a. Igraci koji su imali synthetic @player-login.local nalog moraju ponovo da se registruju preko stvarne emaila na /register; admin ih onda povezuje sa postojecim profilom kroz „Poveži“ — sve statistike, istorija treninga i utakmica se cuvaju. Filler @propeleri.rs adrese koje su bile placeholderi takodje su sklonjene; profili bez emaila sada imaju jasan tehnicki marker @no-login.local i ne salju im se obavestenja.
24. april 2026.
5Onboarding mejl: kad admin odobri novog igraca, pg trigger na profiles.is_approved aktivira edge funkciju send-approval-email koja preko Resend-a salje dobrodoslicu sa linkovima ka /profile i /install (uputstvo za PWA + push). Tri jezicke varijante (sr/ru/en) biraju se prema preferred_locale. Idempotentnost: approval_email_sent_at kolona + atomicni claim. Svaki pokusaj se loguje u approval_email_log. Tehnicki i @player-login.local emailovi se tiho preskacu. Odluka kanalа u docs/adr/approval-email-delivery.md, DNS i tajne u docs/email-setup.md.
RSVP → prisustvo: kad igrac oznaci „Dolazim“, prisustvo i tim se podesavaju automatski iz njegovog default tima u profilu; golmani zauzimaju slot vrata svoje ekipe, univerzalni igraci biraju izmedju polja i gola. Admin sada vidi badge RSVP kod svakog igraca u listi prisustva (realtime). Dodato: stranica /admin/broadcast za push objave svim pretplatnicima (bez dugmadi Dolazim/Ne dolazim), /admin/notifications sa istorijom slanja, i realtime badge u admin hederu za profile koji cekaju potvrdu.
Auth: dodata Google prijava pored lozinke / magic linka / OTP koda. Novi korisnici sada idu kroz /onboarding (ime, prezime, telefon) i čekaju da ih trener potvrdi. U admin panelu pored „Odobri“ postoji dugme „Poveži“ — omogućava spajanje novog naloga sa postojećom profile-only karticom igrača; sva istorija (lineup, stats, training, tournaments) se prenosi na novi nalog, dupla kartica se briše.
Push: osnova za web push notifikacije. Igraci ukljucuju push u /profile (VAPID), prijave se cuvaju u push_subscriptions sa per-user podesavanjima (24h / 3h / otkazivanje / rucno). Service worker vec obradjuje push i notificationclick akcije (Dolazim / Ne dolazim). Trener u admin panelu treninga vidi broj pretplatnika, istoriju slanja, dugmad „Posalji odmah“ i „Otkazi trening“. Edge funkcija send-training-notification i pg_cron raspored su u repo-u i cekaju rucni deploy.
RSVP: prijavljeni igraci jednim tapom oznacavaju dolazak na trening sa stranice treninga — Dolazim / Mozda / Ne dolazim. Trener vidi sumu u realnom vremenu (Dolaze / Mozda / Ne / Bez odgovora) i deep-link /training/<slug>?rsvp=yes automatski pamti izbor iz push notifikacija.
23. april 2026.
2PWA: sajt se sada moze instalirati kao aplikacija na Android (Chrome), iPhone (iOS 16.4+) i desktop. Dugme „Instaliraj“ u navbaru, posebna instrukcija za iOS. Service worker precache-uje shell stranice za offline rad. Toast „Dostupno azuriranje“ poziva korisnike da osveze stranicu posle svakog deploy-a.
Auth: prijavljivanje preko magic linka i OTP koda na /login (nove dve kartice pored postojece lozinke). Novi admin API /api/admin/invite-player i dugme "Pozovi mejlom" na listi igraca — player-only profili mogu da dobiju nalog bez gubitka istorije u roster/stats. Badge "Bez naloga / Pozvan / Aktivan" preko view-a profiles_account_status.
20. april 2026.
13On-page SEO: dodat screen-reader H1 na detaljnoj stranici utakmice, meta-opisi prosireni na 140-160 znakova radi boljeg CTR u SERP, ItemList JSON-LD na 7 list-stranica (games, roster, training, schedule, gallery, events) za sitelinks u Google, width/height na sve logoi-slike protivnika (CLS fix), robots.txt blokira /api/. TRIM naziva turnira u bazi
SEO: dodat JSON-LD na svim detail stranicama. Person na /roster/<slug>, SportsEvent na /tournaments/<slug> i /training/<slug>, Event na /events/<slug>. Svuda dodat BreadcrumbList za Google rich results; sitemap skriva persistent test-korisnika (is_match_only)
Major dependency bump-ovi: TypeScript 6, @types/node 25, @vercel/analytics 2, lucide-react 1.x, shadcn CLI 4. ESLint 10 odložen dok eslint-config-next ne objavi kompatibilnu verziju
Dodat kredit studija u footer sa stilizovanom indeksabilnom linkom na Render Room (pill sa narandžastim pulsnim indikatorom, vidljiv na svim stranicama)
Poboljšan kontrast na tamnoj temi: podignut --muted-foreground sa #9ca3af na #c3c9d3, 'Запланирована' badge promenjen sa text-blue-500 na text-blue-300 — WCAG AA kontrast 4.5:1 na stranici Raspored
Uklonjena legacy `opponents` tabela (10 redova, nigde se ne koristi u kodu) i `games.opponent_id` + `teams.opponent_id` kolone koje su samo duplikat `opponent_team_id` preko `teams` tabele
Očišćeni svi ESLint warning-i (24 -> 0): uklonjeni neiskorišćeni importi i lokalne varijable u admin stranicama, GameForm-u, PlayerStatsTable-u
Next.js nadograđen na 16.2.4 — zatvoreno 6 HIGH ranjivosti (CSRF bypass u Server Actions, HTTP request smuggling, DoS u Server Components, neograničeni image cache), plus transitivni ReDoS fix-evi u picomatch/minimatch/path-to-regexp
Dodat og:image na sve stranice — raniji deljeni linkovi su bili bez slike jer je Metadata API u Next-u potpuno zamenjivao parent openGraph
DB cleanup: indeksirani svi strani ključevi (20+ kolona), RLS policies na profiles/gallery_photos su obavijene `(select auth.uid())` da se ne preračunavaju za svaki red, seasons_write i tournaments_write razdvojene na INSERT/UPDATE/DELETE da ne dupliraju seasons_select i tournaments_select, uklonjeni neiskorišćeni indeksi
Uklonjene široke SELECT policies sa javnih storage bucket-ova (avatars, events, gallery) — listanje fajlova anonimnim korisnicima više nije dozvoljeno, pristup po URL-u kroz /storage/v1/object/public/… i dalje radi
Obrisani mrtvi fajlovi: GameStatsEditor (zamenjen UnifiedGameEditor-om), BracketView/PlacementView/SimpleTournamentMatch (stare verzije), image-loader.ts
Ispravljen prijavljivanje na iOS Safari i drugim striktnim browserima — prilagođeno ime auth-kolačića, tako da @supabase/ssr samo deli session na delove (.0, .1...) ispod limita kolačića; ranije je ceo token išao u jedan kolačić od ~4KB i sistem ga je tiho odbacivao, pa je admin panel video korisnika samo na serveru dok klijentski Supabase mislio da je anoniman
18. april 2026.
2Javne stranice prešle na statičko generisanje (SSG + ISR): svi matchevi, igrači, trening sesije, turniri, eventi unapred pre-render uju se u build-u; dodato on-demand revalidiranje tagova pri svakoj admin izmeni preko /api/revalidate
Novi public Supabase klijent bez cookies() i posvećena data-cache tags mapa (src/lib/cache/tags.ts); AuthProvider sada sam učitava session na klijentu, pa javni layout više nije dinamičan
4. mart 2026.
1Statistički SQL view-ovi prebačeni na SECURITY INVOKER da bi se RLS uvek primenjivao za API pozive i uklonili Security Advisor rizici
22. februar 2026.
7Trening admin: nova kartica Timovi sa drag-and-drop raspodelom u 2 kolone, slotom golmana i slotovima po ulogama (napadač/odbrana/bez pozicije); ista grupacija prikazana i na javnoj stranici treninga
Ispravljeno poravnanje kartica igrača kada je prisutan bedž Gosta (ujednačena visina reda)
Opcija "Može u gol" za igrače koji igraju i u polju i u golu — pojavljuju se i u GK slotu i u linijama
Ispravljen bug sa NULL slug-om pri ažuriranju rezultata turnirskih mečeva (trigger u bazi podataka)
Sortiranje igrača po imenu umesto broja dresa u svim listama (admin panel, roster, editor utakmica)
Veći modal za video golova na desktopu (min 1000px); uklonjene bedževi pozicija sa kartica igrača u grid prikazu
Gost igrači (is_guest) sada se pojavljuju u editoru utakmica za golove i asistencije
16. februar 2026.
1URL-ovi bez prefiksa jezika: jezik se automatski određuje po podešavanjima pregledača (Accept-Language) i čuva u kolačiću. Stari linkovi sa /ru/ i /en/ prefiksima automatski preusmeravaju
15. februar 2026.
9SEO-friendly URL-ovi: sve javne stranice koriste čitljive slug-ove umesto UUID-ova (npr. /games/2025-02-15-vs-zvezda-home, /roster/stefan-milosevic)
Slug polje u svim admin formama sa automatskom generacijom, ručnim uređivanjem i proverom jedinstvenosti
Editor treninga pretvoren u tabove (Info, Dolasci, Meč) sa split prikazom dolazaka na desktopu
Kartica Sastav u editoru utakmice: izabrani igrači prikazani u listi sa strane na desktopu
Statistika sada prikazuje sve igrače iz postava, ne samo one sa poenima (opšta i turnirska)
Unos kazni (PIM) u događaje utakmice, kraći naziv kartice
Podrska za penale (shootout) u turnirskim mečevima + SO oznaka na svim karticama rezultata
Redizajn editora utakmice: spojeni tabovi, vizuelni skor, ogranicena sirina
Statistika igraca na stranici turnira + univerzalna tabela statistike sa avatarima
14. februar 2026.
3Redizajn unosa golova: jednostavniji formular (strelac + opcioni asistenti), progresivni prikaz na mobilnom
Tab za golove u editoru utakmice + prikaz strelaca na posteru rezultata
Ispravljen prikaz logotipa protivnika za turnirske utakmice
13. februar 2026.
14Ujednačen popup za uređivanje igrača: isti dizajn na javnim stranicama i u admin panelu
Kompletna SEO optimizacija: metadata za sve stranice, Open Graph tagovi, robots.txt, sitemap.xml, manifest, JSON-LD strukturirani podaci, višejezični hreflang linkovi
Ispravljen atribut lang na HTML elementu — sada se menja prema izabranom jeziku
Lepljivi zaglavlja na svim admin stranicama, uklonjen nepotreban skrol
Stranica treninga: sledeći trening istaknut, ostali u sklopivim sekcijama
Brzo uređivanje utakmica, treninga i igrača direktno sa javnih stranica za admine
Dodata uloga trenera za članove tima
Poboljšan izbor zemlje sa automatskim dopunjavanjem i zastavicama
Redizajnirane kartice turnirskih mečeva, razdvojena lista mečeva
Turnirski mečevi preusmereni na jedinstveni editor igara
Spinneri zamenjeni skeleton komponentama za učitavanje
Dinamički importi, Map lookups, error boundary za bolje performanse
Poboljšana bezbednost baze podataka i RLS politike
LoadingErrorEmpty primenjen na sve admin stranice, SelectWithNone za timove
12. februar 2026.
13Vercel Web Analytics integrisan u aplikaciju
Testovi pristupačnosti, popravke mobilnog prikaza, WCAG poboljšanja
Brisanje timova i redizajn grid prikaza timova sa velikim avatarima
Admin link dodat u header sa uslovnom vidljivošću
Poboljšan lineup editor sa prikazom svih linija i mobilnim stilom
Dijalog za isecanje avatara sa zumiranjem i pomeranjem
Puna imena sa nadimcima u turnirskom rosteru
Standardizovani zaglavlja admin stranica sa AdminPageHeader
Zamenjeni hardkodirani stringovi i18n prevodima u admin panelu
Ispravljen bug beskonačnog učitavanja u lineup editoru
HockeyRink spojen sa GameLineupEditor u readOnly režimu
Poliranje lineup komponente: veličine krugova, avatari, mobilni layout
Finalizacija dizajna meč kartica i redizajn editora mečeva
11. februar 2026.
17Jedinstvena struktura stranica mečeva sa 5 tabova za sve tipove mečeva
Dodato uređivanje osnovnih polja za obične mečeve
Svi hardkodirani stringovi zamenjeni i18n prevodima
Admin edit link dodat na GameMatchCard sa poboljšanim responsive dizajnom
Mobilna horizontalna navigacija i Playwright e2e testovi
Poboljšano upravljanje igračima i vizuelni dizajn tima
Uprošćeno kreiranje naloga igrača i poboljšan tok treninga
Deklarisani roster za turnire sa izborom lineup-a
Prošireno upravljanje treninzima: zakazivanje, statusi i detalji meča
Redizajn hokejskog terena: vertikalno polupolje sa ledenom površinom
Poboljšana tabela igrača u admin panelu
Redizajn landing stranice sa novim vizualima i logotipom tima
Poboljšan prikaz rasporeda na terenu sa automatskim čuvanjem
Zamena tabele Opponents sa Teams i migracija baze podataka
Kritične ispravke autorizacije i admin panela
Ispravke sesije, brisanja igrača, ESLint grešaka i DOM nesting errora
Ispravljen cookie maxAge umesto nevažećeg lifetime svojstva
10. februar 2026.
5Redizajn lineup editora sa vizuelnim pozicijama i dodati turniri
Logotip tima dodat na sve brendirane elemente
Uređivanje igrača, trening timovi i vizualizacija hokejskog terena
Poboljšan UI svih stranica, priprema za Vercel deployment
Početno postavljanje projekta — sajt hokejskog tima HC Propeleri