Files
Odoo-Modules/docs/superpowers/2026-05-27-fusion-billing-session-handoff.md
gsinghpal 43b2edcbb5 @
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>
@
2026-05-27 08:56:28 -04:00

4.2 KiB
Raw Blame History

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 (tip d770c0c3, pushed to GitHub + Gitea).

    • 11/11 plan tasks, TDD, Opus code-reviewed; all Critical/High bugs fixed (cross-billing cron → match by plan_id; /usage authz 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_audit was deliberately not landed — it stays on feat/fusion-login-audit. A concurrent feat/helpdesk-customer-followup session still carries a pre-landing copy of the billing commits; when it merges, replay its helpdesk-only commits onto main.
  • 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

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 nexacloud DB 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.
  • Resolved already: Stripe is one account (acct_1ShlA9IkwUB1dVox) for everything — no account migration (spec §11 / §15 Q1). Branch strategy — land on main, branch new work off main.

How to run / test

  • Billing tests: bash scripts/fcb_test_on_trial.sh from repo root → pass = FCB_EXIT=0 (~12 min). Syncs the module to the odoo-trial Enterprise sandbox (Proxmox VM 316, db trial) 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.