Page:
Arhitektura
Clone
1
Arhitektura
Dasko edited this page 2026-06-21 02:16:00 +02:00
Arhitektura
Struktura direktorijuma
ntech/
├── assets.go # //go:embed za migrations, web/static, web/templates
├── cmd/ntech/main.go # ulazna tačka: ENV, FS izbor, migracije, ruter
├── go.mod # modul ntech, Go 1.26
├── internal/
│ ├── auth/ # bcrypt, TOTP, generisanje tokena, auth log
│ │ ├── auth.go # HashujLozinku, ProveriLozinku, TOTP operacije
│ │ └── log.go # fail2ban-kompatibilan format loga
│ ├── config/ # Prvo pokretanje (setup wizard)
│ │ ├── firstrun.go # JelPrvoPokretanje
│ │ └── setup.go # PokreniSetup (poseban HTTP server)
│ ├── db/
│ │ ├── repository.go # SVI interfejsi (ArtikalRepo, ServisRepo, ...)
│ │ ├── errors.go # ErrNedovoljnoKolicine
│ │ └── sqlite/ # SQLite implementacije (28 fajlova)
│ ├── handler/ # HTTP handleri — jedan fajl po domenu (26)
│ ├── middleware/ # Auth, CSRF, RBAC, bezbednost, flash
│ └── model/ # Domenske strukture i konstante (19 fajlova)
├── migrations/ # 61 SQL migracija (001-061), idempotentne
└── web/
├── static/ # CSS, JS, slike + uploads/
└── templates/ # Go html/template šabloni (komponente, stranice)
Slojevi i zavisnosti
main.go
└─> handler/ → zna za: middleware, db (interfejsi), db/sqlite, model, auth
└─> middleware/ → zna za: db/sqlite, model
└─> db (interfejsi) → implementira: db/sqlite/
└─> model/ → ne zna ni za koga — čist domen, nula internih importa
└─> auth/ → samostalan, ne zavisi od handler/db
Pravilo: model je list (nema unutrašnje zavisnosti). handler je koren — svi putevi vode kroz njega. Nijedan drugi sloj ne sme da uvozi handler.
Tok pokretanja programa
- MIME tipovi —
.js→text/javascript,.css→text/css godotenv.Load(ntech.env)— učitava ENV iz fajlaauth.InitAuthLog()— auth log u fail2ban formatu- Izbor fajl-sistema — disk-first za razvoj, embed za produkciju/demo
- Prvo pokretanje? → Setup Wizard na portu 8080
- Baza + migracije —
sql.Open("sqlite", ...), WAL mod, migracije redom - Init seme — dozvole, TOTP ključ, bcrypt dummy hash, admin korisnik
- Chi ruter — middleware stack, rute sa RBAC omotačima
http.ListenAndServe— server kreće
Middleware stack
Redosled na chi ruteru:
1. middleware.RequestID # ID svakog zahteva
2. middleware.RealIP # Prava IP iz X-Forwarded-For
3. middleware.Logger # Slog logovanje
4. middleware.Recoverer # panic → 500
5. middleware.Compress(5, gzip) # GZip kompresija (nivo 5)
6. BezbednosniHeaderi # CSP, HSTS, X-Frame-Options, ...
7. CSRF # Double-submit cookie obrazac
8. FlashPoruke # Flash poruke u template kontekstu
--- (javne rute) ---
9. RequireAuth # Sesija → korisnik u context
10. RequireDozvola / RequireDozvolaMut # RBAC (zaštićene rute)
Repository obrazac
Handleri ne pišu SQL. Sva komunikacija sa bazom ide preko interfejsa definisanih u internal/db/repository.go.
Primer interfejsa:
// internal/db/repository.go
type ArtikalRepository interface {
Lista(ctx context.Context, filter ArtikalFilter) ([]model.ArtikalSaKategorijom, error)
DohvatiID(ctx context.Context, id int64) (*model.Artikal, error)
Kreiraj(ctx context.Context, a *model.Artikal) (int64, error)
Izmeni(ctx context.Context, a *model.Artikal) error
Obrisi(ctx context.Context, id int64) error
// ...
}
Implementacija:
// internal/db/sqlite/artikal.go
type ArtikalRepo struct { db *sql.DB }
func NoviArtikalRepo(db *sql.DB) *ArtikalRepo { ... }
func (r *ArtikalRepo) Lista(ctx context.Context, f db.ArtikalFilter) ([]model.ArtikalSaKategorijom, error) {
// SELECT ... FROM artikli JOIN kategorije ...
}
Handler koristi interfejs:
// internal/handler/magacin.go
type MagacinHandler struct {
Artikli db.ArtikalRepository
Kategorije db.KategorijaRepository
}
Ovakav dizajn omogućava:
- Testiranje — mock-ovanje repozitorijuma
- Zamenu baze — iste interfejse može implementirati PostgreSQL drajver
- Jasne granice — handler ne zavisi od SQL dijalekta
Repozitorijumi (interfejsi)
| Interfejs | Domen |
|---|---|
ArtikalRepository |
Artikli, kategorije, cene, dobavljači, arhiviranje |
KategorijaRepository |
Kategorije artikala |
PdvStopaRepository |
Šifarnik PDV stopa |
DobavljacRepository |
Dobavljači |
KlijentRepository |
Klijenti (firme i fizička lica) |
ServisRepository |
Servisni nalozi, delovi, javni token |
ProdajaRepository |
Prodajni nalozi i stavke |
NabavkaRepository |
Nabavke, zavisni troškovi, nivelacije |
MagacinRepository |
Stanje zaliha, prometne kartice |
KorisniciRepository |
Korisnici i dozvole |
SesijeRepository |
Server-side sesije |
LoginIstorijaRepository |
Istorija prijava |
PokusajiPrijaveRepository |
Brute-force evidencija |
PodesavanjaRepository |
Sva sistemska podešavanja |
PodsetniciRepository |
Podsetnici |
PdvEvidencijaRepository |
PDV KIR/KPR evidencija |
IzvestajRepository |
Izveštajni upiti |
RezervniKodoviRepository |
Rezervni kodovi za 2FA |
Handleri
Svaki handler je jedan Go fajl u internal/handler/:
| Fajl | Domen |
|---|---|
admin.go |
Admin panel: korisnici, dozvole |
dashboard.go |
Početna tabla sa statistikama |
dobavljac.go |
CRUD dobavljača |
izvestaji.go |
Izveštaji (promet, stanje, inventura, prihod) |
kategorija.go |
CRUD kategorija |
klijent.go |
CRUD klijenata, filteri |
magacin.go |
Magacin — pregled, pretraga, korekcija |
magacin_forma.go |
Forma za artikal |
nabavka.go |
Nabavke, nivelacije |
pdv_kir.go |
PDV KIR (knjiga izdatih računa) |
pdv_kpr.go |
PDV KPR (knjiga primljenih računa) |
pdv_obracun.go |
PDV obračun |
pdv_stopa.go |
Šifarnik PDV stopa |
podesavanja.go |
Sistemska podešavanja |
podsetnici.go |
Podsetnici |
prijava.go |
Prijava, odjava, TOTP, 2FA |
prodaja.go |
Prodajni nalozi |
profil.go |
Profil korisnika (lozinka, TOTP) |
servis.go |
Servisni nalozi |
handler.go |
Render helperi, Render, RenderStranicu |
kes.go |
Keširanje šablona |
utils.go |
Pomoćne funkcije (parsiranje, prikaz) |
Frontend arhitektura
Frontend koristi tri biblioteke:
- HTMX — navigacija bez punog reload-a (
hx-get,hx-post,hx-target,hx-swap) - Alpine.js — reaktivnost na klijentu (
x-data,x-show,x-model,x-bind) - Chart.js — grafikoni (dashboard, izveštaji)
Stilovi su organizovani u web/static/:
main.css— glavni stil (≈4000 linija)glass.css— glassmorphism efektilogin.css— stilovi za prijavnu stranicu
Šabloni u web/templates/:
templates/
├── stranice/ # Kompletne stranice (dashboard.html, magacin.html, ...)
├── komponente/ # Deljive komponente (navbar.html, sidebar.html, modal.html)
├── teme/ # Varijacije tema
├── setup/ # Setup wizard
└── layout/ # Osnovni layout (base.html)
HTMX pravila
hx-selectodbacuje<head>— stil koji mora da radi posle navigacije ide umain.csshx-targetsa#sadrzaj— glavni kontejner za dinamički sadržajhx-push-url— ažurira URL u adresnoj tracihx-indicator— prikazuje loader tokom zahteva