HexTowerDefence game managers (Economy 30, Combat/Waves 26/20), GameServer zones, code-execution executors, customer command handlers, etc.
(Full list of 51 available via SonarQube; api.spikersoft.com → rule csharpsquid:S3776.)
Suggested approach
Tackle highest-complexity first (SPF/DMARC health checks, LessonValidator, SpikerDbContext model-building). Extract helper methods, replace nested conditionals with guard clauses / lookup tables. Treat as an ongoing epic — close incrementally.
First pass opened as spikersoft-backend PR #13 — the three highest-complexity methods, refactored with extracted helpers (no behaviour change; all healthData keys/values and validation messages preserved):
SpfHealthCheck.ValidateSpfRecord — 72
LessonValidator.ValidateLesson — 62
DmarcHealthCheck.ValidateDmarcRecord — 61
Still open for follow-up passes: SpikerDbContext model-building (~14 methods), TextChunkingService (43), InfluxMetricsRepository (35, 21), HexTowerDefence game managers, GameServer zones, code-execution executors, customer command handlers, etc.
First pass opened as spikersoft-backend PR #13 — the three highest-complexity methods, refactored with extracted helpers (no behaviour change; all healthData keys/values and validation messages preserved):
- [x] `SpfHealthCheck.ValidateSpfRecord` — **72**
- [x] `LessonValidator.ValidateLesson` — **62**
- [x] `DmarcHealthCheck.ValidateDmarcRecord` — **61**
Still open for follow-up passes: `SpikerDbContext` model-building (~14 methods), `TextChunkingService` (43), `InfluxMetricsRepository` (35, 21), HexTowerDefence game managers, GameServer zones, code-execution executors, customer command handlers, etc.
PR #13 now covers the 6 highest-complexity methods. Still open: SpikerDbContext model-building (~14 methods), game managers, GameServer zones, code-execution executors, customer command handlers, etc.
Two more offenders added to PR #13 (no behaviour change; all log messages + metric mappings preserved, 53 chunking/influx tests pass):
- [x] `TextChunkingService.ChunkText` — **43**
- [x] `InfluxMetricsRepository.StreamMetricsAsync` — **35**
- [x] `InfluxMetricsRepository.QueryMetricsBatchAsync` — **21**
PR #13 now covers the 6 highest-complexity methods. Still open: `SpikerDbContext` model-building (~14 methods), game managers, GameServer zones, code-execution executors, customer command handlers, etc.
SpikerDbContext.OnModelCreating — deferred from the mechanical pass. It's already decomposed into ~40 ConfigureXxx methods; the residual S3776 is repeated HasConversion + ValueComparer boilerplate with many subtly different variants (SequenceEqual vs Count equality; null→null vs null→empty-list snapshots; guarded vs unguarded (de)serialization; nullable vs non-nullable comparer types). A one-size helper would silently change EF change-tracking/serialization null semantics, and there is no integration-level coverage to catch it. It needs its own focused PR with exact-match helper overloads + round-trip tests, not a blanket extract.
Still open under this epic: SpikerDbContext (as above), GameServer zones, code-execution executors, customer command handlers, and other smaller offenders.
Progress update:
- **PR #13 (merged)** — 6 highest-complexity methods: `SpfHealthCheck.ValidateSpfRecord` (72), `DmarcHealthCheck.ValidateDmarcRecord` (61), `LessonValidator.ValidateLesson` (62), `TextChunkingService.ChunkText` (43), `InfluxMetricsRepository.StreamMetricsAsync` (35) + `QueryMetricsBatchAsync` (21).
- **PR #14 (open)** — `HexTowerDefenceGameManager` partials: `FireBuildings` (26), `RunResourceCycle` (30), `SpawnWave` (20). 17 HexTowerDefence unit tests pass.
**`SpikerDbContext.OnModelCreating` — deferred from the mechanical pass.** It's already decomposed into ~40 `ConfigureXxx` methods; the residual S3776 is repeated `HasConversion` + `ValueComparer` boilerplate with many *subtly different* variants (SequenceEqual vs Count equality; null→null vs null→empty-list snapshots; guarded vs unguarded (de)serialization; nullable vs non-nullable comparer types). A one-size helper would silently change EF change-tracking/serialization null semantics, and there is no integration-level coverage to catch it. It needs its own focused PR with exact-match helper overloads + round-trip tests, not a blanket extract.
**Still open under this epic:** SpikerDbContext (as above), GameServer zones, code-execution executors, customer command handlers, and other smaller offenders.
PR #15 (open) — ZoneManager handlers: HandleCreateCharacterCommand, HandleLandOnPlanetCommand, HandleLaunchFromPlanetCommand split into focused validation/context/build helpers. 76 ZoneManager unit tests pass. Note: ProcessCommandAsync is a type-switch dispatcher (low cognitive complexity, not an offender) and was intentionally left alone.
Still open under this epic: code-execution executors, customer command handlers, GameServer zones (remaining), other smaller offenders, and SpikerDbContext EF boilerplate (deferred — see earlier note; needs exact-match helpers + round-trip tests).
Progress (safe extract-method pass continued):
- **PR #15 (open)** — `ZoneManager` handlers: `HandleCreateCharacterCommand`, `HandleLandOnPlanetCommand`, `HandleLaunchFromPlanetCommand` split into focused validation/context/build helpers. 76 ZoneManager unit tests pass. Note: `ProcessCommandAsync` is a type-switch dispatcher (low cognitive complexity, not an offender) and was intentionally left alone.
**Still open under this epic:** code-execution executors, customer command handlers, GameServer zones (remaining), other smaller offenders, and `SpikerDbContext` EF boilerplate (deferred — see earlier note; needs exact-match helpers + round-trip tests).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Surfaced by SonarQube (
api.spikersoft.com), rulecsharpsquid:S3776, severity CRITICAL (MAINTAINABILITY). ~51 methods exceed the cognitive-complexity limit of 15.Worst offenders (complexity)
SpikerSoft.Api/Infrastructure/HealthChecks/SpfHealthCheck.cs:224— 72SpikerSoft.Business/Domain/Lessons/Validation/LessonValidator.cs:38— 62SpikerSoft.Api/Infrastructure/HealthChecks/DmarcHealthCheck.cs:231— 61SpikerSoft.Data/Contexts/SpikerDbContext.cs— ~14 methods (45, 36, 33, 30×4, 24, 18×2, 16×2…)SpikerSoft.EventHandlers.Embeddings/Services/TextChunkingService.cs:21— 43SpikerSoft.Data/Repositories/InfluxMetricsRepository.cs— 35, 21(Full list of 51 available via SonarQube;
api.spikersoft.com→ rulecsharpsquid:S3776.)Suggested approach
Tackle highest-complexity first (SPF/DMARC health checks, LessonValidator, SpikerDbContext model-building). Extract helper methods, replace nested conditionals with guard clauses / lookup tables. Treat as an ongoing epic — close incrementally.
Rule: https://rules.sonarsource.com/csharp/RSPEC-3776/
First pass opened as spikersoft-backend PR #13 — the three highest-complexity methods, refactored with extracted helpers (no behaviour change; all healthData keys/values and validation messages preserved):
SpfHealthCheck.ValidateSpfRecord— 72LessonValidator.ValidateLesson— 62DmarcHealthCheck.ValidateDmarcRecord— 61Still open for follow-up passes:
SpikerDbContextmodel-building (~14 methods),TextChunkingService(43),InfluxMetricsRepository(35, 21), HexTowerDefence game managers, GameServer zones, code-execution executors, customer command handlers, etc.Two more offenders added to PR #13 (no behaviour change; all log messages + metric mappings preserved, 53 chunking/influx tests pass):
TextChunkingService.ChunkText— 43InfluxMetricsRepository.StreamMetricsAsync— 35InfluxMetricsRepository.QueryMetricsBatchAsync— 21PR #13 now covers the 6 highest-complexity methods. Still open:
SpikerDbContextmodel-building (~14 methods), game managers, GameServer zones, code-execution executors, customer command handlers, etc.Progress update:
SpfHealthCheck.ValidateSpfRecord(72),DmarcHealthCheck.ValidateDmarcRecord(61),LessonValidator.ValidateLesson(62),TextChunkingService.ChunkText(43),InfluxMetricsRepository.StreamMetricsAsync(35) +QueryMetricsBatchAsync(21).HexTowerDefenceGameManagerpartials:FireBuildings(26),RunResourceCycle(30),SpawnWave(20). 17 HexTowerDefence unit tests pass.SpikerDbContext.OnModelCreating— deferred from the mechanical pass. It's already decomposed into ~40ConfigureXxxmethods; the residual S3776 is repeatedHasConversion+ValueComparerboilerplate with many subtly different variants (SequenceEqual vs Count equality; null→null vs null→empty-list snapshots; guarded vs unguarded (de)serialization; nullable vs non-nullable comparer types). A one-size helper would silently change EF change-tracking/serialization null semantics, and there is no integration-level coverage to catch it. It needs its own focused PR with exact-match helper overloads + round-trip tests, not a blanket extract.Still open under this epic: SpikerDbContext (as above), GameServer zones, code-execution executors, customer command handlers, and other smaller offenders.
Progress (safe extract-method pass continued):
ZoneManagerhandlers:HandleCreateCharacterCommand,HandleLandOnPlanetCommand,HandleLaunchFromPlanetCommandsplit into focused validation/context/build helpers. 76 ZoneManager unit tests pass. Note:ProcessCommandAsyncis a type-switch dispatcher (low cognitive complexity, not an offender) and was intentionally left alone.Still open under this epic: code-execution executors, customer command handlers, GameServer zones (remaining), other smaller offenders, and
SpikerDbContextEF boilerplate (deferred — see earlier note; needs exact-match helpers + round-trip tests).