Support profile aliases for shared Fizzy accounts

Merged
RO
3mo ago
+2351-237

Summary

  • Separate the selected profile name from the account slug/ID used for API routing.
  • Store credentials by profile alias while routing SDK requests through the profile's account.
  • Add fizzy auth login TOKEN --profile NAME --account ACCOUNT for creating an aliased profile.
  • Show profile and account separately in auth, config, quick-start, and doctor output.
  • Preserve profile-specific API URLs while switching, and clean up aliased credentials safely during logout.

Intent

Fixes #200.

The reported use case is two identities working in the same Fizzy account: for example, Walter's token under profile walter and an agent's token under walter2. Keeping those credentials separate lets Fizzy attribute cards and other actions to the correct user, while both profiles still target the same account URL.

Before this change, selecting walter also made walter the account path, resulting in /walter/boards.json and a 404 when the actual account was 1. With this change:

profile walter  -> credential profile:walter  -> /1/boards.json
profile walter2 -> credential profile:walter2 -> /1/boards.json

Migration and backward compatibility

Existing profiles do not require migration when their profile name is already the account slug or ID. A profile without account metadata continues to resolve as:

account = profile name

That preserves existing config.json files, credential keys, setup/signup behavior, and account-scoped URLs.

Profiles that currently use an arbitrary alias and therefore hit the reported 404 need a one-time account association. The supported path is to save each token again with the account:

fizzy auth login "$WALTER_TOKEN" --profile walter --account 1
fizzy auth login "$AGENT_TOKEN" --profile walter2 --account 1

This writes the Fizzy-specific account setting through the shared profile store:

"walter": {
  "base_url": "https://app.fizzy.do",
  "extra": { "account": "1" }
}

Users whose alias-scoped credentials are already saved can add extra.account directly without replacing their token.

There is intentionally no automatic migration for broken aliases: the old profile file does not contain enough information to infer the correct account safely, and guessing could associate the wrong user's credential with an account. New profiles created without an alias continue using the account slug as their name and need no additional metadata.

Validation

  • Began with a failing regression test reproducing the alias-as-account behavior.
  • Tests verify two aliases use distinct bearer tokens while both request /1/boards.json.
  • Tests cover old profile fallback, flag and environment alias creation, switch URL preservation, logout/restart behavior, logout-all legacy cleanup, doctor routing, and config reporting.
  • GOWORK=off make check passes, including vet, lint, race tests, and the CLI surface snapshot.
  • Performed a read-only live check with a temporary alias against a real Fizzy account: identity show and board list both succeeded through the aliased profile. The temporary alias was then removed and the original configuration restored.

Summary by cubic

Add profile aliases so multiple identities can share one Fizzy account by separating “profile” from “account” across the CLI. Fixes 404s from alias-as-account routing, adds --account to fizzy auth login, clears stale alias routing during setup/signup, preserves self-hosted Base URLs, and reports the Account’s source accurately in config show/explain.

  • New Features

    • fizzy auth login TOKEN --profile NAME --account ACCOUNT creates an aliased profile; token saved as profile:NAME, requests route via ACCOUNT.
    • Stronger credential isolation and recovery: validate identifiers, create/update the profile before saving the token, roll back default/profile changes if save fails, fail fast when the profile store is unavailable, skip legacy token migration, clear stale alias routing during setup/signup, and avoid promoting legacy tokens during logout; logout --all also clears account-scoped legacy keys.
    • CLI shows Profile and Account separately in auth status, auth list (adds Account column), config show/explain (adds Account with precedence and precise source, e.g., “profile walter”), quick start, and doctor (routes checks via the account and validates access).
    • Profile switching preserves the target profile’s Base URL, applies it to the session, persists it to YAML, honors --api-url/FIZZY_API_URL, and keeps self-hosted URLs intact when profiles are reconstructed.
    • SDK routes aliases to /ACCOUNT/... using the alias’s token.
  • Migration

    • No action needed if a profile’s name equals the account slug/ID.
    • For aliased profiles that previously 404’d, re-save tokens with an account: fizzy auth login "$WALTER_TOKEN" --profile walter --account 1, fizzy auth login "$AGENT_TOKEN" --profile walter-agent --account 1.
    • Alternatively, add extra.account to the profile in config.json.