Skip to content

feat(backups): take, list, verify and delete database backups in Studio - #2079

Merged
dawsontoth merged 7 commits into
stagefrom
claude/backup-restore-enablement-b5f8f5
Nov 10, 2026
Merged

dawsontoth merged 7 commits into
stagefrom
claude/backup-restore-enablement-b5f8f5

Conversation

@dawsontoth

@dawsontoth dawsontoth commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor
A squirrel checks an acorn jar while each tree keeps its own stash

⊙ Problem

Harper 5.2+ can take and manage database backups. Studio has no screen for them. Fabric customers must type operations into the Operations console.

💡 Solution

  • A Backups tab under Config, for super users on Harper 5.2 or later.
  • Pick a database, then take a backup and follow its job, list backups with id, time, size and attachments, verify one, delete one, or keep only the newest N. A purge first names what it deletes.
  • Each cluster node gets its own card. Every request goes to that node through /HDBInstance/<id>/operation. The cluster's own address reaches whichever node runs first.
  • Harper's own message shows when it refuses a command.
  • The page says backups live on the node's disk, are lost with the node, and can't be restored from Studio yet.

🤔 Keep newest N starts at 1

Harper accepts keep_count: 0, which deletes every backup. The dialog asks for at least 1, so clearing a database's backups takes one Delete per row. Say if 0 should be allowed.

🤔 Leaving the page stops following a job

Studio follows a job only while the page is open. The backup still finishes and shows in the list later, but its result message is lost. Keeping followed jobs per node across pages is possible; say if it's wanted.

⚖️ Alternatives

Decisions the review raised
  • version-gate-waits-for-both: on a cluster either registration_info or the cluster record can show the page, but it says backups are unsupported only once both are in, so neither can flash a verdict the other reverses.
  • verify-lock-scope: Verify waits behind every other write on its node and database, matching Harper's one-at-a-time lock. Two backups can't be verified at once from Studio.
  • delete-refuses-without-timestamp: delete refuses when it can't tell two backups apart. Harper always sends timestamp, so only a malformed answer hits this.

🔧 Changes

✅ Verification

  • Live, against a local Harper 5.3.6 in Local Studio mode: took, verified, purged and deleted backups through the page. Harper's 404 for a backup deleted elsewhere showed as a toast, and the stale row went away.
  • That run found Harper reusing ids once every backup is gone. A verify result now matches on id and timestamp, and delete and verify check the backup before sending.
  • 53 new tests. index.test.tsx drives the page against fake per-node clients with a real QueryClient: jobs followed on their node, a delete refused on id reuse, a partly upgraded cluster. backupNodes.test.ts and backups.test.ts cover member selection and request shapes. Removing any of the node pinning, the busy hold, the list refresh, the identity checks, the any-member rule, the 403 handling, the missing-job recheck or the dialog binding turns a test red.
  • Full gate: vitest (650 files, 7,131 tests), tsc -b, oxlint, dprint. The Fabric per-node route needs Fabric and wasn't run live; it is the client InstanceStatusCell already uses.

Closes #2008

🤖 Generated by Anthropic Claude (Claude Code); posted via @dawsontoth.

Related PRs: #2031 overlaps (Config nav entries and route list), #2065 overlaps (Config nav entries and route list)
Complexity: medium

Deferred findings

  • 2e5a2c17d141883c nit maintainability — src/integrations/api/instance/backups/backups.test.ts — relative imports lack the .ts extension — NOT FILED

Review-Coverage: authored=claude; ran=cursor-composer,gemini,codex,cursor-grok; late=cursor-grok:adjudicated; adjudicated=domain; declined=muse; rounds=6; full=2 @ 293f578

Review-Attention: study ~11m (decisions: do-less-alternative, version-gate-waits-for-both, verify-lock-scope, delete-refuses-without-timestamp) @ 293f578

dawsontoth and others added 6 commits November 9, 2026 10:54
Adds a Backups tab under Config, for super users on Harper 5.2+. Pick a
database, then take a backup (following its job until it ends), list the
backups with id, time, size and whether file attachments are included,
verify one, delete one, or keep only the newest N with a confirmation that
names what goes.

On a cluster each member is listed and reached on its own through
/HDBInstance/<id>/operation, because a backup lives on the disk of the node
that took it and the cluster's own address reaches whichever member runs
first. Restore stays out of scope.

Refs #2008

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Harper reuses backup ids once every backup is deleted, so delete now
re-reads the list and refuses when the confirmed backup's timestamp no
longer matches. A cluster page and its nav entry show once any member
runs 5.2, not on whichever member answers registration_info. A job poll
Harper refuses with a 403 ends the follow as unknown and frees the node,
an accepted create or verify that names no job reads as an unknown
outcome, and Verify waits while a backup is being taken.

Refs #2008

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntity

A job that read as missing once and then turns up keeps being followed.
Delete refuses when either side has no timestamp to tell two backups
apart, and a verify badge needs one too. Verify waits behind the same
per-node hold as every other write, a purge answer without a count no
longer states one, and held buttons say why.

Refs #2008

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A describe_all refetch can change the page's default database while a
dialog is open. Each dialog now records the database it was opened for
and closes if that changes, so a purge never runs against a database
the user didn't choose.

Refs #2008

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching back to the database a dialog was opened for no longer brings
the dialog back unasked.

Refs #2008

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The page no longer flashes a verdict the other answer would reverse, and
a registration_info with no version reads as unreadable rather than
"runs undefined".

Refs #2008

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dawsontoth
dawsontoth marked this pull request as ready for review November 9, 2026 17:04
@dawsontoth
dawsontoth requested a review from a team as a code owner November 9, 2026 17:04
@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 83.56% 18846 / 22553
🔵 Statements 83.42% 19961 / 23926
🔵 Functions 79.12% 5124 / 6476
🔵 Branches 78.88% 15663 / 19855
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/features/instance/config/index.tsx 14.28% 0% 0% 14.28% 43-284
src/features/instance/config/routes.ts 67.21% 100% 51.21% 67.21% 25, 32, 40, 47, 53, 60, 66, 73, 80, 87, 93, 101, 108, 116, 123, 131, 137, 144, 151, 157
src/features/instance/config/backups/BackupDialogs.tsx 87.5% 73.17% 80% 87.5% 50, 84, 119, 145
src/features/instance/config/backups/BackupJobLine.tsx 95.23% 81.13% 100% 95.12% 90, 115
src/features/instance/config/backups/BackupNodeSection.tsx 92.39% 88.04% 88.63% 94.18% 70, 75, 160, 244, 304
src/features/instance/config/backups/backupNodes.ts 100% 85.18% 100% 100%
src/features/instance/config/backups/index.tsx 91.89% 86.11% 83.33% 91.66% 99-102, 134, 138, 153, 155
src/integrations/api/instance/backups/backups.ts 100% 100% 100% 100%
src/react-query/queryClient.ts 98.57% 100% 88.88% 98.55% 136
Generated in workflow #2550 for commit 293f578 by the Vitest Coverage Report Action

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive database backup management feature for Harper databases (version 5.2.0+). It adds a new 'Backups' section under the instance configuration, allowing users to take, verify, delete, and purge backups on a per-node basis. The implementation includes React components for dialogs and job tracking, API integrations, routing updates, detailed design documentation, and extensive unit and integration tests. I have no feedback to provide as there are no review comments to assess.

@kriszyp kriszyp 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.

🤖 Reviewed with Muse Wonder 1.0 · adjudicated by Codex

…ing a 403

Verify now re-reads the list and refuses when the id names a different
backup, as delete does, and both compare size and file count as well as
the timestamp. A job poll answered 403 gives up at once rather than after
three retries, so the node's write hold clears promptly. A member list
that couldn't be read no longer counts as proof that no node runs 5.2.

Refs #2008

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dawsontoth
dawsontoth added this pull request to the merge queue Nov 10, 2026
Merged via the queue into stage with commit c8c8fbd Nov 10, 2026
3 checks passed
@dawsontoth
dawsontoth deleted the claude/backup-restore-enablement-b5f8f5 branch November 10, 2026 14:23
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.

Backups: let customers take and manage database backups in Studio

2 participants