ux(frontend/approval): orphan executions (cloud_account_id=NULL) show '(ambient)' instead of 'Account deleted' · Issue #608 · LeanerCloud/cloud-commitments-cli · GitHub
Skip to content

ux(frontend/approval): orphan executions (cloud_account_id=NULL) show '(ambient)' instead of 'Account deleted' #608

Closed

Description

@cristim

Symptom

When a pending purchase's cloud_account_id is NULL because the referenced account was deleted (see #606 for the ON DELETE SET NULL cascade), the approve modal renders the Account column as (ambient). That label is misleading — "ambient" implies the purchase will execute against the CUDly Lambda's own AWS identity, when in fact:

  • For non-AWS providers (Azure, GCP): the execution is fundamentally broken — no creds exist to authenticate as the deleted account.
  • For AWS providers: the execution is also broken if the deleted account was NOT the host account.

Operators see (ambient) + click Approve + get a confusing chained-credential error from the cloud SDK. They have no way to tell from the UI that the row is unrecoverable.

Fix

In frontend/src/approval-details.ts::formatAccountLabel, distinguish three cases instead of two:

export function formatAccountLabel(
  acct: CloudAccount | undefined,
  recAccountId: string | undefined,
  provider: string,                    // NEW
  hostAWSAccountID: string | undefined, // NEW — from /api/info or similar
): string {
  if (acct) {
    if (acct.external_id) return `${acct.name} (${acct.external_id})`;
    return acct.name;
  }
  if (recAccountId) {
    return `acct ${recAccountId.slice(0, 8)}…`;
  }
  // No account on the rec. Distinguish 'genuine ambient' from 'deleted'.
  if (provider === 'aws' && hostAWSAccountID) {
    return `CUDly host (${hostAWSAccountID})`;
  }
  return '⚠ Account deleted — purchase cannot execute';
}

When the rec has no account AND we're on AWS AND the deployment knows its own STS account, label it as the host account directly (handles the legitimate ambient case from #604). Otherwise — Azure/GCP without account, or AWS without host info — label it as deleted with a warning glyph so the operator knows to cancel rather than approve.

The frontend already has access to the provider on each row (it's in the rec/execution payload). The host AWS account ID needs to come from somewhere — easiest: extend GET /api/info (if present) to include deployment_aws_account_id. If that endpoint doesn't exist, add a minimal one.

Pair with #606

#606 prevents NEW orphan rows. This issue makes EXISTING orphan rows clearly labelled so operators know to cancel them. Both should ship before the user-facing message is trustworthy.

Regression test

frontend/src/__tests__/approval-details.test.ts:

  • recAccountId nil, provider aws, hostAWSAccountID 909626172446 → "CUDly host (909626172446)".
  • recAccountId nil, provider azure → "⚠ Account deleted — purchase cannot execute".
  • recAccountId nil, provider gcp → same.
  • recAccountId nil, provider aws, hostAWSAccountID nil → "⚠ Account deleted" (defensive: missing host info is itself a deployment issue worth flagging).

Severity

P2 — operator UX bug. Doesn't cause new data corruption (that's #606), just makes the existing fallout look approvable when it isn't.

Activity

  1. added a commit that references this issue on May 20, 2026
    a04604a
  2. cristim commented on May 28, 2026

    @cristim
    MemberAuthor

    Verification: shipped in PR #611 (SHA a04604a, merged 2026-05-20). approval-details.ts formatAccountLabel returns 'Account deleted — purchase cannot execute' for orphan executions on non-AWS providers. AWS ambient case returns CUDly host label. Regression tests in approval-details.test.ts. Confirmed on origin/feat/multicloud-web-frontend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions