40 lines
1.5 KiB
Markdown
40 lines
1.5 KiB
Markdown
# Duplicate repair
|
|
|
|
## Problem
|
|
|
|
Duplicate and cloud-conflict files waste space, but deleting either path can
|
|
unmap tracks in crates or Serato's database. DJs need to choose the authoritative
|
|
copy and understand every change before it happens.
|
|
|
|
## Design
|
|
|
|
The web interface requires an analysis, an explicit keeper selection, and a
|
|
dry-run preview. Applying the plan first creates a timestamped backup beneath
|
|
`_Serato_/.serato-doctor-backups/`. The snapshot contains every replaced audio
|
|
file, loaded crate/smart-crate metadata, database V2, and a JSON restore manifest.
|
|
|
|
The non-kept audio path is then replaced with a symbolic link to the keeper.
|
|
This removes the extra audio payload while preserving every existing saved path.
|
|
Crate files and database V2 are never rewritten. The UI exposes immediate
|
|
restore using the manifest.
|
|
|
|
Users may retain all backups or set a positive rotation limit. Rotation occurs
|
|
only after a repair succeeds.
|
|
|
|
## Edge cases
|
|
|
|
- The duplicate group is rescanned and validated immediately before preview and
|
|
apply.
|
|
- Existing symlinks cannot be selected as disposable duplicate files.
|
|
- A partial failure restores already-changed files before reporting the error.
|
|
- Restore refuses to overwrite a real file.
|
|
- Healthy symlink aliases are excluded from future duplicate counts.
|
|
|
|
## Tests
|
|
|
|
- Backup creation includes audio and Serato metadata.
|
|
- The old path resolves to the selected keeper after repair.
|
|
- Restore returns the original file contents.
|
|
- Invalid keeper choices are rejected.
|
|
- Limited and unlimited retention behave deterministically.
|