package audit import ( "context" "encoding/json" "fmt" "github.com/jackc/pgx/v5" ) type Event struct { TenantID *string ActorType string ActorPublicID *string Action string ResourceType string ResourceID *string RequestID string Purpose string Result string Detail map[string]any } type Repository struct{} func NewRepository() *Repository { return &Repository{} } func (r *Repository) Record(ctx context.Context, tx pgx.Tx, event Event) error { detail := event.Detail if detail == nil { detail = map[string]any{} } detailJSON, err := json.Marshal(detail) if err != nil { return fmt.Errorf("encode audit detail: %w", err) } _, err = tx.Exec(ctx, ` INSERT INTO audit_event ( tenant_id, actor_type, actor_public_id, action, resource_type, resource_id, request_id, purpose, result, detail ) VALUES ( $1::uuid, $2, $3::uuid, $4, $5, $6::uuid, NULLIF($7, ''), NULLIF($8, ''), $9, $10::jsonb )`, event.TenantID, event.ActorType, event.ActorPublicID, event.Action, event.ResourceType, event.ResourceID, event.RequestID, event.Purpose, event.Result, detailJSON, ) if err != nil { return fmt.Errorf("insert audit event: %w", err) } return nil }