Skip to content

chore(sonar): burn down 32 Roslyn/analyzer smells across API + tests - #394

Merged
thomasluizon merged 1 commit into
mainfrom
chore/api-sonar-roslyn-b
Jul 13, 2026
Merged

chore(sonar): burn down 32 Roslyn/analyzer smells across API + tests#394
thomasluizon merged 1 commit into
mainfrom
chore/api-sonar-roslyn-b

Conversation

@thomasluizon

Copy link
Copy Markdown
Owner

Clears every open external_roslyn / analyzer smell in the #243 SonarCloud-to-zero campaign (the failed roslyn-b night-run slice). All changes are behavior-preserving; locations were derived from an authoritative dotnet build with the target rules elevated (SonarCloud's line numbers were partly stale, and the build surfaced one extra xUnit1042 SonarCloud had missed).

Rules cleared (32 total)

Rule Count Fix
CA1068 3 CancellationToken moved to last param on IUserStreakService.RecalculateAsync + AiCompletionClient.CompleteText/JsonAsync; every call site updated (production + tests)
CA1873 4 Hoist the expensive log argument into a local inside an IsEnabled guard (AdminController, WaitlistController, MinimumVersionMiddleware, AiUsageSummaryService)
CA1862 3 StringComparison.OrdinalIgnoreCase in SyncControllerMutations; the two EF-query predicates (SetHandleCommand, FriendGraphService) keep ToLower() under a scoped, URL-linked suppression because EF Core cannot translate string.Equals(StringComparison) to SQL (efcore#1222)
CA2016 3 Forward the CancellationToken in IdempotencyBehaviorDbTests handlers
CA2263 3 Generic TypeAssertions.Be<T>() overload in job-enqueue tests
CA1822 1 Mark ProcessUserChatCommand.BuildResponseCards static
CA1869 1 Cache JsonSerializerOptions in GetPublicProfileQueryHandlerTests
SYSLIB1045 1 [GeneratedRegex] partial method in McpToolsDoNotDispatchCommandsTests
CS0618 1 GetDeclaredQueryFilters() replaces obsolete GetQueryFilter()
xUnit1042 7 TheoryData<> member-data return types (OrbitDbContextTests, SyncChangesIndexConfigurationTests, ScheduledJobRegistryTests)
ASP0015 2 Headers.AcceptLanguage property in SubscriptionControllerTests
ASP0025 1 AddAuthorizationBuilder in ServiceCollectionExtensions
RS1038 2 Split code-fix providers into a new Orbit.Analyzers.CodeFixes assembly so the analyzer assembly no longer references Microsoft.CodeAnalysis.Workspaces

Verification (foreground)

  • dotnet build Orbit.slnx: 0 errors, and (with the target rules elevated to warning) 0 remaining target analyzer warnings.
  • dotnet test Orbit.slnx: green — 5284 passed / 0 failed (incl. the 7 analyzer/code-fix tests that validate the RS1038 split).
  • dotnet ef migrations has-pending-model-changes: false (model untouched).
  • No bare // narration added (ORBIT0001); the two suppression WHY notes link an upstream URL.

Refs thomasluizon/orbit-ui-mobile#243

Clears every open external_roslyn / analyzer smell in the #243 SonarCloud-to-zero
campaign (the roslyn-b slice), all behavior-preserving:

- CA1068 (3): move CancellationToken to the last parameter on
  IUserStreakService.RecalculateAsync and AiCompletionClient.CompleteText/JsonAsync;
  update every call site (production + tests).
- CA1873 (4): hoist the expensive log argument into a local inside an IsEnabled guard
  (AdminController, WaitlistController, MinimumVersionMiddleware, AiUsageSummaryService).
- CA1862 (3): StringComparison.OrdinalIgnoreCase in SyncControllerMutations; the two EF
  query predicates (SetHandleCommand, FriendGraphService) keep ToLower() under a scoped,
  URL-linked suppression because EF Core cannot translate string.Equals(StringComparison).
- CA2016 (3): forward the CancellationToken in IdempotencyBehaviorDbTests handlers.
- CA2263 (3): use the generic TypeAssertions.Be<T>() overload in job-enqueue tests.
- CA1822 (1): mark ProcessUserChatCommand.BuildResponseCards static.
- CA1869 (1): cache JsonSerializerOptions in GetPublicProfileQueryHandlerTests.
- SYSLIB1045 (1): [GeneratedRegex] partial method in McpToolsDoNotDispatchCommandsTests.
- CS0618 (1): GetDeclaredQueryFilters() replaces obsolete GetQueryFilter().
- xUnit1042 (7): TheoryData<> member-data return types across OrbitDbContextTests,
  SyncChangesIndexConfigurationTests, ScheduledJobRegistryTests.
- ASP0015 (2): Headers.AcceptLanguage property in SubscriptionControllerTests.
- ASP0025 (1): AddAuthorizationBuilder in ServiceCollectionExtensions.
- RS1038 (2): split code-fix providers into a new Orbit.Analyzers.CodeFixes assembly so the
  analyzer assembly no longer references Microsoft.CodeAnalysis.Workspaces.

Verified: dotnet build 0 errors + 0 target analyzer warnings, dotnet test green (5284),
EF has-pending-model-changes = false.

Refs thomasluizon/orbit-ui-mobile#243

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
19.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: PR #394 — chore(sonar): burn down 32 Roslyn/analyzer smells

Scope: 58 changed files (chore/api-sonar-roslyn-bmain)
Recommendation: APPROVE

Summary

Mechanical, behavior-preserving SonarCloud/Roslyn cleanup: 32 analyzer smells (CA1068, CA1873, CA1862, CA2016, CA2263, CA1822, CA1869, SYSLIB1045, CS0618, xUnit1042, ASP0015, ASP0025, RS1038) across production code, tests, and a new Orbit.Analyzers.CodeFixes project split out to satisfy RS1038. The riskiest change — the IUserStreakService.RecalculateAsync / AiCompletionClient.CompleteText/JsonAsync parameter reorder (CancellationToken moved to last) — was traced across every call site in src/ and tests/, not just the diff: all are consistent, and the three Orbit.Infrastructure/Services/Ai*SuggestionService.cs callers outside the diff already used named cancellationToken: arguments, so the reorder doesn't silently break them. No DTO, Controller route, or packages/shared contract surface changed.

Findings

Critical: None
High: None
Medium: None

Low / Info

  • The CA1862 pragma suppressions in SetHandleCommand.cs:26-33 and FriendGraphService.cs:22-28 are correctly justified with a WHY-URL note (https://github.com/dotnet/efcore/issues/1222), satisfying the comment-policy exception (CLAUDE.md dimension 4 / ORBIT0001).
  • Directory.Build.props's analyzer-reference condition correctly excludes both Orbit.Analyzers and the new Orbit.Analyzers.CodeFixes from self-referencing; every consuming project (including tests/Orbit.Analyzers.Tests) picks up both — no dangling reference.

Subagents

Agent Verdict
security-reviewer PASS — no auth/authz semantic change from the AddAuthorizationBuilder() migration, no new data exposure from IsEnabled(LogLevel.Information) guards, no injection risk from .ToLower() EF predicates (translates to Postgres lower(), not raw SQL)
contract-aligner N/A — diff touches no DTO, Controller route, or packages/shared type; sibling orbit-ui-mobile repo not checked out in this job

Validation

Build / Unit Tests / SonarCloud run as separate required CI checks on this PR (per workflow instructions, not re-executed in this review session). PR body states dotnet build Orbit.slnx: 0 errors, 0 target analyzer warnings, 5284 tests passed / 0 failed (author-reported).

What's good

  • The parameter reorder is fully swept — every call site in the repo (diff and non-diff) is consistent.
  • CA1862 workarounds are properly justified with an upstream-issue WHY-URL rather than silently suppressed.
  • Test changes mirror production changes 1:1.
  • The Orbit.Analyzers.CodeFixes project split cleanly removes the Microsoft.CodeAnalysis.Workspaces dependency from the shipped analyzer assembly.

Recommendation

Clean to merge. No Critical/High/Medium findings.

@thomasluizon
thomasluizon merged commit e35a59b into main Jul 13, 2026
18 of 19 checks passed
@thomasluizon
thomasluizon deleted the chore/api-sonar-roslyn-b branch July 13, 2026 23:55
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.

1 participant