Files
bot_ticket_r6_elite/internal/db/audit_log.go
T
2026-05-10 18:07:51 +02:00

115 lines
3.0 KiB
Go

package db
import (
"context"
"database/sql"
"time"
)
type AuditLogEntry struct {
ID int64
AdminID int64
Action string
EntityType string
EntityID sql.NullInt64
OldValue sql.NullString
NewValue sql.NullString
IPAddress string
CreatedAt time.Time
}
// Audit action constants
const (
AuditCreatePanel = "create_panel"
AuditUpdatePanel = "update_panel"
AuditDeletePanel = "delete_panel"
AuditCreateType = "create_type"
AuditUpdateType = "update_type"
AuditDeleteType = "delete_type"
AuditReorderTypes = "reorder_types"
AuditUpdateConvoc = "update_convocation"
AuditSendPanelDiscord = "send_panel_discord"
AuditDeletePanelMsg = "delete_panel_discord"
AuditRevokeSession = "revoke_session"
AuditRevokeAllSess = "revoke_all_sessions"
AuditAdminLogin = "admin_login"
AuditAdminLoginFail = "admin_login_failed"
AuditAdminLocked = "admin_locked"
)
type AuditFilter struct {
AdminID int64
Action string
EntityType string
From, To time.Time
}
type AuditLogRepo struct{ db *sql.DB }
func NewAuditLogRepo(db *sql.DB) *AuditLogRepo { return &AuditLogRepo{db: db} }
func (r *AuditLogRepo) Insert(ctx context.Context, e *AuditLogEntry) error {
e.CreatedAt = time.Now().UTC()
_, err := r.db.ExecContext(ctx,
`INSERT INTO audit_log(admin_id,action,entity_type,entity_id,old_value,new_value,ip_address,created_at)
VALUES(?,?,?,?,?,?,?,?)`,
e.AdminID, e.Action, e.EntityType, e.EntityID, e.OldValue, e.NewValue, e.IPAddress, e.CreatedAt)
return err
}
func (r *AuditLogRepo) List(ctx context.Context, f AuditFilter, page, pageSize int) ([]*AuditLogEntry, int, error) {
where := "WHERE 1=1"
args := []any{}
if f.AdminID != 0 {
where += " AND admin_id=?"
args = append(args, f.AdminID)
}
if f.Action != "" {
where += " AND action=?"
args = append(args, f.Action)
}
if f.EntityType != "" {
where += " AND entity_type=?"
args = append(args, f.EntityType)
}
if !f.From.IsZero() {
where += " AND created_at>=?"
args = append(args, f.From)
}
if !f.To.IsZero() {
where += " AND created_at<=?"
args = append(args, f.To)
}
var total int
countArgs := make([]any, len(args))
copy(countArgs, args)
if err := r.db.QueryRowContext(ctx, `SELECT COUNT(*) FROM audit_log `+where, countArgs...).Scan(&total); err != nil {
return nil, 0, err
}
if page < 1 {
page = 1
}
offset := (page - 1) * pageSize
args = append(args, pageSize, offset)
rows, err := r.db.QueryContext(ctx,
`SELECT id,admin_id,action,entity_type,entity_id,old_value,new_value,ip_address,created_at
FROM audit_log `+where+` ORDER BY created_at DESC LIMIT ? OFFSET ?`, args...)
if err != nil {
return nil, 0, err
}
defer rows.Close()
var out []*AuditLogEntry
for rows.Next() {
var e AuditLogEntry
if err := rows.Scan(&e.ID, &e.AdminID, &e.Action, &e.EntityType, &e.EntityID,
&e.OldValue, &e.NewValue, &e.IPAddress, &e.CreatedAt); err != nil {
return nil, 0, err
}
out = append(out, &e)
}
return out, total, rows.Err()
}