docs(admin): hash conflicts page — the duplicate-content queue
Sixth admin page. Documents what creates conflict groups (scanner at scan time + the hash backfill retroactively), the group card anatomy (count badge, library + short SHA-256, per-copy rows with usage summary highlighted when that copy holds reading data), and both resolutions with verified semantics: Keep this copy (reparents the other copies' children into the kept copy, deletes their catalog rows, records the resolver — files on disk never touched, consistent with platform-wide delete semantics) and Keep both (mark resolved, stop flagging, nothing merged). Glossary gains Keep both and Keep this copy.
This commit is contained in:
1 parent
3e55ddd88a
commit
aee1aafc74
2 files changed
+64
No files matched your search
@@ -0,0 +1,56 @@
|
||||
<!-- Ground truth: templates/admin_hash_conflicts.templ (cards, actions,
|
||||
confirms), internal/handlers/hash_conflicts.go (ResolveHashConflict:
|
||||
keep_all marks resolved; keep reparents children to the kept copy,
|
||||
deletes the other catalog rows, records who resolved), internal/
|
||||
services/media_scanner.go (recordHashConflictIfAny), internal/services/
|
||||
hash_backfill.go (backfill-created conflicts). Re-verify against these
|
||||
when the page changes. -->
|
||||
|
||||
# Hash Conflicts
|
||||
|
||||
Hash Conflicts is the duplicate-content queue: groups of catalog items
|
||||
whose files are **byte-identical** (same SHA-256) but stored at more than
|
||||
one path in the same library. The scanner flags these as it goes — and
|
||||
the hash backfill job flags them retroactively for content that predates
|
||||
hash tracking — so both fresh scans and old libraries surface their
|
||||
duplicates here.
|
||||
|
||||
Duplicates usually mean the same book was copied into two folders, or a
|
||||
library was reorganized and both the old and new copies got scanned. The
|
||||
harm is quiet but real: split reading histories, double-counted library
|
||||
stats, and two entries for one book.
|
||||
|
||||
## What a conflict looks like
|
||||
|
||||
One card per group: a **Duplicate content** heading, a badge with the
|
||||
copy count, the library and a short fingerprint of the shared hash, and
|
||||
one row per copy — title, author, full path, file size, and a usage
|
||||
summary that's **highlighted when that copy holds reading data** (someone
|
||||
has actually read it).
|
||||
|
||||
## Resolving a group
|
||||
|
||||
Two outcomes, both confirm-guarded:
|
||||
|
||||
### Keep this copy
|
||||
|
||||
Per-copy button. Keeps the copy you chose and folds the **other copies'
|
||||
reading data into it** (their catalog rows are removed; the underlying
|
||||
files on disk are never touched — this platform's deletes act on the
|
||||
catalog, not your files). The row-level usage summaries exist precisely
|
||||
so you can pick the copy that already carries the reading history.
|
||||
|
||||
### Keep both
|
||||
|
||||
The group-level button, for duplicates that are intentional. It records
|
||||
the resolution and stops flagging this group — every copy stays in the
|
||||
catalog exactly as it is, nothing merged, nothing removed.
|
||||
|
||||
After either choice the card is replaced with the outcome, and the group
|
||||
never comes back (unless the same duplicate situation re-arises from a
|
||||
*new* scan, which creates a fresh group).
|
||||
|
||||
## When the page is empty
|
||||
|
||||
"No content duplicates detected." — the queue drains from the top; groups
|
||||
appear as scans and the backfill find them.
|
||||
@@ -284,6 +284,14 @@ label: User Access
|
||||
where: Admin → Libraries → a library's panel → section heading
|
||||
does: Per-user visibility checkboxes — checked (default) shows the library to that user; unchecked hides it everywhere for them, enforced in the database.
|
||||
|
||||
label: Keep both
|
||||
where: Admin → Hash Conflicts → a conflict group card
|
||||
does: Records the resolution and stops flagging the group; every copy stays, nothing merged or removed. For intentional duplicates.
|
||||
|
||||
label: Keep this copy
|
||||
where: Admin → Hash Conflicts → a copy row
|
||||
does: Keeps that copy, folds the other copies' reading data into it, and removes their catalog rows. Files on disk are never touched.
|
||||
|
||||
label: Resume rewind
|
||||
where: audio player → player settings; profile settings
|
||||
does: Rewinds playback a configured few seconds when you resume.
|
||||
|
||||
Reference in new issue
Block a user