dal-license-server/cmd/server/main.go
djuka dc0114e4b7 Inicijalni commit: kompletna implementacija + dokumentacija + testovi
- Kompletna Go implementacija licencnog servera (19 Go fajlova)
- Klijentski API: activate, deactivate, validate
- Admin API: CRUD licence, stats, audit log
- Admin dashboard: htmx + Go templates
- RSA-2048 potpisivanje licencnih podataka
- Rate limiting i API key autentifikacija
- MySQL migracije i seed podaci (ESIR, ARV, LIGHT_TICKET)
- Unit testovi: keygen, crypto, model, middleware (24 testa)
- Dokumentacija: SPEC.md, ARCHITECTURE.md, SETUP.md, API.md, TESTING.md, README.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 07:42:25 +00:00

90 lines
2.2 KiB
Go

package main
import (
"dal-license-server/internal/config"
"dal-license-server/internal/handler"
"dal-license-server/internal/repository"
"dal-license-server/internal/router"
"dal-license-server/internal/service"
"database/sql"
"fmt"
"log"
"net/http"
"os"
"strconv"
_ "github.com/go-sql-driver/mysql"
)
func main() {
cfg := config.Load()
// Connect to MySQL
db, err := sql.Open("mysql", cfg.DSN())
if err != nil {
log.Fatal("DB open: ", err)
}
defer db.Close()
if err := db.Ping(); err != nil {
log.Fatal("DB ping: ", err)
}
// Run migrations
runMigrations(db)
// Crypto service
cryptoSvc, err := service.NewCryptoService(cfg.RSAPrivateKey)
if err != nil {
log.Fatal("Crypto: ", err)
}
// Repositories
licenseRepo := repository.NewLicenseRepo(db)
activationRepo := repository.NewActivationRepo(db)
auditRepo := repository.NewAuditRepo(db)
// Services
licenseSvc := service.NewLicenseService(licenseRepo, auditRepo)
activationSvc := service.NewActivationService(activationRepo, licenseRepo, auditRepo, cryptoSvc, licenseSvc)
// Handlers
clientHandler := handler.NewClientHandler(activationSvc)
adminHandler := handler.NewAdminHandler(licenseSvc, activationSvc, auditRepo)
dashboardHandler := handler.NewDashboardHandler(licenseSvc, activationSvc, auditRepo, "templates", cfg.AdminPassword)
// Rate limits
rlActivate, _ := strconv.Atoi(cfg.RateLimitActivate)
if rlActivate == 0 {
rlActivate = 10
}
rlValidate, _ := strconv.Atoi(cfg.RateLimitValidate)
if rlValidate == 0 {
rlValidate = 60
}
// Router
mux := router.Setup(clientHandler, adminHandler, dashboardHandler, cfg.AdminAPIKey, rlActivate, rlValidate)
addr := ":" + cfg.Port
fmt.Printf("DAL License Server pokrenut na http://localhost%s\n", addr)
if err := http.ListenAndServe(addr, mux); err != nil {
log.Fatal(err)
}
}
func runMigrations(db *sql.DB) {
files := []string{"migrations/001_create_tables.sql", "migrations/002_seed_products.sql"}
for _, f := range files {
data, err := os.ReadFile(f)
if err != nil {
log.Printf("Migration %s: %v", f, err)
continue
}
_, err = db.Exec(string(data))
if err != nil {
log.Printf("Migration %s: %v (may already exist)", f, err)
}
}
}