feat: typed task-relationship link substrate (ADR 0042 phase 1)#3550
Conversation
Adds blocks/followsUp/duplicates/fixes/supersedes as new EntryLink union variants on the existing linked_entries substrate, per ADR 0042 and the implementation plan. Model and storage only, ships alone ahead of any UI writes to open the old-build compatibility window (fallbackUnion: 'basic' degrades unknown types on old builds). - EntryLink gains 5 new variants + an EntryLinkType enum/buildLink factory - linkedDbEntity derives the new type-column strings - typedLinksForTaskIds: type-scoped batch query, both directions - createLink takes an optional linkType (defaults to basic, no call-site churn) and runs a bounded local cycle guard before creating a blocks edge - Sync round-trip and fallback-union tests confirm typed links survive serialize/receive/upsert and degrade safely on unknown future types
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
📝 WalkthroughWalkthroughChangesThe EntryLink union now supports five typed relationship variants with JSON and database discriminator support. Persistence accepts link types, queries typed links in both directions, and applies bounded cycle detection to Typed entry links
Estimated code review effort: 4 (Complex) | ~45 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
lib/database/conversions.dart (1)
260-269: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider a shared constant for the
EntryLinkType→ persisted type-name mapping. Both sites independently hardcode'BlocksLink'(and siblings) as literal strings with no single source of truth, so a future rename could silently desync them without a compiler error.
lib/database/conversions.dart#L260-L269: extract theEntryLinkType→ type-string mapping (e.g. as anEntryLinkTypeextension getter) instead of inline literals inlink.map(...).lib/logic/persistence_entries.dart#L258-L284: reuse the same mapping instead of the independentconst {'BlocksLink'}literal in_wouldCreateBlocksCycle.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/database/conversions.dart` around lines 260 - 269, Create one shared EntryLinkType-to-persisted-name mapping, preferably as an EntryLinkType extension getter, and update the link.map(...) conversion in lib/database/conversions.dart lines 260-269 to use it instead of inline literals. Update _wouldCreateBlocksCycle in lib/logic/persistence_entries.dart lines 258-284 to reuse the same mapping rather than its independent const {'BlocksLink'} literal.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@lib/database/conversions.dart`:
- Around line 260-269: Create one shared EntryLinkType-to-persisted-name
mapping, preferably as an EntryLinkType extension getter, and update the
link.map(...) conversion in lib/database/conversions.dart lines 260-269 to use
it instead of inline literals. Update _wouldCreateBlocksCycle in
lib/logic/persistence_entries.dart lines 258-284 to reuse the same mapping
rather than its independent const {'BlocksLink'} literal.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8bd6ec41-9265-44d8-8e43-fe68c00ac431
📒 Files selected for processing (12)
lib/classes/entry_link.dartlib/classes/entry_link.freezed.dartlib/classes/entry_link.g.dartlib/database/conversions.dartlib/database/database_links_ratings.dartlib/logic/persistence_entries.dartlib/logic/persistence_logic.darttest/classes/entry_link_test.darttest/database/database_links_ratings_test.darttest/features/sync/matrix/sync_event_processor_journal_handlers_test.darttest/logic/persistence_entries_test.darttest/logic/persistence_logic_test.dart
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3550 +/- ##
=======================================
Coverage 99.21% 99.21%
=======================================
Files 1761 1761
Lines 129098 129148 +50
=======================================
+ Hits 128087 128137 +50
Misses 1011 1011
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Summary
docs/implementation_plans/2026-07-23_task_dependency_links.md— the link substrate only, ships alone ahead of any UI writes per ADR 0042's old-build compatibility window.blocks/followsUp/duplicates/fixes/supersedesas newEntryLinkunion variants on the existinglinked_entriestable (no schema change) plus anEntryLinkTypeenum with abuildLinkfactory.linkedDbEntityderives the new type-column strings;typedLinksForTaskIdsis a new type-scoped batch query (both directions, mirrorsbasicLinksForEntryIds's discipline).createLinkgains an optionallinkTypeparameter (defaults tobasic, zero call-site churn) and runs a bounded local cycle guard before creating ablocksedge (ADR 0042 §5).Test plan
flutter analyzeclean project-wideentry_link_test.dart), query direction/type-scoping/tombstone-exclusion (database_links_ratings_test.dart), cycle-guard scenarios — self-loop, 1-hop, 2-hop, dedup, inbound-link filtering (persistence_entries_test.dart), facade delegation (persistence_logic_test.dart), a genuine sync round-trip throughSyncEventProcessoragainst a real in-memory DB, and a fallback-union test proving an unknown future type degrades toBasicLinkwithout crashing (sync_event_processor_journal_handlers_test.dart)Summary by CodeRabbit
New Features
Bug Fixes
Tests