Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/monetize

crates/monetize-ui-server/src/code_red.rs

//! **CODE RED on the console** (owner 2026-10-18): what an automatic path left down — read on
//! every page, acknowledged by an operator. Thin: monetize keeps, decides and mails
//! (`EstateOrder.ListCodeRed` / `AckCodeRed`, the operator bearer's).
//!
//! ```text
//! GET  /api/code-red              → {items: [{key, site, box, what, error, next, raised_at_ms, acked_by, acked_at_ms}]}
//! POST /api/code-red/{key}/ack    → the same, that one acknowledged by the signed-in operator
//! ```

use axum::extract::{Path, State};
use axum::Json;
use monetize_proto as pb;
use serde::{Deserialize, Serialize};

use crate::api::ApiError;
use crate::app::AppState;
use crate::grpc::Fail;

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CodeRedJson {
    pub key: String,
    pub site: String,
    pub r#box: String,
    pub what: String,
    pub error: String,
    pub next: String,
    pub raised_at_ms: i64,
    pub acked_by: String,
    pub acked_at_ms: i64,
}

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CodeRedsJson {
    pub items: Vec<CodeRedJson>,
}

/// Pure: monetize's list as the browser reads it.
pub fn reds_json(r: pb::CodeRedList) -> CodeRedsJson {
    CodeRedsJson {
        items: r
            .items
            .into_iter()
            .map(|c| CodeRedJson { key: c.key, site: c.site, r#box: c.r#box, what: c.what, error: c.error, next: c.next, raised_at_ms: c.raised_at_unix_ms, acked_by: c.acked_by, acked_at_ms: c.acked_at_unix_ms })
            .collect(),
    }
}

fn operator(state: &AppState) -> Result<&crate::grpc::Monetize, ApiError> {
    state.operator.as_ref().ok_or_else(|| ApiError(Fail { code: "unavailable".into(), message: "this console holds no operator credential, so it cannot read CODE RED".into() }))
}

/// `GET /api/code-red`.
pub async fn list(State(state): State<AppState>) -> Result<Json<CodeRedsJson>, ApiError> {
    let r = operator(&state)?.estate_orders().list_code_red(pb::CodeRedListRequest {}).await?.into_inner();
    Ok(Json(reds_json(r)))
}

/// `POST /api/code-red/{key}/ack` — the signed-in operator saw it.
pub async fn ack(State(state): State<AppState>, caller: Option<axum::Extension<crate::auth::Caller>>, Path(key): Path<String>) -> Result<Json<CodeRedsJson>, ApiError> {
    let by = caller.map(|axum::Extension(c)| format!("console:{}", c.name())).unwrap_or_else(|| "console".to_owned());
    let r = operator(&state)?.estate_orders().ack_code_red(pb::CodeRedAckRequest { key: key.clone(), by: by.clone() }).await?.into_inner();
    tracing::info!(target: crate::auth::AUDIT_TARGET, event = "code_red.ack", user = %by, key = %key, "the operator acknowledged a CODE RED");
    Ok(Json(reds_json(r)))
}