feat: abbreviate large numbers on analytics stats cards #2998

Merged
mfreeman451 merged 1 commit from refs/pull/2998/head into staging 2026-03-01 03:54:02 +00:00
mfreeman451 commented 2026-03-01 03:49:00 +00:00 (Migrated from github.com)
Owner

Imported from GitHub pull request.

Original GitHub pull request: #2960
Original author: @mfreeman451
Original URL: https://github.com/carverauto/serviceradar/pull/2960
Original created: 2026-03-01T03:49:00Z
Original updated: 2026-03-01T03:54:04Z
Original head: carverauto/serviceradar:2371-abbreviate-analytics-numbers
Original base: staging
Original merged: 2026-03-01T03:54:02Z by @mfreeman451

User description

Summary

  • Switches analytics stats cards from comma-formatted numbers (50,000) to compact abbreviations (50k, 1.5M, 2.3B)
  • Uses the existing format_compact_number/1 helper instead of format_number/1
  • Applies to stat cards, device availability donut (online/offline counts), and log severity table
  • Removes now-unused format_number/1 and add_commas/1 functions

Closes #2371

Test plan

  • Verify stat cards show abbreviated numbers (e.g. 50k instead of 50,000)
  • Verify small numbers (<1000) still display as-is
  • Verify device availability online/offline counts are abbreviated
  • Verify log severity counts are abbreviated

🤖 Generated with Claude Code


PR Type

Enhancement


Description

  • Replace comma-formatted numbers with compact abbreviations (50k, 1.5M, 2.3B)

  • Apply formatting to stat cards, device availability counts, and log severity table

  • Remove unused format_number/1 and add_commas/1 helper functions


Diagram Walkthrough

flowchart LR
  A["Analytics Display Components"] -->|format_compact_number| B["Abbreviated Numbers"]
  C["Stat Cards"] -->|50k, 1.5M, 2.3B| B
  D["Device Availability"] -->|Online/Offline Counts| B
  E["Log Severity Table"] -->|Count Values| B
  F["Removed Functions"] -.->|format_number, add_commas| G["Cleanup"]

File Walkthrough

Relevant files
Enhancement
index.ex
Switch to compact number formatting throughout analytics 

elixir/web-ng/lib/serviceradar_web_ng_web/live/analytics_live/index.ex

  • Replace format_number/1 calls with format_compact_number/1 in stat
    card display
  • Replace format_number/1 calls with format_compact_number/1 in device
    availability widget (online/offline counts)
  • Replace format_number/1 calls with format_compact_number/1 in log
    severity table row component
  • Remove unused format_number/1 function (4 clauses handling integers,
    floats, and fallback)
  • Remove unused add_commas/1 helper function that formatted numbers with
    comma separators
+4/-21   

Imported from GitHub pull request. Original GitHub pull request: #2960 Original author: @mfreeman451 Original URL: https://github.com/carverauto/serviceradar/pull/2960 Original created: 2026-03-01T03:49:00Z Original updated: 2026-03-01T03:54:04Z Original head: carverauto/serviceradar:2371-abbreviate-analytics-numbers Original base: staging Original merged: 2026-03-01T03:54:02Z by @mfreeman451 --- ### **User description** ## Summary - Switches analytics stats cards from comma-formatted numbers (`50,000`) to compact abbreviations (`50k`, `1.5M`, `2.3B`) - Uses the existing `format_compact_number/1` helper instead of `format_number/1` - Applies to stat cards, device availability donut (online/offline counts), and log severity table - Removes now-unused `format_number/1` and `add_commas/1` functions Closes #2371 ## Test plan - [ ] Verify stat cards show abbreviated numbers (e.g. `50k` instead of `50,000`) - [ ] Verify small numbers (<1000) still display as-is - [ ] Verify device availability online/offline counts are abbreviated - [ ] Verify log severity counts are abbreviated 🤖 Generated with [Claude Code](https://claude.com/claude-code) ___ ### **PR Type** Enhancement ___ ### **Description** - Replace comma-formatted numbers with compact abbreviations (50k, 1.5M, 2.3B) - Apply formatting to stat cards, device availability counts, and log severity table - Remove unused `format_number/1` and `add_commas/1` helper functions ___ ### Diagram Walkthrough ```mermaid flowchart LR A["Analytics Display Components"] -->|format_compact_number| B["Abbreviated Numbers"] C["Stat Cards"] -->|50k, 1.5M, 2.3B| B D["Device Availability"] -->|Online/Offline Counts| B E["Log Severity Table"] -->|Count Values| B F["Removed Functions"] -.->|format_number, add_commas| G["Cleanup"] ``` <details><summary><h3>File Walkthrough</h3></summary> <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table> <tr> <td> <details> <summary><strong>index.ex</strong><dd><code>Switch to compact number formatting throughout analytics</code>&nbsp; </dd></summary> <hr> elixir/web-ng/lib/serviceradar_web_ng_web/live/analytics_live/index.ex <ul><li>Replace <code>format_number/1</code> calls with <code>format_compact_number/1</code> in stat <br>card display<br> <li> Replace <code>format_number/1</code> calls with <code>format_compact_number/1</code> in device <br>availability widget (online/offline counts)<br> <li> Replace <code>format_number/1</code> calls with <code>format_compact_number/1</code> in log <br>severity table row component<br> <li> Remove unused <code>format_number/1</code> function (4 clauses handling integers, <br>floats, and fallback)<br> <li> Remove unused <code>add_commas/1</code> helper function that formatted numbers with <br>comma separators</ul> </details> </td> <td><a href="https://github.com/carverauto/serviceradar/pull/2960/files#diff-ee008fe2b55f4a8443281692cbfd8269f679236499246beb83a39fa497353ca6">+4/-21</a>&nbsp; &nbsp; </td> </tr> </table></td></tr></tbody></table> </details> ___
qodo-code-review[bot] commented 2026-03-01 03:49:23 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2960#issuecomment-3979009221
Original created: 2026-03-01T03:49:23Z

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🟢
🎫 #2371
🟢 Analytics stats cards should abbreviate large numbers (e.g., display 50k devices instead
of 50,000 devices).
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Missing fallback clause: format_compact_number/1 only matches integers/floats and may raise a FunctionClauseError
if any of the new call sites pass nil or a non-number.

Referred Code
defp format_compact_number(n) when is_float(n), do: n |> trunc() |> format_compact_number()

defp format_compact_number(n) when is_integer(n) do
  sign = if n < 0, do: "-", else: ""

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
- Requires Further Human Verification
🏷️ - Compliance label
Imported GitHub PR comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2960#issuecomment-3979009221 Original created: 2026-03-01T03:49:23Z --- ## PR Compliance Guide 🔍 <!-- https://github.com/carverauto/serviceradar/commit/c3939ecc2f30f79561c731b767d776c3f9353b74 --> Below is a summary of compliance checks for this PR:<br> <table><tbody><tr><td colspan='2'><strong>Security Compliance</strong></td></tr> <tr><td>🟢</td><td><details><summary><strong>No security concerns identified</strong></summary> No security vulnerabilities detected by AI analysis. Human verification advised for critical code. </details></td></tr> <tr><td colspan='2'><strong>Ticket Compliance</strong></td></tr> <tr><td>🟢</td> <td> <details> <summary>🎫 <a href=https://github.com/carverauto/serviceradar/issues/2371>#2371</a></summary> <table width='100%'><tbody> <tr><td rowspan=1>🟢</td> <td>Analytics stats cards should abbreviate large numbers (e.g., display <code>50k devices</code> instead <br>of <code>50,000 devices</code>).<br></td></tr> </tbody></table> </details> </td></tr> <tr><td colspan='2'><strong>Codebase Duplication Compliance</strong></td></tr> <tr><td>⚪</td><td><details><summary><strong>Codebase context is not defined </strong></summary> Follow the <a href='https://qodo-merge-docs.qodo.ai/core-abilities/rag_context_enrichment/'>guide</a> to enable codebase context checks. </details></td></tr> <tr><td colspan='2'><strong>Custom Compliance</strong></td></tr> <tr><td rowspan=5>🟢</td><td> <details><summary><strong>Generic: Comprehensive Audit Trails</strong></summary><br> **Objective:** To create a detailed and reliable record of critical system actions for security analysis <br>and compliance.<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Meaningful Naming and Self-Documenting Code</strong></summary><br> **Objective:** Ensure all identifiers clearly express their purpose and intent, making code <br>self-documenting<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Secure Error Handling</strong></summary><br> **Objective:** To prevent the leakage of sensitive system information through error messages while <br>providing sufficient detail for internal debugging.<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Secure Logging Practices</strong></summary><br> **Objective:** To ensure logs are useful for debugging and auditing without exposing sensitive <br>information like PII, PHI, or cardholder data.<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Security-First Input Validation and Data Handling</strong></summary><br> **Objective:** Ensure all data inputs are validated, sanitized, and handled securely to prevent <br>vulnerabilities<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td rowspan=1>⚪</td> <td><details> <summary><strong>Generic: Robust Error Handling and Edge Case Management</strong></summary><br> **Objective:** Ensure comprehensive error handling that provides meaningful context and graceful <br>degradation<br> **Status:** <br><a href='https://github.com/carverauto/serviceradar/pull/2960/files#diff-ee008fe2b55f4a8443281692cbfd8269f679236499246beb83a39fa497353ca6R1009-R1012'><strong>Missing fallback clause</strong></a>: <code>format_compact_number/1</code> only matches integers/floats and may raise a <code>FunctionClauseError</code> <br>if any of the new call sites pass <code>nil</code> or a non-number.<br> <details open><summary>Referred Code</summary> ```elixir defp format_compact_number(n) when is_float(n), do: n |> trunc() |> format_compact_number() defp format_compact_number(n) when is_integer(n) do sign = if n < 0, do: "-", else: "" ``` </details> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td align="center" colspan="2"> <!-- placeholder --> <!-- /compliance --update_compliance=true --> </td></tr></tbody></table> <details><summary>Compliance status legend</summary> 🟢 - Fully Compliant<br> 🟡 - Partial Compliant<br> 🔴 - Not Compliant<br> ⚪ - Requires Further Human Verification<br> 🏷️ - Compliance label<br> </details>
qodo-code-review[bot] commented 2026-03-01 03:50:04 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2960#issuecomment-3979010523
Original created: 2026-03-01T03:50:04Z

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: build

Failed stage: Configure SRQL fixture database for tests []

Failed test name: ""

Failure summary:

The action failed because a required GitHub Actions secret was missing/empty:
- The job aborted with
SRQL_TEST_DATABASE_CA_CERT secret must be configured to verify SRQL fixture TLS. (log line 707),
which caused Process completed with exit code 1 (line 708).
Additional issue observed during
post-job cleanup (not the primary failure):
- Git cleanup warned fatal: No url found for submodule
path </code>swift/FieldSurvey/LocalPackages/arrow-swift<code> in </code>.gitmodules<code> and exited 128 (lines 718-719),
indicating an inconsistent/misconfigured submodule entry during cleanup.

Relevant error logs:
1:  Runner name: 'arc-runner-set-hk6mk-runner-68q4l'
2:  Runner group name: 'Default'
...

139:  ^[[36;1mif command -v apt-get >/dev/null 2>&1; then^[[0m
140:  ^[[36;1m  sudo apt-get update^[[0m
141:  ^[[36;1m  sudo apt-get install -y build-essential pkg-config libssl-dev protobuf-compiler cmake flex bison^[[0m
142:  ^[[36;1melif command -v dnf >/dev/null 2>&1; then^[[0m
143:  ^[[36;1m  sudo dnf install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m
144:  ^[[36;1melif command -v yum >/dev/null 2>&1; then^[[0m
145:  ^[[36;1m  sudo yum install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m
146:  ^[[36;1melif command -v microdnf >/dev/null 2>&1; then^[[0m
147:  ^[[36;1m  sudo microdnf install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m
148:  ^[[36;1melse^[[0m
149:  ^[[36;1m  echo "Unsupported package manager; please install gcc, g++ (or clang), make, OpenSSL headers, pkg-config, and protoc manually." >&2^[[0m
150:  ^[[36;1m  exit 1^[[0m
151:  ^[[36;1mfi^[[0m
152:  ^[[36;1m^[[0m
153:  ^[[36;1mensure_pkg_config^[[0m
154:  ^[[36;1mprotoc --version || (echo "protoc installation failed" && exit 1)^[[0m
155:  shell: /usr/bin/bash -e {0}
...

387:  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
388:  env:
389:  BUILDBUDDY_ORG_API_KEY: ***
390:  SRQL_TEST_DATABASE_URL: ***
391:  SRQL_TEST_ADMIN_URL: ***
392:  SRQL_TEST_DATABASE_CA_CERT: 
393:  DOCKERHUB_USERNAME: ***
394:  DOCKERHUB_TOKEN: ***
395:  TEST_CNPG_DATABASE: serviceradar_web_ng_test
396:  INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp
397:  INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir
398:  ##[endgroup]
399:  ##[group]Run : install rustup if needed
400:  ^[[36;1m: install rustup if needed^[[0m
401:  ^[[36;1mif ! command -v rustup &>/dev/null; then^[[0m
402:  ^[[36;1m  curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail https://sh.rustup.rs | sh -s -- --default-toolchain none -y^[[0m
403:  ^[[36;1m  echo "$CARGO_HOME/bin" >> $GITHUB_PATH^[[0m
...

543:  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
544:  env:
545:  BUILDBUDDY_ORG_API_KEY: ***
546:  SRQL_TEST_DATABASE_URL: ***
547:  SRQL_TEST_ADMIN_URL: ***
548:  SRQL_TEST_DATABASE_CA_CERT: 
549:  DOCKERHUB_USERNAME: ***
550:  DOCKERHUB_TOKEN: ***
551:  TEST_CNPG_DATABASE: serviceradar_web_ng_test
552:  INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp
553:  INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir
554:  CARGO_HOME: /home/runner/.cargo
555:  CARGO_INCREMENTAL: 0
556:  CARGO_TERM_COLOR: always
557:  ##[endgroup]
558:  ##[group]Run : work around spurious network errors in curl 8.0
559:  ^[[36;1m: work around spurious network errors in curl 8.0^[[0m
560:  ^[[36;1m# https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/timeout.20investigation^[[0m
...

611:  SRQL_TEST_DATABASE_CA_CERT: 
612:  DOCKERHUB_USERNAME: ***
613:  DOCKERHUB_TOKEN: ***
614:  TEST_CNPG_DATABASE: serviceradar_web_ng_test
615:  INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp
616:  INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir
617:  CARGO_HOME: /home/runner/.cargo
618:  CARGO_INCREMENTAL: 0
619:  CARGO_TERM_COLOR: always
620:  ##[endgroup]
621:  Attempting to download 1.x...
622:  Acquiring v1.28.1 from https://github.com/bazelbuild/bazelisk/releases/download/v1.28.1/bazelisk-linux-amd64
623:  Adding to the cache ...
624:  Successfully cached bazelisk to /home/runner/_work/_tool/bazelisk/1.28.1/x64
625:  Added bazelisk to the path
626:  ##[warning]Failed to restore: Cache service responded with 400
627:  Restored bazelisk cache dir @ /home/runner/.cache/bazelisk
...

693:  env:
694:  BUILDBUDDY_ORG_API_KEY: ***
695:  SRQL_TEST_DATABASE_URL: ***
696:  SRQL_TEST_ADMIN_URL: ***
697:  SRQL_TEST_DATABASE_CA_CERT: 
698:  DOCKERHUB_USERNAME: ***
699:  DOCKERHUB_TOKEN: ***
700:  TEST_CNPG_DATABASE: serviceradar_web_ng_test
701:  INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp
702:  INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir
703:  CARGO_HOME: /home/runner/.cargo
704:  CARGO_INCREMENTAL: 0
705:  CARGO_TERM_COLOR: always
706:  ##[endgroup]
707:  SRQL_TEST_DATABASE_CA_CERT secret must be configured to verify SRQL fixture TLS.
708:  ##[error]Process completed with exit code 1.
709:  Post job cleanup.
710:  [command]/usr/bin/git version
711:  git version 2.52.0
712:  Temporarily overriding HOME='/home/runner/_work/_temp/9578a9d0-c61d-4d81-b12b-d7453b62094b' before making global git config changes
713:  Adding repository directory to the temporary git global config as a safe directory
714:  [command]/usr/bin/git config --global --add safe.directory /home/runner/_work/serviceradar/serviceradar
715:  Removing SSH command configuration
716:  [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand
717:  [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
718:  fatal: No url found for submodule path 'swift/FieldSurvey/LocalPackages/arrow-swift' in .gitmodules
719:  ##[warning]The process '/usr/bin/git' failed with exit code 128
720:  Cleaning up orphan processes

Imported GitHub PR comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2960#issuecomment-3979010523 Original created: 2026-03-01T03:50:04Z --- ## CI Feedback 🧐 A test triggered by this PR failed. Here is an AI-generated analysis of the failure: <table><tr><td> **Action:** build</td></tr> <tr><td> **Failed stage:** [Configure SRQL fixture database for tests](https://github.com/carverauto/serviceradar/actions/runs/22535337228/job/65281559266) [❌] </td></tr> <tr><td> **Failed test name:** "" </td></tr> <tr><td> **Failure summary:** The action failed because a required GitHub Actions secret was missing/empty:<br> - The job aborted with <br><code>SRQL_TEST_DATABASE_CA_CERT secret must be configured to verify SRQL fixture TLS.</code> (log line 707), <br>which caused <code>Process completed with exit code 1</code> (line 708).<br> Additional issue observed during <br>post-job cleanup (not the primary failure):<br> - Git cleanup warned <code>fatal: No url found for submodule </code><br><code>path \</code>swift/FieldSurvey/LocalPackages/arrow-swift\<code> in \</code>.gitmodules\<code></code> and exited 128 (lines 718-719), <br>indicating an inconsistent/misconfigured submodule entry during cleanup.<br> </td></tr> <tr><td> <details><summary>Relevant error logs:</summary> ```yaml 1: Runner name: 'arc-runner-set-hk6mk-runner-68q4l' 2: Runner group name: 'Default' ... 139: ^[[36;1mif command -v apt-get >/dev/null 2>&1; then^[[0m 140: ^[[36;1m sudo apt-get update^[[0m 141: ^[[36;1m sudo apt-get install -y build-essential pkg-config libssl-dev protobuf-compiler cmake flex bison^[[0m 142: ^[[36;1melif command -v dnf >/dev/null 2>&1; then^[[0m 143: ^[[36;1m sudo dnf install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m 144: ^[[36;1melif command -v yum >/dev/null 2>&1; then^[[0m 145: ^[[36;1m sudo yum install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m 146: ^[[36;1melif command -v microdnf >/dev/null 2>&1; then^[[0m 147: ^[[36;1m sudo microdnf install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m 148: ^[[36;1melse^[[0m 149: ^[[36;1m echo "Unsupported package manager; please install gcc, g++ (or clang), make, OpenSSL headers, pkg-config, and protoc manually." >&2^[[0m 150: ^[[36;1m exit 1^[[0m 151: ^[[36;1mfi^[[0m 152: ^[[36;1m^[[0m 153: ^[[36;1mensure_pkg_config^[[0m 154: ^[[36;1mprotoc --version || (echo "protoc installation failed" && exit 1)^[[0m 155: shell: /usr/bin/bash -e {0} ... 387: shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} 388: env: 389: BUILDBUDDY_ORG_API_KEY: *** 390: SRQL_TEST_DATABASE_URL: *** 391: SRQL_TEST_ADMIN_URL: *** 392: SRQL_TEST_DATABASE_CA_CERT: 393: DOCKERHUB_USERNAME: *** 394: DOCKERHUB_TOKEN: *** 395: TEST_CNPG_DATABASE: serviceradar_web_ng_test 396: INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp 397: INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir 398: ##[endgroup] 399: ##[group]Run : install rustup if needed 400: ^[[36;1m: install rustup if needed^[[0m 401: ^[[36;1mif ! command -v rustup &>/dev/null; then^[[0m 402: ^[[36;1m curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail https://sh.rustup.rs | sh -s -- --default-toolchain none -y^[[0m 403: ^[[36;1m echo "$CARGO_HOME/bin" >> $GITHUB_PATH^[[0m ... 543: shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} 544: env: 545: BUILDBUDDY_ORG_API_KEY: *** 546: SRQL_TEST_DATABASE_URL: *** 547: SRQL_TEST_ADMIN_URL: *** 548: SRQL_TEST_DATABASE_CA_CERT: 549: DOCKERHUB_USERNAME: *** 550: DOCKERHUB_TOKEN: *** 551: TEST_CNPG_DATABASE: serviceradar_web_ng_test 552: INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp 553: INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir 554: CARGO_HOME: /home/runner/.cargo 555: CARGO_INCREMENTAL: 0 556: CARGO_TERM_COLOR: always 557: ##[endgroup] 558: ##[group]Run : work around spurious network errors in curl 8.0 559: ^[[36;1m: work around spurious network errors in curl 8.0^[[0m 560: ^[[36;1m# https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/timeout.20investigation^[[0m ... 611: SRQL_TEST_DATABASE_CA_CERT: 612: DOCKERHUB_USERNAME: *** 613: DOCKERHUB_TOKEN: *** 614: TEST_CNPG_DATABASE: serviceradar_web_ng_test 615: INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp 616: INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir 617: CARGO_HOME: /home/runner/.cargo 618: CARGO_INCREMENTAL: 0 619: CARGO_TERM_COLOR: always 620: ##[endgroup] 621: Attempting to download 1.x... 622: Acquiring v1.28.1 from https://github.com/bazelbuild/bazelisk/releases/download/v1.28.1/bazelisk-linux-amd64 623: Adding to the cache ... 624: Successfully cached bazelisk to /home/runner/_work/_tool/bazelisk/1.28.1/x64 625: Added bazelisk to the path 626: ##[warning]Failed to restore: Cache service responded with 400 627: Restored bazelisk cache dir @ /home/runner/.cache/bazelisk ... 693: env: 694: BUILDBUDDY_ORG_API_KEY: *** 695: SRQL_TEST_DATABASE_URL: *** 696: SRQL_TEST_ADMIN_URL: *** 697: SRQL_TEST_DATABASE_CA_CERT: 698: DOCKERHUB_USERNAME: *** 699: DOCKERHUB_TOKEN: *** 700: TEST_CNPG_DATABASE: serviceradar_web_ng_test 701: INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp 702: INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir 703: CARGO_HOME: /home/runner/.cargo 704: CARGO_INCREMENTAL: 0 705: CARGO_TERM_COLOR: always 706: ##[endgroup] 707: SRQL_TEST_DATABASE_CA_CERT secret must be configured to verify SRQL fixture TLS. 708: ##[error]Process completed with exit code 1. 709: Post job cleanup. 710: [command]/usr/bin/git version 711: git version 2.52.0 712: Temporarily overriding HOME='/home/runner/_work/_temp/9578a9d0-c61d-4d81-b12b-d7453b62094b' before making global git config changes 713: Adding repository directory to the temporary git global config as a safe directory 714: [command]/usr/bin/git config --global --add safe.directory /home/runner/_work/serviceradar/serviceradar 715: Removing SSH command configuration 716: [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand 717: [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :" 718: fatal: No url found for submodule path 'swift/FieldSurvey/LocalPackages/arrow-swift' in .gitmodules 719: ##[warning]The process '/usr/bin/git' failed with exit code 128 720: Cleaning up orphan processes ``` </details></td></tr></table>
qodo-code-review[bot] commented 2026-03-01 03:50:13 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2960#issuecomment-3979010774
Original created: 2026-03-01T03:50:13Z

PR Code Suggestions

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Add a catch-all to prevent crashes

Add a catch-all function clause to format_compact_number/1 that returns "0" for
non-numeric inputs to prevent potential FunctionClauseError crashes, restoring
the robust behavior of the previous format_number/1 function.

elixir/web-ng/lib/serviceradar_web_ng_web/live/analytics_live/index.ex [1009-1011]

 defp format_compact_number(n) when is_float(n), do: n |> trunc() |> format_compact_number()
 
 defp format_compact_number(n) when is_integer(n) do
+defp format_compact_number(_), do: "0"

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that removing the catch-all clause from the old format_number function introduces a regression, potentially causing crashes if non-numeric values are passed to format_compact_number.

Medium
General
Round floats before formatting

In format_compact_number/1, replace trunc() with round() when handling floats to
provide more intuitive rounding (e.g., 1.9K becomes "2K" instead of "1K").

elixir/web-ng/lib/serviceradar_web_ng_web/live/analytics_live/index.ex [1009]

-defp format_compact_number(n) when is_float(n), do: n |> trunc() |> format_compact_number()
+defp format_compact_number(n) when is_float(n), do: n |> round() |> format_compact_number()

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 4

__

Why: The suggestion proposes changing trunc to round for float formatting, which is a reasonable product/UI improvement, but it's a change in logic, not a bug fix, as the PR maintained the original trunc behavior.

Low
  • More
Imported GitHub PR comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2960#issuecomment-3979010774 Original created: 2026-03-01T03:50:13Z --- ## PR Code Suggestions ✨ <!-- c3939ec --> Explore these optional code suggestions: <table><thead><tr><td><strong>Category</strong></td><td align=left><strong>Suggestion&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </strong></td><td align=center><strong>Impact</strong></td></tr><tbody><tr><td rowspan=1>Possible issue</td> <td> <details><summary>Add a catch-all to prevent crashes</summary> ___ **Add a catch-all function clause to <code>format_compact_number/1</code> that returns "0" for <br>non-numeric inputs to prevent potential <code>FunctionClauseError</code> crashes, restoring <br>the robust behavior of the previous <code>format_number/1</code> function.** [elixir/web-ng/lib/serviceradar_web_ng_web/live/analytics_live/index.ex [1009-1011]](https://github.com/carverauto/serviceradar/pull/2960/files#diff-ee008fe2b55f4a8443281692cbfd8269f679236499246beb83a39fa497353ca6R1009-R1011) ```diff defp format_compact_number(n) when is_float(n), do: n |> trunc() |> format_compact_number() defp format_compact_number(n) when is_integer(n) do +defp format_compact_number(_), do: "0" ``` `[To ensure code accuracy, apply this suggestion manually]` <details><summary>Suggestion importance[1-10]: 8</summary> __ Why: The suggestion correctly identifies that removing the catch-all clause from the old `format_number` function introduces a regression, potentially causing crashes if non-numeric values are passed to `format_compact_number`. </details></details></td><td align=center>Medium </td></tr><tr><td rowspan=1>General</td> <td> <details><summary>Round floats before formatting</summary> ___ **In <code>format_compact_number/1</code>, replace <code>trunc()</code> with <code>round()</code> when handling floats to <br>provide more intuitive rounding (e.g., 1.9K becomes "2K" instead of "1K").** [elixir/web-ng/lib/serviceradar_web_ng_web/live/analytics_live/index.ex [1009]](https://github.com/carverauto/serviceradar/pull/2960/files#diff-ee008fe2b55f4a8443281692cbfd8269f679236499246beb83a39fa497353ca6R1009-R1009) ```diff -defp format_compact_number(n) when is_float(n), do: n |> trunc() |> format_compact_number() +defp format_compact_number(n) when is_float(n), do: n |> round() |> format_compact_number() ``` `[To ensure code accuracy, apply this suggestion manually]` <details><summary>Suggestion importance[1-10]: 4</summary> __ Why: The suggestion proposes changing `trunc` to `round` for float formatting, which is a reasonable product/UI improvement, but it's a change in logic, not a bug fix, as the PR maintained the original `trunc` behavior. </details></details></td><td align=center>Low </td></tr> <tr><td align="center" colspan="2"> - [ ] More <!-- /improve --more_suggestions=true --> </td><td></td></tr></tbody></table>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
carverauto/serviceradar!2998
No description provided.