Skip to content

feat(management): add outbox event translator (AIHCM-184)#291

Merged
jsell-rh merged 1 commit intomainfrom
feature/AIHCM-184
Mar 17, 2026
Merged

feat(management): add outbox event translator (AIHCM-184)#291
jsell-rh merged 1 commit intomainfrom
feature/AIHCM-184

Conversation

@jsell-rh
Copy link
Collaborator

@jsell-rh jsell-rh commented Mar 17, 2026

Summary

  • Add ManagementEventTranslator translating 7 domain events to SpiceDB operations
  • Register Management translator in CompositeEventHandler at startup alongside IAM
  • 34 unit tests covering all event types, operation ordering, enum values, and error cases

Event → SpiceDB mappings

Event Operations
KnowledgeGraphCreated Write workspace + tenant relationships
KnowledgeGraphDeleted Delete workspace, tenant + filter-delete admin/editor/viewer (5 ops)
DataSourceCreated Write knowledge_graph + tenant relationships
DataSourceDeleted Delete knowledge_graph + tenant relationships
Updated/SyncRequested No-op (registered for validation)

Test plan

  • 34 translator unit tests pass
  • 17 serializer unit tests pass (from AIHCM-181)
  • 1902 total unit tests pass, zero regressions
  • Management handler registers at startup: "handler": "management", "event_count": 7
  • Pre-existing IAM workspace auth test failure confirmed on main (not a regression)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added ManagementEventTranslator to convert management domain events into access control operations.
    • Supports event translation for knowledge graph and data source lifecycle operations.
  • Tests

    • Added comprehensive unit test suite validating event translation logic, operation formatting, and error handling across all supported event types.

…-184)

Add ManagementEventTranslator that translates 7 Management domain events
to SpiceDB relationship operations:
- KnowledgeGraphCreated → write workspace + tenant relationships
- KnowledgeGraphDeleted → delete workspace, tenant, and filter-delete
  admin/editor/viewer grants (5 operations)
- DataSourceCreated → write knowledge_graph + tenant relationships
- DataSourceDeleted → delete knowledge_graph + tenant relationships
- Updated/SyncRequested events → no-op (registered for validation)

Register ManagementEventTranslator in CompositeEventHandler at startup.
34 translator unit tests covering all event types, operation ordering,
enum values, and error cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

Walkthrough

This change introduces a new ManagementEventTranslator class that translates management domain events into SpiceDB operations. The translator maps seven event types—KnowledgeGraphCreated, KnowledgeGraphUpdated, KnowledgeGraphDeleted, DataSourceCreated, DataSourceUpdated, DataSourceDeleted, and DataSourceSyncRequested—to corresponding write, delete, and filter-delete relationship operations. The translator is wired into the management event handler in the application's main entry point, replacing a placeholder comment. The implementation includes validation that all domain event variants have registered handlers and provides methods to list supported event types and translate serialized event payloads to operation lists.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding an outbox event translator for the management module, with the associated ticket reference.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/AIHCM-184
📝 Coding Plan
  • Generate coding plan for human review comments

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/api/tests/unit/management/infrastructure/outbox/test_translator.py (1)

617-625: Consolidate duplicated unknown-event assertions into one parametrized test.

These two tests validate the same behavior/message path and can be merged to reduce redundancy while keeping coverage intact.

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

Also applies to: 630-638

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/api/tests/unit/management/infrastructure/outbox/test_translator.py`
around lines 617 - 625, Consolidate the two duplicate tests that assert
unknown-event behavior into a single parametrized pytest test: replace the
separate test_raises_value_error_for_unknown_event_type and the similar test at
lines around 630-638 with one test using `@pytest.mark.parametrize`("event_type",
["UnknownEvent", "AnotherUnknownEvent"]) that instantiates
ManagementEventTranslator and asserts translator.translate(event_type, {})
raises ValueError and that "Unknown event type" is in the exception message;
reference the ManagementEventTranslator class and translate method when locating
code to change and keep the assertion message check unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/api/management/infrastructure/outbox/translator.py`:
- Line 117: The translator currently returns handler(payload) directly which
allows missing-field KeyError exceptions from handler internals to leak; wrap
the call to handler (the invocation returning at Line 117) in a try/except that
catches KeyError (and optionally TypeError for malformed payload shapes) and
re-raise a ValueError with a clear message preserving the original exception as
the cause so malformed payloads are normalized at the translation boundary
(i.e., convert KeyError -> ValueError before propagating from the translator
function that calls handler).

---

Nitpick comments:
In `@src/api/tests/unit/management/infrastructure/outbox/test_translator.py`:
- Around line 617-625: Consolidate the two duplicate tests that assert
unknown-event behavior into a single parametrized pytest test: replace the
separate test_raises_value_error_for_unknown_event_type and the similar test at
lines around 630-638 with one test using `@pytest.mark.parametrize`("event_type",
["UnknownEvent", "AnotherUnknownEvent"]) that instantiates
ManagementEventTranslator and asserts translator.translate(event_type, {})
raises ValueError and that "Unknown event type" is in the exception message;
reference the ManagementEventTranslator class and translate method when locating
code to change and keep the assertion message check unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee8b751e-8cba-409f-b257-964368d5c1f1

📥 Commits

Reviewing files that changed from the base of the PR and between 49c45d6 and adc0a96.

📒 Files selected for processing (4)
  • src/api/main.py
  • src/api/management/infrastructure/outbox/__init__.py
  • src/api/management/infrastructure/outbox/translator.py
  • src/api/tests/unit/management/infrastructure/outbox/test_translator.py

if not handler:
raise ValueError(f"No handler for event: {event_type}")

return handler(payload)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Normalize malformed payload failures to ValueError at the translation boundary.

At Line 117, missing required fields currently bubble as KeyError from handler internals, which makes outbox failure handling/error classification inconsistent with the explicit ValueError contract used for unsupported events.

Proposed fix
     def translate(
         self,
         event_type: str,
         payload: dict[str, Any],
     ) -> list[SpiceDBOperation]:
@@
-        return handler(payload)
+        try:
+            return handler(payload)
+        except KeyError as exc:
+            missing_key = exc.args[0]
+            raise ValueError(
+                f"Invalid payload for event {event_type}: "
+                f"missing required field '{missing_key}'"
+            ) from exc

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

📝 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
return handler(payload)
try:
return handler(payload)
except KeyError as exc:
missing_key = exc.args[0]
raise ValueError(
f"Invalid payload for event {event_type}: "
f"missing required field '{missing_key}'"
) from exc
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/api/management/infrastructure/outbox/translator.py` at line 117, The
translator currently returns handler(payload) directly which allows
missing-field KeyError exceptions from handler internals to leak; wrap the call
to handler (the invocation returning at Line 117) in a try/except that catches
KeyError (and optionally TypeError for malformed payload shapes) and re-raise a
ValueError with a clear message preserving the original exception as the cause
so malformed payloads are normalized at the translation boundary (i.e., convert
KeyError -> ValueError before propagating from the translator function that
calls handler).

@jsell-rh jsell-rh merged commit 33c68be into main Mar 17, 2026
11 checks passed
@jsell-rh jsell-rh deleted the feature/AIHCM-184 branch March 17, 2026 19:04
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