2248 feat network sweeper UI #2652
No reviewers
Labels
No labels
1week
2weeks
Failed compliance check
IP cameras
NATS
Possible security concern
Review effort 1/5
Review effort 2/5
Review effort 3/5
Review effort 4/5
Review effort 5/5
UI
aardvark
accessibility
amd64
api
arm64
auth
back-end
bgp
blog
bug
build
checkers
ci-cd
cleanup
cnpg
codex
core
dependencies
device-management
documentation
duplicate
dusk
ebpf
enhancement
eta 1d
eta 1hr
eta 3d
eta 3hr
feature
fieldsurvey
github_actions
go
good first issue
help wanted
invalid
javascript
k8s
log-collector
mapper
mtr
needs-triage
netflow
network-sweep
observability
oracle
otel
plug-in
proton
python
question
reddit
redhat
research
rperf
rperf-checker
rust
sdk
security
serviceradar-agent
serviceradar-agent-gateway
serviceradar-web
serviceradar-web-ng
siem
snmp
sysmon
topology
ubiquiti
wasm
wontfix
zen-engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
carverauto/serviceradar!2652
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "refs/pull/2652/head"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Imported from GitHub pull request.
Original GitHub pull request: #2263
Original author: @mfreeman451
Original URL: https://github.com/carverauto/serviceradar/pull/2263
Original created: 2026-01-12T03:05:50Z
Original updated: 2026-01-12T05:17:55Z
Original head: carverauto/serviceradar:2248-feat-network-sweeper-ui
Original base: staging
Original merged: 2026-01-12T05:16:38Z by @mfreeman451
User description
IMPORTANT: Please sign the Developer Certificate of Origin
Thank you for your contribution to ServiceRadar. Please note, when contributing, the developer must include
a DCO sign-off statement indicating the DCO acceptance in one commit message. Here
is an example DCO Signed-off-by line in a commit message:
Describe your changes
Issue ticket number and link
Code checklist before requesting a review
PR Type
Enhancement, Tests
Description
Network Sweeper UI Implementation: Added comprehensive LiveView interface for managing network sweep configuration with three main tabs (Sweep Groups, Scanner Profiles, Active Scans), dynamic criteria builder supporting 20+ device attributes, and real-time monitoring of active scans with progress tracking and performance metrics
Sweep Jobs Domain: Created complete sweep job management system including
SweepGroup,SweepProfile,SweepGroupExecution, andSweepHostResultAsh resources with scheduling, device targeting via DSL, and execution lifecycle trackingDevice Targeting DSL: Implemented flexible criteria operators (eq, neq, in, contains, in_cidr, has_any, etc.) for device filtering with CIDR/IP range matching and tag support
Sweep Results Ingestion: Added batch processing pipeline for ingesting sweep results, updating device inventory, creating unknown devices, and broadcasting real-time progress events
Agent Configuration Management: Created pluggable configuration compilation system with
ConfigTemplate,ConfigInstance, andConfigVersionresources, ETS-based caching, and NATS-based invalidation eventsSweep Configuration Compiler: Implemented compiler transforming
SweepGroupandSweepProfileinto agent-consumable format with deterministic SHA256 hashing and device criteria resolutionMonitoring and Maintenance: Added
SweepMonitorWorkerfor detecting missed executions,SweepDataCleanupWorkerfor periodic data cleanup, and observability rule seeding for sweep event monitoringDevice Enhancements: Added bulk device selection UI with checkboxes, bulk tag editing modal, quick filter buttons, and sweep status section on device detail pages
Result Buffering: Implemented in-memory buffer in agent gateway for result payloads during core outages with configurable size and flush intervals
Database Schema: Created tables for sweep profiles, groups, executions, host results, and agent configuration versioning with appropriate indexes and foreign key relationships
Comprehensive Testing: Added unit tests for target criteria DSL, integration tests for sweep config distribution and results ingestion, and LiveView tests for UI components
Diagram Walkthrough
File Walkthrough
35 files
index.ex
Network Sweeper UI LiveView with Criteria Builderweb-ng/lib/serviceradar_web_ng_web/live/settings/networks_live/index.ex
three main tabs: Sweep Groups, Scanner Profiles, and Active Scans
dynamic criteria builder supporting 20+ device attributes and multiple
operators
processing, and scanner performance metrics (packets, retries, drop
rates)
completed, failed) with PubSub subscriptions for real-time updates
sweep_results_ingestor.ex
Sweep Results Ingestion and Device Inventory Updateelixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_results_ingestor.ex
with batch processing (500 records per batch)
availability status based on ICMP/TCP scan results
SweepHostResultrecords and broadcasts real-time progressevents after each batch
with proper error handling
sweep_compiler.ex
Sweep Configuration Compiler for Agent Deploymentelixir/serviceradar_core/lib/serviceradar/agent_config/compilers/sweep_compiler.ex
SweepGroupandSweepProfileAshresources into agent-consumable configuration format
criteria), ports, modes, and settings with deterministic SHA256
hashing
settings with group-level overrides
index.ex
Bulk device selection and tag editing UI implementationweb-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex
select-all functionality
multiple devices
sources
MapSetwithsupport for selecting all matching devices
query integration
target_criteria.ex
Device targeting DSL with flexible criteria operatorselixir/serviceradar_core/lib/serviceradar/sweep_jobs/target_criteria.ex
operators (eq, neq, in, contains, in_cidr, has_any, etc.)
matching
operations
sweep_group.ex
Sweep group resource with scheduling and targetingelixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_group.ex
SweepGroupAsh resource for user-configured network sweepgroups
partitions and agents
target_criteriaDSL andstatic_targetslists
recording executions
operator)
show.ex
Device detail page sweep status sectionweb-ng/lib/serviceradar_web_ng_web/live/device_live/show.ex
for a device
integration
and response times
actor/tenant context
results
sweep_group_execution.ex
Sweep execution tracking resourceelixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_group_execution.ex
SweepGroupExecutionAsh resource for tracking sweep executionlifecycle
with timing tracking
automatic duration calculation
recency
sweep.ex
Sweep event processor with inventory updateselixir/serviceradar_core/lib/serviceradar/event_writer/processors/sweep.ex
SweepResultsIngestorduring sweeps
sweep messages
is unavailable
sweep_monitor_worker.ex
Sweep execution monitoring workerelixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_monitor_worker.ex
tenants
expected execution time
logs.internal.sweepfor missed sweepsduration
tolerance
sweep_host_result.ex
Add SweepHostResult resource for sweep execution trackingelixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_host_result.ex
executions
details
status
status
config_cache.ex
Add ETS-based configuration cache with TTL and cleanupelixir/serviceradar_core/lib/serviceradar/agent_config/config_cache.ex
entries
config_instance.ex
Add ConfigInstance resource for agent configuration storageelixir/serviceradar_core/lib/serviceradar/agent_config/config_instance.ex
agents
config_server.ex
Add ConfigServer for config compilation orchestrationelixir/serviceradar_core/lib/serviceradar/agent_config/config_server.ex
change detection
sweep_profile.ex
Add SweepProfile resource for reusable scanner configurationselixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_profile.ex
concurrency)
sweep_data_cleanup_worker.ex
Add worker for cleanup of old sweep execution dataelixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_data_cleanup_worker.ex
SweepHostResultrecords older than 7 days (configurable)SweepGroupExecutionrecords older than 30days (configurable)
sweep_pubsub.ex
Add PubSub broadcaster for sweep execution updateselixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_pubsub.ex
subscriptions
failure
rule_seeder.ex
Add seeder for default observability ruleselixir/serviceradar_core/lib/serviceradar/observability/rule_seeder.ex
LogPromotionRulefor missed sweep detectionStatefulAlertRulefor repeated missed sweepsstatus_processor.ex
Add result buffering and telemetry metrics to status processorelixir/serviceradar_agent_gateway/lib/serviceradar_agent_gateway/status_processor.ex
forward/2function with configurable buffering and metricsemission
tracking
config_template.ex
Add ConfigTemplate resource for reusable config schemaselixir/serviceradar_core/lib/serviceradar/agent_config/config_template.ex
config_version.ex
Add ConfigVersion resource for configuration audit historyelixir/serviceradar_core/lib/serviceradar/agent_config/config_version.ex
config_publisher.ex
Add publisher for config invalidation events to NATSelixir/serviceradar_core/lib/serviceradar/agent_config/config_publisher.ex
status_buffer.ex
Add in-memory buffer for result payloads during outageselixir/serviceradar_agent_gateway/lib/serviceradar_agent_gateway/status_buffer.ex
interval
agent_config_generator.ex
Integrate sweep configuration into agent payload generationelixir/serviceradar_core/lib/serviceradar/edge/agent_config_generator.ex
load_sweep_config/2function to load compiled sweep configurationsConfigServercompiler.ex
Add Compiler behaviour for pluggable config compilationelixir/serviceradar_core/lib/serviceradar/agent_config/compiler.ex
compile/4,config_type/0, andsource_resources/0content_hash/1utility for SHA256 hashing of configstemplate_seeder.ex
Add sweep monitoring templates and alert ruleselixir/serviceradar_core/lib/serviceradar/observability/template_seeder.ex
promote_missed_sweepslog promotion rule for sweep eventsrepeated_missed_sweepsstateful alert rule for repeated missedexecutions
create_version_history.ex
Add change for creating config version historyelixir/serviceradar_core/lib/serviceradar/agent_config/changes/create_version_history.ex
monitoring.pb.ex
Extend sweep completion status with execution tracking and scannerstatselixir/serviceradar_core/lib/serviceradar/proto/monitoring.pb.ex
execution_idandsweep_group_idfields toSweepCompletionStatusSweepScannerStatsmessage with packet, ring, retry, and portmetrics
scanner_statsfield inSweepCompletionStatusfor detailedstatistics
config_invalidation_notifier.ex
Add notifier for config resource change invalidationelixir/serviceradar_core/lib/serviceradar/agent_config/config_invalidation_notifier.ex
ConfigInstanceandConfigTemplateresource changesConfigPublisherfor cluster-widepropagation
application.ex
Add config and rule seeding infrastructure to applicationelixir/serviceradar_core/lib/serviceradar/application.ex
RuleSeederchild process for seeding default observability rulesConfigCacheGenServer for ETS-based config cachingConfigServerGenServer for config compilation orchestrationsweep_jobs.ex
Add SweepJobs domain for sweep configuration managementelixir/serviceradar_core/lib/serviceradar/sweep_jobs.ex
SweepProfile,SweepGroup,SweepGroupExecution, andSweepHostResultresourcessync_ingestor.ex
Add tags field support to device sync ingestionelixir/serviceradar_core/lib/serviceradar/inventory/sync_ingestor.ex
tagsfield extraction from sync updatestagsas empty map in device creationagent_config.ex
Add AgentConfig domain for configuration managementelixir/serviceradar_core/lib/serviceradar/agent_config.ex
ConfigTemplate,ConfigInstance, andConfigVersionresourcesdevice.ex
Add tags attribute to Device resourceelixir/serviceradar_core/lib/serviceradar/inventory/device.ex
tagsattribute as a map for user-defined labelstagsin create and update actionsquery_builder_components.ex
Add query builder UI componentsweb-ng/lib/serviceradar_web_ng_web/components/query_builder_components.ex
query_builder_pill/1component for displaying querycriteria
criteria
5 files
zen_rule_seeder.ex
Add Passthrough Zen Rule for Sweep Logselixir/serviceradar_core/lib/serviceradar/observability/zen_rule_seeder.ex
logs.internal.sweep100
20260111200000_add_sweep_jobs_tables.exs
Database schema for sweep jobs domainelixir/serviceradar_core/priv/repo/tenant_migrations/20260111200000_add_sweep_jobs_tables.exs
sweep_profiles,sweep_groups,sweep_group_executions,sweep_host_resultsexecution tracking
results
settings
20260111194010_add_agent_config_tables.exs
Agent configuration management database schemaelixir/serviceradar_core/priv/repo/tenant_migrations/20260111194010_add_agent_config_tables.exs
agent_config_versions,agent_config_templates,agent_config_instancestracking
references
config.exs
Configure Ash domains and Oban workers for sweep jobselixir/serviceradar_core/config/config.exs
ServiceRadar.AgentConfigandServiceRadar.SweepJobsto Ash domainsSweepDataCleanupWorkercron job (daily at 3 AM)SweepMonitorWorkercron job (every 5 minutes)20260111210000_add_sweep_cleanup_indexes.exs
Add database indexes for sweep data cleanupelixir/serviceradar_core/priv/repo/tenant_migrations/20260111210000_add_sweep_cleanup_indexes.exs
sweep_host_results.inserted_atfor cleanup queriessweep_group_executions.started_atforcompleted/failed executions
5 files
sweep_compiler_test.exs
Sweep compiler and target criteria test suiteelixir/serviceradar_core/test/serviceradar/sweep_jobs/sweep_compiler_test.exs
consistency
TargetCriteriaDSL operators (eq, neq, contains, in_cidr,has_any, etc.)
and types
validation
sweep_results_flow_e2e_test.exs
Add E2E test for sweep results ingestion and device updateselixir/serviceradar_core/test/serviceradar/sweep_jobs/sweep_results_flow_e2e_test.exs
target_criteria_test.exs
Add unit tests for device targeting criteria DSLelixir/serviceradar_core/test/serviceradar/sweep_jobs/target_criteria_test.exs
TargetCriteriamodule covering tag operatorssweep_config_distribution_integration_test.exs
Add integration test for sweep config distributionelixir/serviceradar_core/test/serviceradar/edge/sweep_config_distribution_integration_test.exs
config
networks_live_test.exs
Add tests for network sweep configuration UIweb-ng/test/serviceradar_web_ng_web/live/settings/networks_live_test.exs
2 files
srql_components.ex
Component naming refactor for query builderweb-ng/lib/serviceradar_web_ng_web/components/srql_components.ex
srql_builder_pillcomponent calls toquery_builder_pillthroughout the file
QueryBuilderComponentsmoduleshow.ex
Reformat agent show view task definitionsweb-ng/lib/serviceradar_web_ng_web/live/agent_live/show.ex
63 files
Imported GitHub PR comment.
Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2263#issuecomment-3736732746
Original created: 2026-01-12T03:07:17Z
PR Compliance Guide 🔍
Below is a summary of compliance checks for this PR:
Atom exhaustion
Description: User-controlled
tabvalues are converted withString.to_atom/1, enabling unbounded atomcreation (a VM-wide DoS vector) if an attacker can send arbitrary tab strings.
index.ex [230-232]
Referred Code
Authorization bypass
Description: Multiple Ash reads/gets are executed with
authorize?: false, which can bypassauthorization checks and allow unauthorized users to read sweep groups/profiles/executions
depending on routing/access controls.
index.ex [1900-1947]
Referred Code
Query injection
Description: SRQL is constructed from user-provided criteria and
escape_srql_value/1only quotes spaces(not other SRQL metacharacters), making SRQL query manipulation/injection plausible (e.g.,
injecting operators/parentheses/negations) if SRQL parsing permits it.
index.ex [2216-2353]
Referred Code
🎫 #2248
settings.
discovery_sources),partition, etc., so jobs can apply to matching devices dynamically.
profiles) for tenant users/operators.
the entire inventory.
ports/protocols to check.
selected partition can deliver config over gRPC and run the sweep.
gRPC for config.
(tenant-aware via mTLS), agent-gateway forwards to core (RPC/chunking/streaming), and core
processes results (DIRE) updating device inventory (e.g.,
ocsf_devices) and enrichingavailability.
Codebase context is not defined
Follow the guide to enable codebase context checks.
Generic: Meaningful Naming and Self-Documenting Code
Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting
Status: Passed
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
Generic: Robust Error Handling and Edge Case Management
Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation
Status: 🏷️
Silent error handling: Data-load failures from
Ash.read/2andAsh.get/4are silently converted into empty listsor
nilwithout logging or actionable context, hindering production debugging.Referred Code
Generic: Security-First Input Validation and Data Handling
Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities
Status: 🏷️
Authorization bypass: Multiple reads/gets for sweep configuration and executions explicitly set
authorize?:false, bypassing authorization checks for user-accessible LiveView data operations.Referred Code
Generic: Comprehensive Audit Trails
Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.
Status: 🏷️
Missing audit logging: Critical configuration actions (create/update/delete/toggle of sweep groups and profiles)
are performed without any explicit audit log entries that capture actor, action, and
outcome.
Referred Code
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: 🏷️
Unstructured logging: New log statements emit unstructured string logs (and include identifiers like
tenant_slug) rather than structured fields, requiring verification against theproject's logging standards and sensitivity classification.
Referred Code
Compliance status legend
🟢 - Fully Compliant🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label
Imported GitHub PR review comment.
Original author: @github-advanced-security[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2263#discussion_r2680740763
Original created: 2026-01-12T03:07:49Z
Original path: pkg/agent/server.go
Original line: 914
Size computation for allocation may overflow
This operation, which is used in an allocation, involves a potentially large value and might overflow.
Show more details
Imported GitHub PR review comment.
Original author: @github-advanced-security[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2263#discussion_r2680740764
Original created: 2026-01-12T03:07:49Z
Original path: pkg/agent/server.go
Original line: 983
Size computation for allocation may overflow
This operation, which is used in an allocation, involves a potentially large value and might overflow.
Show more details
Imported GitHub PR comment.
Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2263#issuecomment-3736735024
Original created: 2026-01-12T03:09:12Z
PR Code Suggestions ✨
Latest suggestions up to
d7444e5Fix misplaced module endings
Correct a syntax error by moving the
get_sweep_tenant/1function inside theServiceRadarWebNGWeb.DeviceLive.Showmodule and removing a misplacedendkeyword.
web-ng/lib/serviceradar_web_ng_web/live/device_live/show.ex [1862-1868]
[To ensure code accuracy, apply this suggestion manually]Suggestion importance[1-10]: 9
__
Why: The suggestion correctly identifies a critical syntax error where a misplaced
endkeyword would cause a compilation failure by definingget_sweep_tenant/1outside theServiceRadarWebNGWeb.DeviceLive.Showmodule.Fix mismatched block endings
Remove the extra
endfrom theemit_forward_metrics/4function to fix a syntaxerror that prevents compilation.
elixir/serviceradar_agent_gateway/lib/serviceradar_agent_gateway/status_processor.ex [255-278]
Suggestion importance[1-10]: 9
__
Why: The suggestion correctly identifies a syntax error (an extra
end) that would prevent the code from compiling, which is a critical issue.Add pagination loop termination guard
Add guards to the
fetch_all_uids_paginatedfunction to prevent infiniterecursion by checking if the
next_cursorhas changed and if the last fetchreturned any results.
web-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex [1218-1224]
[To ensure code accuracy, apply this suggestion manually]Suggestion importance[1-10]: 8
__
Why: This suggestion addresses a critical potential issue where a faulty API response during pagination could cause an infinite loop, hanging the LiveView process. Adding checks for an empty result set and a non-changing cursor makes the pagination logic significantly more resilient.
Ensure safe JSONB parameter casting
Explicitly encode the
new_tagsmap to a JSON string before passing it to the SQLfragmentto ensure reliable casting tojsonbin the database.web-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex [281-291]
[To ensure code accuracy, apply this suggestion manually]Suggestion importance[1-10]: 7
__
Why: The suggestion correctly points out that implicit casting of a map to
jsonbcan be unreliable. Explicitly encoding the map to a JSON string withJason.encode!makes the database operation more robust and less prone to driver-specific or version-specific issues.Cap stored port list size
Limit the number of
open_portsstored in the database to a reasonable maximum(e.g., 1024) to prevent performance issues and database bloat.
elixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_results_ingestor.ex [329-348]
Suggestion importance[1-10]: 7
__
Why: This is a valuable performance and scalability improvement, preventing potential database bloat and slow queries by capping the number of stored open ports, which could otherwise be very large.
Prevent tight-loop batch flushing
In the
handle_info(:flush, ...)function, change the0ms delay to a smallpositive value (e.g.,
10) when scheduling the next flush to prevent a tight loopand improve process responsiveness.
elixir/serviceradar_agent_gateway/lib/serviceradar_agent_gateway/status_buffer.ex [79-83]
Suggestion importance[1-10]: 7
__
Why: The suggestion correctly identifies a potential for a tight loop that could starve the
GenServerprocess. Introducing a small delay is a good practice to ensure the process remains responsive.Use consistent progress map keys
Refactor the key access for the
@execution_progressmap into a variable toimprove readability and ensure consistent keying.
web-ng/lib/serviceradar_web_ng_web/live/settings/networks_live/index.ex [952-954]
[To ensure code accuracy, apply this suggestion manually]Suggestion importance[1-10]: 2
__
Why: The suggestion correctly identifies a potential key mismatch but the
existing_codealready attempts to handle it withexecution.execution_id || execution.id. The proposed change only refactors this into a variable, offering a minor readability improvement without altering the logic.Prefer specific records deterministically
Modify the
:for_agentread action to deterministically select the most specificconfiguration by adding sorting and a limit, ensuring an agent-specific config
is preferred over a partition-default one.
elixir/serviceradar_core/lib/serviceradar/agent_config/config_instance.ex [69-79]
Suggestion importance[1-10]: 9
__
Why: This suggestion identifies a critical logical flaw where a non-deterministic query could lead to an agent receiving a generic configuration instead of its specific one, which could cause incorrect behavior.
Support IPv6 CIDR matching
Add support for IPv6 CIDR matching in
ip_matches_cidr?/3to prevent incorrecttargeting for IPv6 devices.
elixir/serviceradar_core/lib/serviceradar/sweep_jobs/target_criteria.ex [320-329]
Suggestion importance[1-10]: 8
__
Why: The suggestion identifies a significant bug where IPv6 addresses would silently fail to match CIDR criteria, leading to incorrect sweep targeting.
Parse SRQL count result
In
get_matching_device_count, handle cases where the SRQL count is a string orfloat, not just an integer, by parsing it to prevent incorrect
nilresults.web-ng/lib/serviceradar_web_ng_web/live/settings/networks_live/index.ex [2294-2309]
[To ensure code accuracy, apply this suggestion manually]Suggestion importance[1-10]: 7
__
Why: This suggestion correctly points out that relying on the
countbeing an integer is too strict, as JSON decoding can produce strings or floats. The proposed change makes the function more robust by handling these other valid numeric types.Stop parsing tenant IDs
Use the
tenant_idvariable directly for PubSub broadcasts instead of parsing itfrom the
tenant_schemastring.elixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_results_ingestor.ex [102-103]
Suggestion importance[1-10]: 7
__
Why: The suggestion correctly points out that parsing the schema name to get the
tenant_idis brittle and a less robust approach than using the already availabletenant_idvariable.Use safe Ecto table prefixes
Refactor the Ecto query to use the
prefixoption for dynamic schemas instead ofstring interpolation, and use
table/1to specify the table name.elixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_data_cleanup_worker.ex [118-143]
[To ensure code accuracy, apply this suggestion manually]Suggestion importance[1-10]: 7
__
Why: The suggestion correctly identifies an unsafe and non-standard Ecto query pattern and proposes using the proper
prefixoption, which improves code robustness, security, and adherence to best practices.Reset bulk selection state
In the
clear_selectionevent handler, reset theselect_all_matchingandtotal_matching_countassigns, in addition toselected_devices, to ensure thebulk selection state is fully cleared.
web-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex [159-161]
[To ensure code accuracy, apply this suggestion manually]Suggestion importance[1-10]: 6
__
Why: The suggestion correctly identifies a state management bug where clearing the selection does not reset the "select all" state, leading to an inconsistent UI for the new bulk actions feature.
Previous suggestions
✅ Suggestions up to commit
8f1186cPrevent runtime JSONB cast failures
Remove the explicit
::jsonbcast on the^new_tagsparameter within thefragment.The database layer already handles map encoding, and this cast could cause
runtime errors.
web-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex [271-276]
Suggestion importance[1-10]: 8
__
Why: This suggestion correctly identifies a potential runtime error by removing an explicit
jsonbcast on a parameter that is already a map, making the database operation more robust.✅
Resolve tenant correctly for historySuggestion Impact:
The change stopped reading tenant_id from changeset attributes and instead uses the tenant from the changeset context (changeset.tenant). It also adds a guard that errors when tenant is nil and passes the resolved tenant into version creation, aligning with the goal of correctly resolving tenant for history creation.code diff:
Correctly resolve the
tenant_idby reading it from the existing record data orthe context, instead of from the changeset attributes where it may be missing
during an update.
elixir/serviceradar_core/lib/serviceradar/agent_config/changes/create_version_history.ex [26-31]
[Suggestion processed]Suggestion importance[1-10]: 8
__
Why: This is a valid and important bug fix that prevents potential data corruption or loss of audit history in a multi-tenant system by ensuring the
tenant_idis correctly resolved.✅
Fix progress lookup key mismatchSuggestion Impact:
Updated the progress lookup to use `execution.execution_id || execution.id` instead of `Map.get(execution, :execution_id) || execution.id`, aligning the key access with the expected `execution_id` field usage.code diff:
Correct the progress lookup key to consistently use
execution.execution_id. Thecurrent fallback to
execution.idmay cause progress updates to fail if theidand
execution_iddiffer.web-ng/lib/serviceradar_web_ng_web/live/settings/networks_live/index.ex [918-920]
Suggestion importance[1-10]: 7
__
Why: This is a valid concern as the progress map is keyed by
execution_id, and falling back toexecution.idwould fail if they differ, preventing real-time progress updates.✅
Prevent runtime crashes on map accessSuggestion Impact:
The code mapping device records to canonical_device_id was changed from dot-access to Map.get(&1, :canonical_device_id), matching the suggestion and preventing potential KeyError crashes.code diff:
Replace unsafe dot-access on a map with
Map.get/2to safely retrieve the:canonical_device_idand prevent potential runtime crashes if the key is absent.elixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_results_ingestor.ex [394-400]
[Suggestion processed]Suggestion importance[1-10]: 7
__
Why: This suggestion correctly identifies that using dot-access (
&1.canonical_device_id) is unsafe for maps and can cause runtime errors if the key is missing, proposing a switch toMap.get/2which improves the code's robustness.✅
Emit metrics for all resultsSuggestion Impact:
Changed emit_forward_metrics/4 to gate telemetry emission with should_buffer?(status) instead of checking only status[:source] == "results", ensuring metrics are emitted for both string and atom sources.code diff:
Update the condition for emitting metrics to match the buffering logic, ensuring
metrics are captured for both string and atom versions of the
resultssource.elixir/serviceradar_agent_gateway/lib/serviceradar_agent_gateway/status_processor.ex [251-277]
[Suggestion processed]Suggestion importance[1-10]: 7
__
Why: The suggestion correctly identifies an inconsistency where telemetry metrics would be missed if
status[:source]is an atom, improving observability by ensuring all relevant events are tracked.Stabilize count return value
In
get_total_matching_count, return0instead ofnilon query failure. Thisensures type stability and prevents confusing UI messages like "All nil matching
device(s) selected".
web-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex [1183-1185]
Suggestion importance[1-10]: 6
__
Why: The suggestion correctly points out that returning
nilcan lead to confusing UI output and makes a good case for returning0to maintain type stability and improve user experience.✅
Avoid ETS race crashSuggestion Impact:
The commit addresses the same general concern (ETS table not existing / being terminated) by adding :ets.whereis(@table_name) == :undefined guards before performing ETS operations (insert/delete/select_delete/info). It does not implement the specific suggested try/rescue around :ets.lookup/2, but it applies a related defensive pattern to avoid crashes when the table is missing.code diff:
Prevent a potential crash from a race condition by wrapping the
:ets.lookup/2call in a
try/rescueblock to handle cases where the ETS table is terminatedunexpectedly.
elixir/serviceradar_core/lib/serviceradar/agent_config/config_cache.ex [46-64]
[Suggestion processed]Suggestion importance[1-10]: 6
__
Why: The suggestion correctly identifies a race condition with ETS table lookups and proposes a valid fix to improve the code's resilience against crashes, making the cache access more robust.
Chunk large bulk updates
Refactor
update_tags_for_uidsto process updates in chunks. This preventspotential database errors when applying bulk actions to a large number of
selected devices.
web-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex [258-297]
Suggestion importance[1-10]: 8
__
Why: The suggestion correctly identifies a potential scalability issue with large bulk updates and proposes a robust solution using chunking to prevent database errors, which is a critical fix for reliability.
Avoid infinite cleanup batching loops
Add a case to handle when
Repo.delete_all/1deletes zero records to prevent apotential infinite loop in the
do_cleanup_batchfunction.elixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_data_cleanup_worker.ex [145-162]
Suggestion importance[1-10]: 8
__
Why: This suggestion correctly identifies and fixes a potential infinite loop in the cleanup worker, which is a significant robustness improvement.
✅
Prevent crashes from bad typesSuggestion Impact:
The patch replaces the direct div/2 call with logic that validates/parses the raw response time value into an integer (accepting integers and integer-strings) before dividing, otherwise returning nil. This prevents div/2 crashes on bad types, aligning with the suggestion’s goal (though it does not add explicit float handling).code diff:
Add type checking before calling
div/2onresponse_time_nsto handle potentialfloat or string values and prevent crashes during result ingestion.
elixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_results_ingestor.ex [304-305]
[Suggestion processed]Suggestion importance[1-10]: 7
__
Why: The suggestion correctly identifies that
div/2will crash with non-integer inputs, and the proposed change adds robust type checking to prevent ingestion failures from malformed data.✅
Include tenant id in actorSuggestion Impact:
The commit updates the fallback "system" actor map to include tenant_id: Scope.tenant_id(scope), matching the suggestion to ensure tenant-aware authorization.code diff:
Add the
tenant_idfrom the scope to the fallback "system" actor inbuild_sweep_actor/1to ensure correct authorization behavior.web-ng/lib/serviceradar_web_ng_web/live/device_live/show.ex [1869-1882]
Suggestion importance[1-10]: 7
__
Why: The suggestion correctly points out that the fallback actor is missing a
tenant_id, which is important for authorization, and the proposed change correctly adds it.✅
Keep selection mode consistentSuggestion Impact:
The toggle_select_all handler was updated to assign selected_devices and also reset select_all_matching to false and total_matching_count to nil, matching the suggested UX consistency improvement.code diff:
Update the
toggle_select_allevent handler to reset theselect_all_matchingstate. This ensures that manually toggling the page selection provides clear and
consistent UI feedback.
web-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex [132-153]
Suggestion importance[1-10]: 6
__
Why: This is a valid UX improvement that makes the bulk selection feature more consistent and less confusing for the user, aligning its behavior with
toggle_device_select.✅
Enforce tenant context for readsSuggestion Impact:
The commit refactored load_sweep_results/2 to call get_sweep_tenant/1 inside a case expression, returning nil when tenant is nil and only building/executing the Ash query when a tenant is present, matching the suggested multitenancy guard.code diff:
Add a guard to ensure a
tenantis present before executing the Ash query inload_sweep_results/2to prevent potential multitenancy bypass.web-ng/lib/serviceradar_web_ng_web/live/device_live/show.ex [1846-1865]
Suggestion importance[1-10]: 8
__
Why: This is a valid security concern, as passing a
niltenant to an Ash query could bypass multitenancy checks, and the proposed change correctly adds a guard to prevent this.✅
Avoid quadratic list concatenationSuggestion Impact:
The commit changed the accumulator updates from `uids ++ acc` to `[uids | acc]` in both pagination branches and updated `finalize_uid_acc/1` to `List.flatten()` after reversing, matching the suggested performance optimization.code diff:
Optimize the
fetch_all_uids_paginatedfunction by prepending UIDs to theaccumulator instead of using list concatenation. This improves performance and
reduces memory usage when fetching all matching device UIDs.
web-ng/lib/serviceradar_web_ng_web/live/device_live/index.ex [1193-1232]
Suggestion importance[1-10]: 7
__
Why: This is a valid performance optimization that avoids quadratic complexity in list concatenation during pagination, which is important for the "select all" feature to work efficiently with large datasets.
✅ Suggestions up to commit
8f1186cValidate fields/operators before SRQL
Harden the SRQL generation by whitelisting
fieldandoperatorvalues incriteria_clause/2to prevent potential injection vulnerabilities.web-ng/lib/serviceradar_web_ng_web/live/settings/networks_live/index.ex [2280-2296]
Suggestion importance[1-10]: 9
__
Why: This is a critical security hardening suggestion that prevents potential SRQL injection by validating user-provided
fieldandoperatorvalues against a known list before constructing the query.✅
Normalize ports before database insertSuggestion Impact:
The commit implements normalization of the open ports field by introducing an open_ports_raw variable and transforming it via List.wrap, Integer.parse for strings, rejecting nils, filtering to valid port range, and applying uniq/sort prior to insertion, preventing batch insert failures from bad data.code diff:
Normalize the
open_portslist by converting all values to integers and filteringout invalid entries before database insertion to prevent batch insertion
failures.
elixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_results_ingestor.ex [307-308]
Suggestion importance[1-10]: 8
__
Why: This suggestion correctly identifies a potential data type mismatch that could cause
Repo.insert_allto fail for an entire batch, improving the robustness of the data ingestion pipeline.✅
Prevent unbounded flush loopingSuggestion Impact:
The commit changed handle_info(:flush) to call flush_queue/2 once, then either immediately re-sends :flush when more items remain or schedules the normal interval flush otherwise. It also removed the recursive flush_all_batches/2 helper, eliminating unbounded recursion in a single handle_info call.code diff:
Modify the flush logic to process only one batch per
:flushevent and schedule asubsequent flush if more items remain, instead of using unbounded recursion
within a single
handle_infocall.elixir/serviceradar_agent_gateway/lib/serviceradar_agent_gateway/status_buffer.ex [76-80]
Suggestion importance[1-10]: 8
__
Why: This suggestion correctly identifies a GenServer anti-pattern that could block the process and cause timeouts, and the proposed fix is the standard, correct way to handle batch work without compromising responsiveness.
✅
Prevent response-time parsing crashesSuggestion Impact:
The commit implemented defensive parsing for icmp response time by introducing a raw value, converting strings via Integer.parse/1, and only performing div/2 when an integer is present, preventing potential runtime crashes. (It also added similar defensive parsing for open ports.)code diff:
Defensively parse the
response_time_nsvalue, handling non-integer types likestrings, to prevent crashes during the division operation and ensure batch
processing is not aborted.
elixir/serviceradar_core/lib/serviceradar/sweep_jobs/sweep_results_ingestor.ex [303-305]
Suggestion importance[1-10]: 7
__
Why: The suggestion correctly identifies that
div/2will crash ifresponse_time_nsis not an integer, which is plausible for JSON data, and this would halt the entire batch processing.✅
Guard ETS access when unavailableSuggestion Impact:
The commit wraps all the specified public ETS access functions (put, invalidate, invalidate_tenant, invalidate_key, clear_all, stats) with an :ets.whereis(@table_name) == :undefined check, returning :ok (or zeroed stats) when the table is missing—matching the suggested robustness fix.code diff:
Imported GitHub PR comment.
Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2263#issuecomment-3736796432
Original created: 2026-01-12T03:57:05Z
Persistent suggestions updated to latest commit
1964dc9Imported GitHub PR comment.
Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2263#issuecomment-3736822791
Original created: 2026-01-12T04:15:37Z
Persistent suggestions updated to latest commit
8f1186c