Skip to content

feat(desktop): preserve connection groups in JSON backups - #2091

Draft
ysfscream wants to merge 1 commit into
mainfrom
ysfscream/backup-connection-groups
Draft

ysfscream wants to merge 1 commit into
mainfrom
ysfscream/backup-connection-groups

Conversation

@ysfscream

@ysfscream ysfscream commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

PR Checklist

What is the current behavior?

Settings > Data Backup exports connection records without collection entities. Recovery clears every connection's parent ID. With Group1/Group2 and one connection in each, recovering the JSON on another installation puts both connections at the root and loses the groups.

Issue Number

Refs #1255

What is the new behavior?

JSON retains its top-level array and adds flat group records with isCollection: true, id, name, parentId, and orderId. Restore groups in parent order and preserve nested/empty groups, ordering, and connection membership. Single-connection JSON includes only its ancestor groups; other export formats retain their existing connection/message output. Messages continue to stream on export and import in batches.

Older connection-only backups remain importable and recover at the root. Repeated imports update matching entity IDs. Reject duplicate IDs, group/connection ID collisions, child IDs owned by another connection, missing group references, and cycles. Restore all entities and closure-table relationships in one transaction; failures return an error and roll back the entire backup. Reuse the existing entity converters and subscription/message services with transaction-scoped repositories.

The import form accepts group records only for JSON, clears stale file selections, and waits for legacy CSV parsing before validating. Streamed JSON omits undefined fields so restored legacy connections without a will can be exported. English and Chinese documentation describe the format and conflict behavior. Script backup (#1309) is outside this change.

Does this PR introduce a breaking change?

  • Yes
  • No

JSON backups containing group records require a Desktop version supporting this format. Older Desktop importers cannot read those group records. Incoming legacy connection-only backups and the other export formats remain supported; no database schema migration is added.

Specific Instructions

Local validation on macOS, Node 22.15.0, TypeORM 0.2.34 / native sqlite3 5.1.6 (SQLite 3.41.1):

  • The minimal issue case failed before the production change: recovery yielded 0 groups; exporting an empty-group-only database returned No data to export. Both pass after the change.
  • Native SQLite regressions use two fresh disk-backed databases per test and never import the application database configuration or access personal settings. Cover nesting, empty groups, order, single-connection ancestors, legacy formats/IDs, repeated import, closure-tree reparenting, conflicts, invalid inputs, 1,001-message batching, progress, and a late SQL error rolling back all six affected tables.
  • Import form tests use temporary files and cover JSON group selection, legacy single-connection JSON, legacy YAML and JSON-only group validation, asynchronous CSV conversion, and clearing stale content after malformed input. The CSV regression fails without awaiting conversion.
  • Full Desktop unit suite: 402 passing.
  • Desktop lint: 0 errors, 179 existing warnings. TypeScript tsc --noEmit, changed-file ESLint/Prettier, git diff --check, and Electron renderer/main production bundling with --skipElectronBuild pass.
  • Native Desktop interactive validation is NOT completed. The computer-use window reader repeatedly did not return, including an attempt by full app path with a requested 15-second timeout after resetting the tool. The temporary launch attempt also exited before opening the app because the launcher resolved Electron incorrectly. No Settings export/recovery interaction was performed. No Web substitute was used. No test Electron process remains running; UI ownership was released. Temporary source/target profiles were initialized under /tmp to prevent application data migration from copying a personal database.
  • Remote checks pass on commit 03222d352aafb35a4ba3e0f701940d8158b186ae: Desktop unit tests (402 passing), Desktop lint, and macOS, Windows, and Linux packaging. Linux packaging initially failed while downloading the AppImage tool with a connection reset; the failed job passed on retry without code changes.
  • No local installer/signing validation or Windows/Linux interactive validation performed.

Other information

Manual Desktop verification still needed:

  1. Launch this branch with a new temporary user-data profile. Create Group1 and Group2, each with one connection; add nested and empty groups.
  2. Use Settings > Data Backup with JSON. Check that the file includes group records and the connections' parent IDs.
  3. Launch a second empty temporary profile and use Settings > Data Recovery. Confirm the same group tree, empty groups, connection membership, and ordering in the sidebar.
  4. Recover the same file again; check that groups, connections, and identified child records are not duplicated. Recover an old connection-only JSON file and confirm root-level connections.
  5. Try an invalid hierarchy or a child-ID conflict; verify that an error is displayed and the existing database is unchanged.

Focused automated check: NODE_OPTIONS=--openssl-legacy-provider yarn test:unit tests/unit/database/connectionBackup.spec.ts tests/unit/components/ImportData.spec.ts tests/unit/utils/jsonStreamWriter.spec.ts.

@ysfscream ysfscream added this to the v1.13.2 milestone Sep 30, 2026
@ysfscream ysfscream added feature This pr is a feature desktop MQTTX Desktop labels Sep 30, 2026
@ysfscream ysfscream self-assigned this Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop MQTTX Desktop feature This pr is a feature

1 participant