You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a user assigns accounts to a purchase plan via PUT /api/plans/:id/accounts, the handler currently accepts any account IDs without validating that each account's provider matches the plan's derived provider. Spec acceptance criterion E-4 requires this be caught early with a clear 400.
Concrete example: assigning an Azure account to a plan whose services map contains only AWS keys (e.g. "aws:ec2", "aws:rds") should fail with a message identifying the mismatched account(s) and their providers.
The frontend already enforces single-provider-per-plan, but backend validation is needed to harden the contract — a misconfigured client or direct API caller can otherwise persist a state the executor can't run.
Derive provider(s) from the plan's services map keys (format "provider:service", e.g. "aws:ec2"); extract the distinct provider set.
For each account_id in the request body: load from cloud_accounts, check provider matches the plan's provider set.
If mismatch: return 400 with an error message listing each offending (account.name, account.provider, expected_provider) triple. Do not partially persist.
If all valid: behaviour unchanged — call SetPlanAccounts (internal/config/store_postgres.go:1890-1915) and return 200.
Existing happy-path tests stay green; add table-driven tests for the new mismatch cases (single mismatch, multiple mismatches, valid plan).
Out of scope
Multi-provider plans — the structural assumption (one plan = one provider) is unchanged in this PR; the spec doesn't propose lifting it.
Auto-filtering of incompatible accounts on the frontend's account-picker — that's a UX nicety; the backend gate must exist independently.
Gap
When a user assigns accounts to a purchase plan via
PUT /api/plans/:id/accounts, the handler currently accepts any account IDs without validating that each account'sprovidermatches the plan's derived provider. Spec acceptance criterion E-4 requires this be caught early with a clear 400.Concrete example: assigning an Azure account to a plan whose
servicesmap contains only AWS keys (e.g."aws:ec2","aws:rds") should fail with a message identifying the mismatched account(s) and their providers.The frontend already enforces single-provider-per-plan, but backend validation is needed to harden the contract — a misconfigured client or direct API caller can otherwise persist a state the executor can't run.
Spec sections:
specs/multi-account-execution/acceptance.mdE-4;specs/multi-account-execution/api.md"PUT /api/plans/:id/accounts".Acceptance criteria
servicesmap keys (format"provider:service", e.g."aws:ec2"); extract the distinct provider set.account_idin the request body: load fromcloud_accounts, checkprovidermatches the plan's provider set.(account.name, account.provider, expected_provider)triple. Do not partially persist.SetPlanAccounts(internal/config/store_postgres.go:1890-1915) and return 200.Out of scope
References
specs/multi-account-execution/acceptance.mdscenario E-4internal/api/handler_accounts.go:1025-1055(setPlanAccounts)internal/config/store_postgres.go:1890-1915(SetPlanAccounts already validates IDs exist; just lacking the provider-match check)