ProofedMesh/services/attest-reconciler/internal/store/store.go

41 lines
1.7 KiB
Go
Raw Normal View History

// Package store contains the pending-rows reader. The reconciler never writes
// to per_diem_rates directly; it hands the attestation ref back through
// AttachAttestation, which goes through the same immutability-safe update
// path admin-api uses.
package store
import (
"context"
"errors"
"basicstack.de/proofedmesh/services/attest-reconciler/internal/attest"
)
// ErrNotFound is returned by AttachAttestation when the rate_id is gone.
var ErrNotFound = errors.New("per_diem_rate: not found")
// PendingRateStore is implemented by the Postgres reader in prod and by a
// fake in tests. ListPending returns every row where
// rate_change_attestation_ref IS NULL — these are what the reconciler re-signs.
//
// Kind is reconstructed from (valid_to, now): a rate with a valid_to that was
// present at creation time is a "create" (valid_to-at-creation stays with the
// row), a rate whose valid_to was set later via Retire is a "retire". Because
// the Transparency Log is idempotent on (envelope, content_hash), a wrong
// Kind guess cannot produce a duplicate log entry — it would just land under
// a different content_hash the first time and converge from then on.
type PendingRateStore interface {
ListPending(ctx context.Context, limit int) ([]PendingRow, error)
AttachAttestation(ctx context.Context, rateID string, attestationRef string) error
}
// PendingRow is the minimal projection of per_diem_rates needed to rebuild a
// RateChangeEvent. The reconciler intentionally does NOT read the admin
// principal fields — it attests under its own service identity (see
// PerformedBy in the main command) because the original admin session is long
// gone by the time a row is picked up.
type PendingRow struct {
Rate attest.Rate
Kind attest.ChangeKind
}