feat: add lifecycle hook system for CRUD operations (#116)#118
Merged
feat: add lifecycle hook system for CRUD operations (#116)#118
Conversation
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)
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the lifecycle hook system proposed in #116, covering all three layers:
add_hook()/remove_hook()API with pre/post hooks for insert, update, delete, and put operations. Pre-hooks can cancel viaHookCancelledor mutate instances; post-hooks run in reverse registration order (middleware unwinding). Zero overhead when no hooks are registered.LifecycleHooktrait withHookContext,PreHookResult(Continue/Reject), andHookRunner. Integrated intoEntityManagerandRelationManagerwith the same semantics as the Python layer.RequestContextwithCrudInfo(operation, type_name, type_kind, etc.) and addedCrudInterceptorconvenience trait withCrudInterceptorAdapterbridging into the existingInterceptorchain. Removed the previous standalone CRUD module in favor of the interceptor-based approach.Commits
a33f83afeat(orm): add lifecycle hook system for CRUD operations (feat: Add lifecycle hook system for CRUD operations #116)0bd3255feat(orm): add Rust lifecycle hook system for CRUD operations (feat: Add lifecycle hook system for CRUD operations #116)6f0a3defeat(server): add CRUD-aware interceptor system for Rust server (feat: Add lifecycle hook system for CRUD operations #116)c6b2979feat(server): add CRUD-aware interceptor system for Rust server (feat: Add lifecycle hook system for CRUD operations #116)942c47cfeat(server): add CRUD-aware interceptor system for Rust server (feat: Add lifecycle hook system for CRUD operations #116)Key Changes
type_bridge/crud/hooks.pywithCrudEvent,HookCancelled,LifecycleHookprotocol, andHookRunner. UpdatedTypeDBManagerto run hooks around CRUD operations. Added 594-line test suite.crates/orm/src/hooks/module (context, error, traits, runner). Integrated hooks intoEntityManagerandRelationManager. Added 777-line test suite.CrudInfoto request context,CrudInterceptortrait, and adapter. Removed the oldcrates/server/src/crud/module (~1,467 lines) that is superseded by the interceptor-based design. Simplified pipeline and HTTP transport.Test Plan
tests/unit/crud/test_hooks.pycrates/orm/tests/hooks_tests.rsCloses #116