Skip to content

feat: add lifecycle hook system for CRUD operations (#116)#118

Merged
ds1sqe merged 7 commits intodevelopfrom
type_bridge-116
Mar 3, 2026
Merged

feat: add lifecycle hook system for CRUD operations (#116)#118
ds1sqe merged 7 commits intodevelopfrom
type_bridge-116

Conversation

@ds1sqe
Copy link
Copy Markdown
Owner

@ds1sqe ds1sqe commented Feb 27, 2026

Summary

Implements the lifecycle hook system proposed in #116, covering all three layers:

  • Python ORM hooks: Per-manager add_hook()/remove_hook() API with pre/post hooks for insert, update, delete, and put operations. Pre-hooks can cancel via HookCancelled or mutate instances; post-hooks run in reverse registration order (middleware unwinding). Zero overhead when no hooks are registered.
  • Rust ORM hooks: LifecycleHook trait with HookContext, PreHookResult (Continue/Reject), and HookRunner. Integrated into EntityManager and RelationManager with the same semantics as the Python layer.
  • Rust Server CRUD-aware interceptors: Enriched RequestContext with CrudInfo (operation, type_name, type_kind, etc.) and added CrudInterceptor convenience trait with CrudInterceptorAdapter bridging into the existing Interceptor chain. Removed the previous standalone CRUD module in favor of the interceptor-based approach.

Commits

Key Changes

  • Python: Added type_bridge/crud/hooks.py with CrudEvent, HookCancelled, LifecycleHook protocol, and HookRunner. Updated TypeDBManager to run hooks around CRUD operations. Added 594-line test suite.
  • Rust ORM: Added crates/orm/src/hooks/ module (context, error, traits, runner). Integrated hooks into EntityManager and RelationManager. Added 777-line test suite.
  • Rust Server: Added CrudInfo to request context, CrudInterceptor trait, and adapter. Removed the old crates/server/src/crud/ module (~1,467 lines) that is superseded by the interceptor-based design. Simplified pipeline and HTTP transport.

Test Plan

  • Python unit tests: tests/unit/crud/test_hooks.py
  • Rust ORM tests: crates/orm/tests/hooks_tests.rs
  • Integration tests with running TypeDB

Closes #116

Add per-manager hook registration so cross-cutting concerns (audit
logging, validation, cache invalidation, auto-populated fields) can
be attached without wrapping every call site.

- CrudEvent enum (8 events: pre/post for insert, update, delete, put)
- HookCancelled exception for pre-hook abort
- CrudHook duck-typed protocol — implement only the methods you need
- HookRunner with registration-order pre-hooks, reverse-order post-hooks
- Zero overhead when no hooks registered (has_hooks guard)
- Instrumented all 8 write methods on TypeDBManager
- 39 unit tests covering runner isolation and manager integration
Add LifecycleHook trait with HookRunner engine for EntityManager and
RelationManager. Pre-hooks run in registration order and can reject
operations; post-hooks run in reverse order with non-fatal errors.
Batch methods run all pre-hooks before the transaction and post-hooks
after commit. Zero overhead when no hooks are registered.
Enrich the server interceptor pipeline with CRUD context so
interceptors can distinguish entity insert from relation delete from
raw query — enabling rate limiting, tenant filtering, and CRUD-aware
audit logging at the HTTP layer.

- CrudInfo struct with operation/type_name/type_kind/attribute_names/iid
- CrudInterceptor convenience trait + CrudInterceptorAdapter bridge
- RequestContext and QueryInput carry crud_info through the pipeline
- All 8 CRUD handlers populate CrudInfo; non-CRUD uses Default
- 13 new unit tests (CrudInfo + CrudInterceptorAdapter)
Enrich the server interceptor pipeline with CRUD context so
interceptors can distinguish entity insert from relation delete from
raw query — enabling rate limiting, tenant filtering, and CRUD-aware
audit logging at the HTTP layer.

- CrudInfo struct with operation/type_name/type_kind/attribute_names/iid
- CrudInterceptor convenience trait + CrudInterceptorAdapter bridge
- RequestContext and QueryInput carry crud_info through the pipeline
- All 8 CRUD handlers populate CrudInfo; non-CRUD uses Default
- PipelineBuilder::with_skip_validation() for tests needing schema without validation
- 100% MC/DC coverage on all changed files (regions/functions/lines)
  - crud_interceptor.rs branches at 87.5% (1 missed: generic monomorphization artifact)
- 295 tests total (25 new)
Enrich the server interceptor pipeline with CRUD context so
interceptors can distinguish entity insert from relation delete from
raw query — enabling rate limiting, tenant filtering, and CRUD-aware
audit logging at the HTTP layer.

- CrudInfo struct with operation/type_name/type_kind/attribute_names/iid
- CrudInterceptor convenience trait + CrudInterceptorAdapter bridge
- RequestContext and QueryInput carry crud_info through the pipeline
- All 8 CRUD handlers populate CrudInfo; non-CRUD uses Default
- PipelineBuilder::with_skip_validation() for tests needing schema without validation
- 100% MC/DC coverage on all changed files (regions/functions/lines)
  - crud_interceptor.rs branches at 87.5% (1 missed: generic monomorphization artifact)
- 295 tests total (25 new)
@ds1sqe ds1sqe changed the title Type bridge 116 feat: add lifecycle hook system for CRUD operations (#116) Feb 27, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 27, 2026

Codecov Report

❌ Patch coverage is 83.02752% with 37 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
type_bridge/crud/typedb_manager.py 47.45% 26 Missing and 5 partials ⚠️
type_bridge/crud/hooks.py 93.84% 1 Missing and 3 partials ⚠️
type-bridge-core/crates/core/src/query_parser.rs 92.00% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

ds1sqe added 2 commits March 3, 2026 09:17
…rceptors (#116)

Expose test_helpers module via `test-helpers` feature flag for external
integration tests. Add 3 test files:

- pipeline_integration_tests.rs (17 tests): end-to-end pipeline flow
  with schema validation, skip_validation, database override,
  interceptor chains, executor errors, validate-only endpoint
- http_integration_tests.rs (18 tests): full HTTP request/response via
  axum tower::ServiceExt oneshot — health, schema, query success/error,
  validation, interceptor via HTTP, routing (404/405)
- interceptor_integration_tests.rs (10 tests): multi-interceptor chain
  ordering (request forward, response reverse), rejection short-circuit,
  metadata propagation, audit log file output through full pipeline
@ds1sqe ds1sqe merged commit 810fa59 into develop Mar 3, 2026
19 checks passed
@ds1sqe ds1sqe linked an issue Mar 3, 2026 that may be closed by this pull request
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.

feat: Add lifecycle hook system for CRUD operations

1 participant