Skip to content

refactor(worker): Capture date in one place, proxy rows added one way (#283) - #288

Merged
bitbiter-dev merged 2 commits into
masterfrom
chore/283-review-findings
Oct 18, 2026
Merged

bitbiter-dev merged 2 commits into
masterfrom
chore/283-review-findings

Conversation

@bitbiter-dev

Copy link
Copy Markdown
Owner

Closes #283.

Summary

Capture date in one place. Month, Day and Year are set only by MediaAsset.DateCaptured's setter and have private setters. The flashback index columns can no longer drift from the capture date, and #250's in-place update gets them right by assigning the date.

 public LocalDateTime DateCaptured
-{ get; set; }
-public int Month { get; set; }   // copied by hand in NewContentWriter and PairedMovResolver
+{
+    get;
+    set { field = value; Month = value.Month; Day = value.Day; Year = value.Year; }
+}
+public int Month { get; private set; }

The last-write-time fallback for a file without an EXIF date is one helper, CaptureDate.FromExifOrLastWrite, used by both builders.

Proxy rows added one way. Both writers hand their rows to IMediaAssetRepository.AddProxyFiles(context.ProxyFilesOf(ownerId)), which wraps AddRange:

 NewContentWriter.TryWriteAsync
   repository.Add(asset)                              // asset built with ProxyFiles = [...] before
+  repository.AddProxyFiles(context.ProxyFilesOf(asset.Id))
 PairedMovProxyWriter.WriteMissingAsync
-  foreach proxy in context.ProxyFiles.Where(AssetId == mov.Id)
-    repository.AddProxyFile(proxy)
+  repository.AddProxyFiles(context.ProxyFilesOf(mov.Id))

An explicit Add keeps a row whose Guid key is already set in the Added state. A row discovered through a navigation can be tracked as Modified instead.

The schema and the EF model are unchanged: docs/schema.sql is current and EF reports no pending model changes. Loading a row writes the backing fields directly, so the setter never runs on read.

Evidence

  • Before: NewContentWriterTests.TryWriteAsync_Always_AddsTheContextsProxyFilesToTheRepositoryAsync and ..._AddsOnlyTheAssetsOwnProxyFilesAsync failed, because rows went through the navigation. MediaAssetTests.DateCaptured_Set_SetsTheFlashbackDateParts failed, because the parts stayed 0.
    After: all pass. Also new: TryWriteAsync_LivePhotoPairWithoutExifDate_DatesEachHalfByItsOwnFileAsync, which dates the HEIC from 2021-03-04 and the MOV from 2021-03-05. It pinned the fallback before the extraction.
  • All test projects pass (1,304 tests), and dotnet format --verify-no-changes is clean.
  • scripts/mutation-changed.sh: 100.00% (77 killed, 0 survived) across MediaAsset, CaptureDate, both builders, IngestionContext, PairedMovProxyWriter, MediaAssetRepository and the pipeline middlewares the end-to-end blurhash test covers.

Merge Danger

Door: two-way

Blast Radius: Worker ingestion writes

No schema change. The risk is EF's insert behaviour on real PostgreSQL. Proxy rows are now separate Added entries next to their asset, not children in its navigation, and EF still orders the inserts by foreign key. CI's unit tests don't run against PostgreSQL, so the first real crawl after merge is the end-to-end check.

🤖 Generated with Claude Code

bitbiter-dev and others added 2 commits October 18, 2026 22:02
…#283)

Month, Day and Year are now set only by MediaAsset.DateCaptured's setter
and have private setters, so the flashback index columns cannot drift
from the capture date. NewContentWriter and PairedMovResolver share one
CaptureDate.FromExifOrLastWrite fallback instead of copying it.

Both writers add proxy rows through IMediaAssetRepository.AddProxyFile,
selected with the new IngestionContext.ProxyFilesOf(ownerId), instead
of the primary's going through the MediaAsset.ProxyFiles navigation.
An explicit Add keeps a row with a preset Guid key in the Added state.

No schema or model change (docs/schema.sql current, no pending model
changes).

Closes #283.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IMediaAssetRepository.AddProxyFile becomes AddProxyFiles(IEnumerable),
backed by AddRange, so NewContentWriter and PairedMovProxyWriter each
hand over their rows in one call instead of repeating the same loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bitbiter-dev
bitbiter-dev merged commit ce56a27 into master Oct 18, 2026
11 checks passed
@bitbiter-dev
bitbiter-dev deleted the chore/283-review-findings branch October 18, 2026 20:10
bitbiter-dev added a commit that referenced this pull request Oct 18, 2026
#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>
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.

chore: Medium and low findings from the 2026-10-18 architecture review

1 participant