{{ currentStepSubtitle }}
+Source validated with warnings
+{{ warn }}
+Last validation snapshot
+Source version: {{ sourceCapabilities.sourceVersion ?? 'Unknown' }}
++ Missing required tables: {{ sourceCapabilities.missingTables.join(', ') }} +
+{{ formatSourceCountLabel(key) }}: {{ count }}
+User suggestions load automatically after source validation.
+ +| Source User | +Target User | +
|---|---|
|
+ {{ row.username }} +{{ row.sourceUserId }} + |
+
+ |
+
| No source users loaded yet. | +|
Path Prefix Mappings
+ ++ Path mappings translate source file paths to target paths so books can be matched by file location. Books are also matched by + ISBN, file hash, and title/author regardless of path mappings. +
+Path validation
++ {{ pathValidation.summary.mappedByPrefix }} of {{ pathValidation.summary.booksWithFilePath }} source books have a mapped path +
++ {{ pathValidation.summary.unmatchedTargetPaths }} mapped paths not found on disk +
++ All {{ pathValidation.summary.matchedTargetPaths }} mapped paths found on disk +
++ Matched: {{ plan.summary?.matchedBooks ?? 0 }} · Unresolved: + {{ plan.summary?.unresolvedBooks ?? 0 }} · Duplicates: + + {{ plan.summary?.duplicateBookMatches ?? 0 }} + +
+Unresolved summary
+{{ friendlyUnresolvedReason(reason) }}: {{ count }}
+Duplicate target matches
+Multiple source books matched the same target book. Select which to use for each.
+Target book #{{ dup.targetBookId }}
+ +Preflight checks
+All checks passed - ready to migrate
+ +No migration run yet. Complete the steps above to start.
+ + ++ Run #{{ run.id }} + {{ run.state }} +
++ {{ run.startedAt ? new Date(run.startedAt).toLocaleString() : 'Not started' }} + · {{ formatDuration(reportData.durationMs) }} +
+Migration failed
+{{ run.errorMessage }}
+Books
++ Cover import skipped - media root path not configured +
+User Data
++ Click "Load Full Report" to include the dry-run match summary in the exported report. +
+ + + +Unresolved books ({{ reportData.unresolvedBooks.length }})
++ These books exist in the source but could not be matched to any book in your library. +
+{{ book.title || `Source book ${book.sourceBookId}` }}
+{{ friendlyUnresolvedReason(book.reason) }}
+