feat(tags): add bulk tagging and tag-based filtering
Some checks failed
CI / lint-and-test (push) Failing after 1m24s

- Add include_tags/exclude_tags query params to /api/events
- Add POST /api/events/bulk-tags endpoint with append/replace modes
- Frontend: add Include tags / Exclude tags filter inputs
- Frontend: add Bulk tag matching button with prompt for tag and mode
- Update filter layout to accommodate new tag fields
- Add tests for tag filtering and bulk tag append/replace
This commit is contained in:
2026-04-16 18:50:57 +02:00
parent 6d00d7cf32
commit 3761aa6d74
4 changed files with 219 additions and 12 deletions

View File

@@ -241,3 +241,68 @@ def test_rules_crud(client):
res5 = client.get("/api/rules")
assert res5.status_code == 200
assert len(res5.json()) == 0
def test_list_events_filter_by_include_tags(client, mock_events_collection):
mock_events_collection.insert_one({
"id": "evt-tagged",
"timestamp": datetime.now(UTC).isoformat(),
"service": "Directory",
"operation": "Add user",
"result": "success",
"actor_display": "Alice",
"raw_text": "",
"tags": ["backup", "auto"],
})
mock_events_collection.insert_one({
"id": "evt-untagged",
"timestamp": datetime.now(UTC).isoformat(),
"service": "Directory",
"operation": "Remove user",
"result": "success",
"actor_display": "Bob",
"raw_text": "",
"tags": [],
})
response = client.get("/api/events?include_tags=backup")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
assert data["items"][0]["id"] == "evt-tagged"
def test_bulk_tags_append(client, mock_events_collection):
mock_events_collection.insert_one({
"id": "evt-bulk",
"timestamp": datetime.now(UTC).isoformat(),
"service": "Exchange",
"operation": "Update",
"result": "success",
"actor_display": "Alice",
"raw_text": "",
"tags": ["existing"],
})
response = client.post("/api/events/bulk-tags?service=Exchange", json={"tags": ["backup"], "mode": "append"})
assert response.status_code == 200
data = response.json()
assert data["matched"] == 1
doc = mock_events_collection.find_one({"id": "evt-bulk"})
assert "backup" in doc["tags"]
assert "existing" in doc["tags"]
def test_bulk_tags_replace(client, mock_events_collection):
mock_events_collection.insert_one({
"id": "evt-bulk2",
"timestamp": datetime.now(UTC).isoformat(),
"service": "Exchange",
"operation": "Update",
"result": "success",
"actor_display": "Alice",
"raw_text": "",
"tags": ["old"],
})
response = client.post("/api/events/bulk-tags?service=Exchange", json={"tags": ["backup"], "mode": "replace"})
assert response.status_code == 200
doc = mock_events_collection.find_one({"id": "evt-bulk2"})
assert doc["tags"] == ["backup"]