Documentation
¶
Overview ¶
Package auditstore owns the heterogeneous audit persistence boundary. Public consumers read typed audit records; this infrastructure model is not a DTO.
Index ¶
- Variables
- func Activities(q orm.Query[Entry]) rows.Query[Entry, Activity]
- func CountBefore(ctx context.Context, executor database.Executor, area string, ...) (int64, error)
- func Page(ctx context.Context, executor database.Executor, q orm.Query[Entry], ...) (orm.PageResult[Entry], error)
- func Prune(ctx context.Context, tx *database.Tx, area string, cutoff temporal.DateTime, ...) (int64, error)
- type Activity
- type Entry
- type EntryTable
Constants ¶
This section is empty.
Variables ¶
var Entries = orm.Define("foundry_audit", func(b orm.Builder[Entry], m *Entry) EntryTable { table := orm.TableOf(b, &m.ID) return EntryTable{Table: table, ID: table.Key(), Sequence: orm.NumberOf(b, &m.Sequence), Area: orm.TextOf(b, &m.Area), Operation: orm.ColumnOf(b, &m.Operation), Action: orm.TextOf(b, &m.Action), Version: orm.NumberOf(b, &m.Version), Subject: orm.NullableJSONOf(b, &m.Subject), SubjectKey: orm.NullableTextOf(b, &m.SubjectKey), Payload: orm.JSONOf(b, &m.Payload), Redacted: orm.ColumnOf(b, &m.Redacted), Redaction: orm.NumberOf(b, &m.Redaction), Origin: orm.JSONOf(b, &m.Origin), ActorKey: orm.NullableTextOf(b, &m.ActorKey), Correlation: orm.NullableTextOf(b, &m.Correlation), RequestMethod: orm.TextOf(b, &m.RequestMethod), RequestRoute: orm.TextOf(b, &m.RequestRoute), CreatedAt: orm.TimeOf(b, &m.CreatedAt)} })
Entries owns the immutable Entry declaration. Example: orm.First(ctx, tx, Entries.Query()).
Functions ¶
func Activities ¶
Activities selects only the declared Activity fields. Example: Activities(Entries.Query()).All(ctx,tx).
func CountBefore ¶
func CountBefore(ctx context.Context, executor database.Executor, area string, cutoff temporal.DateTime) (int64, error)
CountBefore counts the entries Prune would remove for area and cutoff without reading payloads. It uses the same predicate as Prune.
func Page ¶
func Page(ctx context.Context, executor database.Executor, q orm.Query[Entry], request orm.PageRequest) (orm.PageResult[Entry], error)
Page retains the ordinary query layer's count/snapshot and row-limit contract. Rows are newest first by database insertion sequence, so writes made in one transaction keep their actual order despite sharing a transaction timestamp.
func Prune ¶
func Prune(ctx context.Context, tx *database.Tx, area string, cutoff temporal.DateTime, limit int) (int64, error)
Prune selects a bounded oldest window and removes only that window through the existing typed set-based write compiler. No payloads are hydrated and no per-model observers run. A concurrent pruner may remove fewer rows.
Types ¶
type Activity ¶
type Activity struct {
ID model.ID[Entry]
Sequence int64
Area string
Operation lifecycle.Operation
Action string
Version uint32
Subject value.Nullable[value.JSON[model.Identity]]
Origin value.JSON[attribution.Origin]
Correlation value.Nullable[string]
RequestMethod string
RequestRoute string
CreatedAt temporal.DateTime
}
Activity is the payload-free projection used by heterogeneous timelines.
type Entry ¶
type Entry struct {
ID model.ID[Entry]
Sequence int64 `foundry:"default=database"`
Area string
Operation lifecycle.Operation
Action string
Version uint32
Subject value.Nullable[value.JSON[model.Identity]]
SubjectKey value.Nullable[string] `foundry:"default=database"`
Payload value.JSON[json.RawMessage]
Redacted bool
Redaction uint8
Origin value.JSON[attribution.Origin]
ActorKey value.Nullable[string] `foundry:"default=database"`
Correlation value.Nullable[string]
RequestMethod string
RequestRoute string
CreatedAt temporal.DateTime `foundry:"default=database"`
}
Entry stores either a model operation or a versioned domain action. Model capture owns field redaction; domain capture owns its document redaction flag. Redaction records the sensitive-name policy that wrote the row. Sequence is the database-assigned insertion order. SubjectKey and ActorKey are generated lookup keys derived from Subject and Origin; they are never written directly. Registration never installs audit observers for this private storage model.
func Append ¶
Append requires already validated, captured input. Normal declaration writes retain savepoint behavior and never commit the supplied outer transaction.
type EntryTable ¶
type EntryTable struct {
// Table provides model queries and writes. Example: orm.First(ctx, tx, Entries.Query()).
orm.Table[Entry, model.ID[Entry]]
// ID binds Entry.ID.
// Example: orm.KeySet(Entries.ID, id).
ID orm.Key[Entry, model.ID[Entry]]
// Sequence binds Entry.Sequence. Omission retains the database default.
// Example: orm.NumberSet(Entries.Sequence, sequence).
Sequence orm.Number[Entry, int64]
// Area binds Entry.Area.
// Example: orm.TextSet(Entries.Area, area).
Area orm.Text[Entry, string]
// Operation binds Entry.Operation.
// Example: orm.ColumnSet(Entries.Operation, operation).
Operation orm.Column[Entry, lifecycle.Operation]
// Action binds Entry.Action.
// Example: orm.TextSet(Entries.Action, action).
Action orm.Text[Entry, string]
// Version binds Entry.Version.
// Example: orm.NumberSet(Entries.Version, version).
Version orm.Number[Entry, uint32]
// Subject binds Entry.Subject.
// Example: orm.NullableJSONSetNull(Entries.Subject).
Subject orm.NullableJSON[Entry, model.Identity]
// SubjectKey binds Entry.SubjectKey. Omission retains the database default.
// Example: orm.NullableTextSetNull(Entries.SubjectKey).
SubjectKey orm.NullableText[Entry, string]
// Payload binds Entry.Payload.
// Example: encoded, err := value.NewJSON(payload); if err == nil { _ = orm.JSONSet(Entries.Payload, encoded) }.
Payload orm.JSON[Entry, json.RawMessage]
// Redacted binds Entry.Redacted.
// Example: orm.ColumnSet(Entries.Redacted, redacted).
Redacted orm.Column[Entry, bool]
// Redaction binds Entry.Redaction.
// Example: orm.NumberSet(Entries.Redaction, redaction).
Redaction orm.Number[Entry, uint8]
// Origin binds Entry.Origin.
// Example: encoded, err := value.NewJSON(origin); if err == nil { _ = orm.JSONSet(Entries.Origin, encoded) }.
Origin orm.JSON[Entry, attribution.Origin]
// ActorKey binds Entry.ActorKey. Omission retains the database default.
// Example: orm.NullableTextSetNull(Entries.ActorKey).
ActorKey orm.NullableText[Entry, string]
// Correlation binds Entry.Correlation.
// Example: orm.NullableTextSetNull(Entries.Correlation).
Correlation orm.NullableText[Entry, string]
// RequestMethod binds Entry.RequestMethod.
// Example: orm.TextSet(Entries.RequestMethod, requestMethod).
RequestMethod orm.Text[Entry, string]
// RequestRoute binds Entry.RequestRoute.
// Example: orm.TextSet(Entries.RequestRoute, requestRoute).
RequestRoute orm.Text[Entry, string]
// CreatedAt preserves an explicit creation time; omitted values use the database default.
// Example: orm.TimeSet(Entries.CreatedAt, createdAt).
CreatedAt orm.Time[Entry, temporal.DateTime]
}
EntryTable binds the persisted Entry columns. Example: Entries.Query().Limit(10).