Skip to content

SonarCloud: cognitive complexity (S3776) #427

Closed

Description

@don-petry

SonarCloud: cognitive complexity (S3776)

4 open SonarCloud finding(s) in petry-projects/google-app-scripts, worst severity CRITICAL. Generated by the org SonarCloud Audit.

View in SonarCloud →

Findings

Rule Count Representative message
javascript:S3776 4 Refactor this function to reduce its Cognitive Complexity from 19 to the 15 allowed.

Affected files

  • src/gmail-to-drive-by-labels/src/index.js (2)
  • deploy/index.html (1)
  • src/calendar-to-sheets/src/index.js (1)

Priority

Labeled priority:critical — mapped from this bucket's worst SonarCloud severity (CRITICAL).

Acceptance

  • All findings in this workstream resolved to zero in SonarCloud
  • No behavior change; CI green
  • Real fixes (no blanket NOSONAR unless a confirmed false positive, noted inline)

Idempotent issue — updated automatically each audit run; auto-closed when the finding count reaches zero.

Activity

  1. don-petry commented on Jul 7, 2026

    @don-petry
    CollaboratorAuthor

    Dev-Lead Implementation Plan

    Issue: #427 — SonarCloud: cognitive complexity (S3776)

    Scope

    Behavior-preserving refactors to reduce cognitive complexity below the 15 threshold for the 4 flagged functions, verified by the existing test suite (no behavior change).

    Findings (from SonarCloud API)

    File:line Function Complexity
    src/calendar-to-sheets/src/index.js:109 syncCalendarToSheet 25
    src/gmail-to-drive-by-labels/src/index.js:125 processMessageToDoc attachment loop 33
    src/gmail-to-drive-by-labels/src/index.js:690 rebuildDoc 17
    deploy/index.html:1846 handleDeploy 19

    Implementation Checklist

    • src/calendar-to-sheets/src/index.js: extract upsertRows, insertNewRows, computeRowsToDelete helpers out of syncCalendarToSheet
    • src/gmail-to-drive-by-labels/src/index.js: extract attachment dedup/rename helpers out of the processMessageToDoc attachment loop
    • src/gmail-to-drive-by-labels/src/index.js: extract state-machine phase helpers out of rebuildDoc
    • deploy/index.html: extract resolveDeployProjectId + buildDeployErrorHtml helpers out of handleDeploy

    Tests to Write

    • Behavior-preserving refactor: no new behavior, so no new tests required (Phase 2 exception). The existing 301 Jest tests + Playwright deploy/tests/ui.spec.js validate behavior preservation. Any newly extracted helper stays covered via its existing callers to maintain the 99% line / 85% branch coverage thresholds.

    Test Command

    npm test (Jest, includes coverage thresholds via npm test -- --coverage)

  2. don-petry commented on Jul 7, 2026

    @don-petry
    CollaboratorAuthor

    Dev-Lead: Implementation Complete

    Behavior-preserving refactors that reduce cognitive complexity (S3776) below the 15 threshold for all 4 flagged functions. No behavior change — validated by the existing test suite (Phase 2 TDD exception applies to a pure refactor).

    Plan Execution

    • src/calendar-to-sheets/src/index.js — syncCalendarToSheet (25→~5): extracted upsertRows, insertNewRows, shouldDeleteRow, computeRowsToDelete
    • src/gmail-to-drive-by-labels/src/index.js — processMessageToDoc attachment loop (33→~5): extracted isDuplicateAttachment, resolveAttachmentFileName
    • src/gmail-to-drive-by-labels/src/index.js — rebuildDoc (17→~5): extracted clearDocPhase, moveEmailsPhase (null-sentinel preserves original early-return/fall-through control flow)
    • deploy/index.html — handleDeploy (19→~8): extracted resolveDeployProjectId, buildDeployErrorHtml

    Verification

    • npm test — 301/301 passing
    • npm test -- --coverage — exit 0, global thresholds met (branches 90.22 ≥ 85, functions 98.14 ≥ 95, lines 99.37 ≥ 99, statements 98.93 ≥ 95); extracted helpers at 100% function coverage
    • npm run check (prettier --check + eslint) — exit 0 (only pre-existing unused-var warnings in untouched test files)
    • bash .dev-lead/scripts/dev-lead-lint.sh — all checks passed
    • npx prettier --write . applied
    • node --check on both refactored index.js files — OK

    Test Results

    Test Suites: 12 passed, 12 total
    Tests:       301 passed, 301 total
    Snapshots:   0 total
    
    ----------------------------------|---------|----------|---------|---------|
    File                              | % Stmts | % Branch | % Funcs | % Lines |
    ----------------------------------|---------|----------|---------|---------|
    All files                         |   98.93 |    90.22 |   98.14 |   99.37 |
     src/calendar-to-sheets/src       |     100 |      100 |     100 |     100 |
      index.js                        |     100 |      100 |     100 |     100 |
     src/deploy                       |     100 |      100 |     100 |     100 |
     src/gmail-to-drive-by-labels/src |   98.53 |    90.56 |     100 |   99.09 |
      index.js                        |   98.53 |    90.56 |     100 |   99.09 |
    ----------------------------------|---------|----------|---------|---------|
    

    Files Changed

    • src/calendar-to-sheets/src/index.js: split syncCalendarToSheet into upsert/insert/delete helpers
    • src/gmail-to-drive-by-labels/src/index.js: split the attachment loop and rebuildDoc state machine into helpers
    • deploy/index.html: split handleDeploy into project-resolution and error-html helpers

    Notes

    • Pure refactor: no NOSONAR suppressions used. All original console.log/console.error calls and produced values/HTML are preserved verbatim, so runtime behavior is unchanged.
    • deploy/index.html is not part of Jest coverage (covered by the Playwright deploy/tests/ui.spec.js e2e); its inline JS was validated via prettier parse + syntax review. Extracted functions live in the same <script> scope and are hoisted.
    • The similar attachment loop in processLabelGroup was not flagged by SonarCloud and was left untouched to avoid scope creep.
  3. don-petry commented on Jul 14, 2026

    @don-petry
    CollaboratorAuthor

    SonarCloud Audit (2026-07-14): still open — 4 finding(s), worst severity CRITICAL.

  4. don-petry commented on Jul 21, 2026

    @don-petry
    CollaboratorAuthor

    SonarCloud Audit (2026-07-21): still open — 4 finding(s), worst severity CRITICAL.

  5. added
    dev-leadFor dev-lead agent pickup
    and removed
    dev-leadFor dev-lead agent pickup
    on Jul 21, 2026
  6. don-petry commented on Jul 21, 2026

    @don-petry
    CollaboratorAuthor

    Dev-Lead Implementation Plan

    Issue: #427 — SonarCloud: cognitive complexity (S3776)

    Scope

    Refactor the 4 functions flagged by SonarCloud rule javascript:S3776 to reduce cognitive complexity below the 15 threshold, with no behavior change.

    Findings located (verified locally with eslint-plugin-sonarjs)

    File Function Complexity
    src/gmail-to-drive-by-labels/src/index.js attachment forEach loop in processMessageToDoc 33
    src/gmail-to-drive-by-labels/src/index.js rebuildDoc 17
    src/calendar-to-sheets/src/index.js syncCalendarToSheet 25
    deploy/index.html handleDeploy 19

    Implementation Checklist

    • src/calendar-to-sheets/src/index.js — extract upsert loop (applyUpserts) and delete loop (collectRowsToDelete) out of syncCalendarToSheet
    • src/gmail-to-drive-by-labels/src/index.js — extract attachment dedup/save into a helper (processAttachment + findDuplicateFile) used by processMessageToDoc
    • src/gmail-to-drive-by-labels/src/index.js — extract phase bodies of rebuildDoc (clearDocumentPhase, moveEmailsPhase)
    • deploy/index.html — extract per-script deploy body (deployOneScript) and error-html builder (buildDeployErrorHtml) out of handleDeploy

    Tests to Write

    • These are behavior-preserving refactors. The affected JS is already covered by the Jest suite (301 tests) and deploy/index.html by the Playwright e2e suite; both act as the regression net. No new behavior is introduced, so per the Phase 2 exception no new failing tests are added. Coverage thresholds (99% lines) will be kept green since extracted helpers sit on already-exercised paths.

    Test Command

    npm test (Jest + coverage); npm run test:e2e (Playwright, for deploy/index.html); complexity re-verified with eslint-plugin-sonarjs.

  7. don-petry commented on Jul 21, 2026

    @don-petry
    CollaboratorAuthor

    Dev-Lead: Implementation Complete

    Refactored the 4 functions flagged by SonarCloud javascript:S3776 (cognitive complexity) so each drops below the 15 threshold, with no behavior change.

    Plan Execution

    • src/calendar-to-sheets/src/index.js — extracted applyUpdatesAndCollectInserts (upsert loop) and collectRowsToDelete (delete loop) out of syncCalendarToSheet (25 → 0 findings)
    • src/gmail-to-drive-by-labels/src/index.js — extracted isDuplicateAttachment, resolveAttachmentName, processAttachment out of the processMessageToDoc attachment loop (33 → 0 findings)
    • src/gmail-to-drive-by-labels/src/index.js — extracted clearDocumentPhase and moveEmailsPhase out of rebuildDoc (17 → 0 findings)
    • deploy/index.html — extracted deployOneScript (per-script deploy body) and buildDeployErrorHtml (error status builder) out of handleDeploy (19 → 0 findings)

    Verification

    • Cognitive complexity (re-measured with eslint-plugin-sonarjs, S3776, threshold 15): all four files now report 0 findings.
    • Jest: 12 suites, 301 tests passed (unchanged from baseline).
    • Coverage thresholds met: lines 99.37% (≥99), statements 98.92% (≥95), functions 98.13% (≥95), branches 90.19% (≥85). calendar-to-sheets/src/index.js is 100% across the board.
    • Playwright e2e (deploy/tests/ui.spec.js, covers handleDeploy): 65 passed.
    • Lint: npm run check → 0 errors (only pre-existing unused-var warnings in test files). .dev-lead/scripts/dev-lead-lint.sh → all checks passed.
    • npx prettier --write applied.

    Test Results

    Test Suites: 12 passed, 12 total
    Tests:       301 passed, 301 total
    Snapshots:   0 total
    
    deploy/tests/ui.spec.js: 65 passed (22.0s)
    
    Cognitive complexity (eslint-plugin-sonarjs, threshold 15):
      src/gmail-to-drive-by-labels/src/index.js: OK (0 findings)
      src/calendar-to-sheets/src/index.js: OK (0 findings)
      deploy/index.html: OK (0 findings)
    

    Files Changed

    • src/calendar-to-sheets/src/index.js: extracted upsert/delete loops from syncCalendarToSheet into helpers.
    • src/gmail-to-drive-by-labels/src/index.js: extracted attachment dedup/save helpers from processMessageToDoc; extracted rebuildDoc phase bodies into helpers.
    • deploy/index.html: extracted per-script deploy and error-HTML builder from handleDeploy.

    Notes

    • Pure behavior-preserving refactors: no observable behavior changes. All existing Jest and Playwright tests act as the regression net and remain green — so per the Phase 2 exception, no new tests were added. Log messages and control flow were preserved exactly.
    • Removed the now-unused Session binding from processMessageToDoc (it moved into resolveAttachmentName) to keep lint clean.
    • Complexity was located and verified locally with eslint-plugin-sonarjs (same S3776 rule as SonarCloud); the 4 findings map 1:1 to the issue's file counts.
  8. don-petry commented on Jul 28, 2026

    @don-petry
    CollaboratorAuthor

    SonarCloud Audit (2026-07-28): still open — 4 finding(s), worst severity CRITICAL.

  9. don-petry commented on Aug 4, 2026

    @don-petry
    CollaboratorAuthor

    Resolved! No open SonarCloud findings remain in this workstream as of 2026-08-04. Closing automatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    dev-leadFor dev-lead agent pickuppriority:criticalSonarCloud CRITICAL severitysonarcloud-auditSonarCloud audit finding (idempotent marker)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions