Fix/sonarqube critical major debt #11

Merged
bermudalamb merged 10 commits from fix/sonarqube-critical-major-debt into main 2026-05-26 10:36:29 -05:00
10 Commits
Author SHA1 Message Date
Thom LambandClaude Opus 4.7 b3020a0a20 chore: gitignore SonarScanner local artifacts
SonarQube Analysis / sonarqube (pull_request) Successful in 3m7s
Add .sonarqube/ (created by dotnet sonarscanner begin) and scan.log
(from local scan-sonar.ps1 diagnostics) so they don't accidentally
get committed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 10:07:19 -05:00
Thom LambandClaude Opus 4.7 3c8148a6b1 chore(sonar): suppress CS8601 in QueryBreakdownMapper with justification
CS8601 is reported via external_roslyn on the SonarQube server, which does
not expose transitions for external-analyzer issues — so a server-side
Won't Fix is not available. Silence locally with a narrow pragma so the
issue stops appearing in subsequent scans.

Justification: Parameters is Dictionary<string, object> (non-nullable
value annotation), but a SQL parameter value can legitimately be null.
The proper fix is to widen the public dictionary value type to object?,
which ripples through every consumer of QueryBreakdown.Parameters —
deferred to a separate change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 10:03:34 -05:00
Thom LambandClaude Opus 4.7 d92996bd2e docs(skill): add sonarqube cleanup + inspection skill
Codifies (A) how to query the bermudalamb SonarQube 9.9 server's web API
from PowerShell — Basic auth with token-as-username, the
SONARQUBE_URL trailing-slash gotcha, the useful endpoints for triage and
Won't Fix transitions; and (B) the per-rule-group cleanup loop (query →
pick → edit → build → test → commit → scan → verify).

References memory sonarqube-wontfix-rules rather than duplicating the
catalog. Frontmatter follows superpowers:writing-skills (description is
triggering conditions only, no workflow summary).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:34:44 -05:00
Thom LambandClaude Opus 4.7 71cdf8a766 chore(sonar)!: pluralize unused [Flags] enums (S2342)
S2342 requires [Flags] enums to use plural names. Both enums have zero
references anywhere in the repo today.

- ConstraintType -> ConstraintTypes
- TriggerType    -> TriggerTypes

BREAKING CHANGE: external NuGet consumers (if any) referencing these
singular-named types will need to update to the plural names. Internal
codebase has no references.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:32:02 -05:00
Thom LambandClaude Opus 4.7 8211047d6b chore(sonar): use LINQ Select for parameter match projection (S3267)
Snowflake/Breakdowns/ProcedureBreakdown.ParseCallParameters — replace the
foreach over a MatchCollection with a .Cast<Match>().Select(m => m.Groups)
projection. The loop now iterates GroupCollection values directly, indexing
groups[1] and groups[2] for name/value without rebinding the Match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:30:58 -05:00
Thom LambandClaude Opus 4.7 b6ebb8c7cd chore(sonar): demote single-use field to local (S1450)
LinqExpressionVisitor._tableName was only assigned and read inside
VisitConstant immediately before assigning FromClause. Drop the field
entirely and assign FromClause directly from entityType.Name.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:29:13 -05:00
Thom LambandClaude Opus 4.7 c06ab2ea29 chore(sonar): remove pass-through override that just calls base (S1185)
Rules/Rule/Groups/With.GetExpressions only called base.GetExpressions(). The
comment 'do some ordering here??' indicates the override is a TODO stub.
Drop the override and preserve the intent as an inline TODO on the class.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:27:53 -05:00
Thom LambandClaude Opus 4.7 06e826a13c chore(sonar): drop redundant inline init now set in ctor (S3604)
SqlServer/Breakdowns/QueryBreakdown.cs:26 — _clausesCacheDirty was both
initialized inline (= true) and re-assigned in the constructor at line 56.
Drop the inline initializer; the ctor remains authoritative.

The four nearby S3604 false-positives on clause backing fields stay
suppressed via #pragma — they are write-through targets of cache-invalidating
property setters.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:27:15 -05:00
Thom LambandClaude Opus 4.7 e1cdcd77a4 chore(sonar): collapse trivial backing-field properties to auto-properties (S2292)
- WithClause.RecursiveQuery and WithClause.ColumnList had get/set bodies that
  only forwarded to private backing fields. Convert both to auto-properties
  and remove the now-orphaned _recursiveQuery / _columnList fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:26:35 -05:00
Thom LambandClaude Opus 4.7 1124e91141 chore(sonar): remove three unused local variables (S1481)
- LinqQueryBreakdown.cs:211 - drop unused `expr` pattern binding (type test remains)
- LinqQueryBreakdown.cs:279 - drop unused `firstEntity` (empty check already above)
- LinqExpressionVisitor.cs:315 - drop unused `param` pattern binding

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:25:34 -05:00