dal-license-server/internal/repository/audit_repo.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

67 lines
1.6 KiB
Go

package repository
import (
"dal-license-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)
}