feat(billing): importer Test Connection guard + operator runbook

Add action_test_connection — a read-only connectivity/schema check that
reports source row counts and imports nothing, the safe first step before
a dry-run. Wire a "Test Connection" button on the wizard. Document the
end-to-end run in the README: least-privilege read-only DB role SQL, the
fusion_billing.nexacloud_dsn system parameter (libpq DSN = NexaCloud's
URL minus +asyncpg), and the Test → dry-run → real-run flow. Refresh the
stale SCAFFOLD status. 53/53 green on odoo-trial.
This commit is contained in:
gsinghpal
2026-05-27 14:16:32 -04:00
parent d4ef4d55e0
commit bb873e8a7a
4 changed files with 63 additions and 3 deletions

View File

@@ -60,6 +60,22 @@ class FusionBillingImportWizard(models.TransientModel):
"target": "new",
}
def action_test_connection(self):
"""Read-only connectivity + schema check: connect, read the source tables, and
report row counts WITHOUT importing anything. The safe first step before a
dry-run — surfaces a bad DSN, no network route, or a schema drift up front."""
self.ensure_one()
data = self._read_nexacloud_rows()
msg = "Connected. Read %s user(s), %s plan(s), %s subscription(s)." % (
len(data.get("users", [])), len(data.get("plans", [])),
len(data.get("subscriptions", [])))
return {
"type": "ir.actions.client",
"tag": "display_notification",
"params": {"title": "NexaCloud connection OK", "message": msg,
"type": "success", "sticky": False},
}
# ----- read side (the ONLY code that touches NexaCloud) ------------------
def _read_nexacloud_rows(self):
"""Open a READ-ONLY psycopg2 connection to the nexacloud Postgres (DSN in