phase 2 (part 2): sqlc queries, audit/event helpers, event NOTIFY trigger
- sqlc.yaml + internal/db/queries/*.sql: typed queries for entities, relationships, ontology, operations (signals, events, audit, idempotency, entity_status) - internal/db/sqlcgen/: generated Go from sqlc (pgx/v5) - internal/observability/record.go: Audit() and Event() helpers that write in the caller's transaction (SG10). actorLabel is interim text identity in detail JSON until OIDC resolution lands; actor_id column exists but is not yet populated - migrations/008: post-commit pg_notify trigger on events table for SSE fan-out (SG8/SG10)
This commit is contained in:
357
internal/db/sqlcgen/operations.sql.go
Normal file
357
internal/db/sqlcgen/operations.sql.go
Normal file
@@ -0,0 +1,357 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: operations.sql
|
||||
|
||||
package sqlcgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const getIdempotentResponse = `-- name: GetIdempotentResponse :one
|
||||
SELECT response_code, response_body, request_hash FROM idempotency_keys
|
||||
WHERE actor = $1 AND key = $2
|
||||
`
|
||||
|
||||
type GetIdempotentResponseParams struct {
|
||||
Actor string
|
||||
Key string
|
||||
}
|
||||
|
||||
type GetIdempotentResponseRow struct {
|
||||
ResponseCode *int32
|
||||
ResponseBody []byte
|
||||
RequestHash string
|
||||
}
|
||||
|
||||
func (q *Queries) GetIdempotentResponse(ctx context.Context, arg GetIdempotentResponseParams) (GetIdempotentResponseRow, error) {
|
||||
row := q.db.QueryRow(ctx, getIdempotentResponse, arg.Actor, arg.Key)
|
||||
var i GetIdempotentResponseRow
|
||||
err := row.Scan(&i.ResponseCode, &i.ResponseBody, &i.RequestHash)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertAuditEntry = `-- name: InsertAuditEntry :exec
|
||||
INSERT INTO audit_log (actor_type, actor_id, action, entity_id, method, path,
|
||||
status_code, detail, source_ip, correlation_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||
`
|
||||
|
||||
type InsertAuditEntryParams struct {
|
||||
ActorType string
|
||||
ActorID *uuid.UUID
|
||||
Action string
|
||||
EntityID *uuid.UUID
|
||||
Method *string
|
||||
Path *string
|
||||
StatusCode *int32
|
||||
Detail []byte
|
||||
SourceIp *string
|
||||
CorrelationID *string
|
||||
}
|
||||
|
||||
func (q *Queries) InsertAuditEntry(ctx context.Context, arg InsertAuditEntryParams) error {
|
||||
_, err := q.db.Exec(ctx, insertAuditEntry,
|
||||
arg.ActorType,
|
||||
arg.ActorID,
|
||||
arg.Action,
|
||||
arg.EntityID,
|
||||
arg.Method,
|
||||
arg.Path,
|
||||
arg.StatusCode,
|
||||
arg.Detail,
|
||||
arg.SourceIp,
|
||||
arg.CorrelationID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const insertEvent = `-- name: InsertEvent :one
|
||||
INSERT INTO events (type, entity_id, severity, source, data, correlation_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
RETURNING id, ts
|
||||
`
|
||||
|
||||
type InsertEventParams struct {
|
||||
Type string
|
||||
EntityID *uuid.UUID
|
||||
Severity string
|
||||
Source string
|
||||
Data []byte
|
||||
CorrelationID *string
|
||||
}
|
||||
|
||||
type InsertEventRow struct {
|
||||
ID int64
|
||||
Ts time.Time
|
||||
}
|
||||
|
||||
func (q *Queries) InsertEvent(ctx context.Context, arg InsertEventParams) (InsertEventRow, error) {
|
||||
row := q.db.QueryRow(ctx, insertEvent,
|
||||
arg.Type,
|
||||
arg.EntityID,
|
||||
arg.Severity,
|
||||
arg.Source,
|
||||
arg.Data,
|
||||
arg.CorrelationID,
|
||||
)
|
||||
var i InsertEventRow
|
||||
err := row.Scan(&i.ID, &i.Ts)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listEntityStatus = `-- name: ListEntityStatus :many
|
||||
SELECT e.slug, e.type, st.health, st.last_check_at
|
||||
FROM entity_status st JOIN entities e ON e.id = st.entity_id
|
||||
ORDER BY e.slug
|
||||
`
|
||||
|
||||
type ListEntityStatusRow struct {
|
||||
Slug string
|
||||
Type string
|
||||
Health string
|
||||
LastCheckAt *time.Time
|
||||
}
|
||||
|
||||
func (q *Queries) ListEntityStatus(ctx context.Context) ([]ListEntityStatusRow, error) {
|
||||
rows, err := q.db.Query(ctx, listEntityStatus)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ListEntityStatusRow
|
||||
for rows.Next() {
|
||||
var i ListEntityStatusRow
|
||||
if err := rows.Scan(
|
||||
&i.Slug,
|
||||
&i.Type,
|
||||
&i.Health,
|
||||
&i.LastCheckAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listEvents = `-- name: ListEvents :many
|
||||
SELECT id, ts, type, entity_id, severity, source, data, correlation_id
|
||||
FROM events
|
||||
WHERE ($1::text IS NULL OR type = $1)
|
||||
AND ($2::uuid IS NULL OR entity_id = $2)
|
||||
AND ($3::text IS NULL OR severity = $3)
|
||||
AND ($4::text IS NULL OR correlation_id = $4)
|
||||
AND ($5::timestamptz IS NULL OR ts >= $5)
|
||||
AND ($6::timestamptz IS NULL OR ts <= $6)
|
||||
AND ($7::bigint IS NULL OR id < $7)
|
||||
ORDER BY id DESC
|
||||
LIMIT $8
|
||||
`
|
||||
|
||||
type ListEventsParams struct {
|
||||
Type *string
|
||||
EntityID *uuid.UUID
|
||||
Severity *string
|
||||
CorrelationID *string
|
||||
FromTs *time.Time
|
||||
ToTs *time.Time
|
||||
BeforeID *int64
|
||||
Lim int32
|
||||
}
|
||||
|
||||
func (q *Queries) ListEvents(ctx context.Context, arg ListEventsParams) ([]Event, error) {
|
||||
rows, err := q.db.Query(ctx, listEvents,
|
||||
arg.Type,
|
||||
arg.EntityID,
|
||||
arg.Severity,
|
||||
arg.CorrelationID,
|
||||
arg.FromTs,
|
||||
arg.ToTs,
|
||||
arg.BeforeID,
|
||||
arg.Lim,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Event
|
||||
for rows.Next() {
|
||||
var i Event
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Ts,
|
||||
&i.Type,
|
||||
&i.EntityID,
|
||||
&i.Severity,
|
||||
&i.Source,
|
||||
&i.Data,
|
||||
&i.CorrelationID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listEventsAfter = `-- name: ListEventsAfter :many
|
||||
SELECT id, ts, type, entity_id, severity, source, data, correlation_id
|
||||
FROM events WHERE id > $1 ORDER BY id ASC LIMIT $2
|
||||
`
|
||||
|
||||
type ListEventsAfterParams struct {
|
||||
ID int64
|
||||
Limit int32
|
||||
}
|
||||
|
||||
func (q *Queries) ListEventsAfter(ctx context.Context, arg ListEventsAfterParams) ([]Event, error) {
|
||||
rows, err := q.db.Query(ctx, listEventsAfter, arg.ID, arg.Limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Event
|
||||
for rows.Next() {
|
||||
var i Event
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Ts,
|
||||
&i.Type,
|
||||
&i.EntityID,
|
||||
&i.Severity,
|
||||
&i.Source,
|
||||
&i.Data,
|
||||
&i.CorrelationID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listSignals = `-- name: ListSignals :many
|
||||
SELECT sig.entity_id, se.slug, sig.kind, sig.severity, sig.state,
|
||||
te.slug AS target_slug, sig.check_id, sig.evidence, sig.likely_cause,
|
||||
sig.occurrence_count, sig.flap_count, sig.hold_down_until,
|
||||
sig.mute_until, sig.first_seen_at, sig.last_seen_at
|
||||
FROM signals sig
|
||||
JOIN entities se ON se.id = sig.entity_id
|
||||
LEFT JOIN entities te ON te.id = sig.target_entity_id
|
||||
WHERE ($1::text IS NULL OR sig.state = $1)
|
||||
AND ($2::text IS NULL OR sig.severity = $2)
|
||||
AND ($3::text IS NULL OR te.slug = $3)
|
||||
AND ($4::text IS NULL OR sig.kind = $4)
|
||||
AND ($5::text IS NULL OR se.slug > $5)
|
||||
ORDER BY se.slug
|
||||
LIMIT $6
|
||||
`
|
||||
|
||||
type ListSignalsParams struct {
|
||||
State *string
|
||||
Severity *string
|
||||
Target *string
|
||||
Kind *string
|
||||
Cursor *string
|
||||
Lim int32
|
||||
}
|
||||
|
||||
type ListSignalsRow struct {
|
||||
EntityID uuid.UUID
|
||||
Slug string
|
||||
Kind string
|
||||
Severity string
|
||||
State string
|
||||
TargetSlug *string
|
||||
CheckID *uuid.UUID
|
||||
Evidence *string
|
||||
LikelyCause *string
|
||||
OccurrenceCount int32
|
||||
FlapCount int32
|
||||
HoldDownUntil *time.Time
|
||||
MuteUntil *time.Time
|
||||
FirstSeenAt time.Time
|
||||
LastSeenAt time.Time
|
||||
}
|
||||
|
||||
func (q *Queries) ListSignals(ctx context.Context, arg ListSignalsParams) ([]ListSignalsRow, error) {
|
||||
rows, err := q.db.Query(ctx, listSignals,
|
||||
arg.State,
|
||||
arg.Severity,
|
||||
arg.Target,
|
||||
arg.Kind,
|
||||
arg.Cursor,
|
||||
arg.Lim,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ListSignalsRow
|
||||
for rows.Next() {
|
||||
var i ListSignalsRow
|
||||
if err := rows.Scan(
|
||||
&i.EntityID,
|
||||
&i.Slug,
|
||||
&i.Kind,
|
||||
&i.Severity,
|
||||
&i.State,
|
||||
&i.TargetSlug,
|
||||
&i.CheckID,
|
||||
&i.Evidence,
|
||||
&i.LikelyCause,
|
||||
&i.OccurrenceCount,
|
||||
&i.FlapCount,
|
||||
&i.HoldDownUntil,
|
||||
&i.MuteUntil,
|
||||
&i.FirstSeenAt,
|
||||
&i.LastSeenAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const putIdempotentResponse = `-- name: PutIdempotentResponse :exec
|
||||
INSERT INTO idempotency_keys (actor, key, request_hash, response_code, response_body)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
ON CONFLICT (actor, key) DO NOTHING
|
||||
`
|
||||
|
||||
type PutIdempotentResponseParams struct {
|
||||
Actor string
|
||||
Key string
|
||||
RequestHash string
|
||||
ResponseCode *int32
|
||||
ResponseBody []byte
|
||||
}
|
||||
|
||||
func (q *Queries) PutIdempotentResponse(ctx context.Context, arg PutIdempotentResponseParams) error {
|
||||
_, err := q.db.Exec(ctx, putIdempotentResponse,
|
||||
arg.Actor,
|
||||
arg.Key,
|
||||
arg.RequestHash,
|
||||
arg.ResponseCode,
|
||||
arg.ResponseBody,
|
||||
)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user