Commit Graph

2 Commits

Author SHA1 Message Date
MechaCat02
59645e8159 feat(cli): add pic routes + pic admins subcommands
Closes the audit's Critical "operator can't deploy a serverless endpoint
end-to-end from the CLI" finding. Two new subcommand families bring the
CLI coverage from 14 commands to ~25:

- pic routes {ls, create, rm, check, match}: full route CRUD plus the
  dry-run conflict checker and the URL matcher already exposed by the
  dashboard. The create form accepts --path-kind, --host-kind, and
  --dispatch (sync|async) so async routes can finally be created
  headlessly. The ls output adds a dispatch column.

- pic admins {ls, create, show, set, rm}: per-instance admin user
  management. Create reads passwords from stdin via --password - so
  shell history never sees the cleartext. Set is a JSON-Merge-Patch
  shape that lets operators deactivate accounts or rotate roles
  without touching the dashboard.

Six new ignored integration tests follow the established #[ignore]
pattern (DATABASE_URL gates them). They cover the happy-path round
trip, the async-dispatch persistence path, the password-required
error path, and the capability gate (a Member sees HTTP 403). All
pass against the local dev stack with PICLOUD_DEV_MODE=true +
PICLOUD_DEV_INSECURE_KEY=i-understand-this-is-insecure.

The `pic members` and `pic domains` subcommands the audit mentioned
are deferred — the apps_api shape may shift in v1.2 with per-app
roles and rebuilding the CLI surface twice would be churn.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-10 21:35:09 +02:00
MechaCat02
e4851b3deb test(cli): extract shared Fixture into tests/common
The single bare-metal integration test now reuses a `LazyLock<Fixture>`
that spawns picloud once on a private port and shares it across every
test in the binary. Sets the stage for per-surface journey modules
(auth, apps, scripts, invoke, logs, roles, output) without each one
paying for its own server spawn — same trick the dashboard Playwright
suite uses with global-setup.

Notes:
- `tests/cli.rs` becomes a tiny module list; the seed flow moved to
  `tests/integration.rs`. The seed slug now goes through
  `common::unique_slug` so parallel/serial reruns can't collide.
- `autotests = false` + an explicit `[[test]] name = "cli"` keeps Cargo
  from auto-promoting future `tests/*.rs` files into their own binaries
  (which would each respawn picloud).
- Subprocess cleanup uses `libc::atexit` to SIGTERM picloud when the
  test binary exits. PR_SET_PDEATHSIG was tried and rejected: it fires
  when the *thread* that forked dies, and cargo's per-test worker
  threads exit between tests, which killed the fixture mid-suite.
- New helpers: AppGuard/UserGuard (RAII teardown), member_user /
  grant_membership / update_membership (direct API for role tests),
  unique_slug / unique_username, pic_as / pic_no_env.
- Two `fixture_url_is_shared_*` tests prove the LazyLock is actually
  shared, not respawned per test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 21:21:12 +02:00