docs(billing): session handoff — core on main, sub-project #2 (NexaCloud) next Captures resume state for the centralized-billing initiative: core engine done and on main, the 4-chunk decomposition of sub-project #2 (NexaCloud adapter + dual-run reconciliation), the pending "where to start" decision, open questions, and the test/branch workflow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> @
4.2 KiB
fusion_centralize_billing — Session Handoff (2026-05-27)
Resume point for the centralized-billing initiative. Read this first, then continue from "Decision pending" below.
Where we are
-
Sub-project #1 (core billing engine): DONE and on
main(tipd770c0c3, pushed to GitHub + Gitea).- 11/11 plan tasks, TDD, Opus code-reviewed; all Critical/High bugs fixed
(cross-billing cron → match by
plan_id;/usageauthz vs IDOR; input validation → 4xx not 500; correct billing-period window; idempotency scoped to(sub, metric, key); webhook sign-exact-bytes + event-id + SSRF guard). - 39 tests green on Odoo 19 Enterprise.
- Note: the 14 billing commits were rebased off the old login-audit/helpdesk stack and
landed cleanly on
main.fusion_login_auditwas deliberately not landed — it stays onfeat/fusion-login-audit. A concurrentfeat/helpdesk-customer-followupsession still carries a pre-landing copy of the billing commits; when it merges, replay its helpdesk-only commits ontomain.
- 11/11 plan tasks, TDD, Opus code-reviewed; all Critical/High bugs fixed
(cross-billing cron → match by
-
Reference docs (on
main):- Spec:
docs/superpowers/specs/2026-05-27-nexa-billing-centralized-design.md - Core plan:
docs/superpowers/plans/2026-05-27-fusion-centralize-billing-core.md
- Spec:
Next: sub-project #2 — NexaCloud adapter + dual-run reconciliation
Per spec §12, each sub-project is its own spec → plan → build cycle. #2 decomposes into four chunks (dependency order):
| Chunk | What | Risk |
|---|---|---|
| 2a — Mapping + importer | Read nexacloud DB → create res.partner + account.link, product.template + subscription plans, one subscription sale.order per deployment |
Low — read-only on NexaCloud, writes only into Odoo |
| 2b — Usage metering wiring | NexaCloud usage_metering.py pushes CPU-seconds → Odoo /usage; verify aggregation → draft invoice w/ quota + overage + HST |
Edits NexaCloud code |
| 2c — Control loop | NexaCloud consumes Odoo's outbound webhooks (invoice.payment_failed → suspend via existing network_isolation/throttle_checker; subscription.terminated → deprovision) |
Edits NexaCloud code |
| 2d — Dual-run reconciliation | fusion.billing.reconciliation diffs Odoo-computed vs NexaCloud-actual per customer/period for ≥ 1 cycle before any flip |
Safety gate before flipping real billing |
The core engine already built the receiving side (/usage, webhook engine, charge math).
#2 is about connecting NexaCloud to it and proving the numbers match before flipping.
Decision pending (resume here)
We were in the superpowers:brainstorming flow for #2 and stopped at: which slice to
start with?
- (recommended) 2a — Mapping + importer — lowest risk, foundation for everything else.
- 2d — Reconciliation first (front-load the trust mechanism).
- Full #2 design as one spec, then one plan.
- Just write the #2 plan, no code this session.
Open questions to resolve before building #2
- Spec §15 Q2 — NexaCloud billing granularity: confirm one subscription per deployment (spec leans this way) vs one subscription per customer with deployment line items.
- Access / environments needed:
- Read access to the
nexacloudDB schema (LXC 102 / its Postgres on LXC 201) to design the importer mapping. - A NexaCloud staging or safe path for 2b/2c (they edit live NexaCloud code).
- Test target for the Odoo side stays the odoo-trial Enterprise sandbox.
- Read access to the
- Resolved already: Stripe is one account (
acct_1ShlA9IkwUB1dVox) for everything — no account migration (spec §11 / §15 Q1). Branch strategy — land onmain, branch new work offmain.
How to run / test
- Billing tests:
bash scripts/fcb_test_on_trial.shfrom repo root → pass =FCB_EXIT=0(~1–2 min). Syncs the module to the odoo-trial Enterprise sandbox (Proxmox VM 316, dbtrial) and runs--test-enable. Local dev Odoo is Community and cannot install this module.
Branch hygiene (lesson from this session)
Cut each new feature branch from main, and land it before starting the next. For any
cross-branch git surgery, use a throwaway git worktree — never switch the shared
working dir's branch, because a concurrent session may be working on it.