Skip to content

feat(worker): Update the row in place when a file's content changes at its path (#250) - #287

Merged
bitbiter-dev merged 6 commits into
masterfrom
feat/250-content-change-in-place
Oct 18, 2026
Merged

bitbiter-dev merged 6 commits into
masterfrom
feat/250-content-change-in-place

Conversation

@bitbiter-dev

@bitbiter-dev bitbiter-dev commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

Closes #250. Builds on #283, which landed separately as #288.

What changes

A file whose bytes change at a stored path (re-exported, rotated, metadata stripped) used to fail ingestion on every crawl. Its new hash was unknown, so it was inserted at a path the old row already held, which violated IX_MediaAssets_StorageConfigId_FilePath. Now the file is classified ContentChanged and updates that row in place:

  • Kept: Id, interactions, BurstId, PairedAssetId. A Live Photo whose HEIC was edited stays paired to its MOV.
  • New: ContentHash, capture date (DateCaptured, Month, Day, Year), MediaType, LastSeenOnNas, every Metadata field, and the proxy rows.
  • Proxy rows are updated in place by type, so no row is deleted and re-inserted under ix_proxyfiles_assetid_proxytype. Missing types are added and types no longer generated are removed.
  • Old proxy directory: left to the orphan sweeper (feat(worker): Orphaned proxy file sweeper (proxies ↔ DB reconciliation) #174) and documented in CLAUDE.md. It is not deleted after commit, because a copy of the old content elsewhere can be ingested into that same directory in the same crawl.

How

Deliberately not here

Verification

  • dotnet test: all 1,327 tests pass.
  • scripts/mutation-changed.sh (passed ClassificationMiddleware.cs and ImageProxyMiddleware.cs for the two test files that map to no single source): 100.00%, with 271 killed, 1 timeout and 0 survivors, after merging refactor(worker): Capture date in one place, proxy rows added one way (#283) #288. There are no new Stryker directives, so ADR 0005 has no new rows.
  • EF delete and insert ordering was checked in a throwaway SQLite project before the in-place update replaced that approach.

🤖 Generated with Claude Code

bitbiter-dev and others added 6 commits October 18, 2026 21:44
#283)

MediaAsset.SetCaptureDate sets DateCaptured with Month, Day and Year, and
CaptureDate.Resolve holds the last-write fallback. NewContentWriter and
PairedMovResolver both use them, so #250's in-place update can too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#283)

NewContentWriter now adds the primary's proxies with AddProxyFile, as
PairedMovProxyWriter does for the MOV, instead of through the ProxyFiles
navigation. Both pick an owner's proxies with IngestionContext.ProxyFilesOf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t its path (#250)

A file whose bytes change at a stored path is classified ContentChanged and
processed like new content; ContentChangedWriter then updates that row
instead of inserting one beside it, so it no longer fails on every crawl.
The row keeps its Id, interactions, BurstId and PairedAssetId; its hash,
capture date, media type, Metadata and proxy rows (updated by type) are new.

IngestionContext separates AttemptId, which names temporary files and scopes
compensation, from AssetId, the owner of the proxies, which classification
sets to the stored row for ContentChanged. A failed attempt therefore deletes
only its own proxies, never the row's previous ones.

The old content directory is left to the orphan sweeper (#174). An edited
Live Photo MOV is #285.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#288 landed #283 separately. Its API is kept: DateCaptured's setter derives
Month/Day/Year, CaptureDate.FromExifOrLastWrite, AddProxyFiles. This branch's
own #283 commits are superseded; #250 is re-applied on top of it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bitbiter-dev
bitbiter-dev merged commit 036cd5e into master Oct 18, 2026
11 checks passed
@bitbiter-dev
bitbiter-dev deleted the feat/250-content-change-in-place branch October 18, 2026 20:30
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.

Update the row when a file's content changes at the same path

1 participant