licence-server/internal/repository/audit_repo.go
Nenad Djukic 1abe7176ec Preimenovanje: dal-license-server -> licence-server (+ debrendiranje)
Vlasnik izlazi iz DAL price za ovaj projekat - postaje samostalan proizvod.
Preimenovanje je mehanicko (import putanje, imena fajlova/baze/UI naslova),
NIJEDNA linija poslovne logike u internal/handler ili internal/service nije
dirana - go build, go vet i go test ./... prolaze cisto pod novim imenom.

- go.mod: module dal-license-server -> licence-server; 28 import linija u
  13 .go fajlova usaglaseno
- internal/config/config.go (+test): default DB_NAME licence_db
- HTML sabloni (7 stranica) + 7 Playwright e2e spec fajlova: "DAL License
  Server" -> "Licence Server" u title/nav-brand, testovi usaglaseni u istom
  prolazu (nista ne moze da se razdvoji)
- package.json/package-lock.json/.gitignore/.claude/project.json: ime
  projekta/binarnog fajla/work_dir
- Usput: package.json je u repository.url nosio OTVORENU Gitea lozinku u
  cistom tekstu - uklonjena (URL sad bez kredencijala). Lozinka je i dalje
  u staroj git istoriji - preporuka: rotirati je posebno.
- CLAUDE.md/README/API/TESTING/docs/SPEC/ARCHITECTURE/SETUP: naslovi, ASCII
  dijagrami, git clone URL, mysqldump primer, systemd predlozak u SETUP.md
  zamenjen stvarnim (obrazac terminia.service - journal log + graceful
  shutdown, ne stari minimalni predlozak)
- Debrendiranje: "Univerzalni licencni server za sve DAL proizvode" ->
  "za vise proizvoda i klijenata"; potpis "Nenad Djukic / DAL d.o.o." ->
  "Nenad Djukic". NE dirano: nazivi ESIR/ARV/LIGHT_TICKET (tudji proizvodi,
  ne DAL brend), "DAL" kao stvaran naziv org-a u RBAC modelu
  (docs/loggerservice/README.md) - to je podatak, ne branding ovog servera.
- docs/asp-terminia/, docs/loggerservice/: prozni pomeni imena servera

Baza (dal_license_db -> licence_db) i deploy na 151 idu u posebnom koraku,
posle preimenovanja Gitea repoa - vidi CLAUDE.md istorijsku belesku na dnu.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 07:55:26 +02:00

67 lines
1.6 KiB
Go

package repository
import (
"licence-server/internal/model"
"database/sql"
"encoding/json"
"fmt"
)
type AuditRepo struct {
db *sql.DB
}
func NewAuditRepo(db *sql.DB) *AuditRepo {
return &AuditRepo{db: db}
}
func (r *AuditRepo) Log(licenseID *int64, action, ip string, details interface{}) error {
detailsJSON, _ := json.Marshal(details)
var lid sql.NullInt64
if licenseID != nil {
lid = sql.NullInt64{Int64: *licenseID, Valid: true}
}
_, err := r.db.Exec("INSERT INTO audit_log (license_id, action, ip_address, details) VALUES (?, ?, ?, ?)",
lid, action, ip, string(detailsJSON))
if err != nil {
return fmt.Errorf("audit log: %w", err)
}
return nil
}
func (r *AuditRepo) List(licenseID *int64, limit int) ([]model.AuditEntry, error) {
query := `SELECT a.id, a.license_id, a.action, a.ip_address, a.details, a.created_at,
COALESCE(l.license_key, '') as license_key
FROM audit_log a LEFT JOIN licenses l ON a.license_id = l.id`
var args []interface{}
if licenseID != nil {
query += " WHERE a.license_id = ?"
args = append(args, *licenseID)
}
query += " ORDER BY a.created_at DESC LIMIT ?"
args = append(args, limit)
rows, err := r.db.Query(query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
var entries []model.AuditEntry
for rows.Next() {
var e model.AuditEntry
var details sql.NullString
rows.Scan(&e.ID, &e.LicenseID, &e.Action, &e.IPAddress, &details, &e.CreatedAt, &e.LicenseKey)
if details.Valid {
e.Details = json.RawMessage(details.String)
}
entries = append(entries, e)
}
return entries, nil
}
func (r *AuditRepo) Recent(limit int) ([]model.AuditEntry, error) {
return r.List(nil, limit)
}