fix: forward feed context to PostCard on the profile (#48) #104
No reviewers
Labels
No labels
auth
bug
composer
correctness
database
durability
enhancement
feeds
interactions
notifications
performance
reliability
safety
security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
starsetbyte/peregrine!104
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/profile-feed-context-attribution"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #48.
What was wrong
ProfileRoute'sPostCardcall never passedrepostedByorreplyParentAuthor. Both default tonullinPostCard, and the "Replying to X" / "Reposted by X" lines only render when non-null — so on the profile a reply was indistinguishable from a top-level post, and the author's own reposts rendered as posts by the original author.That is the whole of the "Replies tab looks identical to Posts" report.
What was not wrong
The plumbing, which was my first suspicion and is worth writing down so nobody re-investigates it:
ProfileTab.REPLIESsendsposts_with_repliesthroughauthorFeedTypeintogetAuthorFeedcorrectly.(feedType, uri)primary key keeps the tabs from evicting one another.TimelineItem—FeedMappingTesthas covered that round-trip since Phase 3.5.FeedRoutepassed both fields all along.ProfileRoutewas the sole consumer that dropped them.Expectation note
posts_with_repliesis a superset ofposts_no_replies, so the Replies tab legitimately still contains every row the Posts tab shows, plus replies. Replies are now visually marked, which may make that read fine as-is. Whether to relabel the tab, or move it toposts_and_author_threads, is deliberately left open here.Tests
Two contract tests, both failing before the fix:
profile post rows forward reply parent attribution to PostCardprofile post rows forward repost attribution to PostCardThey scope their assertions to the
PostCard( ... )argument block by paren balancing, so they cannot be satisfied by the identifier appearing anywhere else in the file.Suite: 712/712 green (was 710; these two are the delta).
Caveats for review
PostCardGeometryDeviceTest-style androidTest, which CI cannot run — buildserv has no KVM.testDebugUnitTestlocally.assembleDebugandlintare unverified on my side; the main sources did compile as part of the test run, so a compile break is unlikely, but lint is genuinely untested until CI reports.Still open, not addressed here
parseAuthorFeedType(FeedRemoteMediator.kt:102) remains untested — covering it means wideningprivatetointernal. I left it alone because the round-trip is not broken, so a test there would pass on first run: regression coverage, not TDD.Follow-up commit
04fe05aresolves the open question in the PR body.Confirmed on a device build of
c49821e: reply rows do now show "Replying to X", so the attribution fix landed. But the tab still listed standalone posts and reposts, becauseposts_with_repliesis a superset and the first commit only changed labelling, never row composition.Decision was to make the tab mean "replies only, no reposts" rather than relabel it.
isAuthoredReplykeys offpost.record.replyinstead of the feed-levelreplyParentAuthor, because the latter is null for deleted/blocked parents and would have silently hidden those replies.The non-obvious part is that filtering at the persist step can stall the tab: a page with no replies writes no rows, so the PagingSource never invalidates and Paging never requests another append.
collectAuthoredReplieshandles that with a bounded rescan.Known limitation, worth a reviewer's eye: an author whose most recent ~5 pages hold no replies sees an empty tab, and pull-to-refresh rescans the same range rather than advancing. That is inherent to the cap. The alternative considered was persisting an
isReplycolumn (schema v13, additive) and filtering in the DAO, which avoids the stall entirely because every row still gets written — rejected as too much surface area for a display concern, but it is the better shape if this limitation bites.Suite 724/724, lint clean locally.
83be243replaces the filter-on-write approach from04fe05a. Please review the branch as a whole rather than commit by commit — the middle commit is an approach that was reconsidered.Supersedes the limitation flagged in my previous comment. The empty-tab case, the rescan loop and the page cap are all gone. They were scaffolding holding up a constraint that only existed because the filter sat before the write: a page with no replies wrote no rows, so the PagingSource never invalidated and Paging never asked for more.
Every row is now persisted as before and the tab reads through a narrowing query.
posts.isReply(schema v13, additive) is a fact about the post; the tab's rule lives inPostDao.getRepliesForFeedasisReply = 1 AND repostedBy IS NULL, reusing the already-persisted repost attribution rather than adding a second column.Two things worth a reviewer's attention:
12.jsonwas briefly clobbered. An intermediate build regenerated the committed v12 schema with anisReplycolumn, because the entity gained the field before the version was bumped. A v12 schema claiming a column v12 never had would makerunMigrationsAndValidatecheck against a fiction. Restored, andSchemaV13ContractTestnow asserts v12 does not carry the column, so the same slip fails loudly next time. Worth confirminggit log -p app/schemas/looks clean to you.The tab's rule is SQL, which CI cannot execute. The androidTest migration walk now covers v8→v13 and asserts existing rows backfill
isReplyas 0 rather than NULL, but it needs an emulator and buildserv has no KVM. The clauses are additionally pinned by a source-level contract test — that catches a silent loosening of the rule, not a semantic error in the SQL. If you can run the androidTest locally against a device, that is the gap.Also consolidated the "database version matches the newest committed schema" assertion, which had been duplicated into every schema contract test, so each bump meant editing all of them.
Suite 723/723, lint clean, assembleDebug clean. Still unverified on a device.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.