Skip to content

brokkr-broker::dal::work_orders

Rust

Data Access Layer for WorkOrder operations.

This module provides functionality to interact with the work_orders, work_order_log, and work_order_targets tables in the database. It includes methods for creating, claiming, completing, and managing work orders through their lifecycle.

Work Order Lifecycle

  1. Create: Work order is created with status PENDING
  2. Claim: Agent claims work order, status changes to CLAIMED
  3. Complete: Agent reports completion, record moves to work_order_log
    • On failure with retries remaining: status changes to RETRY_PENDING
    • After backoff: status resets to PENDING

Stale Claim Detection

Work orders that have been claimed but not completed within claim_timeout_seconds are considered stale and can be reclaimed by other agents.

pub

Data Access Layer for WorkOrder operations.

Name Type Description
dal &'a DAL Reference to the main DAL instance.

pub

fn create(
&self,
new_work_order: &NewWorkOrder,
) -> Result<WorkOrder, diesel::result::Error>

Creates a new work order in the database.

Parameters:

Name Type Description
new_work_order &NewWorkOrder A reference to the NewWorkOrder struct.

Returns:

Returns the created WorkOrder on success, or a diesel::result::Error on failure.

Source
pub fn create(
&self,
new_work_order: &NewWorkOrder,
) -> Result<WorkOrder, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let work_order: WorkOrder = diesel::insert_into(work_orders::table)
.values(new_work_order)
.get_result(conn)?;
// Emit workorder.created event
let event_data = serde_json::json!({
"work_order_id": work_order.id,
"work_type": work_order.work_type,
"status": work_order.status,
"created_at": work_order.created_at,
});
event_bus::emit_event(
self.dal,
&BrokkrEvent::new(EVENT_WORKORDER_CREATED, event_data),
);
Ok(work_order)
}

pub

fn get(
&self,
work_order_id: Uuid,
) -> Result<Option<WorkOrder>, diesel::result::Error>

Retrieves a work order by its UUID.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order to retrieve.

Returns:

Returns an Option if found, or a diesel::result::Error on failure.

Source
pub fn get(&self, work_order_id: Uuid) -> Result<Option<WorkOrder>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
work_orders::table
.filter(work_orders::id.eq(work_order_id))
.first(conn)
.optional()
}

pub

fn list(&self) -> Result<Vec<WorkOrder>, diesel::result::Error>

Lists all work orders from the database.

Returns:

Returns a Vec of all WorkOrders on success, or a diesel::result::Error on failure.

Source
pub fn list(&self) -> Result<Vec<WorkOrder>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
work_orders::table
.order(work_orders::created_at.desc())
.load::<WorkOrder>(conn)
}

pub

fn list_filtered(
&self,
status: Option<&str>,
work_type: Option<&str>,
) -> Result<Vec<WorkOrder>, diesel::result::Error>

Lists work orders filtered by status and/or work type.

Parameters:

Name Type Description
status Option<&str> Optional status filter (PENDING, CLAIMED, RETRY_PENDING).
work_type Option<&str> Optional work type filter (e.g., “build”).

Returns:

Returns a Vec of filtered WorkOrders on success, or a diesel::result::Error on failure.

Source
pub fn list_filtered(
&self,
status: Option<&str>,
work_type: Option<&str>,
) -> Result<Vec<WorkOrder>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let mut query = work_orders::table.into_boxed();
if let Some(s) = status {
query = query.filter(work_orders::status.eq(s));
}
if let Some(wt) = work_type {
query = query.filter(work_orders::work_type.eq(wt));
}
query
.order(work_orders::created_at.desc())
.load::<WorkOrder>(conn)
}

pub

fn delete(
&self,
work_order_id: Uuid,
) -> Result<usize, diesel::result::Error>

Deletes a work order by its UUID (hard delete).

Note: This also deletes associated work_order_targets via CASCADE.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order to delete.

Returns:

Returns the number of affected rows on success, or a diesel::result::Error on failure.

Source
pub fn delete(&self, work_order_id: Uuid) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::delete(work_orders::table.filter(work_orders::id.eq(work_order_id))).execute(conn)
}

pub

fn list_pending_for_agent(
&self,
agent_id: Uuid,
work_type: Option<&str>,
) -> Result<Vec<WorkOrder>, diesel::result::Error>

Lists pending work orders that are claimable by a specific agent.

A work order is claimable if:

  • Status is PENDING
  • At least one of the following conditions is met (OR logic):
    • Agent is in the work_order_targets (hard targets)
    • Agent has a label matching any of the work order’s labels
    • Agent has an annotation matching any of the work order’s annotations

Parameters:

Name Type Description
agent_id Uuid The UUID of the agent requesting claimable work orders.
work_type Option<&str> Optional work type filter.

Returns:

Returns a Vec of claimable WorkOrders on success, or a diesel::result::Error on failure.

Source
pub fn list_pending_for_agent(
&self,
agent_id: Uuid,
work_type: Option<&str>,
) -> Result<Vec<WorkOrder>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
// Get agent's labels
let agent_label_list: Vec<String> = agent_labels::table
.filter(agent_labels::agent_id.eq(agent_id))
.select(agent_labels::label)
.load::<String>(conn)?;
// Get agent's annotations
let agent_annotation_list: Vec<(String, String)> = agent_annotations::table
.filter(agent_annotations::agent_id.eq(agent_id))
.select((agent_annotations::key, agent_annotations::value))
.load::<(String, String)>(conn)?;
let mut matching_work_order_ids: HashSet<Uuid> = HashSet::new();
// 1. Get work orders where agent is a hard target
let hard_target_ids: Vec<Uuid> = work_order_targets::table
.inner_join(work_orders::table)
.filter(work_order_targets::agent_id.eq(agent_id))
.filter(work_orders::status.eq(WORK_ORDER_STATUS_PENDING))
.select(work_orders::id)
.load::<Uuid>(conn)?;
matching_work_order_ids.extend(hard_target_ids);
// 2. Get work orders with labels matching agent's labels (OR logic)
if !agent_label_list.is_empty() {
let label_matched_ids: Vec<Uuid> = work_order_labels::table
.inner_join(work_orders::table)
.filter(work_order_labels::label.eq_any(&agent_label_list))
.filter(work_orders::status.eq(WORK_ORDER_STATUS_PENDING))
.select(work_orders::id)
.load::<Uuid>(conn)?;
matching_work_order_ids.extend(label_matched_ids);
}
// 3. Get work orders with annotations matching agent's annotations (OR logic)
if !agent_annotation_list.is_empty() {
for (key, value) in &agent_annotation_list {
let annotation_matched_ids: Vec<Uuid> = work_order_annotations::table
.inner_join(work_orders::table)
.filter(work_order_annotations::key.eq(key))
.filter(work_order_annotations::value.eq(value))
.filter(work_orders::status.eq(WORK_ORDER_STATUS_PENDING))
.select(work_orders::id)
.load::<Uuid>(conn)?;
matching_work_order_ids.extend(annotation_matched_ids);
}
}
if matching_work_order_ids.is_empty() {
return Ok(vec![]);
}
// Load and filter the matching work orders
let ids: Vec<Uuid> = matching_work_order_ids.into_iter().collect();
let mut query = work_orders::table
.filter(work_orders::id.eq_any(&ids))
.filter(work_orders::status.eq(WORK_ORDER_STATUS_PENDING))
.into_boxed();
if let Some(wt) = work_type {
query = query.filter(work_orders::work_type.eq(wt));
}
query
.order(work_orders::created_at.asc())
.load::<WorkOrder>(conn)
}

pub

fn claimed_counts_by_agent(
&self) -> Result<Vec<(Uuid, i64,
) -> Result<Vec<(Uuid, i64)>, diesel::result::Error>

Returns the number of CLAIMED work orders per claiming agent in a single grouped query (no per-agent fan-out).

Counts rows WHERE status='CLAIMED' AND claimed_by IS NOT NULL grouped by claimed_by. Agents with no claims are absent from the result.

Returns:

Returns a Vec of (agent_id, claimed_count) pairs, or a diesel::result::Error on failure.

Source
pub fn claimed_counts_by_agent(&self) -> Result<Vec<(Uuid, i64)>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
work_orders::table
.filter(work_orders::status.eq(WORK_ORDER_STATUS_CLAIMED))
.filter(work_orders::claimed_by.is_not_null())
.group_by(work_orders::claimed_by)
.select((
work_orders::claimed_by.assume_not_null(),
diesel::dsl::count_star(),
))
.load::<(Uuid, i64)>(conn)
}

pub

fn pending_counts_by_agent(
&self) -> Result<Vec<(Uuid, i64,
) -> Result<Vec<(Uuid, i64)>, diesel::result::Error>

Returns, per agent, the number of distinct PENDING work orders that agent is eligible to claim — computed with a handful of bounded set-based queries rather than calling list_pending_for_agent once per agent.

The matching semantics exactly mirror list_pending_for_agent (the per-agent ground truth): an agent matches a PENDING work order if ANY of the following hold (OR logic):

  • the agent is a hard target (work_order_targets), OR
  • the agent shares a label with the work order, OR
  • the agent shares a (key, value) annotation with the work order.

Each matched (agent_id, work_order_id) pair is de-duplicated before counting so a work order matched by multiple mechanisms is counted once per agent.

Returns:

Returns a Vec of (agent_id, pending_count) pairs, or a diesel::result::Error on failure.

Source
pub fn pending_counts_by_agent(&self) -> Result<Vec<(Uuid, i64)>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
// Accumulate the distinct set of (agent_id, work_order_id) matches.
let mut matches: HashSet<(Uuid, Uuid)> = HashSet::new();
// 1. Hard targets: every (agent, pending work order) target pair.
let target_pairs: Vec<(Uuid, Uuid)> = work_order_targets::table
.inner_join(work_orders::table)
.filter(work_orders::status.eq(WORK_ORDER_STATUS_PENDING))
.select((work_order_targets::agent_id, work_orders::id))
.load::<(Uuid, Uuid)>(conn)?;
matches.extend(target_pairs);
// 2. Label matches: join agent_labels to work_order_labels on equal
// label text, restricted to pending work orders.
let label_pairs: Vec<(Uuid, Uuid)> = agent_labels::table
.inner_join(
work_order_labels::table.on(work_order_labels::label.eq(agent_labels::label)),
)
.inner_join(work_orders::table.on(work_orders::id.eq(work_order_labels::work_order_id)))
.filter(work_orders::status.eq(WORK_ORDER_STATUS_PENDING))
.select((agent_labels::agent_id, work_orders::id))
.load::<(Uuid, Uuid)>(conn)?;
matches.extend(label_pairs);
// 3. Annotation matches: join agent_annotations to
// work_order_annotations on equal (key, value), restricted to
// pending work orders.
let annotation_pairs: Vec<(Uuid, Uuid)> = agent_annotations::table
.inner_join(
work_order_annotations::table.on(work_order_annotations::key
.eq(agent_annotations::key)
.and(work_order_annotations::value.eq(agent_annotations::value))),
)
.inner_join(
work_orders::table.on(work_orders::id.eq(work_order_annotations::work_order_id)),
)
.filter(work_orders::status.eq(WORK_ORDER_STATUS_PENDING))
.select((agent_annotations::agent_id, work_orders::id))
.load::<(Uuid, Uuid)>(conn)?;
matches.extend(annotation_pairs);
// Aggregate distinct matches into per-agent counts.
let mut counts: std::collections::HashMap<Uuid, i64> = std::collections::HashMap::new();
for (agent_id, _work_order_id) in matches {
*counts.entry(agent_id).or_insert(0) += 1;
}
Ok(counts.into_iter().collect())
}

pub

fn claim(
&self,
work_order_id: Uuid,
agent_id: Uuid,
) -> Result<WorkOrder, diesel::result::Error>

Atomically claims a work order for an agent.

This operation will only succeed if:

  • The work order exists
  • The work order status is PENDING
  • At least one of the following conditions is met (OR logic):
    • Agent is in the work_order_targets (hard targets)
    • Agent has a label matching any of the work order’s labels
    • Agent has an annotation matching any of the work order’s annotations

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order to claim.
agent_id Uuid The UUID of the agent claiming the work order.

Returns:

Returns the updated WorkOrder on success, or a diesel::result::Error on failure. Returns NotFound if the work order doesn’t exist or can’t be claimed.

Source
pub fn claim(
&self,
work_order_id: Uuid,
agent_id: Uuid,
) -> Result<WorkOrder, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
// Check if agent is authorized via any targeting mechanism (OR logic)
let is_authorized =
self.is_agent_authorized_for_work_order(conn, work_order_id, agent_id)?;
if !is_authorized {
return Err(diesel::result::Error::NotFound);
}
// Atomically update the work order status to CLAIMED
let now = Utc::now();
let work_order: WorkOrder = diesel::update(
work_orders::table
.filter(work_orders::id.eq(work_order_id))
.filter(work_orders::status.eq(WORK_ORDER_STATUS_PENDING)),
)
.set((
work_orders::status.eq(WORK_ORDER_STATUS_CLAIMED),
work_orders::claimed_by.eq(agent_id),
work_orders::claimed_at.eq(now),
))
.get_result(conn)?;
// Emit workorder.claimed event
let event_data = serde_json::json!({
"work_order_id": work_order.id,
"work_type": work_order.work_type,
"agent_id": agent_id,
"claimed_at": now,
});
event_bus::emit_event(
self.dal,
&BrokkrEvent::new(EVENT_WORKORDER_CLAIMED, event_data),
);
Ok(work_order)
}

pub

fn release(
&self,
work_order_id: Uuid,
agent_id: Uuid,
) -> Result<WorkOrder, diesel::result::Error>

Releases a claimed work order back to PENDING status.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order to release.
agent_id Uuid The UUID of the agent releasing the work order (must match claimed_by).

Returns:

Returns the updated WorkOrder on success, or a diesel::result::Error on failure.

Source
pub fn release(
&self,
work_order_id: Uuid,
agent_id: Uuid,
) -> Result<WorkOrder, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::update(
work_orders::table
.filter(work_orders::id.eq(work_order_id))
.filter(work_orders::status.eq(WORK_ORDER_STATUS_CLAIMED))
.filter(work_orders::claimed_by.eq(agent_id)),
)
.set((
work_orders::status.eq(WORK_ORDER_STATUS_PENDING),
work_orders::claimed_by.eq(None::<Uuid>),
work_orders::claimed_at.eq(None::<chrono::DateTime<Utc>>),
))
.get_result(conn)
}

pub

fn complete_success(
&self,
work_order_id: Uuid,
result_message: Option<String>,
) -> Result<WorkOrderLog, diesel::result::Error>

Completes a work order successfully and moves it to the log.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order to complete.
result_message Option<String> Optional result message (e.g., image digest).

Returns:

Returns the created WorkOrderLog entry on success, or a diesel::result::Error on failure.

Source
pub fn complete_success(
&self,
work_order_id: Uuid,
result_message: Option<String>,
) -> Result<WorkOrderLog, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let log_result: WorkOrderLog = conn.transaction(|conn| {
// Get the work order
let work_order: WorkOrder = work_orders::table
.filter(work_orders::id.eq(work_order_id))
.first(conn)?;
// Create log entry
let log_entry = NewWorkOrderLog::from_work_order(&work_order, true, result_message);
let log_result: WorkOrderLog = diesel::insert_into(work_order_log::table)
.values(&log_entry)
.get_result(conn)?;
// Delete work order (cascade deletes targets)
diesel::delete(work_orders::table.filter(work_orders::id.eq(work_order_id)))
.execute(conn)?;
Ok::<WorkOrderLog, diesel::result::Error>(log_result)
})?;
// Emit completion event
self.emit_completion_event(&log_result);
Ok(log_result)
}

pub

fn complete_failure(
&self,
work_order_id: Uuid,
error_message: String,
retryable: bool,
) -> Result<Option<WorkOrderLog>, diesel::result::Error>

Completes a work order with failure.

If retryable is true and retries remain, the work order is marked as RETRY_PENDING. If retryable is false or max retries exceeded, the work order is moved to the log.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order that failed.
error_message String The error message describing the failure.
retryable bool Whether this failure type can be retried.

Returns:

Returns either:

  • Ok(None) if the work order was scheduled for retry
  • Ok(Some(WorkOrderLog)) if not retryable or max retries exceeded
  • Err on database error
Source
pub fn complete_failure(
&self,
work_order_id: Uuid,
error_message: String,
retryable: bool,
) -> Result<Option<WorkOrderLog>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let result: Option<WorkOrderLog> = conn.transaction(|conn| {
// Get the work order
let work_order: WorkOrder = work_orders::table
.filter(work_orders::id.eq(work_order_id))
.first(conn)?;
let new_retry_count = work_order.retry_count + 1;
// Move to log immediately if not retryable, or if max retries exceeded
if !retryable || new_retry_count > work_order.max_retries {
// Move to log
let log_entry =
NewWorkOrderLog::from_work_order(&work_order, false, Some(error_message));
let log_result: WorkOrderLog = diesel::insert_into(work_order_log::table)
.values(&log_entry)
.get_result(conn)?;
// Delete work order
diesel::delete(work_orders::table.filter(work_orders::id.eq(work_order_id)))
.execute(conn)?;
Ok::<Option<WorkOrderLog>, diesel::result::Error>(Some(log_result))
} else {
// Schedule retry with exponential backoff
let backoff_multiplier = 2_i64.pow(new_retry_count as u32);
let backoff_duration =
Duration::seconds(work_order.backoff_seconds as i64 * backoff_multiplier);
let now = Utc::now();
let next_retry = now + backoff_duration;
diesel::update(work_orders::table.filter(work_orders::id.eq(work_order_id)))
.set((
work_orders::status.eq(WORK_ORDER_STATUS_RETRY_PENDING),
work_orders::retry_count.eq(new_retry_count),
work_orders::next_retry_after.eq(next_retry),
work_orders::claimed_by.eq(None::<Uuid>),
work_orders::claimed_at.eq(None::<chrono::DateTime<Utc>>),
work_orders::last_error.eq(&error_message),
work_orders::last_error_at.eq(now),
))
.execute(conn)?;
Ok(None)
}
})?;
// Emit completion event if work order was moved to log
if let Some(ref log) = result {
self.emit_completion_event(log);
}
Ok(result)
}

pub

fn process_retry_pending(&self) -> Result<usize, diesel::result::Error>

Resets RETRY_PENDING work orders to PENDING if their backoff period has elapsed.

This should be called periodically by a background job.

Returns:

Returns the number of work orders reset on success, or a diesel::result::Error on failure.

Source
pub fn process_retry_pending(&self) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let now = Utc::now();
diesel::update(
work_orders::table
.filter(work_orders::status.eq(WORK_ORDER_STATUS_RETRY_PENDING))
.filter(work_orders::next_retry_after.le(now)),
)
.set((
work_orders::status.eq(WORK_ORDER_STATUS_PENDING),
work_orders::next_retry_after.eq(None::<chrono::DateTime<Utc>>),
))
.execute(conn)
}

pub

fn process_stale_claims(&self) -> Result<usize, diesel::result::Error>

Resets stale claimed work orders to PENDING.

A claim is stale if: claimed_at + claim_timeout_seconds < NOW()

This should be called periodically by a background job.

Returns:

Returns the number of work orders reset on success, or a diesel::result::Error on failure.

Source
pub fn process_stale_claims(&self) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let now = Utc::now();
// We need to use raw SQL for this because Diesel doesn't support
// arithmetic with columns in WHERE clauses easily
diesel::sql_query(
"UPDATE work_orders
SET status = 'PENDING', claimed_by = NULL, claimed_at = NULL, updated_at = NOW()
WHERE status = 'CLAIMED'
AND claimed_at + (claim_timeout_seconds || ' seconds')::INTERVAL < $1",
)
.bind::<diesel::sql_types::Timestamptz, _>(now)
.execute(conn)
}

pub

fn add_target(
&self,
new_target: &NewWorkOrderTarget,
) -> Result<WorkOrderTarget, diesel::result::Error>

Adds an agent as a target for a work order.

Parameters:

Name Type Description
new_target &NewWorkOrderTarget The new target to add.

Returns:

Returns the created WorkOrderTarget on success, or a diesel::result::Error on failure.

Source
pub fn add_target(
&self,
new_target: &NewWorkOrderTarget,
) -> Result<WorkOrderTarget, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::insert_into(work_order_targets::table)
.values(new_target)
.get_result(conn)
}

pub

fn add_targets(
&self,
work_order_id: Uuid,
agent_ids: &[Uuid],
) -> Result<usize, diesel::result::Error>

Adds multiple agents as targets for a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.
agent_ids &[Uuid] A slice of agent UUIDs to add as targets.

Returns:

Returns the number of targets added on success, or a diesel::result::Error on failure.

Source
pub fn add_targets(
&self,
work_order_id: Uuid,
agent_ids: &[Uuid],
) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let targets: Vec<NewWorkOrderTarget> = agent_ids
.iter()
.filter_map(|&agent_id| NewWorkOrderTarget::new(work_order_id, agent_id).ok())
.collect();
diesel::insert_into(work_order_targets::table)
.values(&targets)
.execute(conn)
}

pub

fn list_targets(
&self,
work_order_id: Uuid,
) -> Result<Vec<WorkOrderTarget>, diesel::result::Error>

Lists all targets for a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.

Returns:

Returns a Vec of WorkOrderTargets on success, or a diesel::result::Error on failure.

Source
pub fn list_targets(
&self,
work_order_id: Uuid,
) -> Result<Vec<WorkOrderTarget>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
work_order_targets::table
.filter(work_order_targets::work_order_id.eq(work_order_id))
.load::<WorkOrderTarget>(conn)
}

pub

fn remove_target(
&self,
work_order_id: Uuid,
agent_id: Uuid,
) -> Result<usize, diesel::result::Error>

Removes a target from a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.
agent_id Uuid The UUID of the agent to remove.

Returns:

Returns the number of targets removed on success, or a diesel::result::Error on failure.

Source
pub fn remove_target(
&self,
work_order_id: Uuid,
agent_id: Uuid,
) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::delete(
work_order_targets::table
.filter(work_order_targets::work_order_id.eq(work_order_id))
.filter(work_order_targets::agent_id.eq(agent_id)),
)
.execute(conn)
}

pub

fn get_log(
&self,
log_id: Uuid,
) -> Result<Option<WorkOrderLog>, diesel::result::Error>

Retrieves a work order log entry by its UUID.

Parameters:

Name Type Description
log_id Uuid The UUID of the log entry to retrieve.

Returns:

Returns an Option if found, or a diesel::result::Error on failure.

Source
pub fn get_log(&self, log_id: Uuid) -> Result<Option<WorkOrderLog>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
work_order_log::table
.filter(work_order_log::id.eq(log_id))
.first(conn)
.optional()
}

pub

fn list_log(
&self,
work_type: Option<&str>,
success: Option<bool>,
agent_id: Option<Uuid>,
limit: Option<i64>,
) -> Result<Vec<WorkOrderLog>, diesel::result::Error>

Lists work order log entries with optional filtering.

Parameters:

Name Type Description
work_type Option<&str> Optional work type filter.
success Option<bool> Optional success status filter.
agent_id Option<Uuid> Optional agent ID filter.
limit Option<i64> Optional limit on number of results.

Returns:

Returns a Vec of WorkOrderLog entries on success, or a diesel::result::Error on failure.

Source
pub fn list_log(
&self,
work_type: Option<&str>,
success: Option<bool>,
agent_id: Option<Uuid>,
limit: Option<i64>,
) -> Result<Vec<WorkOrderLog>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let mut query = work_order_log::table.into_boxed();
if let Some(wt) = work_type {
query = query.filter(work_order_log::work_type.eq(wt));
}
if let Some(s) = success {
query = query.filter(work_order_log::success.eq(s));
}
if let Some(aid) = agent_id {
query = query.filter(work_order_log::claimed_by.eq(aid));
}
query = query.order(work_order_log::completed_at.desc());
if let Some(l) = limit {
query = query.limit(l);
}
query.load::<WorkOrderLog>(conn)
}

pub

fn add_label(
&self,
new_label: &NewWorkOrderLabel,
) -> Result<WorkOrderLabel, diesel::result::Error>

Adds a label to a work order.

Parameters:

Name Type Description
new_label &NewWorkOrderLabel The new label to add.

Returns:

Returns the created WorkOrderLabel on success, or a diesel::result::Error on failure.

Source
pub fn add_label(
&self,
new_label: &NewWorkOrderLabel,
) -> Result<WorkOrderLabel, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::insert_into(work_order_labels::table)
.values(new_label)
.get_result(conn)
}

pub

fn add_labels(
&self,
work_order_id: Uuid,
labels: &[String],
) -> Result<usize, diesel::result::Error>

Adds multiple labels to a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.
labels &[String] A slice of label strings to add.

Returns:

Returns the number of labels added on success, or a diesel::result::Error on failure.

Source
pub fn add_labels(
&self,
work_order_id: Uuid,
labels: &[String],
) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let new_labels: Vec<NewWorkOrderLabel> = labels
.iter()
.filter_map(|label| NewWorkOrderLabel::new(work_order_id, label.clone()).ok())
.collect();
diesel::insert_into(work_order_labels::table)
.values(&new_labels)
.execute(conn)
}

pub

fn list_labels(
&self,
work_order_id: Uuid,
) -> Result<Vec<WorkOrderLabel>, diesel::result::Error>

Lists all labels for a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.

Returns:

Returns a Vec of WorkOrderLabels on success, or a diesel::result::Error on failure.

Source
pub fn list_labels(
&self,
work_order_id: Uuid,
) -> Result<Vec<WorkOrderLabel>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
work_order_labels::table
.filter(work_order_labels::work_order_id.eq(work_order_id))
.load::<WorkOrderLabel>(conn)
}

pub

fn remove_label(
&self,
work_order_id: Uuid,
label: &str,
) -> Result<usize, diesel::result::Error>

Removes a label from a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.
label &str The label to remove.

Returns:

Returns the number of labels removed on success, or a diesel::result::Error on failure.

Source
pub fn remove_label(
&self,
work_order_id: Uuid,
label: &str,
) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::delete(
work_order_labels::table
.filter(work_order_labels::work_order_id.eq(work_order_id))
.filter(work_order_labels::label.eq(label)),
)
.execute(conn)
}

pub

fn add_annotation(
&self,
new_annotation: &NewWorkOrderAnnotation,
) -> Result<WorkOrderAnnotation, diesel::result::Error>

Adds an annotation to a work order.

Parameters:

Name Type Description
new_annotation &NewWorkOrderAnnotation The new annotation to add.

Returns:

Returns the created WorkOrderAnnotation on success, or a diesel::result::Error on failure.

Source
pub fn add_annotation(
&self,
new_annotation: &NewWorkOrderAnnotation,
) -> Result<WorkOrderAnnotation, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::insert_into(work_order_annotations::table)
.values(new_annotation)
.get_result(conn)
}

pub

fn add_annotations(
&self,
work_order_id: Uuid,
annotations: &std::collections::HashMap<String, String>,
) -> Result<usize, diesel::result::Error>

Adds multiple annotations to a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.
annotations &std::collections::HashMap<String, String> A HashMap of key-value pairs to add.

Returns:

Returns the number of annotations added on success, or a diesel::result::Error on failure.

Source
pub fn add_annotations(
&self,
work_order_id: Uuid,
annotations: &std::collections::HashMap<String, String>,
) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
let new_annotations: Vec<NewWorkOrderAnnotation> = annotations
.iter()
.filter_map(|(key, value)| {
NewWorkOrderAnnotation::new(work_order_id, key.clone(), value.clone()).ok()
})
.collect();
diesel::insert_into(work_order_annotations::table)
.values(&new_annotations)
.execute(conn)
}

pub

fn list_annotations(
&self,
work_order_id: Uuid,
) -> Result<Vec<WorkOrderAnnotation>, diesel::result::Error>

Lists all annotations for a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.

Returns:

Returns a Vec of WorkOrderAnnotations on success, or a diesel::result::Error on failure.

Source
pub fn list_annotations(
&self,
work_order_id: Uuid,
) -> Result<Vec<WorkOrderAnnotation>, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
work_order_annotations::table
.filter(work_order_annotations::work_order_id.eq(work_order_id))
.load::<WorkOrderAnnotation>(conn)
}

pub

fn remove_annotation(
&self,
work_order_id: Uuid,
key: &str,
value: &str,
) -> Result<usize, diesel::result::Error>

Removes an annotation from a work order.

Parameters:

Name Type Description
work_order_id Uuid The UUID of the work order.
key &str The annotation key.
value &str The annotation value.

Returns:

Returns the number of annotations removed on success, or a diesel::result::Error on failure.

Source
pub fn remove_annotation(
&self,
work_order_id: Uuid,
key: &str,
value: &str,
) -> Result<usize, diesel::result::Error> {
let conn = &mut self.dal.conn()?;
diesel::delete(
work_order_annotations::table
.filter(work_order_annotations::work_order_id.eq(work_order_id))
.filter(work_order_annotations::key.eq(key))
.filter(work_order_annotations::value.eq(value)),
)
.execute(conn)
}