Skip to content

feat(cli): add database usage, backup list, restore, and connection rotate#106

Merged
AmanVarshney01 merged 5 commits into
mainfrom
feat/database-usage-backups-restore-rotate
Jul 3, 2026
Merged

feat(cli): add database usage, backup list, restore, and connection rotate#106
AmanVarshney01 merged 5 commits into
mainfrom
feat/database-usage-backups-restore-rotate

Conversation

@AmanVarshney01

@AmanVarshney01 AmanVarshney01 commented Jul 2, 2026

Copy link
Copy Markdown
Member

Adds the remaining Prisma Postgres surface to the database group: usage metrics, backups, restore, and credential rotation. Spec-first (command-spec.md + resource-model.md updated in the same change).

$ prisma-cli database usage acme-production --from 2026-06-01 --to 2026-06-30
│  operations:  12500 ops
│  storage:     1.25 GiB

$ prisma-cli database backup list acme-production
│  Id        Type   Status      Size      Created
│  bkp_101   full   completed   1.0 MiB   2026-06-20T00:00:00.000Z

$ prisma-cli database restore db_123 --backup bkp_101 --confirm db_123
✔ Restoring database...   # status becomes "recovering"; connections preserved

$ prisma-cli database connection rotate conn_123 --confirm conn_123
✔ Rotated credentials for "acme-preview". The previous credentials no longer work.
postgresql://...   # new one-time URL, printed exactly once on stdout

Design notes

  • Restore and rotate are destructive (restore overwrites the target's data; rotate revokes the old credentials), so both use the exact-id --confirm convention; --yes never satisfies it.
  • Cross-database restore via --source-database (e.g. a production backup into a scratch database).
  • Structured recovery codes for agents: DATABASE_BACKUPS_UNSUPPORTED (remote/BYO), DATABASE_BACKUP_NOT_FOUND, DATABASE_RESTORE_CONFLICT (target provisioning/recovering), plus CONFIRMATION_REQUIRED with expectedConfirm/receivedConfirm meta.
  • --from/--to accept YYYY-MM-DD (expanded to midnight UTC, matching the API's ISO-datetime contract) or a full ISO datetime; impossible dates like 2026-02-30 are rejected.

Testing: 13 new integration tests (27 in the file), full suite green, and every command verified against the live Management API on a scratch database (rotation genuinely minted new credentials; restore's 404/conflict paths exercised).

…otate

Extends the database group with the remaining Management API surface:

- database usage <database> [--from --to]: operations and storage
  metrics for a period
- database backup list <database> [--limit]: platform-created backups
  with retention metadata
- database restore <database> --backup <id> [--source-database <db>]
  --confirm <database-id>: destructive in-place restore; status goes to
  recovering and connections/credentials are preserved
- database connection rotate <connection> --confirm <connection-id>:
  mints new credentials and prints the new one-time URL exactly once on
  stdout, matching the connection create output contract

Restore and rotate follow the exact-id --confirm convention because
they are destructive (restore overwrites data; rotate revokes the
previous credentials). All commands support --json with structured
error codes (DATABASE_BACKUPS_UNSUPPORTED, DATABASE_BACKUP_NOT_FOUND,
DATABASE_RESTORE_CONFLICT) for agent consumption.

Spec-first: command-spec.md and resource-model.md updated alongside
the implementation.
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ca291541-7315-4377-b706-5b309bc1608d

📥 Commits

Reviewing files that changed from the base of the PR and between 61f8e8c and 3576c87.

📒 Files selected for processing (4)
  • docs/product/command-spec.md
  • docs/product/error-conventions.md
  • packages/cli/src/controllers/database.ts
  • packages/cli/tests/database.test.ts

Summary by CodeRabbit

  • New Features

    • Added CLI commands to view database usage, list backups, restore from backups, and rotate connection credentials.
    • Expanded command output to include backup retention, usage metrics, restore details, and one-time connection URLs.
  • Bug Fixes

    • Tightened confirmation checks for destructive database actions.
    • Added clearer errors for missing backups, unsupported backups, restore conflicts, and invalid date or limit inputs.
  • Documentation

    • Updated command and error documentation to cover the new database workflow and related error messages.

Walkthrough

This PR adds four new database CLI capabilities: database usage (read-only usage metrics reporting), database backup list (backup enumeration with retention metadata), database restore (async restore from backup requiring exact confirmation), and database connection rotate (credential rotation requiring exact confirmation). Changes span type definitions, provider integration with Management API endpoints, controller logic with input validation, presenters for rendering/serialization, CLI command wiring, shell descriptors, mock API fixtures, documentation, and tests. Three new error codes (DATABASE_BACKUPS_UNSUPPORTED, DATABASE_BACKUP_NOT_FOUND, DATABASE_RESTORE_CONFLICT) are documented, and requireExactConfirmation is extended to support customizable error message overrides.

Changes

Area Description
Types New interfaces for usage, backup list, restore, and connection rotation results
Provider New DatabaseProvider methods for usage, backups, restore, rotation with error mapping
Mock API New fixture data and MockApi methods for backups, usage, restore, rotation
Controller New command handlers with flag parsing/validation and confirmation flows
Presenters New render/serialize functions for all four new result types
CLI Commands New subcommand registrations and descriptors
Docs Command spec, resource model, and error conventions updates
Tests New coverage and updated help snapshots

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Controller
  participant DatabaseProvider
  CLI->>Controller: runDatabaseUsage(context, ref, flags)
  Controller->>Controller: parseUsageDate(from/to)
  Controller->>DatabaseProvider: getUsage(databaseId, period)
  DatabaseProvider-->>Controller: DatabaseUsageRecord
  Controller-->>CLI: DatabaseUsageResult
  CLI->>Controller: runDatabaseRestore(context, ref, flags)
  Controller->>Controller: requireExactConfirmation
  Controller->>DatabaseProvider: restoreDatabase(input)
  DatabaseProvider-->>Controller: outcome
  Controller-->>CLI: DatabaseRestoreResult
Loading

Related Issues: None referenced in the provided changes.

Related PRs: None referenced in the provided changes.

Suggested labels: feature, cli, database, documentation

Suggested reviewers: Reviewers familiar with the CLI database command family, Management API provider integration, and confirmation/error-handling conventions.

Poem
A rabbit dug through backups deep,
Restored the fields while databases sleep,
Rotated keys with a confirming nod,
Usage metrics counted, ops and storage trod,
Four new commands hop into the CLI sod! 🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main CLI database features added in this change.
Description check ✅ Passed The description is clearly related to the PR and matches the added database usage, backup, restore, and rotation changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/database-usage-backups-restore-rotate
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/database-usage-backups-restore-rotate

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/product/command-spec.md`:
- Around line 1041-1053: Add the missing confirmation-failure behavior to the
rotation docs in the command spec: update the `database connection rotate`
section that already references `--confirm <connection-id>` and `--yes` so it
explicitly states the structured `CONFIRMATION_REQUIRED` error is returned when
the confirmation value is missing or does not exactly match. Keep the wording
aligned with the existing output/error contract in this block so JSON consumers
can reliably detect and handle the failure path.
- Around line 930-938: Update the restore command spec section to include the
missing structured failure cases promised by the PR contract. In the restore
flow description near the existing `database restore` validation bullets, add
the `DATABASE_BACKUP_NOT_FOUND` failure for an invalid or missing `--backup
<backup-id>` and add `CONFIRMATION_REQUIRED` for a missing or mismatched
`--confirm <database-id>` value. Keep the wording aligned with the surrounding
restore validation rules and place these alongside the existing
`DATABASE_RESTORE_CONFLICT`, `DATABASE_NOT_FOUND`, and `DATABASE_AMBIGUOUS`
entries so the `database restore` documentation fully matches the command
behavior.

In `@packages/cli/src/controllers/database.ts`:
- Around line 492-500: The restore confirmation flow in database restore is
dropping the resolved source database from the recovery command. Update the
nextStep passed to requireExactConfirmation in database restore so it preserves
the source database identifier via --source-database alongside the backup and
confirm target, using the resolved database/backup values already available in
database.ts.
- Around line 366-368: The usage date check in database controller logic is too
permissive because Date.parse can accept non-ISO datetime strings and invalid
calendar dates. Tighten parseUsageDate so it only accepts strict YYYY-MM-DD
input and rejects invalid dates, then update the from/to comparison in the
database controller to compare the normalized date strings directly instead of
parsing them again.

In `@packages/cli/src/presenters/database.ts`:
- Around line 443-456: The backup list serializer is dropping each item’s real
status by hardcoding status to null in serializeDatabaseBackupList, which
weakens the standard list envelope for JSON consumers. Update the mapping in
serializeDatabaseBackupList so each backup item passes through backup.status
into the serializeList item status field, keeping the existing noun/label/id
structure intact and preserving the same serialization shape used by the list
presenters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b546c46a-7364-4fa4-8201-5f50bd9f3ac4

📥 Commits

Reviewing files that changed from the base of the PR and between f152fe3 and 51d96b2.

📒 Files selected for processing (11)
  • docs/product/command-spec.md
  • docs/product/resource-model.md
  • packages/cli/fixtures/mock-api.json
  • packages/cli/src/adapters/mock-api.ts
  • packages/cli/src/commands/database/index.ts
  • packages/cli/src/controllers/database.ts
  • packages/cli/src/lib/database/provider.ts
  • packages/cli/src/presenters/database.ts
  • packages/cli/src/shell/command-meta.ts
  • packages/cli/src/types/database.ts
  • packages/cli/tests/database.test.ts

Comment thread docs/product/command-spec.md
Comment thread docs/product/command-spec.md
Comment thread packages/cli/src/controllers/database.ts Outdated
Comment thread packages/cli/src/controllers/database.ts
Comment thread packages/cli/src/presenters/database.ts
- Validate --from/--to strictly: accept YYYY-MM-DD (expanded to midnight
  UTC, matching the API's ISO datetime contract) or a full ISO datetime,
  and reject rollover dates like 2026-02-30 that Date.parse silently
  accepts
- Keep --source-database in the CONFIRMATION_REQUIRED recovery command
  for cross-database restores
- Document DATABASE_BACKUP_NOT_FOUND and the date normalization rules in
  the command spec

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/tests/database.test.ts`:
- Around line 594-611: The `rejects impossible calendar dates for usage periods`
test only covers a date-only rollover case, but `database.usage` also accepts
ISO datetimes. Extend this test in `packages/cli/tests/database.test.ts` by
adding a datetime rollover input alongside `--from "2026-02-30"` to cover the
datetime parsing branch as well. Keep the same assertions on
`executeCli`/`payload` so both supported formats are validated by the
`database.usage` command path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7e6ee1bd-05e6-468a-934d-cd5ebbc4997f

📥 Commits

Reviewing files that changed from the base of the PR and between 51d96b2 and 8b86215.

📒 Files selected for processing (3)
  • docs/product/command-spec.md
  • packages/cli/src/controllers/database.ts
  • packages/cli/tests/database.test.ts

Comment thread packages/cli/tests/database.test.ts
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 2, 2026
… runner

usage/backup/restore/rotate recovery commands, confirmation nextSteps,
and result nextSteps now render through the project's package runner
(pnpm dlx / bunx / npx -y with @prisma/cli@latest) instead of the
hardcoded prisma-cli bin name, matching the agent group's convention.
The management provider takes an optional formatter so its error
factories stay consistent with the invoking directory.
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 2, 2026
luanvdw
luanvdw previously approved these changes Jul 3, 2026

@luanvdw luanvdw left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work on this @AmanVarshney01

The overall shape looks right to me, one thing to consider fixing before merge, date-only --to currently normalizes the same way as --from, so --to 2026-06-30 becomes 2026-06-30T00:00:00.000Z before it is sent as endDate (packages/cli/src/controllers/database.ts). The spec/example reads like a calendar-day-inclusive range (--from 2026-06-01 --to 2026-06-30 for June usage), but this ends the query at the very start of June 30 unless the API has hidden special handling for that case.

What about either expand date-only --to to the end of the UTC day, or explicitly document --to as an instant bound and adjust the example. I’d also add a focused test so we don’t lock in the current midnight behavior.

I ran the focused database tests, tsc --noEmit, and git diff --check and all tests passed passed, so this flag is more a narrow contract fix rather than a broad implementation concern.

A date-only --to normalized to midnight, so --from 2026-06-01 --to
2026-06-30 ended the query at the very start of June 30 unless the API
applied its own end-of-day handling. Calendar dates now expand
per-bound (--from to start of day, --to to end of day) so the range is
calendar-day inclusive by contract, not by server behavior. Adds the
new database error codes to error-conventions.md and a same-day range
test.
@AmanVarshney01 AmanVarshney01 dismissed stale reviews from luanvdw and coderabbitai[bot] via 3576c87 July 3, 2026 08:25
@AmanVarshney01

Copy link
Copy Markdown
Member Author

@luanvdw Good catch, fixed in 3576c87: a calendar-date --to now expands to T23:59:59.999Z (with --from staying at start of day), so the documented calendar-day-inclusive range holds by client contract instead of server behavior. Spec bullet rewritten accordingly and a same-day --from 2026-06-15 --to 2026-06-15 test locks it in. For the record, the API does end-of-day its endDate server-side (verified against production earlier), so behavior was correct before, but agreed that relying on that silently was fragile.

@AmanVarshney01 AmanVarshney01 merged commit c14accc into main Jul 3, 2026
10 checks passed
@AmanVarshney01 AmanVarshney01 deleted the feat/database-usage-backups-restore-rotate branch July 3, 2026 08:49
AmanVarshney01 added a commit that referenced this pull request Jul 3, 2026
Completes the `project` group's remote lifecycle: rename, remove, and
transfer. Spec-first (`command-spec.md` + `resource-model.md` updated in
the same change).

```bash
$ prisma-cli project rename "Acme Dashboard v2"
✔ Renamed. Directory bindings pin the project id, so they stay valid.

$ prisma-cli project remove proj_999 --confirm proj_999
✔ The project, its databases, and its apps were removed.
  This directory's local project binding was cleared.

$ prisma-cli project transfer proj_123 --to-workspace "Prisma Labs" --confirm proj_123
✔ The project now belongs to the recipient workspace.
  This directory's local project binding now points at the recipient workspace.
```

Design notes
- The transfer API authorizes with a recipient *access token*, not a
workspace id. `--to-workspace` resolves a locally stored OAuth session
(same targets as `auth workspace use`) through a new workspace-pinned
`FileTokenStorage` view that refreshes via the SDK and can never move
the active-workspace selection; `--recipient-token` is the
cross-account/headless path. Under `PRISMA_SERVICE_TOKEN`,
`--to-workspace` fails with `TRANSFER_RECIPIENT_UNAVAILABLE`.
- Remove and transfer take an explicit positional target (never the
bound project) plus exact-id `--confirm`.
- Local pin hygiene: remove clears a matching `.prisma/local.json`;
transfer rewrites it to the recipient workspace when known, else clears
it; both best-effort with warnings.
- Structured codes: `PROJECT_REMOVE_BLOCKED` (active deployments),
`PROJECT_TRANSFER_REJECTED`, `PROJECT_RENAME_FAILED`,
`TRANSFER_RECIPIENT_REQUIRED`/`_UNAVAILABLE`, `CONFIRMATION_REQUIRED`
with meta.

Testing: 14 new integration tests, full suite green, and all three
commands verified against the live Management API with scratch projects,
including a real cross-workspace transfer (project visible in the
recipient workspace, pin rewritten, cleaned up afterwards).

Note: merge after #106 or rebase; both touch `mock-api.ts`/fixtures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants