pub struct SqlxKeepsakeRepository<B, C = NoopRelationCache>where
B: KeepsakeSqlxBackend,{ /* private fields */ }Expand description
SQLx-backed keepsake repository.
Implementations§
Source§impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
Sourcepub async fn append_audit_event(
&self,
event: &AuditEvent,
) -> RepositoryResult<i64>
pub async fn append_audit_event( &self, event: &AuditEvent, ) -> RepositoryResult<i64>
Appends an explicit audit event without mutating lifecycle state.
Prefer apply and revoke for lifecycle mutations so state and audit
rows commit together. This helper is for application-owned audit events
that do not have a built-in repository command.
Sourcepub async fn audit_events_for_keepsake(
&self,
keepsake_id: Uuid,
after: Option<&AuditCursor>,
limit: i64,
) -> RepositoryResult<Vec<AuditEventRecord>>
pub async fn audit_events_for_keepsake( &self, keepsake_id: Uuid, after: Option<&AuditCursor>, limit: i64, ) -> RepositoryResult<Vec<AuditEventRecord>>
Reads audit events for a keepsake in stable (occurred_at, id) order.
Sourcepub async fn audit_events_for_relation(
&self,
relation_id: RelationId,
after: Option<&AuditCursor>,
limit: i64,
) -> RepositoryResult<Vec<AuditEventRecord>>
pub async fn audit_events_for_relation( &self, relation_id: RelationId, after: Option<&AuditCursor>, limit: i64, ) -> RepositoryResult<Vec<AuditEventRecord>>
Reads audit events for a relation in stable (occurred_at, id) order.
Sourcepub async fn audit_outbox(
&self,
after: Option<&AuditOutboxCursor>,
limit: i64,
) -> RepositoryResult<Vec<AuditOutboxRecord>>
pub async fn audit_outbox( &self, after: Option<&AuditOutboxCursor>, limit: i64, ) -> RepositoryResult<Vec<AuditOutboxRecord>>
Exports undelivered audit outbox rows in stable id order.
Sourcepub async fn claim_audit_outbox(
&self,
worker_id: &str,
now: DateTime<Utc>,
lease_until: DateTime<Utc>,
limit: i64,
) -> RepositoryResult<Vec<AuditOutboxRecord>>
pub async fn claim_audit_outbox( &self, worker_id: &str, now: DateTime<Utc>, lease_until: DateTime<Utc>, limit: i64, ) -> RepositoryResult<Vec<AuditOutboxRecord>>
Claims a stable batch of undelivered audit outbox rows until lease_until.
Sourcepub async fn ack_audit_outbox(
&self,
outbox_id: i64,
delivered_at: DateTime<Utc>,
) -> RepositoryResult<bool>
pub async fn ack_audit_outbox( &self, outbox_id: i64, delivered_at: DateTime<Utc>, ) -> RepositoryResult<bool>
Acknowledges delivery of a claimed outbox row.
Sourcepub async fn release_audit_outbox(
&self,
outbox_id: i64,
) -> RepositoryResult<bool>
pub async fn release_audit_outbox( &self, outbox_id: i64, ) -> RepositoryResult<bool>
Releases a claimed outbox row for another worker to retry.
Source§impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
Sourcepub async fn fulfillment_snapshot(
&self,
keepsake_id: Uuid,
) -> RepositoryResult<FulfillmentSnapshot>
pub async fn fulfillment_snapshot( &self, keepsake_id: Uuid, ) -> RepositoryResult<FulfillmentSnapshot>
Reads the persisted fulfillment snapshot (counters and checklist) for a keepsake.
Sourcepub async fn due_fulfilled_expiry(
&self,
limit: i64,
) -> RepositoryResult<Vec<FulfilledExpiryCandidate>>
pub async fn due_fulfilled_expiry( &self, limit: i64, ) -> RepositoryResult<Vec<FulfilledExpiryCandidate>>
Lists fulfillment expiry candidates in stable batch order.
Sourcepub async fn expire_due_fulfilled(
&self,
now: DateTime<Utc>,
limit: i64,
) -> RepositoryResult<u64>
pub async fn expire_due_fulfilled( &self, now: DateTime<Utc>, limit: i64, ) -> RepositoryResult<u64>
Expires a stable batch whose persisted fulfillment snapshots satisfy policy.
Sourcepub async fn upsert_counter_projection(
&self,
keepsake_id: Uuid,
key: &str,
value: i64,
observed_at: DateTime<Utc>,
) -> RepositoryResult<()>
pub async fn upsert_counter_projection( &self, keepsake_id: Uuid, key: &str, value: i64, observed_at: DateTime<Utc>, ) -> RepositoryResult<()>
Upserts a simple fulfillment counter projection.
Sourcepub async fn increment_counter_projection(
&self,
keepsake_id: Uuid,
key: &str,
delta: i64,
observed_at: DateTime<Utc>,
) -> RepositoryResult<i64>
pub async fn increment_counter_projection( &self, keepsake_id: Uuid, key: &str, delta: i64, observed_at: DateTime<Utc>, ) -> RepositoryResult<i64>
Atomically adds delta to a fulfillment counter and returns the new value.
Unlike upsert_counter_projection, the
increment is computed in the database, so concurrent writers cannot lose
updates to a read-modify-write race.
Sourcepub async fn upsert_checklist_projection(
&self,
keepsake_id: Uuid,
item: &str,
complete: bool,
observed_at: DateTime<Utc>,
) -> RepositoryResult<()>
pub async fn upsert_checklist_projection( &self, keepsake_id: Uuid, item: &str, complete: bool, observed_at: DateTime<Utc>, ) -> RepositoryResult<()>
Upserts a checklist item completion projection.
Source§impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
Sourcepub async fn due_timed_expiry(
&self,
now: DateTime<Utc>,
limit: i64,
) -> RepositoryResult<Vec<TimedExpiryCandidate>>
pub async fn due_timed_expiry( &self, now: DateTime<Utc>, limit: i64, ) -> RepositoryResult<Vec<TimedExpiryCandidate>>
Lists due timed expiry candidates in stable batch order.
Sourcepub async fn expire_due_timed(
&self,
now: DateTime<Utc>,
limit: i64,
) -> RepositoryResult<u64>
pub async fn expire_due_timed( &self, now: DateTime<Utc>, limit: i64, ) -> RepositoryResult<u64>
Expires a stable batch of due timed keepsakes.
Source§impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
Sourcepub async fn apply(
&self,
command: &ApplyKeepsake,
) -> RepositoryResult<AppliedKeepsake>
pub async fn apply( &self, command: &ApplyKeepsake, ) -> RepositoryResult<AppliedKeepsake>
Applies a command idempotently and records its audit event atomically.
If an active keepsake already exists for the subject and relation, the existing
row is returned with duplicate_prevented set to true, even if the relation
has since been disabled. Disabled relations reject new non-duplicate applies.
Sourcepub async fn revoke(&self, command: &RevokeKeepsake) -> RepositoryResult<bool>
pub async fn revoke(&self, command: &RevokeKeepsake) -> RepositoryResult<bool>
Revokes an active keepsake from a command and records its audit event atomically.
Sourcepub async fn revoke_by_subject(
&self,
command: &RevokeBySubject,
) -> RepositoryResult<Option<KeepsakeId>>
pub async fn revoke_by_subject( &self, command: &RevokeBySubject, ) -> RepositoryResult<Option<KeepsakeId>>
Revokes the active keepsake for a subject and relation pair.
Returns the revoked keepsake id, or None when no active keepsake exists
for the pair. The active uniqueness invariant guarantees at most one match.
Source§impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
Sourcepub async fn active_for_subject(
&self,
subject: &SubjectRef,
) -> RepositoryResult<Vec<Keepsake>>
pub async fn active_for_subject( &self, subject: &SubjectRef, ) -> RepositoryResult<Vec<Keepsake>>
Returns active keepsakes for a subject.
Sourcepub async fn active_relations_for_subject(
&self,
subject: &SubjectRef,
) -> RepositoryResult<Vec<ActiveRelation>>
pub async fn active_relations_for_subject( &self, subject: &SubjectRef, ) -> RepositoryResult<Vec<ActiveRelation>>
Returns active keepsakes for a subject with their relation definitions.
Sourcepub async fn active_relations_for_subject_by_ids(
&self,
subject: &SubjectRef,
relation_ids: &[RelationId],
) -> RepositoryResult<Vec<ActiveRelation>>
pub async fn active_relations_for_subject_by_ids( &self, subject: &SubjectRef, relation_ids: &[RelationId], ) -> RepositoryResult<Vec<ActiveRelation>>
Returns active keepsakes for a subject, filtered by relation ids.
This is the bounded variant of Self::active_relations_for_subject for
request paths that use typed relation specs or another stable relation-id
catalogue. Missing ids are ignored, duplicate requested ids do not
duplicate output rows, and disabled relation definitions are still
returned when their keepsake is active.
Sourcepub async fn active_relations_for_subject_by_keys(
&self,
subject: &SubjectRef,
keys: &[RelationKey],
) -> RepositoryResult<Vec<ActiveRelation>>
pub async fn active_relations_for_subject_by_keys( &self, subject: &SubjectRef, keys: &[RelationKey], ) -> RepositoryResult<Vec<ActiveRelation>>
Returns active keepsakes for a subject, filtered by relation keys.
This is the bounded variant of Self::active_relations_for_subject for
request paths that know the small set of relation keys they care about.
Missing keys are ignored, and disabled relation definitions are still
returned when their keepsake is active.
Sourcepub async fn active_membership_scan(
&self,
relation_id: RelationId,
limit: i64,
) -> RepositoryResult<Vec<Keepsake>>
pub async fn active_membership_scan( &self, relation_id: RelationId, limit: i64, ) -> RepositoryResult<Vec<Keepsake>>
Scans active memberships for a relation in stable order.
Sourcepub async fn active_membership_scan_after(
&self,
relation_id: RelationId,
after: Option<&MembershipCursor>,
limit: i64,
) -> RepositoryResult<Vec<Keepsake>>
pub async fn active_membership_scan_after( &self, relation_id: RelationId, after: Option<&MembershipCursor>, limit: i64, ) -> RepositoryResult<Vec<Keepsake>>
Scans active memberships after a keyset cursor in stable order.
Source§impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
Sourcepub async fn upsert_relation(
&self,
relation: &RelationDefinition,
at: DateTime<Utc>,
) -> RepositoryResult<RelationDefinition>
pub async fn upsert_relation( &self, relation: &RelationDefinition, at: DateTime<Utc>, ) -> RepositoryResult<RelationDefinition>
Inserts or updates a relation definition by its natural relation key.
If a relation already exists for the same kind/name, its stable id is preserved and the returned definition contains the existing id.
Sourcepub async fn upsert_relation_spec<Spec>(
&self,
at: DateTime<Utc>,
) -> RepositoryResult<RelationDefinition>where
Spec: RelationSpec,
pub async fn upsert_relation_spec<Spec>(
&self,
at: DateTime<Utc>,
) -> RepositoryResult<RelationDefinition>where
Spec: RelationSpec,
Inserts or updates a typed relation spec by its natural relation key.
Sourcepub async fn relation_by_id(
&self,
relation_id: RelationId,
) -> RepositoryResult<Option<RelationDefinition>>
pub async fn relation_by_id( &self, relation_id: RelationId, ) -> RepositoryResult<Option<RelationDefinition>>
Looks up a relation definition by stable id.
Sourcepub async fn relation_by_key(
&self,
key: &RelationKey,
) -> RepositoryResult<Option<RelationDefinition>>
pub async fn relation_by_key( &self, key: &RelationKey, ) -> RepositoryResult<Option<RelationDefinition>>
Looks up a relation definition by its natural relation key.
Sourcepub async fn set_relation_enabled(
&self,
relation_id: RelationId,
enabled: bool,
at: DateTime<Utc>,
) -> RepositoryResult<bool>
pub async fn set_relation_enabled( &self, relation_id: RelationId, enabled: bool, at: DateTime<Utc>, ) -> RepositoryResult<bool>
Enables or disables a relation.
Source§impl<B, C> SqlxKeepsakeRepository<B, C>where
B: KeepsakeSqlxBackend,
C: RelationCache,
impl<B, C> SqlxKeepsakeRepository<B, C>where
B: KeepsakeSqlxBackend,
C: RelationCache,
Sourcepub const fn at(
&self,
at: DateTime<Utc>,
) -> TimedSqlxKeepsakeRepository<'_, B, C>
pub const fn at( &self, at: DateTime<Utc>, ) -> TimedSqlxKeepsakeRepository<'_, B, C>
Creates a timestamp-scoped repository view.
Use this at request or job boundaries to keep one explicit clock read while avoiding repeated timestamp plumbing through related repository calls.
Sourcepub fn with_relation_cache<Next>(
self,
cache: Next,
) -> SqlxKeepsakeRepository<B, Next>where
Next: RelationCache,
pub fn with_relation_cache<Next>(
self,
cache: Next,
) -> SqlxKeepsakeRepository<B, Next>where
Next: RelationCache,
Enables relation definition caching for read helper methods.
Sourcepub fn with_local_relation_cache(
self,
config: LocalRelationCacheConfig,
) -> SqlxKeepsakeRepository<B, LocalRelationCache>
pub fn with_local_relation_cache( self, config: LocalRelationCacheConfig, ) -> SqlxKeepsakeRepository<B, LocalRelationCache>
Enables local in-process relation definition caching for read helper methods.
This cache is per-process and has no cross-pod invalidation. Keep the
default NoopRelationCache when relation definitions change frequently
or when a multi-pod deployment needs invalidation guarantees.
Source§impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
impl<C> SqlxKeepsakeRepository<PostgresBackend, C>where
C: RelationCache,
Sourcepub async fn migrate(&self) -> RepositoryResult<()>
pub async fn migrate(&self) -> RepositoryResult<()>
Runs embedded migrations.
Trait Implementations§
Source§impl<B, C> Clone for SqlxKeepsakeRepository<B, C>where
B: KeepsakeSqlxBackend,
C: Clone,
impl<B, C> Clone for SqlxKeepsakeRepository<B, C>where
B: KeepsakeSqlxBackend,
C: Clone,
Auto Trait Implementations§
impl<B, C = NoopRelationCache> !RefUnwindSafe for SqlxKeepsakeRepository<B, C>
impl<B, C = NoopRelationCache> !UnwindSafe for SqlxKeepsakeRepository<B, C>
impl<B, C> Freeze for SqlxKeepsakeRepository<B, C>where
C: Freeze,
impl<B, C> Send for SqlxKeepsakeRepository<B, C>where
C: Send,
impl<B, C> Sync for SqlxKeepsakeRepository<B, C>where
C: Sync,
impl<B, C> Unpin for SqlxKeepsakeRepository<B, C>
impl<B, C> UnsafeUnpin for SqlxKeepsakeRepository<B, C>where
C: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> DynActiveRelationSource for Twhere
T: ActiveRelationSource,
impl<T> DynActiveRelationSource for Twhere
T: ActiveRelationSource,
Source§type Error = <T as ActiveRelationSource>::Error
type Error = <T as ActiveRelationSource>::Error
Source§fn active_relations_for_subject<'a>(
&'a self,
subject: &'a SubjectRef,
) -> Pin<Box<dyn Future<Output = Result<Vec<ActiveRelation>, <T as DynActiveRelationSource>::Error>> + Send + 'a>>
fn active_relations_for_subject<'a>( &'a self, subject: &'a SubjectRef, ) -> Pin<Box<dyn Future<Output = Result<Vec<ActiveRelation>, <T as DynActiveRelationSource>::Error>> + Send + 'a>>
Source§fn active_relations_for_subject_by_ids<'a>(
&'a self,
subject: &'a SubjectRef,
relation_ids: &'a [Uuid],
) -> Pin<Box<dyn Future<Output = Result<Vec<ActiveRelation>, <T as DynActiveRelationSource>::Error>> + Send + 'a>>
fn active_relations_for_subject_by_ids<'a>( &'a self, subject: &'a SubjectRef, relation_ids: &'a [Uuid], ) -> Pin<Box<dyn Future<Output = Result<Vec<ActiveRelation>, <T as DynActiveRelationSource>::Error>> + Send + 'a>>
Source§fn active_relations_for_subject_by_keys<'a>(
&'a self,
subject: &'a SubjectRef,
keys: &'a [RelationKey],
) -> Pin<Box<dyn Future<Output = Result<Vec<ActiveRelation>, <T as DynActiveRelationSource>::Error>> + Send + 'a>>
fn active_relations_for_subject_by_keys<'a>( &'a self, subject: &'a SubjectRef, keys: &'a [RelationKey], ) -> Pin<Box<dyn Future<Output = Result<Vec<ActiveRelation>, <T as DynActiveRelationSource>::Error>> + Send + 'a>>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more