Skip to main content

haste_repository/
failed_indexing.rs

1use crate::types::FHIRMethod;
2use haste_fhir_operation_error::OperationOutcomeError;
3use haste_jwt::{ProjectId, TenantId, VersionId};
4use sqlx::types::time::OffsetDateTime;
5
6/// Plain, storage-agnostic reference to a resource that failed search
7/// indexing. Never carries the resource body - just enough identity to look
8/// it back up.
9#[derive(Clone, Debug)]
10pub struct FailedIndexRecord {
11    pub tenant: TenantId,
12    pub project: ProjectId,
13    pub version_id: VersionId,
14    pub resource_type: String,
15    pub fhir_method: FHIRMethod,
16    pub error_message: String,
17}
18
19/// A previously recorded indexing failure, as read back for display -
20/// includes the bookkeeping columns (`attempt_count`, timestamps) that only
21/// exist once a `FailedIndexRecord` has actually been persisted.
22#[derive(sqlx::FromRow, Clone, Debug)]
23pub struct FailedIndexEntry {
24    pub id: String,
25    pub version_id: String,
26    pub resource_type: String,
27    pub fhir_method: FHIRMethod,
28    /// Current sequence position of this version in the `resources` table -
29    /// looked up at read time since it isn't part of the failure record itself.
30    pub sequence: i64,
31    pub attempt_count: i32,
32    pub error_message: String,
33    pub first_failed_at: OffsetDateTime,
34    pub last_failed_at: OffsetDateTime,
35    pub resolved_at: Option<OffsetDateTime>,
36}
37
38pub trait FailedIndexingProvider {
39    /// Durably records resources that failed search indexing so they can be
40    /// skipped (instead of retried forever) and inspected later. No-op on an
41    /// empty list.
42    fn record_failures(
43        &self,
44        failures: &[FailedIndexRecord],
45    ) -> impl std::future::Future<Output = Result<(), OperationOutcomeError>> + Send;
46
47    /// Lists recorded indexing failures for a tenant/project, most recently
48    /// failed first.
49    fn search(
50        &self,
51        tenant: &TenantId,
52        project: &ProjectId,
53    ) -> impl std::future::Future<Output = Result<Vec<FailedIndexEntry>, OperationOutcomeError>> + Send;
54}