Conversation
DownloadHistoryService.AddUnifiedAsync wrote every download event into the unified History table without ever setting History.AudiobookId. It put the id into AudiobookExternalId instead, because the id it had to hand was the Guid? on DownloadHistory while History.AudiobookId is an int?. The per-book History tab reads through EfHistoryRepository.GetByAudiobookIdAsync, which filters on the int? column. No row written by AddUnifiedAsync could ever match it, so grabs, imports and failures never appeared under a book. That holds for Grabbed rows that already exist, not only for failures. The library key is an int: Audiobook.Id is int, History.AudiobookId is int?, and DownloadService already carries the audiobook as int?. The Guid? on DownloadHistory is the odd one out and is legacy compatibility plumbing with no production caller, so this takes the audiobook id as an int? on RecordGrabbedAsync and RecordImportedAsync, carries it into AddUnifiedAsync, and writes it to History.AudiobookId. DownloadService now passes the id it already holds, which it previously dropped because the Guid? parameter could not take it. No schema change, so no migration. The legacy DownloadHistories table and its Guid? column are untouched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
m4bard
force-pushed
the
fix/history-audiobook-id
branch
from
September 15, 2026 18:35
2e79c83 to
32ee37e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #974.
DownloadHistoryService.AddUnifiedAsyncnever setsHistory.AudiobookId. It writes the value intoAudiobookExternalIdinstead, because the object it is handed carries the audiobook id as aGuid?whileHistory.AudiobookIdisint?, and theGuidcannot go in that column. The per-book History tab (AudiobookDetailView.vue) filters onHistory.AudiobookId, so no download event has ever been able to match it, and the tab is empty for every book. There is a second contributing gap: the one production caller ofRecordGrabbedAsyncalready holds the audiobook id as anint?and, having noGuidto convert, calls the method with no audiobook id at all.The library key is
inteverywhere else that matters (Audiobook.Id,History.AudiobookId,HistoryQuery.AudiobookId, the repository'sGetByAudiobookIdAsync). TheGuid?onDownloadHistoryis the outlier, and as far as I can tell it has no production caller left. So this branch takes the audiobook id asint?instead of converting aGuid:IDownloadHistoryService.RecordGrabbedAsyncandRecordImportedAsynctakeint? audiobookId.AddUnifiedAsyncwrites that id toHistory.AudiobookIddirectly;AudiobookExternalIdkeeps its existing meaning.DownloadServicepasses theaudiobookIdit already holds at the grab site, guarded so zero or negative stays null.No migration. Changing
DownloadHistory.AudiobookIdfromGuid?toint?would also change theDownloadHistoriestable's column type and pull in other callers, none of which is needed to make the History tab work.Four tests added to
DownloadHistoryServiceTests, three of which read back through the sameGetByAudiobookIdAsyncquery the History tab actually uses rather than asserting on the column directly, plus one confirming a grab with no audiobook id leaves the row unattached. Reverting the single production line that setsHistory.AudiobookIdfails three of the four.Suite run against current canary (
upstream/canaryata630572e9, which this branch is built on): targeted filterDownloadHistoryServiceTests, 11 passed, 0 failed.Note from the issue: this touches the same method as the separate
Protocolcolumn fix (#973), so the two need applying in a chosen order rather than merged blind. Reproduction steps and the excludedDownloadHashRetrievalServicepath (which has the identical gap but is out of scope here) are in the issue.Disclosure: drafted with Claude Code at my direction; I read the cited code at commit a630572 and reviewed this before posting.