Skip to content

refactor: resolve SonarCloud code smells across web, api, and packages - close #180#179

Merged
soroushm merged 19 commits into
mainfrom
refactor/sonarcloud-cleanup
Jun 26, 2026
Merged

refactor: resolve SonarCloud code smells across web, api, and packages - close #180#179
soroushm merged 19 commits into
mainfrom
refactor/sonarcloud-cleanup

Conversation

@soroushm

@soroushm soroushm commented Jun 26, 2026

Copy link
Copy Markdown
Member

Summary

Cleans up SonarCloud-reported code smells across the monorepo without changing behavior. Spans the web app, the worker API, shared packages, and CI hardening.

Changes

  • web — Resolved smells across theme components (Radio, Switch, TextInput, Paper, Typography, ThemeProvider), graph/utilities, stories, and the API client/logger/request helpers; tightened a few configs.
  • api — Reduced cognitive complexity of the contact route via extracted helpers, narrowed ContactRow value typing for safe stringification, and resolved smells in worker services and utils.
  • packages — Resolved smells in schema, vite-plugin-sitemap (extracted nested template literal), and eslint-config.
  • CI — Pinned action SHAs and scoped workflow permissions to the job level.
  • chore — Gitignored generated build-log.txt.

Verification

  • pnpm lint
  • pnpm test:coverage — 100% on touched files
  • pnpm build

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability of forms, contact submission, and captcha handling.
    • Fixed image fallback behavior and kept images visible after repeated load failures.
    • Made navigation and page rendering more robust across browser environments.
    • Strengthened API error handling so failures are reported more consistently.
    • Updated site graph and coverage-related checks for more reliable results.
  • Chores

    • Hardened automated build, test, and deployment workflows with stricter access and pinned tooling.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR pins GitHub Actions in the CI/CD workflows, updates shared theme and Storybook typings and state helpers, refactors graph visibility and graph-building helpers, and changes renderer, article-page, contact-page, API client, and worker request flows.

Changes

Build and workflow hardening

Layer / File(s) Summary
GitHub Pages CD workflow
.github/workflows/cd-web.yml
The workflow removes workflow-scoped permissions, adds job-scoped permissions, and pins the artifact, checkout, setup-node, upload-pages-artifact, and deploy-pages actions to commit SHAs.
CI workflow
.github/workflows/ci.yml
The CI workflow removes workflow-scoped permissions, adds job-scoped permissions for the jobs, and pins checkout, paths-filter, upload-artifact, setup-node, cache, codecov, and chromaui actions to commit SHAs.
Build scripts and config helpers
.gitignore, apps/web/scripts/*, apps/web/vite.config.ts, apps/web/vitest.config.ts, packages/eslint-config/base.js, packages/vite-plugin-sitemap/src/index.ts
The ignored log file, coverage parser, experience-graph generator helper, path imports, lint selector, and sitemap helpers switch to the updated literal and module-specifier forms.

Shared UI, theme, and Storybook changes

Layer / File(s) Summary
Theme contracts
apps/web/src/theme/themes.ts, apps/web/src/theme/index.ts, apps/web/src/theme/AppBar/*, apps/web/src/theme/Button/Button.tsx, apps/web/src/theme/Checkbox/Checkbox.tsx, apps/web/src/theme/Radio/Radio.tsx
PaletteColor is added to the theme types and reused by Theme, AppBar, Button, Checkbox, and Radio exports.
Readonly common signatures
apps/web/src/common/..., apps/web/src/pages/design/system/components/CardTitle.tsx
Common shell and page-design components update their exported prop parameter types to Readonly<...>.
Readonly theme signatures
apps/web/src/theme/...
Theme display, form, and input components update their exported prop parameter types to Readonly<...>.
Theme behavior changes
apps/web/src/theme/Avatar/Avatar.tsx, apps/web/src/theme/Button/Button.tsx, apps/web/src/theme/Field/Field.tsx, apps/web/src/theme/TextInput/*, apps/web/src/theme/ThemeProvider/ThemeProvider.tsx, apps/web/src/theme/utils/luminance.ts, apps/web/src/pages/design/system/components/CircularProgressCard.{tsx,test.tsx}, apps/web/src/theme/Image/Image.test.tsx
Button, Avatar, Field, TextInput, ThemeProvider, luminance, CircularProgressCard, and Image-related behavior change in their branches, memoization, parsing, or assertions.
Storybook controlled-state helpers
apps/web/src/theme/utils/test/*, apps/web/src/theme/.../*.stories.tsx
Shared toggle helpers and the AppBar, Checkbox, Radio, Switch, and TextInput stories move controlled state into decorators and consume injected args.

Graph views and graph construction

Layer / File(s) Summary
NetworkGraph visibility
apps/web/src/common/NetworkGraph/..., apps/web/src/common/NetworkGraph/components/...
NetworkGraph, GraphControls, and GraphHeader props become readonly, visibility expansion is centralized, relation lookup and role selection are simplified, and the click assertion uses toHaveLength.
ExperienceGraph construction
apps/web/src/section/ExperienceGraph/components/GraphLegend/GraphLegend.tsx, apps/web/src/section/ExperienceGraph/utils/buildGraph.ts
GraphLegend props become readonly and buildGraph is split into indexing, validation, link construction, containment, reachability, gate resolution, and materialization helpers.

Renderer and page helpers

Layer / File(s) Summary
App bootstrap and renderer flow
apps/web/src/main.tsx, apps/web/src/renderer/*
MSW initialization moves to top-level await, the renderer branches on hydration first, invalid config throws TypeError, and head escaping uses replaceAll.
Article page modules
apps/web/src/pages/article/@id/*
The article page component and metadata exports switch to readonly props typing and named constants while keeping the same generated strings.
Contact page and widget helpers
apps/web/src/hooks/useTurnstile.ts, apps/web/src/section/ContactInquire/...
Turnstile access uses globalThis, decoy ids use crypto.getRandomValues, and the contact form back buttons and validation flow update to the new helpers.

API client and worker backend

Layer / File(s) Summary
Request and response helpers
apps/web/src/utils/api/*
Client.call throws when fetch is missing, request errors reject Error instances, headers spread directly from defaults, and the request tests assert the new rejection shape.
Logger fs specifier
apps/web/src/utils/api/logger.*
The logger and its test switch to the node:fs module specifier.
Worker support helpers
packages/schema/src/contact.ts, workers/api/src/app.ts, workers/api/src/services/email.ts, workers/api/src/utils/*
The exempt-path list becomes a Set, the contact phone regex changes, HTML escaping and CR/LF sanitization use replaceAll, control-character filtering uses code points, and table literals narrow row values.
Contact POST flow
workers/api/src/routes/contact.ts
The contact route adds honeypot, captcha, and field-error helpers and uses them to short-circuit bot submissions, reject captcha failures, and map schema errors.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ContactRoute
  participant Turnstile
  participant ContactSchema
  Client->>ContactRoute: POST /contact
  ContactRoute->>ContactRoute: isBot(body)
  ContactRoute->>Turnstile: passedCaptcha(token)
  ContactRoute->>ContactSchema: safeParse(body)
  ContactRoute->>ContactRoute: fieldErrors(result.error)
  ContactRoute-->>Client: ok / 403 / fieldErrors
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.15% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: fixing SonarCloud code smells across the monorepo, with the main affected areas named.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/sonarcloud-cleanup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 1.47kB (0.0%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
@soroush.tech/dev-esm 38.07MB 1.47kB (0.0%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: @soroush.tech/dev-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
entries/src_pages_experience.mjs 822 bytes 92.15kB 0.9%
chunks/chunk-BiwMYH9i.js (New) 76.14kB 76.14kB 100.0% 🚀
entries/src_pages_design_system.mjs 3 bytes 45.83kB 0.01%
entries/src_pages_contact.mjs 537 bytes 24.82kB 2.21%
chunks/chunk-DYFOmQdk.js (New) 14.74kB 14.74kB 100.0% 🚀
entries/src_pages_article_-id.mjs -36 bytes 10.57kB -0.34%
chunks/chunk-B9vJHKk2.js (New) 4.1kB 4.1kB 100.0% 🚀
chunks/chunk-C3RnyHJv.js (New) 2.6kB 2.6kB 100.0% 🚀
chunks/chunk-C6X4mW0Z.js (New) 2.13kB 2.13kB 100.0% 🚀
chunks/chunk-DnI51kez.js (New) 1.9kB 1.9kB 100.0% 🚀
chunks/chunk-CTsHbCIt.js (New) 1.77kB 1.77kB 100.0% 🚀
chunks/chunk-Dwui5r7o.js (New) 1.6kB 1.6kB 100.0% 🚀
chunks/chunk-DYZfWr7y.js (New) 1.43kB 1.43kB 100.0% 🚀
chunks/chunk-DKY5WeBm.js (New) 1.23kB 1.23kB 100.0% 🚀
chunks/chunk-DSmgzDc6.js (New) 1.03kB 1.03kB 100.0% 🚀
chunks/chunk-B8IYPMf7.js (Deleted) -76.02kB 0 bytes -100.0% 🗑️
chunks/chunk-CLkGH4DX.js (Deleted) -14.74kB 0 bytes -100.0% 🗑️
chunks/chunk-Cd-08pu1.js (Deleted) -4.1kB 0 bytes -100.0% 🗑️
chunks/chunk-CJXdBW4v.js (Deleted) -2.6kB 0 bytes -100.0% 🗑️
chunks/chunk-DSOZLwMf.js (Deleted) -2.11kB 0 bytes -100.0% 🗑️
chunks/chunk-D_xc0_Q-.js (Deleted) -1.9kB 0 bytes -100.0% 🗑️
chunks/chunk-DNfeMudB.js (Deleted) -1.77kB 0 bytes -100.0% 🗑️
chunks/chunk-CJA8m71F.js (Deleted) -1.6kB 0 bytes -100.0% 🗑️
chunks/chunk-B0SP-c61.js (Deleted) -1.43kB 0 bytes -100.0% 🗑️
chunks/chunk-BDclXzcw.js (Deleted) -1.23kB 0 bytes -100.0% 🗑️
chunks/chunk-DEU5CKOq.js (Deleted) -1.03kB 0 bytes -100.0% 🗑️

Files in entries/src_pages_experience.mjs:

  • ./src/common/NetworkGraph/NetworkGraph.tsx → Total Size: 1.43kB

  • ./src/common/NetworkGraph/hooks/useGraphState.ts → Total Size: 1.95kB

  • ./src/common/NetworkGraph/hooks/useGraphSimulation.ts → Total Size: 7.69kB

  • ./src/common/NetworkGraph/utils/computeVisibleIds.ts → Total Size: 2.36kB

  • ./src/common/NetworkGraph/components/GraphHeader/GraphHeader.tsx → Total Size: 1.05kB

  • ./src/common/NetworkGraph/utils/buildNodes.ts → Total Size: 2.12kB

  • ./src/common/NetworkGraph/utils/linkStyle.ts → Total Size: 1.14kB

  • ./src/common/NetworkGraph/components/GraphControls/GraphControls.tsx → Total Size: 1.45kB

Files in chunks/chunk-BiwMYH9i.js:

  • ./src/common/NavLink/NavLink.tsx → Total Size: 385 bytes

  • ./src/common/Providers.tsx → Total Size: 233 bytes

  • ./src/common/Logo/Logo.tsx → Total Size: 384 bytes

  • ./src/common/Bootstrap.tsx → Total Size: 317 bytes

  • ./src/common/CookieNotice/CookieNotice.tsx → Total Size: 2.15kB

  • ./src/common/Blueprint/Blueprint.tsx → Total Size: 1.43kB

  • ./src/common/Navbar/Navbar.tsx → Total Size: 599 bytes

  • ./src/common/Layout/Layout.tsx → Total Size: 825 bytes

  • ./src/common/Header/Header.tsx → Total Size: 2.15kB

Files in entries/src_pages_design_system.mjs:

  • ./src/common/FontStyle/FontStyle.tsx → Total Size: 1.26kB

  • ./src/common/Headline/Headline.tsx → Total Size: 535 bytes

Files in entries/src_pages_article_-id.mjs:

  • ./src/common/Markdown/Markdown.tsx → Total Size: 2.71kB

Files in chunks/chunk-B9vJHKk2.js:

  • ./src/common/Eyebrow/Eyebrow.tsx → Total Size: 689 bytes

  • ./src/common/IconCard/IconCard.tsx → Total Size: 876 bytes

Files in chunks/chunk-DKY5WeBm.js:

  • ./src/common/PageHeader/PageHeader.tsx → Total Size: 999 bytes

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

…Cloud duplication

Radio and Checkbox stories carried byte-identical ControlledArgs/WithCheckedState
decorators plus a duplicated Colors-story scaffold, driving new_duplicated_lines_density
to 6% against the 3% gate on PR #179. Extract both into a shared storiesToggle helper
(ControlledArgs, WithCheckedState, colorSwatches, ColorSwatchRows) consumed by both
story files, with a co-located test at 100% coverage.
soroushm added 4 commits June 26, 2026 08:10
…submission

Add an `error` listener to the injected Turnstile script so `loadTurnstile`
always settles — a failed load (CSP, network, blockers) can no longer leave the
promise hanging and the submit button silently disabled forever. The hook now
exposes an `error` state, and ContactInquire shows a message prompting the user
to disable blockers and refresh.
…view nits

Use the `src/theme/themes` alias for the PaletteColor re-export (alias-only
import rule) and correct the AppBar `elevation` JSDoc to state the `4` default.
@soroushm soroushm changed the title refactor: resolve SonarCloud code smells across web, api, and packages refactor: resolve SonarCloud code smells across web, api, and packages - close #180 Jun 26, 2026
@soroushm soroushm merged commit 3203bf4 into main Jun 26, 2026
21 checks passed
@soroushm soroushm deleted the refactor/sonarcloud-cleanup branch June 26, 2026 06:55
@sonarqubecloud

Copy link
Copy Markdown

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