pub struct Observation {
pub user_id: Uuid,
pub last_seen_at: Option<DateTime<Utc>>,
pub has_live_agent: bool,
pub longest_finished_day: Option<(NaiveDate, i64, WorkdayKind)>,
pub open_day: Option<(NaiveDate, DateTime<Utc>)>,
pub work_rate: Decimal,
}Expand description
What the rules are evaluated against, for one person, at one moment.
A plain struct assembled by the sweep’s queries rather than the rows themselves, so every rule below is a function of values and can be tested without a database. The arithmetic is the part most worth testing, and logic inside a query can only be tested through one - the same reason the signals do their statistics in Rust.
Fields§
§user_id: Uuid§last_seen_at: Option<DateTime<Utc>>When anything last arrived from any of this person’s live agents: the
later of a request that used the token and a pulse. None for somebody
whose agent has never said anything at all.
Both, and the freshest wins. agents.last_seen_at alone is what a
first version of this rule read, and a live run against the demo showed
what that costs: nine of twelve people flagged as silent, six of them
having pulsed seconds earlier. The two stamps answer different
questions - “the token was used” and “kasl is watching a person work”
(ADR 0014) - and an agent can go a long time doing only the second: a
machine whose employee is on holiday pulses idle all week and uploads
nothing at all. Reading one of them is how a rule about silence
alerts on somebody who is plainly talking.
has_live_agent: boolWhether this person has any live agent token. Somebody with none is not silent - they were never asked to speak.
longest_finished_day: Option<(NaiveDate, i64, WorkdayKind)>The finished day with the most seconds worked in the window the sweep
looks at, as (date, worked_seconds, kind).
open_day: Option<(NaiveDate, DateTime<Utc>)>A day still open, as (date, started_at). At most one: the schema
allows a person one day per date, and a second open day would be a much
louder problem than this rule.
work_rate: DecimalThis person’s share of a full day.
Trait Implementations§
Source§impl Clone for Observation
impl Clone for Observation
Auto Trait Implementations§
impl Freeze for Observation
impl RefUnwindSafe for Observation
impl Send for Observation
impl Sync for Observation
impl Unpin for Observation
impl UnsafeUnpin for Observation
impl UnwindSafe for Observation
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,
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
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