Static Code Analysis Report — SonarQube

Project: FieldNotes AI Initial Scan Date: March 23, 2026 Final Scan Date: March 28, 2026 Tool: SonarQube (via ReflectSonar)


1. What is SonarQube?

SonarQube is a static code analysis tool used to automatically review source code for bugs, security risks, and maintainability issues without running the application. It reads through the codebase and flags patterns known to cause problems, assigning each finding a severity level and linking it to a documented rule explaining why it matters and how to fix it.

It organises findings into three main categories: Security, Reliability, and Maintainability. Each category receives a letter grade from A (best) to E (worst). It also reports on test coverage (how much of the code is tested) and code duplication.


2. Overall Results

Category Initial Grade Final Grade Issues Resolved
Security A A 0 open (stable)
Reliability D A 111 resolved + 49 new = 160 total resolved
Maintainability A A 464 resolved + 278 new = 742 total resolved
Security Hotspots 27 open A (0 open) All 27 resolved
Test Coverage 46.8% 81% Improved by 34.2 percentage points
Duplications A A 4.8% reduced to 0%
Initial SonarQube Scan Final SonarQube Scan
Figure 1: Initial Scan Figure 2: Final Scan

The most significant improvement was in Reliability, which moved from a D grade to A, reflecting the resolution of all open bugs. Test coverage also saw a major jump, rising from 46.8% to 81%. The sections below explain what was found in the initial scan and what was addressed by the final scan.


3. Security

Initial Grade: A | Final Grade: A

Security vulnerabilities remained at zero across both scans. However, the initial scan flagged 27 Security Hotspots — areas of code that are not necessarily broken, but involve sensitive operations requiring a developer to manually review and confirm they are handled safely.

Given that this application handles sensitive client records, session recordings, and practitioner data, resolving all 27 was an important step. The hotspots fell into four categories:

Authentication (2 hotspots — High): Hard-coded test passwords were embedded directly in a mock authentication provider used for testing. Credentials like "password123" and "admin123" were present in source code. While not used in production, their presence was flagged as a risk and addressed.

Denial of Service via Regex (12 hotspots — Medium): Several email and phone validation patterns used regular expressions that, under certain conditions, could take an extremely long time to process a maliciously crafted input — a class of vulnerability known as ReDoS (Regular Expression Denial of Service). Each pattern was reviewed and assessed for real-world risk.

Insecure Protocol Usage (2 hotspots — Low): Mock URLs using http:// instead of https:// appeared in test configuration files. These carried no production risk but were flagged for review and corrected.

File System Usage (2 hotspots — Low): The export utility writes files to the device's document or cache directory, which SonarQube flagged as a publicly writable location. This is standard behaviour for mobile app file exports but was reviewed to confirm it is handled safely.

Weak Cryptography (9 hotspots — Medium): Several places in the codebase used Math.random() to generate IDs and UUIDs. Math.random() is not cryptographically secure, meaning its output could theoretically be predicted. For non-security-critical ID generation this is generally acceptable, but each case was reviewed individually.

All 27 hotspots were reviewed and resolved, bringing the Security Hotspot rating to A.


4. Reliability

Initial Grade: D | Issues: 112 (High: 7, Medium: 18, Low: 87) Final Grade: A | Issues: 160 total resolved (all open issues cleared)

The initial scan returned a D grade for Reliability, indicating a meaningful number of bugs in the codebase. The original 112 issues were resolved, and a further 48 were identified and fixed as part of the same process, bringing the total resolved to 160. All issues were cleared before the final scan.

High Priority (7 initial, 8 total resolved)

Missing sort comparison function (4 issues)

When sorting a list of names or text without specifying how to compare them, JavaScript falls back to a basic character-by-character sort that can produce inconsistent or incorrect results, particularly with names containing accents or special characters. The fix was to provide an explicit comparison function that handles text sorting correctly across different languages. This is especially relevant for a Social Work application where client names may come from many different cultural backgrounds.

Unsafe return inside a finally block (2 issues)

A finally block is meant only for cleanup tasks like closing connections. Placing a return statement inside one causes the function to silently ignore any errors and return an unexpected value instead. This was fixed by moving the return statement outside the finally block.

Unreliable number truncation (2 issues)

A shorthand coding trick (| 0) was being used to convert a decimal number to a whole number. This silently produces wrong results for very large numbers. It was replaced with the standard Math.trunc() function, which works correctly in all cases.

Medium Priority (18 initial, 24 total resolved)

Unhandled promise returns (12 issues)

Several functions that perform background tasks, such as saving data or navigating between screens, were connected to buttons or events in a way that caused any errors they encountered to be silently ignored. This meant failures could happen without the user or developer being notified. These were fixed by ensuring errors are properly caught and handled.

Incorrect conditional rendering in React (3 issues)

In React Native, using a number directly as a condition in a display expression can cause that number (such as 0) to appear visibly on screen when it should show nothing. The fix was to convert the condition to a proper true/false check before using it.

Other medium issues included a conditional in the login screen that returned the same value regardless of which branch ran, missing property definitions on mock components, and a regular expression that could match more than intended due to operator ordering.

Low Priority (87 initial, 128 total resolved)

The low-priority reliability issues were mostly about replacing older JavaScript methods with newer, safer equivalents. The most common were replacing String#replace() with String#replaceAll() across dozens of files, and replacing global parseInt and isNaN with Number.parseInt and Number.isNaN, which are stricter and less prone to unexpected type coercion.


5. Maintainability

Initial Grade: A | Issues: 528 (Blocker: 1, High: 47, Medium: 122, Low: 358) Final Grade: A | Issues: 742 total resolved (all open issues cleared)

Despite the initial A grade, the scan still identified 528 maintainability issues. The grade reflects the proportion of technical debt relative to project size. All original 528 were resolved and a further 214 new ones were identified and fixed, bringing the total addressed to 742. All were cleared before the final scan.

Blocker (1 issue)

Function that always returns the same value

A mock function used in testing had multiple branches but always returned the same result regardless of which branch ran. This was cleaned up to remove the redundant branching.

High Priority (47 initial, 68 total resolved)

Functions that are too complex (largest category)

SonarQube measures how difficult a function is to understand by counting how many decisions and branches it contains. The recommended maximum is 15. In the initial scan, the worst offending functions, found in the export utility and auto-fill services, scored as high as 83. These were broken down into smaller, more focused functions to improve readability and testability. In total, 51 overly complex functions were identified and refactored across both scans.

Functions nested too deeply (6 issues)

Code nested inside multiple layers of other code becomes hard to read and test. These were refactored to reduce nesting depth.

Other high-priority issues included unnecessary use of the void operator in several screen files and the same unreliable number truncation flagged under Reliability.

Medium Priority (122 initial, 163 total resolved)

Nested conditional expressions (approximately 55 issues)

Chaining multiple conditions together in a single line is difficult to read quickly. These were rewritten as clearer if/else blocks. Many were caught in the initial scan and more were identified in the final scan.

React components defined inside other components (approximately 20 issues)

When a component is defined inside another component's render logic, it gets recreated from scratch every time the parent updates, which can cause visual glitches, lost state, and unnecessary performance overhead. These were moved to the top level of their respective files.

Array index used as a list key in React (approximately 10 issues)

React requires each item in a rendered list to have a stable, unique identifier. Using the item's position in the array as that identifier causes problems when items are reordered, added, or removed. The fix was to use a proper unique ID such as a database record ID.

Useless variable assignments (approximately 20 issues)

Variables were assigned values that were never actually used, typically leftover from earlier refactors. These were removed.

Other notable medium issues included a React authentication context that recreated its data object on every screen update (causing unnecessary processing), commented-out code, duplicate import statements, a skipped test without explanation in the unit test suite, and branches of conditional logic containing identical code when they should have differed.

Low Priority (358 initial, 510 total resolved)

The low-priority maintainability findings grew between scans as more files were brought under review. The most common categories across both scans were:

  • React component props not marked as read-only, found across approximately 80 component files
  • Conditions written in a negated form where reversing them would be clearer to read
  • References to browser-specific globals that should use globalThis instead
  • Verbose array access patterns that can be simplified with newer built-in methods such as .at()
  • Multiple consecutive Array.push() calls that could be combined into one
  • Use of JSON.parse(JSON.stringify(...)) for deep copying objects, replaced with the modern structuredClone() function
  • Unused imports and deprecated API references across component and test files

6. Test Coverage

Initial Coverage: 46.8% (on 9,440 lines) Final Coverage: 81.0% (on 9,081 lines)

Test coverage improved significantly, rising from 46.8% to 81%. This means the automated test suite now exercises over four-fifths of the application's code. SonarQube does not assign a letter grade to coverage directly; it is measured as a percentage against a configurable threshold. At 81%, the project sits above the commonly used 80% benchmark, and the test suite spans unit, integration, acceptance, and accessibility tests across both admin and practitioner workflows.


7. Code Duplication

Initial Duplication: 4.8% (on 39,297 lines) Final Duplication: 0% (on 37,427 lines)

Code duplication dropped from 4.8% to 0%, meaning all significant repeated code identified in the initial scan was extracted into shared utilities, services, or components. The final report's PDF showed a D grade for this category, which appears to be a display error in the report generator. The actual measured duplication is 0%, which is an excellent result.


8. Summary

Category Initial Final Change
Security Grade A A Stable
Reliability Grade D A Improved
Maintainability Grade A A Stable
Security Hotspots 27 open 0 open All resolved
Reliability Issues 112 0 open 160 total resolved
Maintainability Issues 528 0 open 742 total resolved
Test Coverage 46.8% 81.0% +34.2 percentage points
Code Duplication 4.8% 0% Fully eliminated

The most impactful outcomes were the Reliability grade moving from D to A, clearing all open bugs; the resolution of all 27 security hotspots, which is critical given the sensitivity of the data this application handles; a 34-point increase in test coverage; and the complete elimination of code duplication. The maintainability work, while already at an A grade, involved addressing 742 issues in total, with the most significant effort going into reducing the complexity of the auto-fill and export service functions.