crates/monetize-server/src/services/estate_order.rs
//! **`EstateOrder`** — the buy page's calls over [`crate::estate_order`]:
//! `Quote` (price + picture), `Start`, `Status`, the operator's `List`, and
//! for a delivered estate `Renew` and `ChangePlan`.
//! Thin: the job decides; this maps its words and refusals onto the wire.
use std::sync::Arc;
use monetize_proto as pb;
use monetize_proto::estate_order_server::EstateOrder;
use tonic::{Request, Response, Status};
use crate::estate_order::{self, EstateRun, EstateSizes, StartRefusal};
use crate::services::blocking;
use crate::state::AppState;
pub struct EstateOrderService(pub Arc<AppState>);
fn apex(s: &AppState) -> String {
apex_on(s, None)
}
/// ★ ST-5: **the apex of the site `site`** (the calling estate): `<company>.<apex>` is named
/// on the site it is bought on; the configured one where sites are not declared.
fn apex_on(s: &AppState, site: Option<&str>) -> String {
let Some(base) = s.estates.cfg.as_ref() else {
return String::new();
};
estate_order::terms_on(s, base, site)
.map(|c| c.apex)
.unwrap_or_else(|_| base.apex.clone())
}
/// The apex of the site `run` was bought on.
fn run_apex(s: &AppState, run: &EstateRun) -> String {
estate_order::run_terms(s, run)
.map(|c| c.apex)
.unwrap_or_else(|| apex(s))
}
/// ★ **A visitor's order, its account made when it is paid** (`EstateOrder.Start{new_account}`,
/// owner 2026-10-22): the name and the address judged as a signup's, the name held for the page,
/// the order started as [`estate_order::OrderedBy::NewAccount`]. ★ A33-1/A33-3: the ONE path a
/// visitor's order takes — the site's relay through `EstateOrder.Start`, and the operator's Test
/// buy (`test_purchase::start`), whose order differs only in `test_payer` (A33-2: data, the
/// vendor's TEST card paying the hold; empty: the visitor pays at the vendor's page).
pub fn start_visitor_order(
s: &AppState,
site: Option<&str>,
r: &pb::EstateOrderStartRequest,
sizes: &EstateSizes,
test_payer: &str,
) -> Result<EstateRun, Status> {
let account = estate_order::account::plain_account(site, r.account.trim()).map_err(|_| {
Status::invalid_argument("the account name: an account on this site, without @<site>/")
})?;
let cancel_to = crate::services::signup::order_cancel_page(s, site, &r.cancel_url)?;
let mut na = crate::services::signup::new_account_for_order(
s,
site,
&account,
r.email.trim(),
&r.welcome_url,
)?;
na.cancel_to = cancel_to;
na.test_payer = test_payer.to_owned();
let page_ms = s
.estates
.cfg
.as_ref()
.map(|c| c.order_ttl_secs.saturating_mul(1_000))
.unwrap_or(0);
crate::services::signup::hold_for_order(s, &na, page_ms)?;
let held = na.clone();
let run = estate_order::start_new_account(
s,
site,
r.company.trim(),
r.email.trim(),
r.domain.trim(),
sizes,
na,
)
.map_err(|e| {
crate::services::signup::release_order_hold(s, &held);
to_status(s)(e)
})?;
// ★ F-B-01: the visitor's retry was answered its own order: the name stays held for THAT
// order's page, never for the session this retry minted.
if let Some(own) = run
.new_account
.as_ref()
.filter(|own| own.session != held.session)
{
crate::services::signup::release_order_hold(s, &held);
crate::services::signup::hold_for_order(s, own, page_ms)?;
}
Ok(run)
}
/// **The SITE a call comes from** — its estate's own bearer ([`crate::auth::CallerEstate`]).
fn site_of<T>(req: &Request<T>) -> Option<String> {
req.extensions()
.get::<crate::auth::CallerEstate>()
.map(|e| e.0.clone())
}
/// **The operator, about one of his own SITE runs** (an operator-site order): the operator
/// marker ([`crate::auth::Operator`]: the operator bearer) on a call that is NOT a site's own
/// ([`crate::auth::CallerEstate`]). `Status`, `Cancel` and `Terminate` then need no account
/// ticket for a run that is a site order — and only for such a run.
fn operator_only<T>(req: &Request<T>) -> bool {
req.extensions().get::<crate::auth::Operator>().is_some()
&& req
.extensions()
.get::<crate::auth::CallerEstate>()
.is_none()
}
/// Whether `company` (a run's name, or a site's label) is a site order the operator may act on.
fn operators_site_run(s: &AppState, operator: bool, company: &str) -> bool {
operator && s.estates.get(company).is_some_and(|r| r.site_order)
}
/// The operator reads every refusal of a site order whole (these are his own sites).
pub(crate) fn site_refused(e: StartRefusal) -> Status {
match e {
StartRefusal::BadName(w) => Status::invalid_argument(w),
StartRefusal::Taken(w) => Status::already_exists(w),
StartRefusal::Vendor(w) | StartRefusal::Busy(w) => Status::unavailable(w),
StartRefusal::NotFound(w) => Status::not_found(w),
StartRefusal::NotSold(w) | StartRefusal::Price(w) | StartRefusal::NotNow(w) => {
Status::failed_precondition(w)
}
}
}
/// The buyer's sizes as the wire carries them, the product's own order (v2.0 P3) read as JSON:
/// an order that is not a JSON object is refused before anything is asked.
fn sizes_of(p: Option<pb::EstateSizes>) -> Result<EstateSizes, Status> {
let p = p.unwrap_or_default();
let order = estate_order::price::order_from_wire(&p.order).map_err(Status::invalid_argument)?;
Ok(EstateSizes {
front_plan: p.front_plan,
main_plan: p.main_plan,
main_data_gib: p.main_data_gib,
order,
})
}
/// The sizes as the wire carries them, the order as JSON.
fn sizes_to_wire(s: &EstateSizes) -> pb::EstateSizes {
pb::EstateSizes {
front_plan: s.front_plan.clone(),
main_plan: s.main_plan.clone(),
main_data_gib: s.main_data_gib,
order: estate_order::price::order_to_wire(&s.order),
}
}
/// ★ **What a visitor's paid order says about their new account** (pay once, owner
/// 2026-10-22) — never the account's name (the status is anyone's to read).
pub const ACCOUNT_LINK_MAILED: &str = "The sign-in link for your new account is in your mail: open it to register your passkey, then sign in.";
/// What a visitor reads where no private estate of the product is sold now — never this file's
/// keys or a cloud's name (A04; the operator's line is the log's), the product called as `w` says.
pub fn not_sold_here(w: &estate_order::lifecycle::ProductWords) -> String {
format!("A private {} is not sold here right now.", w.title)
}
/// **The buyer's words for what this shop sells** (its lifecycle's; none sold: neutral).
fn product_words(s: &AppState) -> estate_order::lifecycle::ProductWords {
estate_order::lifecycle::words_of(s.estates.cfg.as_ref())
}
/// **The proof a run's own domain carries** — its product's ([`estate_order::lifecycle::Lifecycle::proof_name`]).
fn run_proof(s: &AppState, run: &EstateRun) -> String {
estate_order::run_terms(s, run)
.as_ref()
.or(s.estates.cfg.as_ref())
.and_then(|c| estate_order::lifecycle::of(c).ok())
.map(|l| l.proof_name())
.unwrap_or_default()
}
/// **The buyer's words for one run** — on the terms of the site it was bought on.
fn run_words(s: &AppState, run: &EstateRun) -> estate_order::lifecycle::ProductWords {
estate_order::lifecycle::words_of(
estate_order::run_terms(s, run)
.as_ref()
.or(s.estates.cfg.as_ref()),
)
}
/// What a visitor reads for a size that cannot be priced now — never the
/// provider's cost, the margin, the currency rule or a plan list (wiring
/// trace B, ladder cap words; the operator's sentence is the log's).
pub const NOT_OFFERED_NOW: &str = "This size is not offered right now.";
fn to_status(s: &AppState) -> impl Fn(StartRefusal) -> Status + '_ {
move |e| to_status_in(e, &product_words(s))
}
fn to_status_in(e: StartRefusal, words: &estate_order::lifecycle::ProductWords) -> Status {
match e {
StartRefusal::NotSold(w) => {
eprintln!(
"monetize-server: estate order: not sold here: {}",
estate_order::log_safe(&w)
);
Status::failed_precondition(not_sold_here(words))
}
StartRefusal::BadName(w) => Status::invalid_argument(w),
StartRefusal::Taken(w) => Status::already_exists(w),
StartRefusal::Vendor(w) => Status::unavailable(w),
StartRefusal::Price(w) => {
eprintln!("monetize-server: estate order: a size not offered: {w}");
Status::failed_precondition(NOT_OFFERED_NOW)
}
StartRefusal::NotNow(w) => Status::failed_precondition(w),
// Transient: the run's pen stayed taken; nothing was held or changed.
StartRefusal::Busy(w) => Status::unavailable(w),
StartRefusal::NotFound(w) => Status::not_found(w),
}
}
/// An account that is not proven, on the wire: UNAUTHENTICATED in one
/// sentence, or UNAVAILABLE when the shop's Gunnar could not be asked.
fn unproven(s: &AppState) -> impl Fn(estate_order::account::Unproven) -> Status + '_ {
move |e| unproven_in(e, &product_words(s))
}
fn unproven_in(
e: estate_order::account::Unproven,
w: &estate_order::lifecycle::ProductWords,
) -> Status {
match e {
estate_order::account::Unproven::Refused => {
Status::unauthenticated(estate_order::account::not_proven(w))
}
estate_order::account::Unproven::Unavailable(why) => {
Status::unavailable(format!("the account cannot be checked right now: {why}"))
}
}
}
fn day(ms: u64) -> String {
if ms == 0 {
String::new()
} else {
estate_order::iso_date(ms)
}
}
#[tonic::async_trait]
impl EstateOrder for EstateOrderService {
async fn start(
&self,
req: Request<pb::EstateOrderStartRequest>,
) -> Result<Response<pb::EstateOrderStartResponse>, Status> {
let site = site_of(&req);
let r = req.into_inner();
// **A private Gunnar is its buyer's** (private ownership, 2026-10-07):
// the order names the account its first admin is to have, or nothing
// is held — the kit installs no sold estate under its own operator.
if r.account.trim().is_empty() {
return Err(Status::invalid_argument(format!("a private {} is its buyer's: name the account its first admin is to have (EstateOrderStartRequest.account)", product_words(&self.0).title)));
}
// **…and the account is PROVEN** (one shop, 2026-10-07): the `estate`
// ticket THIS shop's own Gunnar minted for it, checked before anything
// is held. The run's account is the proven one.
// ★ **Or it is a visitor's NEW account, paid once** (owner 2026-10-22): no ticket, the
// name and the address judged as a signup's before any money, the name held for the
// page, and the account made when the order is paid.
let state = self.0.clone();
let sizes = sizes_of(r.sizes.clone())?;
if r.actor_ticket.is_empty() && r.new_account {
let run = blocking(&self.0, move |s| {
start_visitor_order(s, site.as_deref(), &r, &sizes, "")
})
.await?;
estate_order::nudge(&state).await;
let (st, words, _) =
run.customer_view_as(&run_apex(&state, &run), &run_words(&state, &run));
return Ok(Response::new(pb::EstateOrderStartResponse {
reference: run.reference,
checkout_url: run.checkout_url,
state: st,
words,
price_words: run.amount.in_words(),
}));
}
let run = blocking(&self.0, move |s| {
// ★ ST-3/ST-5: proven under the calling site's key, held through ITS account.
let account = estate_order::account::plain_account(site.as_deref(), r.account.trim())
.map_err(|_| unproven(s)(estate_order::account::Unproven::Refused))?;
estate_order::account::proven(s, site.as_deref(), &account, &r.actor_ticket)
.map_err(unproven(s))?;
// ★ The account's OWN address (owner 2026-10-22: the e-mail is not changed in the buy).
let email = crate::services::signup::account_email(
s,
site.as_deref(),
&account,
r.email.trim(),
)?;
// A10 row 6: the console's own cancel page, when it names one.
let cancel_to =
crate::services::signup::order_cancel_page(s, site.as_deref(), &r.cancel_url)?;
if cancel_to.is_empty() {
estate_order::start_on(
s,
site.as_deref(),
r.company.trim(),
&email,
r.domain.trim(),
&account,
&sizes,
)
.map_err(to_status(s))
} else {
let by = estate_order::OrderedBy::Shop {
back_to: String::new(),
cancel_to,
};
estate_order::start_with_on(
s,
site.as_deref(),
r.company.trim(),
&email,
r.domain.trim(),
&account,
&sizes,
&by,
)
.map_err(to_status(s))
}
})
.await?;
// The job is driven from here on by the tick; nudge it now so the
// page's first poll already sees the vendor's answer.
estate_order::nudge(&state).await;
let (st, words, _) =
run.customer_view_as(&run_apex(&state, &run), &run_words(&state, &run));
Ok(Response::new(pb::EstateOrderStartResponse {
reference: run.reference,
checkout_url: run.checkout_url,
state: st,
words,
price_words: run.amount.in_words(),
}))
}
async fn status(
&self,
req: Request<pb::EstateOrderStatusRequest>,
) -> Result<Response<pb::EstateOrderStatusResponse>, Status> {
let site = site_of(&req);
let operator = operator_only(&req);
let r = req.into_inner();
let company = r.company.trim().to_string();
let run = self
.0
.estates
.get(&company)
.ok_or_else(|| Status::not_found(format!("no order for {company:?}")))?;
// The operator reads his own site run whole, with no account ticket.
let operators = operator && run.site_order;
let apex = run_apex(&self.0, &run);
let w = run_words(&self.0, &run);
let (state, words, url) = if operators {
estate_order::site::operator_view_held(&self.0, &run, run.operator_view_as(&apex, &w))
} else {
run.customer_view_as(&apex, &w)
};
// An install that makes no progress names why, to the operator (test3-holger-rs 2026-10-22).
let words = if operators {
estate_order::install_why::with_why(&self.0, &run, words)
} else {
words
};
// ★ Pay once (owner 2026-10-22): a visitor's paid order made their account; its link is mailed.
let words = if run.new_account.is_some()
&& run.captured_at_ms > 0
&& !operators
&& !estate_order::phase::is_gone(&run.phase)
{
format!("{words} {ACCOUNT_LINK_MAILED}")
} else {
words
};
// **An order's dates, records and address are its account's** (A18):
// with its `estate` ticket the whole answer; without one the state
// word and its sentence only.
if r.actor_ticket.is_empty() && !operators {
return Ok(Response::new(pb::EstateOrderStatusResponse {
company: run.company.clone(),
state,
words,
..Default::default()
}));
}
if !operators {
let (company, ticket) = (company.clone(), r.actor_ticket.clone());
blocking(&self.0, move |s| {
estate_order::account::owner_of(s, site.as_deref(), &company, &ticket)
.map(|_| ())
.map_err(unproven(s))
})
.await?;
}
let dns_records = if run.phase == estate_order::phase::WAITING_DNS {
run.customer_records_as(&apex, &run_proof(&self.0, &run))
.into_iter()
.map(|r| pb::EstateDnsRecord {
name: r.name,
kind: r.kind,
value: r.value,
})
.collect()
} else {
Vec::new()
};
// FIRST-LINK-1: a laid site's first-admin door, the operator's alone (its own door is
// asked while the custody holds the invite; after the hand-off, its main's answer).
// HOL-MAIL: and the newest order its main answered, mailed or refused.
// MAIL-RELAY: and the newest `refeed` order its primary answered, kept or refused.
let (
(first_admin_door, first_admin_door_words),
(first_link_answered, first_link_mailed),
(refeed_answered, refeed_kept, refeed_words),
) = if operators {
let run = run.clone();
blocking(&self.0, move |s| {
Ok((
estate_order::first_link::door_of(s, &run),
estate_order::first_link::answer_of(s, &run),
estate_order::refeed::answer_of(s, &run),
))
})
.await?
} else {
Default::default()
};
let shown = run.change.as_ref().or(run.changes.last());
let change_status = shown.map(|c| c.status.clone()).unwrap_or_default();
// What the change does; WHY only when it failed — a change that waits
// (for the day's batch, the notice, the operator's cap) is the
// operator's business, never the buyer's (A53).
let change_words = shown
.map(|c| {
if c.status == estate_order::change::status::FAILED && !c.why.is_empty() {
c.why.clone()
} else {
c.words.clone()
}
})
.unwrap_or_default();
Ok(Response::new(pb::EstateOrderStatusResponse {
company: run.company.clone(),
state,
words,
url,
phase: run.phase.clone(),
dns_records,
// A site never lapses: no "paid until" (2026-10-14).
paid_until: if run.site_order {
String::new()
} else {
day(run.paid_until_ms)
},
change_status,
change_words,
// The run's own reason, the operator's alone (test3-holger-rs 2026-10-22).
why: if operators {
run.why_said().map(|w| w.0).unwrap_or_default()
} else {
String::new()
},
why_since: if operators {
run.why_said().map(|w| w.1).unwrap_or_default()
} else {
String::new()
},
first_admin_door,
first_admin_door_words,
first_link_answered,
first_link_mailed,
refeed_answered,
refeed_kept,
refeed_words,
}))
}
async fn send_sign_in_again(
&self,
req: Request<pb::EstateOrderSignInAgainRequest>,
) -> Result<Response<pb::EstateOrderSignInAgainResponse>, Status> {
let site = site_of(&req);
let req = req.into_inner();
let company = req.company.trim().to_string();
let words = blocking(&self.0, move |s| {
// The order's account alone (its `estate` ticket) asks for its sign-in link.
estate_order::account::owner_of(s, site.as_deref(), &company, &req.actor_ticket)
.map_err(unproven(s))?;
estate_order::send_sign_in_again(s, &company).map_err(to_status(s))
})
.await?;
Ok(Response::new(pb::EstateOrderSignInAgainResponse { words }))
}
async fn renew(
&self,
req: Request<pb::EstateOrderRenewRequest>,
) -> Result<Response<pb::EstateOrderRenewResponse>, Status> {
let site = site_of(&req);
let req = req.into_inner();
let company = req.company.trim().to_string();
let state = self.0.clone();
let (r, paid_until) = blocking(&self.0, move |s| {
// An estate is its account's to renew (A52): its `estate` ticket.
estate_order::account::owner_of(s, site.as_deref(), &company, &req.actor_ticket)
.map_err(unproven(s))?;
let r = estate_order::renew(s, &company).map_err(to_status(s))?;
let paid = s
.estates
.get(&company)
.map(|run| run.paid_until_ms)
.unwrap_or(0);
Ok((r, paid))
})
.await?;
estate_order::nudge(&state).await;
let term = state
.estates
.get(r.reference.split('/').nth(1).unwrap_or_default())
.map(|run| estate_order::price::term_words(run.quote.term_months, run.quote.term_days))
.unwrap_or_else(|| "1 month".into());
let words = format!(
"{term} more: {} ({} a month). Pay on the payment page; it is charged at once.",
r.amount.in_words(),
r.monthly.in_words()
);
Ok(Response::new(pb::EstateOrderRenewResponse {
reference: r.reference,
checkout_url: r.checkout_url,
price_words: r.amount.in_words(),
paid_until: day(paid_until),
words,
}))
}
/// **The account's own** (one shop, 2026-10-07): a plan change stops main
/// and holds money, so it is taken only for the run's account's `estate`
/// ticket ([`estate_order::account::owner_of`]).
/// **The operator** (the operator bearer, no site's own beside it) changes one of his own
/// SITE runs with no ticket, as `Cancel` and `Terminate` (MONETIZE-FIX 2026-11-01: a gate
/// drives a site's grow); `test_order` holds a dearer change with the site's vendor's TEST
/// card. A customer's sold estate stays its account's.
async fn change_plan(
&self,
req: Request<pb::EstateOrderChangePlanRequest>,
) -> Result<Response<pb::EstateOrderChangePlanResponse>, Status> {
let site = site_of(&req);
let operator = operator_only(&req);
let r = req.into_inner();
let state = self.0.clone();
let sizes = sizes_of(r.sizes)?;
let company = r.company.trim().to_string();
let c = blocking(&self.0, move |s| {
if operators_site_run(s, operator, &company) {
let run = s.estates.get(&company).ok_or_else(|| Status::not_found(format!("{company} is gone")))?;
let payer = if r.test_order { Some(estate_order::site::site_test_card(s, &run.estate).map_err(site_refused)?) } else { None };
return estate_order::change::change_paid_by(s, &run.company, &sizes, None, payer.as_deref()).map_err(site_refused);
}
estate_order::account::owner_of(s, site.as_deref(), &company, &r.actor_ticket).map_err(unproven(s))?;
if r.test_order {
return Err(Status::invalid_argument("REFUSED [test-order-not-a-site] a test change is the operator's, of his own site: nothing was held"));
}
estate_order::change::change(s, &company, &sizes).map_err(to_status(s))
})
.await?;
estate_order::nudge(&state).await;
Ok(Response::new(pb::EstateOrderChangePlanResponse {
reference: c.reference,
checkout_url: c.checkout_url,
status: c.status,
words: c.words,
price_words: c.amount.in_words(),
twin_plan: c.to_twin,
}))
}
async fn ladder(
&self,
req: Request<pb::EstateOrderLadderRequest>,
) -> Result<Response<pb::EstateOrderLadderResponse>, Status> {
let site = site_of(&req);
let r = req.into_inner();
let company = r.company.trim().to_string();
// **The page's price list never waits on a busy cloud** (A32): the
// new-estate ladder last priced is answered at once while it is
// younger than a minute, and an older one is answered and priced
// again beside. An ESTATE's step is its account's, priced now.
// Kept per CALLING site: each site's page reads the ladder priced on its own terms.
let key = site.clone().unwrap_or_default();
if company.is_empty() {
let now = self.0.now();
let kept = self
.0
.estates
.ladder_seen
.lock()
.unwrap_or_else(|p| p.into_inner())
.get(&key)
.cloned();
if let Some((l, at)) = kept {
if now.saturating_sub(at) >= estate_order::SELLS_FRESH_MS
&& self
.0
.estates
.ladder_refreshing
.lock()
.unwrap_or_else(|p| p.into_inner())
.insert(key.clone())
{
// A jera job on the site's lane (A32-14, LADDER-1): a re-price that fails is said
// and a FAILED row, and the site is let go on every path (a panicked detached
// task left it "refreshing" for good: its ladder was never priced again).
let (st, k, on) = (self.0.clone(), key.clone(), site.clone());
let started =
crate::jobs::once(LADDER_JOB, &crate::jobs::of(&self.0, &key), move || {
let (st2, k2) = (st.clone(), k.clone());
let _let_go = crate::jobs::Finally(move || {
st2.estates
.ladder_refreshing
.lock()
.unwrap_or_else(|p| p.into_inner())
.remove(&k2);
});
let fresh = estate_order::ladder::ladder_on(&st, on.as_deref(), "")
.map_err(|e| format!("the ladder could not be priced: {e}"))?;
let at = st.now();
st.estates
.ladder_seen
.lock()
.unwrap_or_else(|p| p.into_inner())
.insert(k.clone(), (fresh, at));
Ok(())
});
if !matches!(started, Ok(true)) {
self.0
.estates
.ladder_refreshing
.lock()
.unwrap_or_else(|p| p.into_inner())
.remove(&key);
}
}
return Ok(Response::new(ladder_response(l)));
}
}
let fresh_for_page = company.is_empty();
let l = blocking(&self.0, move |s| {
if !company.is_empty() {
estate_order::account::owner_of(s, site.as_deref(), &company, &r.actor_ticket)
.map_err(unproven(s))?;
}
estate_order::ladder::ladder_on(s, site.as_deref(), &company).map_err(to_status(s))
})
.await?;
if fresh_for_page {
self.0
.estates
.ladder_seen
.lock()
.unwrap_or_else(|p| p.into_inner())
.insert(key, (l.clone(), self.0.now()));
}
Ok(Response::new(ladder_response(l)))
}
/// **What an account bought here** (one shop, 2026-10-07): its private
/// Gunnars, newest first — every order it owns that is not gone — and its
/// room here, for the account's `estate` ticket.
async fn purchases(
&self,
req: Request<pb::EstateOrderPurchasesRequest>,
) -> Result<Response<pb::EstateOrderPurchasesResponse>, Status> {
let site = site_of(&req);
let r = req.into_inner();
let out = blocking(&self.0, move |s| {
let site = site.as_deref();
// ★ ST-3/ST-4: the calling site's account, proven under that site's key; its
// orders are the ones bought on that site, its room is on that site's ledger name.
let account = estate_order::account::plain_account(site, r.account.trim())
.map_err(|_| unproven(s)(estate_order::account::Unproven::Refused))?;
estate_order::account::proven(s, site, &account, &r.actor_ticket)
.map_err(unproven(s))?;
let mut runs: Vec<EstateRun> = estate_order::list(s)
.into_iter()
.filter(|run| run.account == account && !estate_order::phase::is_gone(&run.phase))
.filter(|run| {
site.is_none() || estate_order::site_of_run(s, run).as_deref() == site
})
.collect();
runs.sort_by_key(|run| std::cmp::Reverse(run.ordered_at_ms));
let estates = runs
.iter()
.map(|run| purchase_of(s, run, &run_apex(s, run)))
.collect();
let product = match site.and_then(|e| s.registry.product_of_estate(e)) {
Some(p) => p,
None => s
.sold_product()
.map_err(Status::failed_precondition)?
.to_owned(),
};
let product = product.as_str();
let account = crate::site_ticket::tenant_on(s, product, site, &account)
.map_err(|_| unproven(s)(estate_order::account::Unproven::Refused))?;
let facts = s
.ledger
.entitlements(product)
.map_err(|e| Status::internal(format!("ledger: {e}")))?;
let facts = crate::signup::with_signup_facts(s, product, facts)
.map_err(|e| Status::internal(format!("signup store: {e}")))?;
let meter = s.signup_plans.cap_meter_of(product);
let rooms = estate_order::account::rooms_of(&facts, &account, &meter)
.into_iter()
.map(|room| pb::RoomPurchase {
state: room.state,
paid_until: room.paid_until_ms.map(day).unwrap_or_default(),
cap_bytes: room.cap_bytes,
})
.collect();
let account_here = estate_order::account::is_account_here(&facts, &account, &meter);
Ok(pb::EstateOrderPurchasesResponse {
estates,
rooms,
account_here,
})
})
.await?;
Ok(Response::new(out))
}
/// **LEGACY (G16, ONE monetize):** the notice a sold estate's OWN
/// monetize heard from its shop. No estate runs a monetize, and the ONE
/// monetize is nobody's sold estate: always nothing. A sold estate hears
/// its resize notice on the pull channel.
async fn notice(
&self,
_req: Request<pb::EstateNoticeRequest>,
) -> Result<Response<pb::EstateNoticeResponse>, Status> {
Ok(Response::new(pb::EstateNoticeResponse::default()))
}
/// **Whether private estates are sold here** (the sign-up page, owner
/// 2026-10-08): `[estate_orders]` is configured AND a step of the ladder
/// can be bought now ([`estate_order::sells_now`]; test2 2026-10-08: every
/// step was unavailable — its cloud lays no estate — and the page still
/// offered "Private Gunnar"). The console offers no private choice where
/// it is not, so its visitor never reads a refusal about this file or this
/// cloud. Moves nothing: the provider's price list is read until the first
/// step is priced, as the ladder reads it.
/// **The buyer stops renewing** (A51): the account's own, by its ticket.
async fn cancel(
&self,
req: Request<pb::EstateOrderCancelRequest>,
) -> Result<Response<pb::EstateOrderCancelResponse>, Status> {
let site = site_of(&req);
let operator = operator_only(&req);
let r = req.into_inner();
let company = r.company.trim().to_string();
let c = blocking(&self.0, move |s| {
if operators_site_run(s, operator, &company) {
let company = s
.estates
.get(&company)
.map(|r| r.company)
.unwrap_or(company);
return estate_order::cancel(s, &company).map_err(to_status(s));
}
estate_order::account::owner_of(s, site.as_deref(), &company, &r.actor_ticket)
.map_err(unproven(s))?;
estate_order::cancel(s, &company).map_err(to_status(s))
})
.await?;
Ok(Response::new(pb::EstateOrderCancelResponse {
words: c.words,
paid_until: day(c.paid_until_ms),
delete_on: day(c.delete_on_ms),
}))
}
/// **S8: the buyer asks its lost front back from its daily backup** — the account's own, by
/// its ticket (as `cancel`); never the front's call (a dead front signs nothing).
async fn restore_front(
&self,
req: Request<pb::EstateOrderRestoreFrontRequest>,
) -> Result<Response<pb::EstateOrderRestoreFrontResponse>, Status> {
let site = site_of(&req);
let r = req.into_inner();
let company = r.company.trim().to_string();
let a = blocking(&self.0, move |s| {
let run =
estate_order::account::owner_of(s, site.as_deref(), &company, &r.actor_ticket)
.map_err(unproven(s))?;
estate_order::sold::restore_front(
s,
&company,
estate_order::sold::RestoreBy::Buyer(run.account),
)
.map_err(sold_status)
})
.await?;
Ok(Response::new(pb::EstateOrderRestoreFrontResponse {
words: a.words,
moved: a.moved,
public_ipv4: a.machine.public_ipv4,
}))
}
/// **TERMINATE a sold Gunnar** (owner 2026-10-12): the operator's own sites are refused as
/// protected before anything is asked; then the account's own, by its ticket (as
/// `cancel`); the name typed back, the backup offered first ([`estate_order::terminate`]).
/// **The operator** (the operator bearer, never a site's own beside it) ends a SOLD estate
/// too, by the same path with no ticket (owner 2026-10-22): no backup offered, the history
/// saying the operator did it, no money moved ([`estate_order::terminate::terminate_as`]).
async fn terminate(
&self,
req: Request<pb::EstateOrderTerminateRequest>,
) -> Result<Response<pb::EstateOrderTerminateResponse>, Status> {
let site = site_of(&req);
let operator = operator_only(&req);
let r = req.into_inner();
let company = r.company.trim().to_ascii_lowercase();
let t = blocking(&self.0, move |s| {
if let Some(why) = estate_order::terminate::protected(s, &company) {
return Err(Status::failed_precondition(why));
}
// The operator ends his own site run, and a customer's sold estate (owner
// 2026-10-22), with no account ticket (its protection — `terminable` — and the name
// typed back are the terminate's own to judge).
let by = if operator {
estate_order::terminate::AskedBy::Operator
} else {
estate_order::terminate::AskedBy::Account
};
if !operator {
estate_order::account::owner_of(s, site.as_deref(), &company, &r.actor_ticket)
.map_err(unproven(s))?;
}
estate_order::terminate::terminate_as(
s,
site.as_deref(),
&company,
r.confirm.trim(),
by,
)
.map_err(to_status(s))
})
.await?;
Ok(Response::new(pb::EstateOrderTerminateResponse {
words: t.words,
done: t.done,
}))
}
/// **The operator sends a laid site's first sign-in link again, to a new address** (owner
/// 2026-10-22, [`estate_order::first_link`]). The operator's alone.
async fn first_link(
&self,
req: Request<pb::EstateOrderFirstLinkRequest>,
) -> Result<Response<pb::EstateOrderFirstLinkResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"sending a site's first sign-in link is the operator's: the operator bearer",
));
}
let r = req.into_inner();
let a = blocking(&self.0, move |s| {
estate_order::first_link::first_link_asking(s, &r.estate, &r.to).map_err(site_refused)
})
.await?;
Ok(Response::new(pb::EstateOrderFirstLinkResponse {
words: a.words,
asked: a.asked,
}))
}
/// **The operator feeds a laid estate's boxes its keys again** (MAIL-RELAY + NIGHT-PUBREPO
/// 2026-10-28, [`estate_order::refeed`]). The operator's alone.
async fn refeed(
&self,
req: Request<pb::EstateOrderRefeedRequest>,
) -> Result<Response<pb::EstateOrderRefeedResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"feeding a site's boxes their keys again is the operator's: the operator bearer",
));
}
let r = req.into_inner();
let a = blocking(&self.0, move |s| {
estate_order::refeed::feed(s, &r.estate, &r.only).map_err(site_refused)
})
.await?;
Ok(Response::new(pb::EstateOrderRefeedResponse {
words: a.words,
asked: a.asked,
}))
}
/// **A product's own order on one of the operator's sites** (MONETIZE-FIX,
/// [`estate_order::product_order`]). The operator's alone.
async fn product_order(
&self,
req: Request<pb::EstateProductOrderRequest>,
) -> Result<Response<pb::EstateProductOrderResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"a product order on a site is the operator's: the operator bearer",
));
}
let r = req.into_inner();
let params: std::collections::BTreeMap<String, String> = r.params.into_iter().collect();
let q = blocking(&self.0, move |s| {
estate_order::product_order::queue(
s,
&r.estate,
&r.kind,
¶ms,
(!r.file.is_empty()).then_some(r.file.as_slice()),
)
.map_err(site_refused)
})
.await?;
Ok(Response::new(pb::EstateProductOrderResponse {
words: q.words,
seq: q.seq,
role: q.role,
}))
}
async fn product_order_answer(
&self,
req: Request<pb::EstateProductOrderAnswerRequest>,
) -> Result<Response<pb::EstateProductOrderAnswerResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"a site's product order answers are the operator's: the operator bearer",
));
}
let r = req.into_inner();
let a = blocking(&self.0, move |s| {
estate_order::product_order::answer(s, &r.estate, r.seq).map_err(site_refused)
})
.await?;
Ok(Response::new(pb::EstateProductOrderAnswerResponse {
kind: a.kind,
answered: a.answered,
ok: a.ok,
detail: a.detail,
}))
}
async fn product_order_kinds(
&self,
req: Request<pb::EstateProductOrderKindsRequest>,
) -> Result<Response<pb::EstateProductOrderKindsResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"a site's product orders are the operator's: the operator bearer",
));
}
let r = req.into_inner();
let kinds = blocking(&self.0, move |s| {
estate_order::product_order::kinds(s, &r.estate).map_err(site_refused)
})
.await?;
let kinds = kinds
.into_iter()
.map(|k| pb::EstateProductOrderKind {
kind: k.kind,
role: k.role,
words: k.words,
params: k
.params
.into_iter()
.map(|p| pb::EstateProductOrderParam {
name: p.name,
words: p.words,
required: p.required,
})
.collect(),
file: k.file,
})
.collect();
Ok(Response::new(pb::EstateProductOrderKindsResponse { kinds }))
}
/// **The operator orders one of his own sites laid by this box** ([`estate_order::site`]).
/// The operator's alone: never a site's own bearer, never the service bearer.
async fn order_site(
&self,
req: Request<pb::EstateOrderSiteRequest>,
) -> Result<Response<pb::EstateOrderSiteResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied("ordering a site is the operator's: the operator bearer — never a site's own, never the service bearer"));
}
let r = req.into_inner();
let state = self.0.clone();
// ★ `site test-order`: the vendor's TEST card pays it server-side, a test key's only.
if r.test_order && !r.return_url.trim().is_empty() {
return Err(Status::invalid_argument("REFUSED [test-order-return] a test order opens no page, so it names no return page"));
}
let (run, card) = blocking(&self.0, move |s| {
let sizes = estate_order::site::sizes_of_on(s, Some(r.estate.trim()), &r.size)
.map_err(Status::invalid_argument)?;
if r.test_order {
estate_order::site::start_site_test(
s,
r.estate.trim(),
r.email.trim(),
&sizes,
&r.seed_key,
)
.map_err(site_refused)
} else {
estate_order::site::start_site_back_to(
s,
r.estate.trim(),
r.email.trim(),
&sizes,
&r.seed_key,
&r.return_url,
)
.map(|run| (run, String::new()))
.map_err(site_refused)
}
})
.await?;
// Nudged now, so the next read already sees the vendor's answer.
estate_order::nudge(&state).await;
let words = if card.is_empty() {
format!(
"{} is ordered: pay {} at the payment page, and this box lays it",
run.estate,
run.amount.in_words()
)
} else {
format!("{} is ordered and paid with the vendor's TEST card ({card}): {} held, nobody pays at a page, and this box lays it", run.estate, run.amount.in_words())
};
Ok(Response::new(pb::EstateOrderSiteResponse {
reference: run.reference,
checkout_url: run.checkout_url,
price_words: run.amount.in_words(),
words,
company: run.company,
}))
}
/// **The operator's sites** and the sizes on offer ([`estate_order::site::sites`]).
async fn list_sites(
&self,
req: Request<pb::EstateSitesRequest>,
) -> Result<Response<pb::EstateSitesResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"the sites are the operator's to read: the operator bearer",
));
}
let (sites, sizes) = blocking(&self.0, |s| {
Ok((
estate_order::site::sites(s),
estate_order::site::sizes_on_offer(s),
))
})
.await?;
let sites = sites
.into_iter()
.map(|v| pb::EstateSite {
estate: v.estate,
domain: v.domain,
vendor: v.vendor,
first_admin: v.first_admin,
dns_words: v.dns_words,
dns_writes: v.dns_writes,
cloud_words: v.cloud_words,
state: v.state,
words: v.words,
checkout_url: v.checkout_url,
orderable: v.why_not.is_empty(),
why_not: v.why_not,
terminable: v.terminable,
recheckable: v.recheckable,
why: v.why,
why_since: v.why_since,
price_words: v.price_words,
})
.collect();
Ok(Response::new(pb::EstateSitesResponse { sites, sizes }))
}
/// **An estate's own console about its MAIN** (main rebuild, owner 2026-10-12): the estate
/// is the one the site bearer names ([`site_of`]); see [`crate::fleet::rebuild_main`].
async fn rebuild_main(
&self,
req: Request<pb::EstateRebuildMainRequest>,
) -> Result<Response<pb::EstateRebuildMainResponse>, Status> {
let site = site_of(&req);
let r = req.into_inner();
let a = blocking(&self.0, move |s| {
crate::fleet::rebuild_main(s, site.as_deref(), r.press, &r.principal, r.strong).map_err(
|e| match e {
crate::fleet::RebuildRefusal::NotAnEstate(w) => Status::unauthenticated(w),
crate::fleet::RebuildRefusal::Nothing(w) => Status::failed_precondition(w),
crate::fleet::RebuildRefusal::Press(p) => {
crate::services::fleet::press_refusal(p)
}
},
)
})
.await?;
Ok(Response::new(pb::EstateRebuildMainResponse {
finding: a.finding,
words: a.words,
remedy: a.remedy,
case_id: a.case_id,
case_state: a.case_state,
steps: a.steps,
outcome: a.outcome,
auto_fix: a.auto_fix,
}))
}
/// **The operator settles an order** (A23/A50): `retry` | `refund`. The
/// OPERATOR's alone — the bearer the customer-facing BFF holds is refused.
async fn settle(
&self,
req: Request<pb::EstateOrderSettleRequest>,
) -> Result<Response<pb::EstateOrderSettleResponse>, Status> {
if req.extensions().get::<crate::auth::Operator>().is_none() {
return Err(Status::permission_denied(
"settling an order is the operator's: the operator bearer or a console principal",
));
}
let r = req.into_inner();
let state = self.0.clone();
let (company, action) = (r.company.trim().to_string(), r.action.trim().to_string());
let run = blocking(&self.0, move |s| {
estate_order::settle(s, &company, &action).map_err(to_status(s))
})
.await?;
estate_order::nudge(&state).await;
let words = run
.history
.last()
.map(|t| t.note.clone())
.unwrap_or_default();
Ok(Response::new(pb::EstateOrderSettleResponse {
phase: run.phase,
words,
}))
}
async fn sells(
&self,
_req: Request<pb::EstateOrderSellsRequest>,
) -> Result<Response<pb::EstateOrderSellsResponse>, Status> {
// **Never waits on a busy cloud** (A32: a lay holds the cloud guest's
// one lock for minutes, and the console waits two seconds): a kept
// answer, however old, is given at once and refreshed beside.
let estates = match estate_order::sells_kept(&self.0) {
Some((sells, true)) => sells,
Some((sells, false)) => {
if !self
.0
.estates
.sells_refreshing
.swap(true, std::sync::atomic::Ordering::SeqCst)
{
// A jera job (A32-14): the flag is put back on every path (a panicked detached
// task left it set, and the sells word was never read again).
let st = self.0.clone();
let started = crate::jobs::once(
SELLS_JOB,
&crate::jobs::of(&self.0, "sells"),
move || {
let st2 = st.clone();
let _let_go = crate::jobs::Finally(move || {
st2.estates
.sells_refreshing
.store(false, std::sync::atomic::Ordering::SeqCst)
});
estate_order::sells_refresh(&st);
Ok(())
},
);
if !matches!(started, Ok(true)) {
self.0
.estates
.sells_refreshing
.store(false, std::sync::atomic::Ordering::SeqCst);
}
}
sells
}
None => blocking(&self.0, |s| Ok(estate_order::sells_now(s))).await?,
};
Ok(Response::new(pb::EstateOrderSellsResponse { estates }))
}
/// **The operator updates an estate or site this box laid** ([`estate_order::update`]).
async fn update_estate(
&self,
req: Request<pb::EstateUpdateRequest>,
) -> Result<Response<pb::EstateUpdateResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"updating an estate is the operator's: the operator bearer",
));
}
let r = req.into_inner();
let estate = r.estate.trim().to_string();
let st = blocking(&self.0, move |s| {
if r.front_first {
estate_order::update::start_front_first(s, &estate, r.release.trim(), "operator")
} else {
estate_order::update::start(s, &estate, r.release.trim(), "operator")
}
.map_err(sold_status)?;
estate_order::update::status(s, &estate).map_err(sold_status)
})
.await?;
Ok(Response::new(update_pb(st)))
}
/// Where an estate's update stands.
async fn update_status(
&self,
req: Request<pb::EstateUpdateStatusRequest>,
) -> Result<Response<pb::EstateUpdateResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"an estate's update is the operator's to read: the operator bearer",
));
}
let estate = req.into_inner().estate.trim().to_string();
let st = blocking(&self.0, move |s| {
estate_order::update::status(s, &estate).map_err(sold_status)
})
.await?;
Ok(Response::new(update_pb(st)))
}
/// ★ A32-7: the operator cancels an estate's open update ([`estate_order::update::cancel`]).
async fn cancel_update(
&self,
req: Request<pb::EstateUpdateStatusRequest>,
) -> Result<Response<pb::EstateUpdateResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"cancelling an estate's update is the operator's: the operator bearer",
));
}
let estate = req.into_inner().estate.trim().to_string();
let st = blocking(&self.0, move |s| {
estate_order::update::cancel(s, &estate, "operator").map_err(sold_status)?;
estate_order::update::status(s, &estate).map_err(sold_status)
})
.await?;
Ok(Response::new(update_pb(st)))
}
/// Live updates on or OFF for one estate.
async fn set_live_update(
&self,
req: Request<pb::EstateSetLiveUpdateRequest>,
) -> Result<Response<pb::EstateUpdateResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"live updates are the operator's to switch: the operator bearer",
));
}
let r = req.into_inner();
let estate = r.estate.trim().to_string();
let st = blocking(&self.0, move |s| {
estate_order::update::set_live(s, &estate, r.on, "operator").map_err(sold_status)?;
estate_order::update::status(s, &estate).map_err(sold_status)
})
.await?;
Ok(Response::new(update_pb(st)))
}
/// **The operator adopts a kit-installed site** ([`estate_order::adopt`]): its run made, its
/// client key minted; the front's feed lines answered once.
async fn list_code_red(
&self,
req: Request<pb::CodeRedListRequest>,
) -> Result<Response<pb::CodeRedList>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"CODE RED is the operator's to read: the operator bearer",
));
}
Ok(Response::new(code_red_pb(estate_order::code_red::list(
&self.0,
))))
}
async fn ack_code_red(
&self,
req: Request<pb::CodeRedAckRequest>,
) -> Result<Response<pb::CodeRedList>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"CODE RED is the operator's to acknowledge: the operator bearer",
));
}
let r = req.into_inner();
let by = if r.by.trim().is_empty() {
"operator".to_string()
} else {
r.by.trim().to_string()
};
estate_order::code_red::ack(&self.0, r.key.trim(), &by).map_err(Status::not_found)?;
Ok(Response::new(code_red_pb(estate_order::code_red::list(
&self.0,
))))
}
async fn raise_code_red(
&self,
req: Request<pb::CodeRed>,
) -> Result<Response<pb::CodeRedList>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"CODE RED is raised by the box itself: the operator bearer",
));
}
let c = req.into_inner();
if c.key.trim().is_empty() {
return Err(Status::invalid_argument("a CODE RED is raised under a key"));
}
estate_order::code_red::raise(
&self.0,
c.key.trim(),
&c.site,
&c.r#box,
&c.what,
&c.error,
&c.next,
);
Ok(Response::new(code_red_pb(estate_order::code_red::list(
&self.0,
))))
}
async fn clear_code_red(
&self,
req: Request<pb::CodeRedClearRequest>,
) -> Result<Response<pb::CodeRedList>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied(
"CODE RED is cleared by the box itself: the operator bearer",
));
}
let prefix = req.into_inner().prefix;
if prefix.trim().is_empty() {
return Err(Status::invalid_argument(
"a CODE RED is cleared by its key's prefix, never all at once",
));
}
estate_order::code_red::clear(&self.0, prefix.trim());
Ok(Response::new(code_red_pb(estate_order::code_red::list(
&self.0,
))))
}
/// **DEV-NARRATE's logs of a narrated site** ([`estate_order::narrate::tail`], lane N2):
/// the operator's alone.
async fn narrate_log(
&self,
req: Request<pb::EstateNarrateLogRequest>,
) -> Result<Response<pb::EstateNarrateLogResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied("[narrate-operator] a site's boot logs are the operator's to read: the operator bearer"));
}
let r = req.into_inner();
let logs = blocking(&self.0, move |s| {
estate_order::narrate::tail(s, &r.estate, &r.vm, r.max_bytes as usize)
.map_err(Status::not_found)
})
.await?;
Ok(Response::new(pb::EstateNarrateLogResponse {
estate: logs.estate,
narrated: logs.narrated,
words: logs.words,
vms: logs
.vms
.into_iter()
.map(|v| pb::EstateNarrateVm {
vm: v.vm,
text: v.text,
bytes: v.bytes,
updated_unix_ms: v.updated_unix_ms as i64,
})
.collect(),
}))
}
/// **A box's install log, as this box's pairing read it** ([`estate_order::setup_log::install_log`]):
/// the operator's alone.
async fn install_log(
&self,
req: Request<pb::EstateInstallLogRequest>,
) -> Result<Response<pb::EstateInstallLogResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied("[install-log-operator] a box's install log is the operator's to read: the operator bearer"));
}
let r = req.into_inner();
let l = blocking(&self.0, move |s| {
estate_order::setup_log::install_log(s, &r.estate, &r.vm, r.since)
.map_err(Status::not_found)
})
.await?;
Ok(Response::new(pb::EstateInstallLogResponse {
estate: l.estate,
vm: l.vm,
text: l.text,
next: l.next,
lines: l.lines,
}))
}
async fn adopt_estate(
&self,
req: Request<pb::EstateAdoptRequest>,
) -> Result<Response<pb::EstateAdoptResponse>, Status> {
if !operator_only(&req) {
return Err(Status::permission_denied("adopting a site is the operator's: the operator bearer — never a site's own, never the service bearer"));
}
let r = req.into_inner();
let ask = estate_order::adopt::AdoptAsk {
estate: r.estate.trim().to_string(),
zone: r.zone.trim().to_string(),
machines: r
.machines
.into_iter()
.map(|m| monetize_cloud::lay::LaidMachine {
role: m.role.trim().to_string(),
hostname: m.hostname,
title: m.title,
plan: m.plan,
server: m.server,
public_ipv4: m.public_ipv4.trim().to_string(),
utility_ipv4: m.utility_ipv4.trim().to_string(),
disks: m
.disks
.into_iter()
.map(|d| monetize_cloud::lay::LaidDisk {
title: d.title,
id: d.id,
gib: d.gib,
tier: d.tier,
address: d.address,
})
.collect(),
medium_clone: String::new(),
})
.collect(),
release_of: r.release_of.into_iter().collect(),
again: r.again,
by: "operator".into(),
};
let a = blocking(&self.0, move |s| {
estate_order::adopt::adopt(s, &ask).map_err(site_refused)
})
.await?;
let host = run_apex(&self.0, &a.run);
Ok(Response::new(pb::EstateAdoptResponse {
company: a.run.company.clone(),
reference: a.run.reference.clone(),
host,
client_key: a.run.client_key.clone(),
feed: a.feed.into_iter().collect(),
words: a.words,
}))
}
}
/// One private Gunnar of an account, as `Purchases` shows it: what is LAID
/// (the quote follows the laid sizes, ownership (d)), the step it is laid at.
fn purchase_of(s: &AppState, run: &EstateRun, apex: &str) -> pb::EstatePurchase {
let (state, words, url) = run.customer_view_as(apex, &run_words(s, run));
let step = estate_order::ladder(s, &run.company)
.ok()
.and_then(|l| {
l.current
.and_then(|i| l.steps.get(i).map(|p| p.step.name.clone()))
})
.unwrap_or_default();
let host = if run.site_order {
apex.to_string()
} else if run.domain.is_empty() {
format!("{}.{apex}", run.company)
} else {
run.domain.clone()
};
pb::EstatePurchase {
company: run.company.clone(),
repair_words: estate_order::sold::repair_words(run, &host, s.now()),
host,
url,
state,
words,
step,
resources_words: estate_order::resources_words(&run.quote),
monthly_words: estate_order::charge_words(&run.quote, run.operator_test),
paid_until: if run.site_order {
String::new()
} else {
day(run.paid_until_ms)
},
}
}
/// The ladder as the wire carries it (`EstateOrder.Ladder`).
fn ladder_response(l: estate_order::Ladder) -> pb::EstateOrderLadderResponse {
let steps = l
.steps
.iter()
.map(|p| {
let available = p.available();
match &p.quote {
Some(q) => pb::EstateLadderStep {
name: p.step.name.clone(),
sizes: Some(sizes_to_wire(&q.sizes)),
twin_plan: q.twin_plan.clone(),
machines: q
.machines
.iter()
.map(|m| pb::EstateMachineLine {
role: m.role.clone(),
plan: m.plan.clone(),
cores: m.cores,
memory_mib: m.memory_mib,
disks_gib: m.disks_gib.clone(),
})
.collect(),
resources_words: estate_order::resources_words(q),
monthly_words: estate_order::monthly_words(q),
total_words: estate_order::total_words(q),
pay_words: q.total.in_words(),
available,
reason: p.reason.clone(),
},
// A step that could not be priced: the visitor reads one plain
// sentence; why (the provider, the margin) is the log's,
// written where the ladder is priced.
None => pb::EstateLadderStep {
name: p.step.name.clone(),
sizes: Some(sizes_to_wire(&p.step.sizes())),
available: false,
reason: NOT_OFFERED_NOW.to_owned(),
..pb::EstateLadderStep::default()
},
}
})
.collect();
pb::EstateOrderLadderResponse {
steps,
start: l.start as u32,
laid: l.current.is_some(),
current: l.current.unwrap_or(0) as u32,
floor: l.floor as u32,
apex: l.apex,
term_months: l.term_months,
}
}
// ── a sold estate at its shop (one shop, 2026-10-07) ─────────────────────────
// (H16: the old `SoldEstate` door is gone — a sold estate's front asks the same calls on
// `Fleet.Ask`, [`crate::services::fleet`]; the answers below are its messages.)
fn sold_status(e: estate_order::sold::SoldRefusal) -> Status {
use estate_order::sold::SoldRefusal;
match e {
SoldRefusal::NotSigned => Status::unauthenticated(estate_order::sold::NOT_SIGNED),
SoldRefusal::Refused(w) => Status::failed_precondition(w),
SoldRefusal::Unavailable(w) => Status::unavailable(w),
}
}
/// CODE RED on the wire.
fn code_red_pb(v: Vec<estate_order::code_red::CodeRed>) -> pb::CodeRedList {
pb::CodeRedList {
items: v
.into_iter()
.map(|c| pb::CodeRed {
key: c.key,
site: c.site,
r#box: c.r#box,
what: c.what,
error: c.error,
next: c.next,
raised_at_unix_ms: c.raised_at_ms as i64,
acked_by: c.acked_by,
acked_at_unix_ms: c.acked_at_ms as i64,
})
.collect(),
}
}
/// An update's status on the wire: the open update, else the last one.
fn update_pb(st: estate_order::update::Status) -> pb::EstateUpdateResponse {
let shown = st.open.clone().or(st.last.clone());
let words = match (&st.open, &st.last) {
(Some(u), _) => u.line(),
(None, Some(u)) => format!("last: {}", u.line()),
(None, None) => "no update yet".into(),
};
let o = st.offer.clone();
pb::EstateUpdateResponse {
up_to_date: o.up_to_date,
offered: o.offered,
why_not: o.why_not,
release_name: o.release_name,
boxes: o
.boxes
.into_iter()
.map(|b| pb::EstateUpdateBox {
role: b.role,
state: b.state,
words: b.words,
})
.collect(),
host: st.host,
release: st.release,
release_of: st.release_of.into_iter().collect(),
live_on: st.live_on,
state: shown.as_ref().map(|u| u.state.clone()).unwrap_or_default(),
steps: shown
.as_ref()
.map(|u| {
u.steps
.iter()
.map(|x| pb::EstateUpdateStep {
role: x.role.clone(),
state: x.state.clone(),
how: x.how.clone(),
words: x.words.clone(),
at_unix_ms: x.at_ms as i64,
})
.collect()
})
.unwrap_or_default(),
update_release: shown
.as_ref()
.map(|u| u.release.clone())
.unwrap_or_default(),
update_live: shown.as_ref().is_some_and(|u| u.live),
words,
}
}
fn live_pb(a: Option<estate_order::update::LiveApp>) -> Option<pb::EstateLiveApp> {
a.map(|a| pb::EstateLiveApp {
base: a.record.base,
app: a.record.app,
app_len: a.record.app_len,
sig: a.record.sig,
url: a.url,
sha256: a.sha256,
release: a.record.release,
release_sig: a.record.release_sig,
env: a.record.env,
})
}
/// The sold calls' answers on the wire: a front's `Fleet.Ask` carries each message encoded.
pub(crate) fn recharge_pb(a: estate_order::sold::RechargeAnswer) -> pb::EstateRechargeResponse {
pb::EstateRechargeResponse {
server: a.machine.server,
public_ipv4: a.machine.public_ipv4,
utility_ipv4: a.machine.utility_ipv4,
words: a.words,
}
}
pub(crate) fn upgrade_pb(a: estate_order::sold::UpgradeAnswer) -> pb::EstateUpgradeResponse {
pb::EstateUpgradeResponse {
upgraded: a.upgraded,
server: a.machine.server,
public_ipv4: a.machine.public_ipv4,
utility_ipv4: a.machine.utility_ipv4,
words: a.words,
}
}
pub(crate) fn material_pb(a: estate_order::sold::MaterialAnswer) -> pb::EstateTakeMaterialResponse {
pb::EstateTakeMaterialResponse {
bundle: a.bundle,
words: a.words,
}
}
pub(crate) fn take_pb(a: estate_order::update::TakeAnswer) -> pb::EstateUpdateTakeResponse {
pb::EstateUpdateTakeResponse {
open: a.open,
release: a.release,
live: a.live,
role: a.role,
app: live_pb(a.app),
front: live_pb(a.front),
words: a.words,
}
}
/// The jera job kind of a site's ladder re-priced behind its kept answer (A32-14, LADDER-1).
pub const LADDER_JOB: &str = "monetize_ladder_reprice";
/// The jera job kind of the sells word read again behind its kept answer (A32-14).
pub const SELLS_JOB: &str = "monetize_sells_refresh";
#[cfg(test)]
mod sells_tests {
use super::*;
/// ★ **A monetize says whether it sells private estates** (the sign-up
/// page, owner 2026-10-08: with "Private Gunnar" chosen on test2 the page
/// showed "this monetize sells no private estates ([estate_orders] is
/// absent)"). The console asks this and offers no private choice where
/// none is sold; nothing is priced and nothing dialled to answer it.
#[tokio::test]
async fn a_monetize_says_whether_it_sells_private_estates() {
let bare = Arc::new(AppState::in_memory(crate::registry::Registry::new()));
let none = EstateOrderService(bare)
.sells(Request::new(pb::EstateOrderSellsRequest {}))
.await
.unwrap()
.into_inner();
assert!(!none.estates, "no [estate_orders]: none sold");
let dir =
std::env::temp_dir().join(format!("monetize-sells-{}-{}", std::process::id(), line!()));
let mut state = AppState::in_memory(crate::registry::Registry::new());
state.estates = estate_order::EstateOrders::with(
estate_order::EstateOrderConfig::default(),
dir.join("estate-orders"),
Arc::new(estate_order::NoInstaller),
Arc::new(estate_order::NoDns),
crate::custody::Custody::open(dir.join("custody")).unwrap(),
);
// `[estate_orders]` set over no cloud this monetize links: no step is
// priced, so none is sold (the steps priced over a cloud that can, or
// cannot, lay an estate: estate_order::tests).
let unpriced = EstateOrderService(Arc::new(state))
.sells(Request::new(pb::EstateOrderSellsRequest {}))
.await
.unwrap()
.into_inner();
assert!(
!unpriced.estates,
"[estate_orders] set, no step can be priced: none sold"
);
let _ = std::fs::remove_dir_all(&dir);
}
}