Repository navigation
chore(channels): drop the vestigial Channel EF entity, its table and IColorable - #216
Conversation
|
/agentic_review |
PR Summary by QodoRemove vestigial Channel EF entity and database table
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can add REVIEW.md to your repo root and Qodo follows it on every PR |
|
Qodo-clean, CI green — ready for review. Qodo's review is anchored to |
…IColorable Ports daqifi-desktop#691. `Daqifi.Desktop.Channel.Channel` is an EF entity that was never constructed, had no DbSet, and whose table has no writer or reader; it existed only to give `LoggingSession.Channels` a type, and that navigation property has no reader either. Its `SetColor` assigned its own by-value parameter and discarded the value — a real defect, on a method with zero call sites in production, tests or XAML. With the entity gone, `IColorable` has no reason to exist here: its single member had one remaining implementor (`AbstractChannel`) and still no callers, and this repo's test doubles derive from `AbstractChannel` rather than implementing `IChannel` by hand, so unlike upstream it can go too. Nothing a user can see changes. The live colour path is `ChannelsPaneViewModel.SetColor`, which assigns `SelectedChannel.ChannelColorBrush` directly and never touched any of this. The migration takes upstream's `IF EXISTS`-guarded raw SQL rather than `DropTable`, so it is a no-op on a database that does not have the table instead of a startup failure. It deliberately leaves out upstream's unrelated `Samples` index rename, which their generated migration swept in; that drift exists here too and is left exactly as visible as it is today. Closes #206 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1f4d9a3 to
922b742
Compare
|
/agentic_review |
|
Code review by qodo was updated up to the latest commit 922b742 |
|
Rebased onto It had branched at
Body updated to match. Not merging. |
Not merging — for review.
Closes #206. Ports daqifi-desktop#691.
What this is
This removes dead weight and a latent trap. It changes nothing a user can see.
Daqifi.Desktop.Channel.Channelis an EF entity that was never constructed, had noDbSet, and whose table has no writer and no reader. It existed only to giveLoggingSession.Channelsa type, and that navigation property has no reader either. ItsSetColoris genuinely broken —color = ChannelColorBrush;, writing the by-value parameter and discarding the value — but it has zero call sites in production, tests or.axaml, and no reflective access. #206 has the full proof, including an executed contract test that fails on this implementor and passes on the other.Channel colour works correctly today and is untouched by this. The live path is
ChannelsPaneViewModel.SetColor, bound fromChannelsPanePrototype.axamlandChannelsMobileView.axamlasSetColorCommand, and it assignsSelectedChannel.ChannelColorBrushdirectly. That property and every XAML binding to it survive verbatim. There is no screenshot here on purpose: nothing renders differently, so a picture of unchanged UI would be a cost rather than a courtesy.What got smaller
git diff --numstat origin/main...HEAD— 10 files, +552 / −255. Split by what it is:DropChannelTable+ designer)The deletion half, in detail:
Channel/Channel.cs(deleted)Migrations/LoggingContextModelSnapshot.csConfiguration/IColorable.cs(deleted)Channel/AbstractChannel.csLoggers/LoggingContext.csLoggers/LoggingSession.csChannel/IChannel.csTwo whole types go, and one layer with them:
IColorableis a one-member interface every channel was forced to carry. Upstream had to keep it, because their test doubles implementIChannelby hand and so must implementSetColor; this repo's fake (LoggingManagerSubscribedChannelsTests.TestChannel) derives fromAbstractChannel, so nothing here needs the member at all.IChannelstops deriving from anything, andAbstractChannel.SetColor— the correct implementation, also with zero callers — goes too.The
+4onIChannel.csis a comment saying why this repo diverges from upstream at that line.The database change, plainly
This is the part with real consequences, so here is what happens to each shape of database a user can have. The table is always empty in anything this app or the upstream WPF app produced — nothing has ever written a row — so no logged data is at stake either way. Sessions, samples and device metadata are untouched.
EnsureCreated()byDatabaseMigrator.SeedMigrationHistoryIfNeededagainst a model that no longer declares it: theIF EXISTSguard makes this a no-op. An unguardedmigrationBuilder.DropTable("Channel")would throw here, and the throw travels out of startup, leaving the user unable to reach any of their logs. Upstream added this guard in response to their own review; it is the single most important line in the migration, and it is pinned by a test.Migrate()runs each migration in a transaction and only records it in__EFMigrationsHistoryon success, so an interruption rolls this one back and the next launch retries from a database that still has the table. Retrying after a partial success is safe for the same reason the missing-table case is — the statement is idempotent, and that is pinned too.DatabaseMigratoralso copies the file to*.migration-backupbefore migrating and restores it if migration throws.What
Down()can and cannot do. It recreates the table with the exact column, key, foreign-key and index shapeInitialSQLiteMigrationgave it, so an older build finds the schema it expects and starts. It does not restore rows —DROP TABLEis not reversible and nothing retains them. In practice that loses nothing, because the table has no writer in any released version, but the down migration is a schema rollback and should not be read as a data rollback. The test asserts the restored table is empty, which is the honest half of that claim rather than an oversight.Down()is deliberately unguarded whereUp()is guarded:Uphas to tolerate databases it did not create, whileDownonly ever runs against a database this migration has already dropped the table from, so aChanneltable standing there means something else made it and silently merging with it would be worse than failing.Deliberately narrower than upstream
Upstream generated their migration with
dotnet ef migrations add, which diffed the whole model and swept in an unrelated rename of theSamplescomposite index (IX_Samples_LoggingSessionID_TimestampTicks→IX_Samples_SessionTime) plus a drop ofIX_Samples_LoggingSessionID. That drift exists in this repo too —LoggingContextasks forIX_Samples_SessionTimewhileAddSamplesSessionTimeIndexcreates the longer name — and it is left alone here. Renaming an index on a user's database has its own risk profile and deserves its own justification; it does not belong inside a dead-code deletion. The model snapshot is therefore hand-edited to remove only theChannelentity, which leaves the pre-existing drift exactly as visible, and as suppressed viaRelationalEventId.PendingModelChangesWarning, as it is onmaintoday.The migration and its designer are hand-written for a mechanical reason:
dotnet efshells out to thedotnetonPATH, which cannot satisfy this repo's pinnedglobal.jsonSDK, so the tool cannot run here at all. The shape is verified by execution instead of by generation — see below.Tests
Daqifi.Avalonia.Tests/Loggers/DropChannelTableMigrationTests.cs, 5 tests, driving EF's ownIMigratorover the real migration chain against real SQLite files:Channeltable survives, nothing left pending.IF EXISTSguard's test.These also cover something a hand-written migration can get wrong invisibly, and which no compile-time check would catch: EF builds the target model of every migration it applies, including the designer snapshots of older migrations, which still name the now-deleted
Daqifi.Desktop.Channel.Channeltype. If those could no longer be built, a fresh install would fail on first launch with a green build behind it.Verification
This branch has been rebased onto
5e4e1a3, currentorigin/main. It was originally cut atcd44a11, six commits behind (#138, #203, #204, #205, #209, #211). The rebase was clean, andgit diff --numstat origin/main...HEADis byte-identical before and after it — same 10 files, same +552/−255 — so the rebase moved the base without altering the change. Everything below is measured on the rebased branch, which now is the merged state rather than a projection of it.The rebase was not cosmetic. It matters for two independent reasons:
mainafter this branch was cut. While this PR sat oncd44a11that step was not failing — it was absent from the job entirely, so the PR's green tick was earned on a pipeline that no longer exists. On the rebased head it is present and passing (step 10 of Desktop head on macOS).MERGEABLE/CLEANwith zero file overlap and still failed the merge queue withCS0115. Rebasing turns that class of breakage into a local compile error instead of a merge-queue ejection.dotnet build Daqifi.Avalonia.Desktopon the rebased branch — succeeded.dotnet restore+dotnet build Daqifi.Avalonia.iOS -c Release -r iossimulator-arm64 --no-restoreon the rebased branch — succeeded. (Android is not buildable on this machine; CI covers it, and the Android head passes on this PR. No locally-built Android status is claimed.)dotnet teston the rebased branch — 391 passed, 0 failed, against 386 on5e4e1a3: exactly the 5 new tests, no collisions with the 42DiskSpaceMonitortests test(disk-space): pin DiskSpaceMonitor, the gate on whether a session starts and whether one gets killed #211 added after this branched.packages.lock.jsonunchanged everywhere — no-ron any restore..axamlgrepped forChannel,SetColor,IColorable,Channelsand every removed member. The onlySetColorhits are the view-model'sSetColorCommand(ChannelsPanePrototype.axaml:624,ChannelsMobileView.axaml:396) — untouched. All six colour bindings resolve toChannelColorBrush, which stays onIChannel. No.axamlreferences theDaqifi.Desktop.Channelnamespace, nothing bindsLoggingSession.Channels, there is noInclude(s => s.Channels), and no raw SQL against theChanneltable.third_party/oxyplot-avalonia/objon both, comparing the distinct first-party set (third_party/excluded): 175 on5e4e1a3→ 167 on the rebased branch, −8. Every one of the eight is aCS8618in the deletedChannel.cs. ThreeLoggingSession.cswarnings shifted three lines up because a property was removed above them; same codes, same members, so the set is otherwise identical. Counted at file+line granularity instead the same measurement reads 222 → 214 — the same −8, the same eight warnings.🤖 Generated with Claude Code