feat(books): rework cross-library moves with preview and progress

Replaces the implementation from #818 with a job-backed flow. Moves are
planned up front and surfaced as a preview the user confirms, then run
through a planner/executor split against a book_move_jobs table, so
progress is trackable and partial failures roll back.

The dialog-based flow from #818 is superseded: its module, service, and
repository are removed here in favour of the job-based equivalents. Its
e2e coverage is replaced by a book-move suite that exercises preview
classification, the collision policies, file relocation, preserved user
state, and the books-before-book_files update ordering that the
composite folder foreign key constrains.

Also adds dashboard shelf layout configuration.

Ref #257
This commit is contained in:
neon
2026-08-02 17:03:14 +00:00
parent 41fd6f1881
commit f4cfc3ca5d
93 changed files with 23743 additions and 2871 deletions
+21 -22
View File
@@ -250,28 +250,6 @@ export const E2E_SUITES = Object.freeze({
...SHARED_DB_AND_HELPER_PATHS,
],
},
"book-move": {
id: "book-move",
name: "Book Move",
timeout: 45,
lane: "full",
description: "Moving books between libraries: DB re-parenting, file relocation, and constraint consistency",
vitestTarget: "test/book-move.e2e-spec.ts",
junitOutput: `${TEST_RESULTS_DIR}/book-move-e2e-junit.xml`,
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/book-move/**",
"server/src/modules/book/**",
"server/src/modules/file-write/**",
"server/src/modules/library/**",
"server/src/modules/scanner/**",
"server/test/book-move.e2e-spec.ts",
"server/test/e2e/metadata-write/**",
...SHARED_TYPES_PATHS,
...SHARED_DB_AND_HELPER_PATHS,
],
},
"jump-buckets-invariant": {
id: "jump-buckets-invariant",
name: "Jump Buckets Invariant",
@@ -636,6 +614,27 @@ export const E2E_SUITES = Object.freeze({
...SHARED_DB_AND_HELPER_PATHS,
],
},
"book-move": {
id: "book-move",
name: "Book Move",
timeout: 120,
lane: "full",
description: "Cross-library book move suite covering preview classification, collision policies, and file relocation",
vitestTarget: "test/book-move.e2e-spec.ts",
junitOutput: `${TEST_RESULTS_DIR}/book-move-e2e-junit.xml`,
prepareDedicatedDatabase: true,
useDedicatedDatabase: true,
changedPaths: [
"server/src/modules/book-move/**",
"server/src/modules/scanner/**",
"server/src/modules/app-settings/**",
"server/test/book-move.e2e-spec.ts",
"server/test/e2e/metadata-write/**",
"packages/types/src/book-move.ts",
"packages/types/src/book-selection.ts",
...SHARED_DB_AND_HELPER_PATHS,
],
},
});
export function listE2ESuites() {