chore(quality): resolve SonarQube code smells across website #88

Merged
whitlocktech merged 1 commits from chore/sonar-code-smells into main 2026-07-21 14:28:00 +00:00
Member

What

Clears all 124 CODE_SMELL findings from the SonarQube scan of the website repo (server, client, and bot). Every change is a behaviour-preserving refactor — no route, protocol, schema, or config changes — so no Swagger regen or docs/ update is required.

Verification

  • Server tests: 381 pass (node --test, DB stubbed)
  • Client tests: 43 pass — including the shardEvents and regionBuckets suites that cover the two most substantial rewrites, plus apiClient covering the client.js changes
  • Client production build: clean

By rule

Rule Count Approach
S3776 cognitive complexity 20 Extract helpers/handlers below the threshold: shard-state upsert builders, page/wiki update, block validation, notification-stream mapping (→ dispatch table), SSO mobile login, shard-ingest deps, uo-link socket backfill/connect, the two bot slash-command dispatchers + discord manager, and the Shard/UserDetail/HeroEditor/CharacterStats components
S4624 nested template literals 34 Inner templates lifted to locals / a withQs() helper; shardEvents.describe() rewritten as a formatter table
S3358 nested ternaries 35 Lifted to if/else vars, lookup maps, small components, or guarded JSX expressions
S6479 array-index React keys 12 Key by stable content instead of index (two in-editor lists left as index keys — see note below)
S6353 [0-9]\d 6 Concise character classes
S125 commented-out code 5 Reworded state-shape comments (// { qr, otpauthUrl }) that parsed as code — not dead code
S6481 context value churn 2 useMemo on the Auth/Site context values (+ SiteContext.brand)
S1126 if/else→return 2 Single return
S3800 / S3782 botScore 2/1 JSDoc-typed PATH_WEIGHTS tuples resolves both
S4144 identical functions 1 Deduped HeroEditor upload handler into useImageUpload()
S6035 / S5869 / S5843 regex 1/1/1 (s|m|h|d)[smhd]; dropped redundant A-Z under /i; town-name alternation → prefix list

Notes / intentional exceptions

These remain and should be marked Won't Fix in Sonar (not code-fixed here):

  • S3800 ×2trustProxy.js parseTrustProxy/applyTrustProxy return number \| false \| string \| array by design (that's exactly what Express's trust proxy setting accepts).
  • S6479 ×2 — the HeroEditor line/item editor lists keep index keys: they're edited by index and a content-derived key would remount the inputs and drop focus mid-edit. A proper fix needs synthetic ids in the persisted layout schema, which is out of scope for a lint pass.

AI disclosure

AI-assisted (Claude). Commits carry the Co-Authored-By: Claude trailer per org policy.

🤖 Generated with Claude Code

## What Clears all **124 `CODE_SMELL` findings** from the SonarQube scan of the website repo (server, client, and bot). Every change is a **behaviour-preserving refactor** — no route, protocol, schema, or config changes — so no Swagger regen or `docs/` update is required. ## Verification - ✅ Server tests: **381 pass** (`node --test`, DB stubbed) - ✅ Client tests: **43 pass** — including the `shardEvents` and `regionBuckets` suites that cover the two most substantial rewrites, plus `apiClient` covering the `client.js` changes - ✅ Client production build: clean ## By rule | Rule | Count | Approach | |---|---|---| | **S3776** cognitive complexity | 20 | Extract helpers/handlers below the threshold: shard-state upsert builders, page/wiki `update`, block validation, notification-stream mapping (→ dispatch table), SSO mobile login, shard-ingest deps, uo-link socket `backfill`/`connect`, the two bot slash-command dispatchers + discord manager, and the `Shard`/`UserDetail`/`HeroEditor`/`CharacterStats` components | | **S4624** nested template literals | 34 | Inner templates lifted to locals / a `withQs()` helper; `shardEvents.describe()` rewritten as a formatter table | | **S3358** nested ternaries | 35 | Lifted to `if/else` vars, lookup maps, small components, or guarded JSX expressions | | **S6479** array-index React keys | 12 | Key by stable content instead of index (two in-editor lists left as index keys — see note below) | | **S6353** `[0-9]`→`\d` | 6 | Concise character classes | | **S125** commented-out code | 5 | Reworded state-shape comments (`// { qr, otpauthUrl }`) that parsed as code — not dead code | | **S6481** context value churn | 2 | `useMemo` on the Auth/Site context values (+ `SiteContext.brand`) | | **S1126** if/else→return | 2 | Single `return` | | **S3800 / S3782** botScore | 2/1 | JSDoc-typed `PATH_WEIGHTS` tuples resolves both | | **S4144** identical functions | 1 | Deduped HeroEditor upload handler into `useImageUpload()` | | **S6035 / S5869 / S5843** regex | 1/1/1 | `(s\|m\|h\|d)`→`[smhd]`; dropped redundant `A-Z` under `/i`; town-name alternation → prefix list | ## Notes / intentional exceptions These remain and should be marked **Won't Fix** in Sonar (not code-fixed here): - **S3800 ×2** — `trustProxy.js` `parseTrustProxy`/`applyTrustProxy` return `number \| false \| string \| array` **by design** (that's exactly what Express's `trust proxy` setting accepts). - **S6479 ×2** — the `HeroEditor` line/item editor lists keep index keys: they're edited by index and a content-derived key would remount the inputs and drop focus mid-edit. A proper fix needs synthetic ids in the persisted layout schema, which is out of scope for a lint pass. ## AI disclosure AI-assisted (Claude). Commits carry the `Co-Authored-By: Claude` trailer per org policy. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
wtclaude added 1 commit 2026-07-21 09:36:18 +00:00
chore(quality): resolve SonarQube code smells across website
All checks were successful
PR Checks / bot-install (pull_request) Successful in 13s
PR Checks / client-build (pull_request) Successful in 22s
PR Checks / server-tests (pull_request) Successful in 11m13s
12d50fd615
Clears the 124 CODE_SMELL findings from the SonarQube scan (server, client,
and bot). All changes are behaviour-preserving refactors — no route, protocol,
schema, or config changes — verified against the full server (381) and client
(43) test suites plus a clean client build.

By rule:
- S3776 (20, cognitive complexity): extract helpers/handlers so each function
  drops under the threshold — shard model upsert builders, page/wiki update,
  block validation, notification stream mapping (dispatch table), SSO mobile
  login, shard ingest deps, uo-link socket backfill/connect, the bot slash-
  command dispatchers + discord manager, and the Shard/UserDetail/HeroEditor/
  CharacterStats React components.
- S4624 (34, nested template literals): pull inner templates into locals /
  a withQs() helper; rewrite shardEvents.describe() as a formatter table.
- S3358 (35, nested ternaries): lift to if/else vars, lookup maps, small
  components, or guarded JSX expressions.
- S6479 (12, array-index React keys): key by stable content instead of index
  (two in-editor lists left as-is; index matches their by-index edit model).
- S6353 (6): [0-9]/[^0-9] -> \d/\D.  S125 (5): reword state-shape comments that
  parsed as code.  S3800/S3782 (botScore): JSDoc-type PATH_WEIGHTS tuples.
- S6481 (2): memoize Auth/Site context values (and SiteContext brand).
- S4144: dedupe HeroEditor upload handler into useImageUpload().
- S1126 (2), S6035, S5869 (redundant A-Z under /i), S5843 (town-name regex ->
  prefix list): assorted one-liners.

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech approved these changes 2026-07-21 14:27:49 +00:00
whitlocktech merged commit 9b0f2d93d8 into main 2026-07-21 14:28:00 +00:00
whitlocktech deleted branch chore/sonar-code-smells 2026-07-21 14:28:01 +00:00
Sign in to join this conversation.
No description provided.