// Package store defines the persistence contract for approval_sessions, // approval_previews, and approvals. Phase 1 ships an in-memory impl; the // Postgres schema is in db/trust/migrations/0004_approval_sessions.*.sql // and wired via a skeleton Postgres type (see postgres.go) so the HTTP // layer stays unchanged when the real pgxpool wiring lands. package store import ( "context" "errors" "time" "basicstack.de/proofedmesh/services/approval-service/internal/signer" ) // ErrNotFound is returned by lookup methods when the row does not exist // or has expired. var ErrNotFound = errors.New("store: not found") // ErrAlreadyConsumed is returned by ConsumePreview when the preview has // already been consumed — the confirm endpoint MUST reject a replay. var ErrAlreadyConsumed = errors.New("store: preview already consumed") // Session is a per-browser-login approval session. active_until bounds // how long previews may be created against it. type Session struct { ID string UserSub string ActiveUntil time.Time CreatedAt time.Time } // Preview is a server-rendered approval payload that has not yet been // confirmed. ContentCanonical lets the confirm endpoint recompute // H_content deterministically from the stored row. type Preview struct { ID string SessionID string UserSub string ContentHash string ContentCanonical []byte Salt []byte Nonce []byte VerificationDigits string ExpiresAt time.Time CreatedAt time.Time ConsumedAt *time.Time } // TLogStatus is the three-valued state of the Transparency-Log submit. type TLogStatus string const ( TLogPending TLogStatus = "attestation-pending" TLogLogged TLogStatus = "logged" TLogFailed TLogStatus = "failed" ) // Approval is the confirmed, DSSE-signed approval record. If TLogStatus // is TLogPending/TLogFailed, log_index is nil and the attest-reconciler // (or a future worker) will replay the Transparency-Log submit against // the server's idempotent /api/v1/log/entries contract. type Approval struct { ID string PreviewID string SessionID string UserSub string ContentHash string Envelope signer.Envelope AttestationRef string TLogStatus TLogStatus LogIndex *int64 TLogError string ConfirmedAt time.Time LoggedAt *time.Time } // Store is the full persistence surface the HTTP service depends on. type Store interface { CreateSession(ctx context.Context, s Session) error GetSession(ctx context.Context, id string) (Session, error) SavePreview(ctx context.Context, p Preview) error GetPreview(ctx context.Context, id string) (Preview, error) ConsumePreview(ctx context.Context, id string, now time.Time) (Preview, error) SaveApproval(ctx context.Context, a Approval) error MarkApprovalLogged(ctx context.Context, id string, logIndex int64, loggedAt time.Time) error MarkApprovalTLogError(ctx context.Context, id string, errorMsg string) error }