Commit Graph
234 Commits
Author SHA1 Message Date
Dasko bd2e781139 Servis: preimenovanje labela, čuvanje garancije pri toglu, avans na otpremnici
- „Konačna cena" → „Cena rada" u formi i štampanom nalogu
- toggleGarancija čuva prethodnu vrednost datuma pre brisanja i vraća je pri ponovnom uključivanju
- Otpremnica ne prikazuje red avansa kada je avans 0 ili nije unesen
2026-06-20 00:41:54 +02:00
Dasko a2353d642e Servis: pregled troškova, auto-cena delova, modalni prozor za potvrdu
- Detalji naloga prikazuju cenu usluge, ugrađene delove, ukupno i za naplatu kao zasebne stavke
- Otpremnica uključuje stavku ugrađenih delova u obračun
- Biranje artikla u formi za delove automatski popunjava cenu po komadu
- Zamenjen confirm() sa prilagođenim modalnim prozorom za sve potvrde
2026-06-20 00:40:29 +02:00
Dasko d9b6387a93 Izveštaji: popis magacina (inventura)
- Nova stranica /izvestaji/popis — forma za unos stvarnog stanja
- Razlika se prikazuje u realnom vremenu (JS) dok se kuca
- Pri snimanju: samo izmenjene količine upisuju se kao korekcija
u magacinske_promene sa napomenom (podrazumevano "Godišnji popis")
- Nova metoda KorigujKolicinu u ArtikalRepository — transakciona,
ažurira kolicina i upisuje promenu tipa korekcija
- Link Popis (inventura) dodat na stranicu izveštaja
2026-06-19 19:56:02 +02:00
Dasko a5dc104e29 Izveštaji: prometni list magacina i stanje zaliha
- Prometni list: sve promene magacina po periodu (filter od/do datuma),
bojama označeni tipovi promena (ulaz/prodaja/servis/povraćaj/korekcija)
- Stanje zaliha: svi artikli sa stanjem, min. količinom, cenama i
ukupnom vrednošću zalihe; kritične zalihe istaknute crvenom bojom
- Brzi linkovi na oba izveštaja sa glavne stranice izveštaja
2026-06-19 19:53:06 +02:00
Dasko c730705051 Servis: dodata otpremnica pri preuzimanju uređaja
- Nova stranica /servis/{id}/otpremnica — dokument za klijenta
- Prikazuje: isporučilac/primalac, uređaj, opis radova, delovi,
obračun sa odobitkom avansa, garancijski rok, prostor za potpise
- Dugme Otpremnica dodata pored Radni nalog u detaljima naloga
2026-06-19 19:48:48 +02:00
Dasko b8c918e427 Servis: dodata štampa servisnog naloga
- Nova stranica /servis/{id}/stampa — print-friendly A4 dokument
- Prikazuje: zaglavlje firme, broj naloga, status, klijent, tehničar,
uređaj sa opisom kvara i pribором, ugrađene delove sa ukupnim iznosom,
cene usluge i prostor za potpise
- Dugme Štampaj nalog dodata na stranicu detalja naloga
2026-06-19 19:46:05 +02:00
Dasko 74b7c88d99 Magacin: dodata prometna kartica artikla
- Nova stranica /magacin/kartica/{id} — sve promene stanja po artiklu
- Prikazuje tip promene (ulaz/izlaz/servis/povraćaj/korekcija) sa bojama
- Dugme Kartica dodata u listu magacina (desktop i mobilni prikaz)
2026-06-19 19:42:08 +02:00
Dasko c6aa28a760 Magacin: dodati šifra i barkod artikla sa auto-generisanjem
- Migracija 055: kolone sifra i barkod u tabeli artikli (UNIQUE indeksi)
- Model, repozitorijum i handleri ažurirani za nova polja
- Pretraga u magacinu pokriva i šifru i barkod
- Forma predlaže sledeću šifru (ART-NNNNN), korisnik može izmeniti
- Ako se ostavi prazno, šifra se auto-dodeljuje po ID-u pri čuvanju
2026-06-19 19:35:24 +02:00
Dasko 809d29ea49 Demo mod: Secure kolačići i blokada TOTP aktivacije
- Secure flag na kolačićima se postavlja i u demo modu (HTTPS kroz Caddy)
- Podešavanje 2FA je blokirano u demo modu — handler odbija zahtev,
a šablon sakriva dugme i prikazuje obaveštenje
2026-06-19 01:54:36 +02:00
Dasko 4467211ddd Demo mod: ograničenje bekapa i blokada promene lozinke
- Bekap se ograničava na 2 kopije u demo modu (umesto 7)
- Promena lozinke je blokirana u demo modu — handler odbija zahtev,
a šablon sakriva formu i prikazuje obaveštenje korisniku
2026-06-19 01:16:24 +02:00
Dasko 3e79d94558 Demo mod, favicon ispravka i putanja ntech.env uz bazu
- NTECH_ENV=demo aktivira demo mod: korisnik Demo/Demo1234 (admin)
se kreira ili resetuje pri svakom pokretanju
- Login ekran u demo modu prikazuje pre-popunjena polja i "DEMO verzija"
- ntech.env se čuva u istom direktorijumu kao SQLite baza (umesto
uvek u radnom direktorijumu) — rešava Docker volume problem
- favicon.svg: uklonjen width="100%" koji je sprečavao prikaz ikone u brauzeru
2026-06-19 01:11:40 +02:00
Dasko 9e76e10307 Servis forma, animacije, hover efekti i pojačane senke
Servis:
- Nova polja: ostecenja, pin_uredjaja, pribor (migracija 051)
- Default garancija iz podešavanja, svič "Bez garancije" u formi
- Podešavanja → Servis: konfigurabilan rok garancije (migracija 052)
- Default datum prijema = danas; datum_prijema se eksplicitno upisuje
- Sidebar link za Servis podešavanja
PDV/Nivelacije:
- Default raspon datuma = početak/kraj tekućeg meseca (KIR, KPR, Nivelacije)
- Dodata class="tabela" na tabele bez klase (KIR, KPR, Obračun, Nivelacije)
Animacije (Moj profil → Tema):
- Korisnik bira vrstu animacije: bez, fadeInUp, fadeIn, scaleIn, slideLeft
- Čuva se po korisniku u korisnici.lokalna_animacija (migracija 053)
- CSS [data-animacija] radi na body (globalno) i na preview wrapperima (izolovano)
- Preview animacije izolovan: data-animacija na #anim-preview-wrap, ne na body
- Mobilne kartice se animiraju kad korisnik odabere stil (podrazumevano ne)
- Animacija primenjena direktno na .tabela tbody tr (bez potrebe za .animiraj)
Hover efekti (Moj profil → Tema):
- Opcije: podrazumevano, bez, podizanje, svetlost, zoom, boja
- Čuva se po korisniku u korisnici.lokalni_hover (migracija 054)
- CSS [data-hover] radi izolovano; preview menja samo #hover-preview-wrap
- Pojačane senke u oba teme (--senka i nova --senka-hover promenljiva)
- Transition dodat za transform i background na karticama
Grafikon (Izveštaji): toggle zamenjen globalnim .toggl/.toggl-klizac svičom
2026-06-18 02:21:06 +02:00
Dasko 5518d2071c Verzija na login ekranu; konsolidacija build skripti
- Prijava: prosleđuje h.Verzija šablonu i prikazuje je ispod forme
- start.sh: objedinjena skripta (verzija, okruženje, platforma, UPX, build, Docker push)
- build.sh: obrisano (zamenjeno sa start.sh)
2026-06-16 22:20:47 +02:00
Dasko 3048b1e808 Bezbednost: _next whitelist umesto url.Parse (CodeQL taint analiza) 2026-06-16 03:37:01 +02:00
Dasko 18dd2fc460 Bezbednost: open redirect i kolačići bez Secure atributa
- _next parametar: sanitizacija preko url.Parse (Host+Scheme prazan = relativan URL)
umesto ručnog string check-a koji CodeQL nije prepoznavao
- Kolačići: dodat Secure atribut (true u produkciji, false u razvoju)
na 4 mesta: ntech_sesija brisanje (auth.go, prijava.go),
ntech_flash_greska postavljanje i brisanje (auth.go, dashboard.go)
2026-06-16 03:32:07 +02:00
Dasko 3054041257 Bezbednost: ispravka otvorene redirekcije (open redirect)
- podesavanja.go: _next parametar sada odbacuje putanje koje počinju sa "//"
(npr. "//evil.com" prolazilo je staru proveru jer počinje sa "/")
- profil.go: Referer zaglavlje se parsira i koristi samo putanja (RequestURI),
bez hosta — sprečava preusmeravanje na spoljne domene
2026-06-16 03:22:45 +02:00
DaskoandGitHub f036fe4010 Potential fix for code scanning alert no. 9: Bad redirect check
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-06-16 03:13:43 +02:00
Dasko 5f8c72c2e9 Ispravke: ugnježdena forma, greška čitanja fajla, mrtvi flag, refaktor struct
- podesavanja_opste.html: forma za uklanjanje loga premešena van forme za
otpremanje — ugnježdene forme su nevažeći HTML
- ProfilOtpremiAvatar: greška iz fajl.Read(buf) se sada proverava (dozvoljava
io.EOF, odbacuje pravi problem čitanja)
- TopbarLogoTekst uklonjen: iz modela, oba handlera i struct-a u podesavanja.go
(podešavanje nije korišćeno ni u jednom šablonu)
- korisnici.go: dodeliOpcijeKorisnika prima korisnikOpcije struct umesto dugačke
liste parametara; skeniraiKorisnika i Lista ažurirani
2026-06-16 03:00:38 +02:00
Dasko 684fc67ba4 Topbar: logo firme + naslov; avatar upload; uklanjanje logo zone
- Topbar: logo slika firme (toggle on/off) pa naslov stranice; bez teksta firme
- Sidebar: samo naziv firme i podnaslov (tekst), bez slike loga
- Avatar: korisnik uploaduje ličnu sliku u Profil > Tema > Avatar;
prikazuje se kao dugme za meni (desno u topbaru); fallback inicijali
- Logo firme kartica: dugme "Ukloni sliku" + ruta /podesavanja/logo/ukloni
- Logo zona iz podešavanja uklonjena; jedan iOS toggle za prikaz loga u topbaru
- Migracije 049 (topbar_logo_slika/tekst) i 050 (avatar_putanja na korisnicima)
- iOS-style .toggl switch u main.css
2026-06-16 02:46:48 +02:00
Dasko 677b94be98 Ispravka boje tačke na kritičnim zalihama i uklanjanje CSS warning-a
- Boja tačke na kritičnim zalihama: crvena kad je količina upola manja od minimalne
- Uklonjen preload pozadinske slike (nepotreban, izazivao warning u konzoli)
- @view-transition umotan u @supports da ne izaziva warning u browserima koji ne podržavaju
2026-06-16 01:40:43 +02:00
Dasko e41a491d17 feat(podesavanja): podstavka „Kalkulacija i PDV" — marža + PDV stope na jednom mestu
- PdvStope handler: dodata podrazumevana marža; stranica „podesavanja-kalkulacija-pdv",
naslov „Kalkulacija i PDV", ruta /admin/podesavanja/kalkulacija-pdv
- pdv_stope.html: sekcija „Kalkulacija" (forma marže preko /podesavanja/sacuvaj) iznad šifarnika
- marža uklonjena iz stranice „Sistem"
- sidebar: podstavka „PDV stope" → „Kalkulacija i PDV"
2026-06-14 17:40:38 +02:00
Dasko 13b9386d85 Merge feature/kw-kalkulacija-prodajna: dvosmerna marža↔prodajna + status PDV obveznika 2026-06-14 17:16:58 +02:00
Dasko 0e7247c9c1 feat(nabavka): dvosmerna marža↔prodajna + poštovanje statusa PDV obveznika
- ručni unos prodajne cene preračunava maržu (izracunajMarzu): obrnuta formula
marža = (prodajna / (nabavna × (1+pdv/100)) − 1) × 100
- kalkulacija poštuje da li je firma PDV obveznik: ako nije, prodajna se ne
uvećava za PDV (pdvStopa = 0); PodaciFormeNabavke.PdvObveznik → JS _ntechPdvObveznik
- proširena kolona „Marža %" da se vidi cela vrednost
2026-06-14 17:16:24 +02:00
Dasko 73d893a4d6 feat(pdv): uvoz robe — KPR zastavica i mapiranje u PPPDV 006/106
- migracija 048: kolona uvoz na pdv_kpr (0=domaća nabavka, 1=uvoz)
- model PdvKpr.Uvoz; MapirajPPPDV(kir, kprDomace, kprUvoz) rutira uvoz u 006/106,
domaće u 008/108; test ažuriran + uvozni scenario
- repo: KPR Lista/DohvatiID/Kreiraj čitaju i pišu uvoz
- obračun: KPR se razdvaja na domaće/uvozne; obaveza ostaje na ukupnom KPR-u
- KPR forma: kvačica „Uvoz (JCI)"; lista: oznaka UVOZ uz broj dokumenta
2026-06-14 17:16:01 +02:00
Dasko 6b5db5186d feat(nabavka): UI zavisnih troškova — forma i prikaz u detaljima (Faza C, celina 2)
- forma nabavke: sekcija „Zavisni troškovi" (slobodne stavke naziv+iznos,
dodavanje/uklanjanje) + izbor metoda raspodele (po vrednosti / po količini)
- JS: kalkNabavna (kalkulativna nabavna po stavci, prati server) i preracunajSve —
promena troška/metoda/količine/cene preračunava prodajne svih stavki
- detalji nabavke: prikaz zavisnih troškova, metoda raspodele i ukupnog iznosa
- handler DetaljiNabavke dohvata troškove (DohvatiTroskove)
2026-06-14 16:23:11 +02:00
Dasko a66d966d45 feat(kalkulacija): Faza C — marža po kategoriji/artiklu + zavisni troškovi (backend)
Celina 1 (kompletna) — marža po kategoriji/artiklu:
- migracija 046: nullable marza na artikli i kategorije
- model Marza *float64 (Artikal, Kategorija) + KategorijaMarza u ArtikalSaKategorijom
- repo: čitanje/pisanje marže; nove DohvatiID/Izmeni za kategoriju
- dozvola kategorija.izmeni; handler IzmeniKategoriju + ruta
- UI: polje marže u formi artikla i kategorije; modal izmene kategorije
- nabavka: fallback predlog marže artikal → kategorija → globalna (izaberiArtikal)
Celina 2 (backend) — zavisni troškovi nabavke:
- migracija 047: tabela nabavka_troskovi + kolona metod_raspodele na nabavke
- model NabavkaTrosak, MetodRaspodele; čista funkcija RasporediTroskove + test
- repo: Kreiraj upisuje troškove i metod; DohvatiTroskove
- handler: parsiranje troškova/metoda; kalkulativna nabavna cena na serveru
UI forme troškova i prikaz u detaljima nabavke slede.
2026-06-14 16:12:03 +02:00
Dasko 443df348d5 feat(nabavka): kalkulacija — formiranje prodajne cene pri nabavci (Faza B)
Po stavci nabavke: marža% (predpopunjena globalnom iz podešavanja,
kalkulacija_marza) i prodajna cena = nabavna × (1+marža/100) × (1+PDV/100),
živo računato u Alpine, izmenjivo. Na čuvanje se ažurira nabavna+prodajna
cena artikla (ArtikalRepo.AzurirajCene) i upiše nivelacija 'kalkulacija';
prazna/nulta prodajna se preskače. ArtikliJSON nosi pdv_stopa. Postavka
podrazumevane marže u Podešavanja → Sistem.
2026-06-14 10:13:56 +02:00
Dasko 6ce3d39679 feat(magacin): nivelacija — promena cene uz trag (Faza A)
Tabela nivelacije (migr 045) beleži svaku promenu prodajne cene:
artikal, stara→nova cena, razlog, izvor, korisnik, datum. Dva okidača:
posebna akcija „Promeni cenu" (modal, izvor 'rucno') i auto-trag pri
izmeni artikla (izvor 'izmena'). PromeniCenu je transakciono (update
cene + upis zapisa). Pregled /nivelacije sa filterom perioda i razlikom
(+/− i %). Modal otvara svoj nextElementSibling — radi i na mobilnom
uprkos dupliranim id-jevima iz dva rasporeda.
2026-06-14 09:37:49 +02:00
Dasko e35bc5d2e5 feat(pdv): PPPDV mapiranje na stranici obračuna
model.MapirajPPPDV preslikava zbirove KIR/KPR na polja zvaničnog
obrasca PPPDV (001-005/103-105, 006-009/106-109, 110, povraćaj) u
celim dinarima; zbirovi se računaju iz zaokruženih polja. Uvoz
(006/106) i nadoknada poljoprivredniku (007/107) se ne prate → 0.
Sekcija PPPDV dodata na /pdv/obracun. Prikaz za popunjavanje, ne
elektronska predaja.
2026-06-14 08:53:18 +02:00
Dasko f295203208 feat(pdv): obračun PDV za period (KIR − KPR)
Interni obračun: izlazni (dugovani) PDV iz KIR i odbitni (prethodni)
PDV iz KPR po stopama, konačna obaveza za uplatu ili povraćaj/prenos.
PdvBezOdbitka se ne računa u odbitni PDV. Stranica /pdv/obracun
(podrazumevano tekući mesec), link u sidebaru. Brojčana podloga za
budući zvanični PPPDV/POPDV obrazac.
2026-06-14 08:34:33 +02:00
Dasko bf541cda72 feat(nabavka): brzi unos dobavljača i artikla iz forme nabavke
Dugmad otvaraju modale koji preko AJAX-a (X-Requested-With: fetch) čuvaju
novi zapis i vraćaju JSON; novi dobavljač se odmah ubacuje u listu i bira.
Modal artikla proširen na sva polja kao puna stranica. Centriranje modala
prebačeno u .modal-overlay klasu (x-show je brisao inline display:flex).
2026-06-14 08:16:51 +02:00
Dasko 889c4f7510 feat(pdv): nabavka → KPR automatski (Faza 2b-2)
PDV se izvodi iz stope artikla po stavci (aproksimacija: nabavna cena
= osnovica bez PDV). Grupisanje po stopi (20→opšta, 10→posebna,
ostalo→oslobođena nabavka), broj dokumenta NAB-<id>, veza izvor/izvor_id.
Auto-zapisi se ne mogu ručno brisati u KPR; brisanje nabavke uklanja
vezani KPR zapis.
2026-06-14 08:16:41 +02:00
Dasko 0177cdaa5e feat(pdv): prodaja → KIR automatski (Faza 2b-1)
Kad se sačuva prodaja na klijenta (PDV obveznik), zapis se sam zavede u
KIR (model.KirIzProdaje grupiše stavke po stopi). Storno/brisanje prodaje
uklanja vezani KIR zapis (ObrisiPoIzvoru). Maloprodaja građanima (bez
klijenta) se preskače — ide preko fiskalizacije (Faza 3). Helper
modulUkljucen; auto-zapisi u UI nemaju ručno brisanje. Test.
2026-06-14 02:45:07 +02:00
Dasko 90801cc71a feat(pdv): KPR — knjiga primljenih računa + PIB/mesto dobavljača (Faza 2a)
KPR (handler, rute pod RequireModul("pdv"), UI sa sumama po stopama,
izbor dobavljača, datum plaćanja, PDV bez odbitka / oslobođena nabavka)
+ stavka u meniju. Dobavljači dobili PIB i mesto (migracija 043) jer KPR
traži PIB dobavljača za POPDV. Time je Faza 2a kompletna (KIR + KPR).
2026-06-14 02:05:33 +02:00
Dasko 9c880d78ab feat(pdv): izbor klijenta u KIR formi + mesto/grad u klijentima
KIR forma nudi padajuću listu postojećih klijenata koja popunjava naziv,
PIB/JMBG i mesto kupca (uz ručni unos za kupce van baze). KIR i dalje
čuva kupca kao tekst, ne kao vezu. Klijenti dobili polje mesto (migracija
042), provučeno kroz model, repo, formu i handler.
2026-06-14 01:39:06 +02:00
Dasko ca10fa541b feat(pdv): KIR — handler, RequireModul, rute i UI (Faza 2a)
Pregled knjige izdatih računa (filter perioda + sume po stopama), forma
unosa (server računa ukupno) i brisanje. Nove dozvole pdv.*; prvi put
montiran RequireModul("pdv") — KIR je vidljiv u meniju (.Moduli) i
dostupan samo PDV obveznicima, uz RBAC. Oznaka PIB/JMBG po broju cifara.
2026-06-13 23:45:24 +02:00
Dasko eae47f9dfb feat(pdv): KIR/KPR evidencija — migracija, model i repozitorijum (Faza 2a)
Tabele pdv_kir i pdv_kpr (iznosi po vrsti stope), modeli PdvKir/PdvKpr,
repozitorijumi sa filterom perioda i integracioni test (datum round-trip,
nullable datum plaćanja).
2026-06-13 21:22:48 +02:00
Dasko df79aec9ef feat(pdv): šifarnik PDV stopa — handler, rute i UI (Faza 1)
Handleri (prikaz, dodaj, izmeni, arhiviraj/vrati) sa validacijom i flash
porukama; rute pod /admin/podesavanja/pdv-stope (dozvole podesavanja.*);
stranica pdv_stope registrovana u kes.go i dodata u meni Podešavanja.
Šifarnik je opšti (bez RequireModul) jer ga koristi i kalkulacija.
2026-06-13 20:45:43 +02:00
Dasko 26ff6c80e9 feat(pdv): šifarnik PDV stopa — migracija, model i repozitorijum (Faza 1)
Tabela pdv_stope (seed 20/10/0%), model PdvStopa, PdvStopaRepository
+ SQLite implementacija (arhiviranje umesto brisanja) i integracioni
test (migracija + CRUD round-trip).
2026-06-13 20:33:48 +02:00
Dasko 64657d5fee feat(moduli): mehanizam uključenih modula — Moduli mapa i RequireModul (Faza 0)
config.SviModuli + PodaciStranice.Moduli (uslovni meni, analogno Dozvole)
i middleware.RequireModul (zaštita ruta, analogno RequireDozvola). Sloj
iznad RBAC-a: zahtev mora proći i „modul uključen" i „korisnik sme".
Dopunjen test (TestSviModuli). Time je Faza 0 kompletna.
2026-06-13 20:23:24 +02:00
Dasko 3701152e30 feat(podesavanja): profil firme — pravni i poreski status (Faza 0)
Dodata kartica „Pravni i poreski status" na Podešavanja → Opšte:
pravni oblik, režim rada, PDV obveznik, fiskalizacija. Čuva se u
postojećoj key-value tabeli podesavanja (bez migracije). Fiskalizacija
se zasivi i forsira na „Ne" u režimu „samo evidencija".
2026-06-13 19:27:26 +02:00
Dasko 8371c50c6c fix(cache): HTML stranice no-cache da nova verzija odmah stigne do korisnika
HTML nije imao Cache-Control, pa je browser servirao staru keširanu stranicu
sa starim AssetV tokenom i posle deploya — stari CSS/JS. Dodato no-cache na
renderujTemplate i renderujStandalone: browser revalidira HTML, dobija svež
AssetV token koji povlači svež CSS/JS. Statika ostaje immutable + ?v=verzija.
2026-06-13 10:45:23 +02:00
Dasko ce624fdc87 feat(2fa): rezervni (jednokratni) kodovi za 2FA
Alternativa TOTP-u kada uređaj nije dostupan. Po specifikaciji:
10 kodova pri aktivaciji, čuvani kao bcrypt heš.
Backend:
- migracija 039 (tabela rezervni_kodovi, FK CASCADE)
- auth.GenerisiRezervneKodove (Crockford base32, XXXX-XXXX) + NormalizujRezervniKod
- RezervniKodoviRepository (Zameni/Iskoristi/BrojPreostalih/Obrisi) + SQLite impl
- žičenje u Handler (+ reinicijalizuj)
Prijava:
- VerifikujTotp prvo proba TOTP, pa rezervni kod (isto polje); kod je jednokratni
- totp_provera.html: input opušten (slova/crtica), napomena o rezervnom kodu
Profil:
- aktivacija generiše i prikazuje kodove JEDNOM; dugme Regeneriši; brojač preostalo X/10
- deaktivacija briše kodove
Testovi: auth (generisanje/format/normalizacija), repo (jednokratnost/regeneracija),
prijava rezervnim kodom end-to-end. Ukupno 36 test funkcija.
2026-06-12 23:44:09 +02:00
Dasko dd7aaa05be test: validatori forme (parseFormu*)
internal/handler/parseformu_test.go — tabelarni testovi za:
- parseFormuArtikla (naziv obavezan, negativna količina, neispravna cena)
- parseFormuKlijenta (fizičko/pravno obavezna polja, email, podrazumevani tip)
- parseFormuProdaje (bez stavki, količina 0, neispravan artikal, nesklad, validno)
- parseFormuNaloga (uređaj/opis obavezni, podrazumevani status)
Ukupno 32 test funkcije u repozitorijumu.
2026-06-12 23:12:56 +02:00
Dasko c8ca09b4f9 test: integracioni testovi tokova prijave
internal/handler/prijava_test.go — Handler nad privremenom SQLite bazom (prave
migracije), TemplatesFS na korenu repo-a za standalone render. Pokrivено:
- uspešna prijava (303 -> /dashboard + sesijski kolačić)
- pogrešna lozinka (greska=1, bez kolačića, zabeležen neuspeh)
- nepostojeći korisnik i neaktivan nalog (bez sesije)
- zaključavanje IP-a posle 5 neuspeha (ni ispravna lozinka ne daje sesiju)
- TOTP tok: prijava -> /prijava/totp -> validan kod -> /dashboard (potvrđeno)
- pogrešan TOTP kod (greska=1, sesija ostaje nepotvrđena)
Ukupno 28 test funkcija u repozitorijumu.
2026-06-12 23:09:55 +02:00
Dasko 98faf0a9de refactor(izvestaji): direktan SQL dashboard/izveštaja u IzvestajRepository
dashboard.go i izvestaji.go više ne sadrže direktan SQL — svih 12 upita
prebačeno u novi IzvestajRepository (internal/db/sqlite/izvestaj.go). Repo vraća
sirove redove (model.*Red tipovi), a handleri zadržavaju prezentaciju
(formatiranje datuma, boje tačaka, rang, sklapanje niza 12 meseci). Žičenje kroz
Handler.IzvestajRepo (+ reinicijalizuj).
Dobici: testabilnost (dodati integracioni testovi izvestaj_test.go) i put ka
Postgres-u bez prepravke handlera. dashboard.prihod provera ostaje u handleru.
Van obima: middleware/flash.go i backup VACUUM INTO (ne pripadaju repo sloju).
2026-06-12 22:53:15 +02:00
Dasko 4c1794ffc6 refactor(log): prelazak sa log na log/slog (strukturisano logovanje)
Uveden podrazumevani slog logger u main.go (podesiLog): JSON u produkciji,
tekst u razvoju, nivo Info. Svih ~70 poziva log.Printf/Println/Fatalf zamenjeno
slog.Error/Warn/Info: greška se prosleđuje kao atribut "error", informativne
vrednosti kao imenovani atributi (port, broj, putanja...), Fatalf -> Error +
os.Exit(1). Upozorenja (inicijalizacija/čišćenje dozvola, migracija kolone) idu
kao slog.Warn.
Auth log (internal/auth/log.go) namerno NIJE diran — ostaje zaseban *log.Logger
u fail2ban formatu. (slog.SetDefault usput preusmerava i standardni log paket.)
2026-06-12 22:33:42 +02:00
Dasko 88fbea94b2 test: prva grupa testova (kripto, model, RBAC, helperi, TOTP repo)
Dodati testovi pored koda:
- internal/model: CenaBezPdv/PdvIznos, Klijent.PunoIme, PreostaloZaNaplatu
- internal/middleware: ImaDozvolu matrica po ulogama + SveDozvole
- internal/handler: izvuciIP, parseOpcionuCenu, validnoImeBackupa (anti path-traversal)
- internal/db/sqlite: integracioni nad privremenom SQLite bazom + prave migracije
(TOTP šifrovan u mirovanju, brisanje, ZasifrujPostojeceTotp + idempotentnost)
19 test funkcija, prolaze i sa -race. Dopunjava kripto_test.go iz ranije.
2026-06-12 22:07:32 +02:00
Dasko c8eb8de651 fix(backup): pozadinske gorutine koriste svežu konekciju posle obnove
Auto-backup i čišćenje sesija/pokušaja su koristili originalni db handle iz
main.go, koji posle obnove backupa (VratiBackup) ostaje zatvoren — gorutine bi
prestale da rade do restarta. Sada rade preko novog helpera h.SaBazom, koji pod
deljenim zaključavanjem prosleđuje trenutnu h.DB, pa vide zamenjenu konekciju.
Gorutine su premeštene da startuju posle kreiranja h. time.Sleep je van
zaključavanja da ne odlaže obnovu.
2026-06-12 21:56:17 +02:00
Dasko daf62f7de7 fix(backup): bezbedna zamena baze pri obnovi (sync.RWMutex + drain)
Obnova backupa (VratiBackup) je menjala Handler.DB i repozitorijume bez
zaključavanja dok drugi zahtevi rade — data race i moguć upit nad zatvorenom
konekcijom. Uveden Handler.mu (sync.RWMutex): zahtevi drže deljeno zaključavanje
preko middleware-a ZakljucajCitanje, a sama zamena (close+copy+reopen+reinit)
uzima ekskluzivno zaključavanje u zasebnoj gorutini, pa sačeka da svi tekući
zahtevi završe (drain) pre zamene. Zasebna gorutina je nužna jer zahtev još
drži deljeno zaključavanje (inače deadlock).
Poznato ograničenje: pozadinske gorutine i dalje koriste stari db handle iz
main.go — zaseban slučaj za kasnije.
2026-06-12 19:43:40 +02:00