feat(transfer): action-first launcher with .sql/.csv/.xlsx restore + Oracle hardening - #55
Closed
Blankll wants to merge 3 commits into
Closed
feat(transfer): action-first launcher with .sql/.csv/.xlsx restore + Oracle hardening#55Blankll wants to merge 3 commits into
Blankll wants to merge 3 commits into
Conversation
…l pagination Four correctness fixes to the scope-first transfer module: 1. backup_server partial-failure summary parity Mirror migrate_server semantics via new summarize_backup_outcome helper. Per-table failures aggregated with db.schema.table context. - All succeed -> Completed, error=None - Partial -> Completed, error=Some(summary) - All fail -> Failed, error=Some(summary) 2. PG + MSSQL ensure_target_database always probes accessibility Previously only verified connectivity when CREATEing the DB. Now opens a temp adapter to target and runs SELECT 1 whether DB was just created or already existed, surfacing inaccessible targets upfront instead of mid-transfer. MySQL unchanged (same-connection semantics). 3. System database exclusion in whole-server scope New list_databases_for_connection(exclude_system_databases) + should_exclude_system_database + filter_system_databases_for_whole_server. Applied only via expand_selection implicit expansion; explicit user selections respected; browse.rs::list_databases unchanged (UI sidebar unaffected). - MySQL : mysql, information_schema, performance_schema, sys - PG : template0, template1 (kept 'postgres' as legitimate user DB) - MSSQL : master, msdb, tempdb, model 4. SQL Server pagination New paginate_clause(db_type, offset, limit, base_has_order_by) helper. - MySQL/PG/SQLite -> LIMIT n OFFSET m - MSSQL -> [ORDER BY (SELECT NULL)] OFFSET n ROWS FETCH NEXT m ROWS ONLY The synthetic ORDER BY is suppressed when the base query already has one (e.g. ExportSource.order_by), preventing invalid T-SQL with two ORDER BY clauses. Replaces inline LIMIT/OFFSET in export.rs (batch and preview paths) and migration.rs. Gates: cargo fmt clean, cargo test --lib 82/82 (+6 new tests), vue-tsc clean, eslint 0 errors, jest 276/276. Stacked on feat/transfer-redesign-scope-first (PR #54).
Blankll
force-pushed
the
feat/transfer-hardening
branch
from
May 23, 2026 13:11
4dfa37d to
569a915
Compare
Action-first Transfer page (/transfer) with Action -> Source -> Target -> Options -> Launch flow. Restore-from-file as first-class action supporting .sql, .csv, .xlsx. Page-scoped JobsDrawer at bottom; cascading dropdowns for source/target picking. Backend (src-tauri/): - restore_backup: accept job_id, support 'excel' alias, split schema.table targets - DatabaseAdapter: new execute_batch_with_params trait method - pg/mysql/mssql/sqlite: parameterized batch INSERT implementations - restore.rs: new SQL splitter handles dollar quotes ($$, $tag$), same-line semicolons, string literals, comments; streaming CSV/XLSX batches; schema-qualified quoting - import.rs: fix Excel header double-consume bug Frontend (src/components/transfer/launcher/): - TransferLauncher, ActionPicker, SourcePicker, TargetPicker, OptionsPanel, JobsDrawer, PresetsBar (new) - File format selector + auto-detect; target table input for csv/xlsx - Async race guards in cascading dropdowns - Schema-keyed table selection - NaN% guard in JobsDrawer progress - transferApi/transferStore wire jobId through restoreBackup Removed destructive dropTargetFirst from tabular restore paths. i18n: 3 new launcher keys in en/zh. Gates: cargo fmt/clippy/test 116/116, vue-tsc 0 errors, eslint 0E/1W (pre-existing), jest 276/276.
Redesign launcher from stacked cards to console-style split layout: - Context bar with live breadcrumb (CONN → SCOPE → DB → ACTION → FMT) - Side-by-side source/destination panels for at-a-glance awareness - Summary bar showing scope, tables, format, status with READY/INCOMPLETE - Action tiles replacing card grid, with accent highlight on selection - Activity bar replacing floating drawer, always visible at bottom - Monospace labels, steel-blue-gray palette, teal accents Design tokens in CSS variables across light/dark mode: - OKLCH color system with tinted neutrals - JetBrains Mono, Sofia Sans, Wix Madefor Text fonts - Transfer console component classes (panels, sections, tiles, bar) Also: - Add .impeccable.md design context document - Ignore .omo/ agent runtime data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reshape Transfer as an action-first launcher at
/transfer: user picks Action → Source → Target → Options → Launch. Restore-from-file is a first-class action supporting.sql,.csv,.xlsx. Page-scoped JobsDrawer at bottom; cascading dropdowns replace tree pickers.Why
Previous Transfer UI required users to right-click in the sidebar tree for backup/migrate. We removed right-click entirely — users now go directly to /transfer and act through the interactive launcher. Restore wasn't even a first-class action before; it is now.
What changed
Backend (
src-tauri/)restore_backupTauri command: acceptsjob_id: Option<String>so JobsDrawer subscription matches; supports'excel'alias for'xlsx'; splitsschema.tabletargets into proper schema/table.DatabaseAdaptertrait: newexecute_batch_with_params(statement, column_count, values)method using native driver bind APIs.tokio_postgresToSql bindsmysql_async::Value::Bytespositional paramstiberius::Query::bindrusqlite::params_from_iterrestore.rs(new, 491 LoC + tests):$$,$tag$), single/double quotes, line/block comments, splits every semicolon outside any quoted/dollar context (incl. same-line statements). 4 new tests.qualified_table()helper: proper"schema"."table"quoting per dialect.import.rs: fix Excel header double-consume —rows_iterwas advanced thenrange.rows()re-iterated from top.dropTargetFirstDROP TABLE from CSV/XLSX restore arms (flag still accepted, silently ignored for tabular — tabular restore targets EXISTING tables).Frontend (
src/components/transfer/launcher/)TransferLauncher,ActionPicker,SourcePicker,TargetPicker,OptionsPanel,JobsDrawer,PresetsBar+types.ts,index.ts.OptionsPanel:fileFormatSelect (sql/csv/excel) with auto-detect from file extension; conditionaltargetTableInput for csv/xlsx; removed dangerous dropTargetFirst Checkbox from restore (kept in migrate).TransferLauncher: validation rejects restore without fileFormat or missing targetTable for csv/xlsx; schema-keyed table selection (db.schemakey) for PG/MSSQL schema disambiguation.SourcePicker+TargetPicker:requestIdrace guards on cascading dropdown loaders — late responses from cancelled requests are dropped.JobsDrawer: progress renders0%whentotal === 0instead ofNaN%.transferApi.restoreBackup+transferStore.startRestore: passrequestedJobIdso JobsDrawer subscribes BEFORE invoke.transfer.launcher.fileFormat,.targetTable,.targetTablePlaceholder) in en/zh.Oracle review
Previous Oracle review (
bg_8e9948fb) rejected with 6 P0s + 5 P1s + 3 P2s. All addressed in this PR.commands/transfer.rs:1891commands/transfer.rs:1759OptionsPanel.vueTransferLauncher.vueJobsDrawer.vue:121qualified_table()helperfunctionper antfutop-level-functionruleimport.rs:384Gates
cargo fmt✓cargo clippy --all-targets -- -D warnings✓cargo test✓ (116/116; integration tests requiring live DBs ignored as expected)vue-tsc -b✓ (pre-existing tsconfig.node.json noEmit warning, unrelated)npm run lint:check✓ (0 errors, 1 pre-existing warning in ExportWizard.vue:152)npm test✓ (276/276)Manual QA checklist (deferred)