gohorsejobs/backend/internal/services/audit_service.go
2025-12-22 16:37:05 -03:00

72 lines
1.5 KiB
Go

package services
import (
"context"
"database/sql"
"strings"
"github.com/rede5/gohorsejobs/backend/internal/models"
)
type AuditService struct {
DB *sql.DB
}
func NewAuditService(db *sql.DB) *AuditService {
return &AuditService{DB: db}
}
type LoginAuditInput struct {
UserID string
Identifier string
Roles []string
IPAddress *string
UserAgent *string
}
func (s *AuditService) RecordLogin(ctx context.Context, input LoginAuditInput) error {
roles := strings.Join(input.Roles, ",")
query := `
INSERT INTO login_audit (user_id, identifier, roles, ip_address, user_agent)
VALUES ($1, $2, $3, $4, $5)
`
_, err := s.DB.ExecContext(ctx, query, input.UserID, input.Identifier, roles, input.IPAddress, input.UserAgent)
return err
}
func (s *AuditService) ListLogins(ctx context.Context, limit int) ([]models.LoginAudit, error) {
if limit <= 0 {
limit = 50
}
query := `
SELECT id, user_id, identifier, roles, ip_address, user_agent, created_at
FROM login_audit
ORDER BY created_at DESC
LIMIT $1
`
rows, err := s.DB.QueryContext(ctx, query, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var audits []models.LoginAudit
for rows.Next() {
var entry models.LoginAudit
if err := rows.Scan(
&entry.ID,
&entry.UserID,
&entry.Identifier,
&entry.Roles,
&entry.IPAddress,
&entry.UserAgent,
&entry.CreatedAt,
); err != nil {
return nil, err
}
audits = append(audits, entry)
}
return audits, nil
}