Skip to content

Next release - #1693

Merged
jokob-sk merged 2 commits into
mainfrom
next_release
Jul 1, 2026
Merged

Next release#1693
jokob-sk merged 2 commits into
mainfrom
next_release

Conversation

@jokob-sk

@jokob-sk jokob-sk commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added new workflow condition operators for negative matching, including “is not” and “does not contain.”
    • Workflow conditions can now combine multiple checks, helping target devices more precisely.
  • Bug Fixes

    • Improved device selection so workflows can exclude the triggering device when matching on shared IP addresses.
  • Documentation

    • Updated workflow examples to explain the new matching options and device-archiving behavior.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c08dc1a8-ba08-4d8c-b8bf-3424a417df23

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
📝 Walkthrough

Walkthrough

This PR adds not_equals and not_contains operators to the workflow condition system. Changes span Condition.evaluate, DeviceInstance.queryByConditions SQL clause construction, the UI operator dropdown, new backend unit tests, and updated workflow documentation examples demonstrating device exclusion via devMac not_equals.

Changes

New operator support

Layer / File(s) Summary
Condition evaluation and query logic
server/workflows/conditions.py, server/models/device_instance.py
Condition.evaluate adds not_equals and not_contains branches; queryByConditions docstring and SQL clause builder add != and NOT LIKE handling for the new operators.
UI operator dropdown
front/workflowsCore.php
operatorTypes array expanded to include not_equals and not_contains alongside existing options.
Tests and documentation for new operators
test/backend/test_workflows.py, docs/WORKFLOW_EXAMPLES.md
New unit tests cover not_equals, not_contains, and combined conditions; Example 4 documentation updated to use devMac not_equals to exclude the triggering device from archival.

Sequence Diagram(s)

No sequence diagram generated; the changes are operator additions to existing evaluation/query logic without new multi-component interaction flows.

Possibly related PRs

  • netalertx/NetAlertX#1675: Introduces DeviceInstance.queryByConditions with equals/contains support, which this PR directly extends with not_equals/not_contains.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is generic and does not describe the actual change set. Rename it to reflect the main change, such as adding not_equals/not_contains workflow operator support and related docs/tests.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch next_release

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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/models/device_instance.py`:
- Around line 134-142: The `not_equals` and `not_contains` branches in the
filter builder are excluding NULL field values because `field != ?` and `field
NOT LIKE ?` do not match NULLs. Update the logic in `device_instance.py` so the
query treats NULL as a valid non-match for these operators, using the existing
clause-building flow around `operator`, `clauses`, and `params`. Keep the
behavior of `contains` unchanged, and make sure the negation semantics for
`not_equals` and `not_contains` include rows where the target field is NULL.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b91e9f21-bc2d-4721-afee-40382c5fe454

📥 Commits

Reviewing files that changed from the base of the PR and between a0c4af0 and b29d279.

📒 Files selected for processing (5)
  • docs/WORKFLOW_EXAMPLES.md
  • front/workflowsCore.php
  • server/models/device_instance.py
  • server/workflows/conditions.py
  • test/backend/test_workflows.py

Comment on lines +134 to +142
elif operator == "not_equals":
clauses.append(f"{field} != ?")
params.append(value)
elif operator == "contains":
clauses.append(f"{field} LIKE ?")
params.append(f"%{value}%")
elif operator == "not_contains":
clauses.append(f"{field} NOT LIKE ?")
params.append(f"%{value}%")

@coderabbitai coderabbitai Bot Jul 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

NULL rows silently excluded from not_equals/not_contains results.

In SQL, field != ? and field NOT LIKE ? evaluate to NULL (not TRUE) when field is NULL, so devices with a NULL value for the compared field are dropped from the result set even though "NULL is not equal to X" is intuitively true. This diverges from the negation semantics implied by the operator names.

🛠️ Proposed fix
             elif operator == "not_equals":
-                clauses.append(f"{field} != ?")
+                clauses.append(f"({field} != ? OR {field} IS NULL)")
                 params.append(value)
             elif operator == "contains":
                 clauses.append(f"{field} LIKE ?")
                 params.append(f"%{value}%")
             elif operator == "not_contains":
-                clauses.append(f"{field} NOT LIKE ?")
+                clauses.append(f"({field} NOT LIKE ? OR {field} IS NULL)")
                 params.append(f"%{value}%")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
elif operator == "not_equals":
clauses.append(f"{field} != ?")
params.append(value)
elif operator == "contains":
clauses.append(f"{field} LIKE ?")
params.append(f"%{value}%")
elif operator == "not_contains":
clauses.append(f"{field} NOT LIKE ?")
params.append(f"%{value}%")
elif operator == "not_equals":
clauses.append(f"({field} != ? OR {field} IS NULL)")
params.append(value)
elif operator == "contains":
clauses.append(f"{field} LIKE ?")
params.append(f"%{value}%")
elif operator == "not_contains":
clauses.append(f"({field} NOT LIKE ? OR {field} IS NULL)")
params.append(f"%{value}%")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/models/device_instance.py` around lines 134 - 142, The `not_equals`
and `not_contains` branches in the filter builder are excluding NULL field
values because `field != ?` and `field NOT LIKE ?` do not match NULLs. Update
the logic in `device_instance.py` so the query treats NULL as a valid non-match
for these operators, using the existing clause-building flow around `operator`,
`clauses`, and `params`. Keep the behavior of `contains` unchanged, and make
sure the negation semantics for `not_equals` and `not_contains` include rows
where the target field is NULL.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot implement suggestion

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jokob-sk, noted — this request is directed at @copilot, so I'll step back and let them implement the fix. Feel free to tag me if you'd like me to review the change once it's applied, or if you'd prefer I implement it instead.


🧠 Learnings used
Learnt from: jokob-sk
Repo: netalertx/NetAlertX PR: 1621
File: server/auth/ldap_provider.py:97-97
Timestamp: 2026-04-27T00:51:56.385Z
Learning: In the NetAlertX server-side Python code, treat logging text inside `mylog(...)` as developer/debug-only: keep it in English and do not add those strings to `front/php/templates/language/en_us.json`. By contrast, any string that is user-facing (e.g., error messages returned from API responses that are rendered in the login page/front-end) must be added as a translation key to `front/php/templates/language/en_us.json` so it can be translated via Weblate.

Learnt from: jokob-sk
Repo: netalertx/NetAlertX PR: 1621
File: server/auth/ldap_provider.py:165-165
Timestamp: 2026-04-27T00:52:02.534Z
Learning: In the NetAlertX codebase, do not use inline/dynamic imports in Python (e.g., `import ...` inside functions/methods). Require all imports to be at module top level so they are auditable and missing dependencies fail at import/load time rather than later at runtime. If an optional dependency must be handled, use a top-level `try/except ImportError` block (e.g., for `ldap3`) instead of a deferred inline import.

@jokob-sk

jokob-sk commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai re check

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@jokob-sk Sure, I'll re-check the PR now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@jokob-sk
jokob-sk merged commit 82049d1 into main Jul 1, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant