Repository navigation
Description
Summary
Power users with many accounts and many overrides currently have only the per-row UI (LeanerCloud/cloud-commitments-cli#72/#106) or direct API calls to manage their override state. There's no way to export the current override config (e.g., to back it up, diff against a known-good baseline, or transplant it into a fresh tenant) or to import a desired-state file.
CSV (or JSON / YAML) import/export of account_service_overrides rows would unblock:
- Disaster recovery — capture override config as-of-now, restore later.
- Migration between environments (dev → staging → prod) — each environment keeps its own overrides, but a baseline can be cloned.
- Bulk audit — diff exports across time to see what changed.
- Bootstrap — a customer with N accounts and consistent override patterns can craft one CSV and import once.
Scope sketch
Export
GET /api/accounts/service-overrides/export.csv (or .json) — returns every override row across all accounts the user has access to, with columns: account_id, account_name, provider, service, enabled, term, payment, coverage, ramp_schedule, include_engines, exclude_engines, include_regions, exclude_regions, include_types, exclude_types, created_at, updated_at.
Frontend: a button in Settings → Accounts (or a dedicated "Export overrides" link) that triggers a download.
Import
POST /api/accounts/service-overrides/import accepting the same schema. Behaviour:
- Strict mode: fail on first error (unknown account_id, unknown service, validity-rule violation per ux(settings): account override UIs should reuse commitmentOptions validity rules (e.g., RDS 3yr no-upfront) cloud-commitments-cli#107). Don't apply any rows.
- Best-effort mode: apply what's valid; surface a per-row report of what was rejected and why.
Frontend: a file-picker + dry-run mode (preview which rows would be inserted/updated/no-op) before actual apply.
Concerns
- Account_id portability: account UUIDs are not portable across tenants. An export from Tenant A imported into Tenant B needs a reconciliation step keyed on
provider:external_id(the AWS account number, Azure subscription, GCP project) instead of the UUID. This is the bulk of the implementation complexity. - Validity rules: imports should respect ux(settings): account override UIs should reuse commitmentOptions validity rules (e.g., RDS 3yr no-upfront) cloud-commitments-cli#107's rules. Bad combinations rejected with clear errors.
- Audit log integration: each imported row should generate the same
config_audit_eventsentry as a UI edit (issue #N+).
Recommendation
Defer until a customer specifically requests it. The export side is cheaper than import and could ship first (read-only, no validation complexity). Import follows when there's clear demand.
Acceptance criteria (when prioritised)
- Export endpoint produces a complete, well-formed CSV / JSON of current overrides.
- Import endpoint accepts the same shape and reports per-row results.
- Validity-rule violations rejected per ux(settings): account override UIs should reuse commitmentOptions validity rules (e.g., RDS 3yr no-upfront) cloud-commitments-cli#107.
- Account-id reconciliation works across tenants via
provider:external_id. - Tests cover round-trip (export → re-import → no diff), validity rejection, and partial-failure reporting.
Out of scope
- CSV import for
service_configs(global defaults). Different use case — the global config is one row per (provider, service), so the diff-patch story is much simpler. - API-side bulk apply (already possible by N parallel PUT calls).
Activity
cristim commentedon Apr 28, 2026
P3: the issue body itself recommends deferring until a customer requests it. Export is cheaper to ship first (read-only), but neither side is blocking active feature delivery. The account-id portability concern makes import genuinely complex (L effort). (triage agent wave1-C)
IAmJSD commentedon Oct 26, 2026
Claiming: working on this
feat(accounts): export and import account service overrides (#1486)
cristim commentedon Nov 12, 2026
Verified on origin/main 447a98b: export and import of account_service_overrides is met.
Closing as completed.