Skip to content

feat(worker): Report duplicate content, never merge it (#36) - #291

Merged
bitbiter-dev merged 4 commits into
masterfrom
feat/36-report-duplicates
Oct 19, 2026
Merged

bitbiter-dev merged 4 commits into
masterfrom
feat/36-report-duplicates

Conversation

@bitbiter-dev

Copy link
Copy Markdown
Owner

Closes #36. Follow-up for a per-user duplicates view: #290.

What

Report-only, as decided on #36: nothing is merged, hidden, deleted or written to the database.

  • Within one storage config: KnownFileReconciler already classified a second copy as DuplicateCopy. It now logs the copy at Debug with its content hash, its config and both paths, and counts it in DuplicateCopyTally, a singleton that is safe to use from the concurrent consumers.
  • Across one user's configs: after each crawl cycle, Worker.CrawlAllAsync runs SharedContentReporter over the configs it has just crawled. One read-only query (IMediaAssetRepository.FindSharedContentAsync) finds active rows of the same user that share a ContentHash, and every pair is logged at Debug.
  • Summary: one Information line per user per cycle with the number of copies within one config and the number of pairs across configs. A user with nothing duplicated gets no line.
  • Duplicates across different users are never reported.
  • A failed report is logged and never stops the crawl loop. A shutdown during the report still stops it. The report also runs when one config's crawl failed.

Decisions (agreed in session)

  • Cross-config detection is a read-only DB query, not state collected during the crawl. It is scoped to the crawled configs, so a dedicated worker only reports its own user.
  • One line per pair: a hash in 3 configs gives 3 pairs.
  • Pair details go to Debug with one Information summary per user. Per-pair Information lines would repeat thousands of lines every cycle for a mirrored config. A real surface for duplicates is spec: Per-user duplicates view — track duplicate content and show it to its owner #290.
  • Two new identical copies racing in the same crawl: the loser hits the unique index and is skipped quietly, so the duplicate is first reported on the next crawl. This is the same delay Report duplicate content (report-only; never merges or deletes) #36 already accepts for moves.

Query

Npgsql output, checked through ToQueryString: one statement, StorageConfigId = ANY(@ids), with an EXISTS that groups by (UserId, ContentHash) and has HAVING count(*) > 1. The partial unique index allows one active row per hash per config, so a count above 1 means at least two configs.

Verification

  • dotnet test: all green (Worker 549, Core 165, API 521, Infrastructure 61, Architecture 25, Testing 30).
  • scripts/mutation-changed.sh: 100.00% (99 killed, 0 survived) over KnownFileReconciler, ClassificationMiddleware, DuplicateCopyTally, SharedContentReporter, Worker, MediaAssetRepository and WorkerServiceCollectionExtensions. No new Stryker directives or exclusions.
  • /code-review (medium): no correctness bugs. Its one finding, log volume, led to the Debug + summary change.

🤖 Generated with Claude Code

bitbiter-dev and others added 4 commits October 19, 2026 13:57
Within a config, a copy of already-ingested content is now logged at
Information with its content hash, storage config and both paths.

Across one user's configs, SharedContentReporter runs after each crawl
cycle over the configs just crawled and logs every pair of active rows
that share a content hash. Duplicates across different users are not
reported. A failed report is logged and never stops the crawl loop.

Nothing is written to the database. Two new identical copies racing in
the same crawl are first reported on the next crawl, the same delay the
issue accepts for moves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bug (#36)

A library with a mirrored config produced one Information line per
duplicate on every crawl cycle. Each copy and pair is now logged at
Debug, and the end-of-cycle report logs one Information summary per
user: copies within one storage config, counted by DuplicateCopyTally
while the crawl runs, and pairs across storage configs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bitbiter-dev
bitbiter-dev merged commit 7439198 into master Oct 19, 2026
12 checks passed
@bitbiter-dev
bitbiter-dev deleted the feat/36-report-duplicates branch October 19, 2026 02:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Report duplicate content (report-only; never merges or deletes)

1 participant