53 lines
1.2 KiB
Go
53 lines
1.2 KiB
Go
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
|
||
|
|
}
|