Phase 4 — Per-node billing-record push (hero_proc cron + Forgejo REST + OTOML) #5
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Tracks Phase 4 of the onboarding milestone (parent: #1). Lands the producer side of the billing pipeline: each Hero node accumulates
UsageRecordrows locally, a hero_proc cron action ticks every hour, the server-side push handler batches new records into per-hour OTOML files and commits them to a centralized billing repo. Phase 5 (aggregator) reads from the same repo to update the centralBillingrow.Scope landing this session (s2-006)
POST /record_usageonhero_onboarding_server— admin-only viaX-Hero-Onboarding-Admin-Secretheader. Accepts(node_id, user_sid, amount_cents, resource_kind, idempotency_key, description), writes aUsageRecordvia OSIS. Idempotency dedupe onidempotency_key.POST /admin/push-usage-nowonhero_onboarding_server— admin-secret-gated, triggers a single push immediately. Invoked by the admin CLI + smoke script.crates/hero_onboarding_server/src/usage_push.rs(new) —push_unsent_records()reads~/hero/var/hero_onboarding/last_pushed_sidmarker, enumerates newUsageRecordrows, groups by hour bucket, serializes each batch as OTOML (UsageBatch { records: Vec<UsageRecord> }), commits to the billing repo via Forgejo RESTPUT /repos/{owner}/{repo}/contents/{path}atnodes/<node-name>/usage_<YYYY-MM-DD-HH>.otoml. Auto-creates the billing repo on first push if missing. Marker updates only after successful commit; forge-unreachable → log warn, retry next tick.hero_onboarding_admin push-usage --once— thin CLI subcommand that loads the admin secret and POSTs tohttp://127.0.0.1:9920/admin/push-usage-now. Non-zero exit on failure so hero_proc cron sees the failure.hero_onboarding --startregisters a 3rd actionhero_onboarding_billing_cronalongside the existing server + admin actions: script =~/hero/bin/hero_onboarding_admin push-usage --once,schedule_policy.interval_ms = 3_600_000, notis_process().scripts/smoke_usage_push.sh— white-box E2E against real local Forgejo: bootstrap test user → POST/record_usage× 3 + duplicate-idempotency-key check → adminpush-usage --once→ curl Forgejo to verify OTOML file landed → idempotency check (re-trigger, no duplicate commit) → cleanup (delete test billing repo, reset marker).D-14 — per-node billing layout (locked this session, revisable when Kristof/Emre answer #1 open questions)
lhumina_code(existing org; sidestepshero_opsorg creation)lhumina_code/hero_onboarding_billing(per-node disambiguation via subdirectory)nodes/<node-name>/usage_<YYYY-MM-DD-HH>.otoml(<node-name>fromHERO_NODE_IDenv, hostname fallback)[[records]]array ofUsageRecordrows via oschema serde_otomlinterval_ms = 3_600_000invoking admin CLI~/hero/var/hero_onboarding/last_pushed_sid(no schema churn)Full rationale + the consumer-side implications for Phase 5 in
decisions/D-14-per-node-billing-layout.md.Acceptance gates
cargo check --workspacegreencargo test -p hero_onboarding_server(push module unit tests if any) greenlab build --release --install --workspaceVICTORY (3 binaries built / 0 failed)lab infocheck3/3 cleanscripts/smoke_usage_push.shend-to-end green against real local Forgejo (OTOML file lands, idempotency holds, cleanup leaves no test artifacts)Out of scope (Phase 5)
Billingrows.Parent: #1