pub struct Incident {Show 18 fields
pub id: Uuid,
pub org_id: Uuid,
pub workspace_id: Option<Uuid>,
pub source: String,
pub source_ref: Option<String>,
pub dedupe_key: String,
pub severity: String,
pub status: String,
pub title: String,
pub description: Option<String>,
pub postmortem_url: Option<String>,
pub assigned_to: Option<Uuid>,
pub acknowledged_at: Option<DateTime<Utc>>,
pub acknowledged_by: Option<Uuid>,
pub resolved_at: Option<DateTime<Utc>>,
pub resolved_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}Expand description
Persistent incident row. dedupe_key is source-scoped — the noisy
sources (drift detection, observability alerts) collapse repeat fires
onto a single open row via the partial-unique index in the migration.
Fields§
§id: Uuid§org_id: Uuid§workspace_id: Option<Uuid>§source: String§source_ref: Option<String>§dedupe_key: String§severity: String§status: String§title: String§description: Option<String>§postmortem_url: Option<String>§assigned_to: Option<Uuid>§acknowledged_at: Option<DateTime<Utc>>§acknowledged_by: Option<Uuid>§resolved_at: Option<DateTime<Utc>>§resolved_by: Option<Uuid>§created_at: DateTime<Utc>§updated_at: DateTime<Utc>Implementations§
Source§impl Incident
impl Incident
pub async fn list_by_org( pool: &Pool<Postgres>, org_id: Uuid, status_filter: Option<&str>, limit: i64, ) -> Result<Vec<Incident>, Error>
pub async fn find_by_id( pool: &Pool<Postgres>, id: Uuid, ) -> Result<Option<Incident>, Error>
Sourcepub async fn raise(
pool: &Pool<Postgres>,
input: RaiseIncidentInput<'_>,
) -> Result<Incident, Error>
pub async fn raise( pool: &Pool<Postgres>, input: RaiseIncidentInput<'_>, ) -> Result<Incident, Error>
Insert a new incident, or no-op if there’s already an open one with the same (org_id, source, dedupe_key). Returns the incident in either case, so callers always have an id to reference.
Relies on the partial-unique index idx_incidents_open_dedupe —
ON CONFLICT DO NOTHING against that index keeps repeated fires
idempotent without needing application-side coordination.
Sourcepub async fn auto_resolve(
pool: &Pool<Postgres>,
org_id: Uuid,
source: &str,
dedupe_key: &str,
) -> Result<u64, Error>
pub async fn auto_resolve( pool: &Pool<Postgres>, org_id: Uuid, source: &str, dedupe_key: &str, ) -> Result<u64, Error>
Mark all open incidents matching (org_id, source, dedupe_key) as resolved. Used by sources that auto-resolve when the underlying signal recovers (e.g., next clean drift check).
pub async fn acknowledge( pool: &Pool<Postgres>, id: Uuid, actor_id: Uuid, ) -> Result<Option<Incident>, Error>
pub async fn resolve( pool: &Pool<Postgres>, id: Uuid, actor_id: Uuid, ) -> Result<Option<Incident>, Error>
pub async fn list_events( pool: &Pool<Postgres>, incident_id: Uuid, ) -> Result<Vec<IncidentEvent>, Error>
Sourcepub async fn list_pending_dispatch(
pool: &Pool<Postgres>,
limit: i64,
) -> Result<Vec<Incident>, Error>
pub async fn list_pending_dispatch( pool: &Pool<Postgres>, limit: i64, ) -> Result<Vec<Incident>, Error>
Open incidents that haven’t been dispatched to notification channels
yet. The dispatcher worker polls this; once it inserts a
notification_dispatched incident_event for an incident, that
incident drops out of the list.
Capped at limit rows so a backlog can’t OOM the worker.
Sourcepub async fn record_notification_attempt(
pool: &Pool<Postgres>,
incident_id: Uuid,
channel_id: Uuid,
result: &Value,
) -> Result<(), Error>
pub async fn record_notification_attempt( pool: &Pool<Postgres>, incident_id: Uuid, channel_id: Uuid, result: &Value, ) -> Result<(), Error>
Worker-callback: record one dispatch attempt per (incident, channel).
result is freeform JSON — typically {"ok": true, "status": 204}
for success or {"ok": false, "error": "..."} for failure.
Multiple rows per incident are expected (one per channel).
Sourcepub async fn mark_dispatched(
pool: &Pool<Postgres>,
incident_id: Uuid,
summary: &Value,
) -> Result<(), Error>
pub async fn mark_dispatched( pool: &Pool<Postgres>, incident_id: Uuid, summary: &Value, ) -> Result<(), Error>
Worker-callback: incident has been processed by the dispatcher.
Inserting this row removes the incident from
list_pending_dispatch. Idempotent: a duplicate insert is fine —
the next poll just finds zero pending rows.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Incident
impl<'de> Deserialize<'de> for Incident
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<Incident, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Incident, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl<'a, R> FromRow<'a, R> for Incidentwhere
R: Row,
&'a str: ColumnIndex<R>,
Uuid: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
Option<Uuid>: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
String: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
Option<String>: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
Option<DateTime<Utc>>: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
DateTime<Utc>: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
impl<'a, R> FromRow<'a, R> for Incidentwhere
R: Row,
&'a str: ColumnIndex<R>,
Uuid: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
Option<Uuid>: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
String: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
Option<String>: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
Option<DateTime<Utc>>: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
DateTime<Utc>: Decode<'a, <R as Row>::Database> + Type<<R as Row>::Database>,
Source§impl Serialize for Incident
impl Serialize for Incident
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Auto Trait Implementations§
impl Freeze for Incident
impl RefUnwindSafe for Incident
impl Send for Incident
impl Sync for Incident
impl Unpin for Incident
impl UnsafeUnpin for Incident
impl UnwindSafe for Incident
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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> 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