feat: pass QueryContext into QueryProcessor (#320)#324
Merged
Conversation
…ocessor (#320) Requirements spec for adding optional IQueryContext parameter to IQueryProcessor.Execute and ExecuteAsync, following Brighter's InitRequestContext pattern. Four rounds of adversarial review completed and all findings resolved. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ADR 0010, approved tasks, review files, and updated requirements for the QueryContext parameter feature. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…320) Phase 2: Update IQueryProcessor.Execute and QueryProcessor.Execute to accept optional IQueryContext parameter. When null, context is created inline from factory (replacing CreateQueryContext). Initialize QueryContext.Bag to empty dictionary. Update FakeQueryProcessor to implement new interface signature. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Regression guard: when a caller passes an IQueryContext to Execute, the handler receives that exact instance with its Bag entries intact. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Token (#320) Phase 2: Update IQueryProcessor.ExecuteAsync and QueryProcessor.ExecuteAsync to accept optional IQueryContext parameter (before CancellationToken). When null, context is created inline from factory. Update FakeQueryProcessor to implement new interface signature. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…320) Regression guard: when a caller passes an IQueryContext to ExecuteAsync, the handler receives that exact instance with its Bag entries intact. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…#320) Both Execute and ExecuteAsync now create context inline; CreateQueryContext() is no longer called. Remove it along with the unused System.Linq import. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eryProcessor (#320) Phase 2: QueryProcessor accepts optional IPolicyRegistry<string> in constructor. InitQueryContext sets context.Policies from the registry when the caller hasn't provided one (caller-wins: ??= semantics). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…xt (#320) Regression guard: when caller's context already has Policies set, InitQueryContext (??= semantics) must not overwrite them with the processor's registry. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace Context.Bag lookup with Context.Policies typed property in both sync and async RetryableQueryDecorator, throwing ConfigurationException when no registry is configured. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cies null (#320) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ettings (#320) Replace Context.Bag lookup with constructor-injected JsonSerializerSettings in both sync and async QueryLoggingDecorator. Move RetryableQueryHandler and LoggingQueryHandler test doubles to TestDoubles/ per project convention, reusing SyncTestQuery across policy and logging decorator tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…320) Inline JsonConvert.SerializeObject directly in both logging decorators, remove the AddContextBagItem call from AddJsonQueryLogging, and delete the now-unused NewtonsoftJsonSerializer wrapper class. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add PolicyRegistry property to QueryProcessorBuilder (public for cross-assembly access from the Policies extension package). Update Policies() and DefaultPolicies() non-generic methods to store the registry on the builder; update generic AddPolicies/AddDefaultPolicies to drop the AddContextBagItem call. Remove ContextBagKey constant from both Policies and QueryLogging packages (no more callers). Fix nullable annotation syntax for netstandard2.0 compatibility in logging decorators. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ions (#320) Remove AddContextBagItem from IQueryProcessorExtensionBuilder, QueryProcessorBuilder, and ServiceCollectionDarkerHandlerBuilder. The _contextBagData dictionary stays in QueryProcessorBuilder temporarily until Build() is updated in the next task. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…320) Update Build() to pass PolicyRegistry instead of _contextBagData; remove _contextBagData dictionary and contextBagData constructor param from QueryProcessor. Update ServiceCollectionExtensions to resolve IPolicyRegistry<string> from DI instead of DarkerContextBag. Remove DarkerContextBag and update ServiceCollectionDarkerHandlerBuilder. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…320) Add Policies and QueryLogging references to DI extension project. Add IServiceCollection Services to IDarkerHandlerBuilder. Add IDarkerHandlerBuilder.AddAsyncHandlers() for async handler registration. Add PolicyDIExtensions with DI-specific AddPolicies/AddDefaultPolicies overloads that register IPolicyRegistry<string> as singleton alongside decorator types. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add QueryLoggingDIExtensions with AddJsonQueryLogging(IDarkerHandlerBuilder) that registers JsonSerializerSettings as a singleton so DI injects it into QueryLoggingDecorator constructors, mirroring the PolicyDIExtensions pattern for IPolicyRegistry<string>. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uteAsync (#320) Add LastProvidedContext property to FakeQueryProcessor so tests can assert which IQueryContext was passed to Execute or ExecuteAsync; null when no context is provided. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Gates Passed
4 Quality Gates Passed
See analysis details in CodeScene
Quality Gate Profile: Clean Code Collective
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.
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
IQueryContext queryContext = nullparameter toIQueryProcessor.ExecuteandExecuteAsync, letting callers supply a context (caller-wins semantics via??=)IPolicyRegistry<string> Policiesproperty toIQueryContext/QueryContext;QueryProcessorconstructor accepts and propagates a policy registry viaInitQueryContextRetryableQueryDecoratorreads policies fromContext.Policiesinstead ofContext.BagQueryLoggingDecoratorreceivesJsonSerializerSettingsvia constructor injection instead ofContext.BaglookupAddDefaultPolicies/AddPoliciesregisterIPolicyRegistry<string>as singleton;AddJsonQueryLoggingregistersJsonSerializerSettingsas singleton — both via a newPolicyDIExtensions/QueryLoggingDIExtensionspatternAddContextBagItem,DarkerContextBag,_contextBagData,NewtonsoftJsonSerializer,Constants.ContextBagKeyFakeQueryProcessorgainsLastProvidedContextpropertyTest plan
src/🤖 Generated with Claude Code