No description
  • Rust 85.2%
  • Shell 14.8%
Find a file
mik-tf 4684f1d377 Phase 4: per-node billing-record push (hero_proc cron + Forgejo REST + OTOML)
Producer side of the billing pipeline. Two new admin-secret-gated routes on
hero_onboarding_server:

- POST /record_usage — accepts (node_id, user_sid, amount_cents,
  resource_kind, idempotency_key, occurred_at) and writes a UsageRecord row
  via OSIS. Idempotency dedupe on idempotency_key (per schema @index).

- POST /admin/push-usage-now — invokes push_unsent_records() which reads all
  UsageRecord rows, groups by hour bucket, fetches existing bucket files from
  the centralized billing repo, merges-by-idempotency_key, and re-uploads only
  when content changes. Forge IS the dedup state — no marker file.

Triggered hourly by a new hero_proc cron action (hero_onboarding_billing_cron)
registered by `hero_onboarding --start` with SchedulePolicy.interval_ms =
3_600_000. The cron runs `hero_onboarding_admin push-usage --once` which posts
to /admin/push-usage-now with X-Hero-Onboarding-Admin-Secret. Server-side
handler owns the OSIS handle (single-process).

Layout (D-14, revisable when Kristof/Emre answer hero_onboarding#1 open Qs):

- Repo:    lhumina_code/hero_onboarding_billing (single repo; per-node
  disambiguation via subdirectory)
- Path:    nodes/<node-name>/usage_<YYYY-MM-DD-HH>.otoml
- Format:  OTOML — UsageBatch { records: Vec<UsageRecord> } via plain toml
  crate (OTime is a u32-wrapper that serialises as a quoted string and
  round-trips cleanly through the toml crate)

hero_onboarding_admin refactored from Phase 1 placeholder daemon into clap-
based dispatcher: default mode runs the daemon (placeholder web UI),
`push-usage --once` subcommand runs the cron one-shot. FORWARDED_ENV in the
lifecycle CLI extended with Phase 4 secrets + path vars.

Acceptance (workstation):
- cargo check workspace green
- cargo test workspace 20/20 (19 Phase 3 + 1 new hour_bucket)
- lab build --release --install --workspace VICTORY 3/3 (13.0s)
- lab infocheck 3/3 clean
- cargo fmt --check clean
- cargo clippy --workspace --all-targets -- -D warnings clean
- scripts/smoke_usage_push.sh: 24/24 white-box E2E pass against real local
  Forgejo (admin-secret gating + producer happy/dedup + push happy path +
  bucket-file landing + push idempotency + merge-on-new-record + cleanup
  via DELETE /repos/...)

Tracking: #5
2026-05-20 18:03:14 -04:00
crates Phase 4: per-node billing-record push (hero_proc cron + Forgejo REST + OTOML) 2026-05-20 18:03:14 -04:00
scripts Phase 4: per-node billing-record push (hero_proc cron + Forgejo REST + OTOML) 2026-05-20 18:03:14 -04:00
.gitignore Phase 2: Stripe Checkout sandbox + signature-verified webhook + OSIS persistence 2026-05-20 15:58:22 -04:00
Cargo.lock Phase 4: per-node billing-record push (hero_proc cron + Forgejo REST + OTOML) 2026-05-20 18:03:14 -04:00
Cargo.toml Phase 4: per-node billing-record push (hero_proc cron + Forgejo REST + OTOML) 2026-05-20 18:03:14 -04:00
README.md Phase 1 scaffold: workspace + 4 crates + oschema + lab build/infocheck green 2026-05-20 14:08:34 -04:00

hero_onboarding

Onboarding website + billing backend for the Hero ecosystem.

Status: Phase 1 scaffold. The skeleton ships the canonical 4-crate layout (CLI + server + admin + schema) so subsequent phases can land without restructuring. Real payment, KYC, mycelium-address proof-of-control auth, per-node billing-record push, and the centralized aggregator all land in later phases.

Full plan + phasing + acceptance criteria: #1 — Hero onboarding website + billing backend — full plan

Crates

Crate Kind Purpose
hero_onboarding cli Command-line launcher. Phase 1 stub — points at lab service hero_onboarding_server --start.
hero_onboarding_server web End-user onboarding website (login + dashboard + payment). Phase 1: in-memory state, mycelium-address login stubbed, payment stubbed.
hero_onboarding_admin admin Operator dashboard. Phase 1 placeholder; full admin surface lands in Phase 5.
hero_onboarding_schema library oschema definitions (User, Billing, UsageRecord, PaymentEvent) with build.rs codegen via hero_rpc_osis. Generated module gated behind the onboarding feature flag.

Phase 1 acceptance (this scaffold)

Per #1's "Phased delivery > Phase 1":

  • Workspace layout (Cargo.toml, 4 crates, 3 service.toml, build.rs)
  • hero_onboarding_schema/User / Billing / UsageRecord / PaymentEvent in oschema
  • hero_onboarding_server/kind=web skeleton, mycelium-address login (stubbed), dashboard, payment stub
  • hero_onboarding_admin/kind=admin daemon placeholder
  • README + service.toml entries follow canonical D-10 / D-11 shape
  • lab build --release --install clean
  • lab infocheck clean
  • lab service hero_onboarding_server --start opens the page; login + dashboard render

Quick start (dev)

# Build the workspace
lab build --release --install

# Start the onboarding daemon (binds 127.0.0.1:9920 by default)
lab service hero_onboarding_server --start

# Visit http://127.0.0.1:9920 in a browser

Roadmap

Phase Scope Tracking
1 Schema scaffold + skeleton web service (this PR) #1
1.5 Mycelium-address proof-of-control auth + canonical hero_login pattern (to file)
2 Stripe sandbox integration (lifted from in-house top-up flow) (to file)
3 ClickPesa sandbox integration (to file)
4 Per-node billing-record push via hero_proc cron + lab repo push (to file)
5 Centralized aggregator + hash-resume idempotency (to file)
6 Production keys + Idenfy KYC + PoolAssignmentProvisioner + live wiring (to file)

See #1 for the canonical phasing, pricing model, architecture (per-node Forge billing repos + hash-resume aggregator + agnostic Provisioner trait), and the 9 open questions for Kristof + Emre.