Files

57 lines
1.8 KiB
Go

package audit
import (
"context"
"encoding/json"
"fmt"
"github.com/jackc/pgx/v5/pgxpool"
)
type Entry struct {
ID int64 `json:"id"`
OccurredAt string `json:"occurred_at"`
ActorUserID *string `json:"actor_user_id,omitempty"`
Action string `json:"action"`
TargetType string `json:"target_type"`
TargetID *string `json:"target_id,omitempty"`
Outcome string `json:"outcome"`
Details map[string]any `json:"details"`
}
type Store struct{ DB *pgxpool.Pool }
func (s Store) Record(ctx context.Context, actorUserID *string, action, targetType string, targetID *string, outcome string, details map[string]any) error {
data, err := json.Marshal(details)
if err != nil {
return fmt.Errorf("encode audit details: %w", err)
}
_, err = s.DB.Exec(ctx, `INSERT INTO bell_audit_log(actor_user_id,action,target_type,target_id,outcome,details) VALUES($1,$2,$3,$4,$5,$6)`, actorUserID, action, targetType, targetID, outcome, data)
if err != nil {
return fmt.Errorf("append audit entry: %w", err)
}
return nil
}
func (s Store) List(ctx context.Context, limit int) ([]Entry, error) {
if limit < 1 || limit > 200 {
limit = 50
}
rows, err := s.DB.Query(ctx, `SELECT id,occurred_at::text,actor_user_id::text,action,target_type,target_id,outcome,details FROM bell_audit_log ORDER BY id DESC LIMIT $1`, limit)
if err != nil {
return nil, err
}
defer rows.Close()
entries := make([]Entry, 0, limit)
for rows.Next() {
var e Entry
var data []byte
if err := rows.Scan(&e.ID, &e.OccurredAt, &e.ActorUserID, &e.Action, &e.TargetType, &e.TargetID, &e.Outcome, &data); err != nil {
return nil, err
}
_ = json.Unmarshal(data, &e.Details)
entries = append(entries, e)
}
return entries, rows.Err()
}