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

nordisk/monetize

crates/monetize-server/src/services/reconcile_admin.rs

//! **`ReconcileAdmin.ListPaidAtVendor`** — the operator's read of what the
//! vendor says it took and monetize did not fulfil.
//!
//! One rpc, no write side. The store is [`crate::reconcile::ReconcileStore`],
//! written by the poller's reconcile pass alone, from the vendor's answer to
//! OUR authenticated read. An operator who acts on a row does so at the vendor
//! (a refund, by hand — nothing here refunds) or through `Entitlement.Set`,
//! where the act is recorded as an operator's.
//!
//! # Why a list as well as the bus
//!
//! The same reason `CallbackAdmin.ListRefusals` gives: every new case is also
//! published on `Events.Watch`, which lights up a console that is already
//! open, but the console that matters is the one opened after the fact, and
//! the bus is a ring with no log. "Tell me as it happens" and "tell me what
//! happened" are two questions.

use std::sync::Arc;

use monetize_proto::reconcile_admin_server::ReconcileAdmin;
use monetize_proto::{self as pb};
use tonic::{Request, Response, Status};

use super::blocking;
use crate::state::AppState;

pub struct ReconcileAdminService(pub Arc<AppState>);

#[tonic::async_trait]
impl ReconcileAdmin for ReconcileAdminService {
    async fn list_paid_at_vendor(
        &self,
        req: Request<pb::ListPaidAtVendorRequest>,
    ) -> Result<Response<pb::ListPaidAtVendorResponse>, Status> {
        let limit = req.into_inner().limit as usize;
        let out = blocking(&self.0, move |s| {
            let stats = s
                .reconcile
                .stats()
                .map_err(|e| Status::internal(format!("reconcile store: {e}")))?;
            let cases = s
                .reconcile
                .list(limit)
                .map_err(|e| Status::internal(format!("reconcile store: {e}")))?;
            Ok(pb::ListPaidAtVendorResponse {
                cases: cases
                    .iter()
                    .map(crate::reconcile::PaidUnfulfilled::to_pb)
                    .collect(),
                total: stats.total,
                needs_operator: stats.needs_operator,
                settled: stats.settled,
                last_reconcile_unix_ms: stats.last_pass_unix_ms,
            })
        })
        .await?;
        Ok(Response::new(out))
    }
}