Skip to content

Code review sweep: harden every CoreEx package, close doc/reality gaps - #181

Merged
chullybun merged 16 commits into
mainfrom
coreex-review
Aug 8, 2026
Merged

Code review sweep: harden every CoreEx package, close doc/reality gaps#181
chullybun merged 16 commits into
mainfrom
coreex-review

Conversation

@chullybun

@chullybun chullybun commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

A full RPI (Research → Plan → Implement) code-review pass across every package in the repo — 15 commits, ~190 files. Each package was researched for real bugs (not style nits), verified against actual behavior (empirical repro where possible, revert-and-reproduce for the highest-priority fixes), fixed, and covered with regression tests. Breakdown below by project.

CoreEx.Events

  • Cancellation classification: only host-shutdown (own-token) cancellations now bubble up; unrelated OperationCanceledExceptions are handled normally.
  • EventFormatter applies InvariantCulture casing for Title/Source (fixes non-deterministic behavior under cultures like Turkish "I").
  • SubscribeAttribute/SubscribedBase glob matching now uses RegexOptions.CultureInvariant.
  • EventSubscriberMetrics now correctly classifies every IEventSubscriberException outcome (previously most fell through to a generic bucket) and records a subscribed tag.
  • Removed dead ErrorHandler.AddAssignableFrom overloads; removed a debug-only event-payload log leak from EventPublisherBase (moved to test-only via EventPublisherDecorator).

CoreEx.Azure.Messaging.ServiceBus

  • Fixed StopAsync invoking OnStopAsync even when the receiver was never started.
  • All semaphore waits now use .ConfigureAwait(false).
  • ServiceBusErrorClassifier treats SessionCannotBeLocked as info, not a lock-lost condition.
  • Fixed DI registration key confusion causing WithKeyedSubscriber(...).WithHostedService() to fail to resolve.
  • Partition-key-less events now use a fixed "$none" session (not a random GUID) — bounds session growth and preserves ordering.
  • CloudEvent trace context/identity attributes are now preserved in Binary-mode round-trips even when includeAttributes is false.
  • Circuit-breaker/catastrophic pause-resume logic now logs failures instead of swallowing them as unobserved task exceptions.

CoreEx.Caching.FusionCache

  • Cache tags are now qualified via ICacheKeyProvider — previously unqualified tags could cause cross-tenant/cross-domain cache invalidation when multiple domains shared one IFusionCache.
  • ConfigureEntryOptions accepts both HybridCacheEntryOptions and FusionCacheEntryOptions; AddFusionHybridCache supports a DI-time configure callback.

CoreEx.AspNetCore

  • Security hardening: MapHealthChecks's detailed endpoints are now disabled by default (previously anonymous-by-default, exposing full HealthReport diagnostics); a warning is logged if enabled without securing them. MapHostedServices (pause/resume/status endpoints for background services) now logs a warning if mapped without a securing delegate — previously silent and unauthenticated by default. Both <remarks> now clarify that only the absence of a configure delegate is checked, not whether a supplied one is actually effective.
  • Fixed a header-mutation race and Set-Cookie leak in the idempotency-key replay path; request body is now hashed in chunks instead of buffered wholesale; tracing tags are set after key validation, not before.
  • Paging uses long arithmetic to prevent overflow in next/prev links.
  • PATCH endpoints enforce correct media type; delete behavior is configurable; GraphQL Lite errors include error codes.
  • GlobalUsing.cs consolidated per house convention.

CoreEx.AspNetCore.NSwag

  • AcceptsAttribute.IsOptional now actually wires through to OpenApiRequestBody.IsRequired (previously declared but ignored).
  • AddCoreExConfiguration accepts an Action<OpenApiOptions> so custom JsonSerializerOptions propagate to schema generation.
  • OpenAPI headers/content now use indexer assignment instead of .Add(...), preventing duplicate-key exceptions.
  • Fixed doc comments (ProducesNotFoundProblemAttribute is 404 not 200; QueryAttribute.SupportsFilter defaults true not false).

CoreEx.Data

  • Fixed argument-placeholder renumbering collisions in the query filter writer (could silently corrupt query parameters).
  • QueryFilterParser now rejects duplicate field registrations and correctly supports both 32- and 36-character GUID formats.
  • Stricter token validation in logical/function expressions (previously malformed input could produce wrong-but-valid queries).
  • QueryOrderByParser enforces its direction allow-list correctly and fixes default-ordering format.

CoreEx.Data.GraphQL

  • GetIdentifier<TId> now correctly converts boxed variable-supplied values (e.g. longint, stringGuid) instead of an unsafe direct cast.
  • Filter translator now consults QueryFilterParser for correct OData quoting of Guid/DateTime/etc. (previously always quoted as string, breaking non-string filters) — with injection-safety guards on the unquoted path.
  • Introspection schema builder detects and rejects CLR type name collisions instead of silently merging shapes.
  • decimal filter values now round-trip via decimal first (previously always widened through double, losing precision).
  • Debug logging of filter/order-by text is now opt-in (EnableSensitiveDataLogging), not on by default.

CoreEx.DomainDriven

  • Aggregate<TId,TSelf>.AddEvent/ClearEvents now correctly throw when the aggregate is read-only (previously silently allowed mutation).
  • EntityBase.Remove now fires the Mutated event before marking the entity read-only, matching its own documented contract (previously inverted).

CoreEx.Generator

  • Added TextJsonName support on [ReferenceData] for a customizable JSON name on the generated "Text" property, and the generator now correctly omits the property entirely when Text = false (previously always emitted regardless of the flag).

CoreEx.UnitTesting

  • New CoreEx.UnitTesting.Test.Unit test project — this package had no dedicated tests despite being the thing every other test suite trusts for correct assertions.
  • Fixed an asymmetric guard that let event content-assertors silently get discarded when chained with count/custom assertions.
  • Fixed ExpectIdentifier's non-default-value check (compared the entity's type instead of the identifier's type — never worked for Guid/int/long IDs).
  • Fixed a copy-paste bug in ExpectChangeLogCreated/Updated that checked the wrong field.
  • Fixed ETag/Identifier expectation casts to use the read-only interfaces actually verified, not the stricter mutable ones.
  • Fixed an empty-string false positive in ExpectChangeLogCreated/Updated where an explicitly-empty createdBy/updatedBy silently matched any actual value.
  • Bumped GetAndClearAzureServiceBusAsync's internal poll timeout from 1ms to 1s to avoid dropping messages under real broker latency (verified against the live emulator).
  • Added the new AssertWithValue(valueFactory, ...) factory overload (for testers with no returned value to assert against) with tests and doc coverage.

CoreEx.CodeGen

  • Corrected AGENTS.md's example config and the generator/template/output-mapping tables across AGENTS.md/README.md (previously described a RootGenerator/ApiGenerator split that didn't match reality).
  • Note: an initial pass in this PR also "fixed" IRepository_cs.hbs to filter repository: None entities out of the generated interface, matching the implementation template. That was reverted after review — the asymmetry is intentional (the interface declares every entity's member as a compile-time forcing function so repository: None entities must be hand-implemented in a partial-class extension; only the auto-generatable implementation is filtered). No functional change remains in this package from this PR beyond the doc corrections.

CoreEx.Template

  • Security: the coreex-relay scaffold left app.UseAuthorization() commented out (unlike coreex-api/coreex-subscribe) — meant the RequireAuthorization() guidance on MapHealthChecks/MapHostedServices silently did nothing even if uncommented. Now enabled by default, matching the other hosts — with AddAuthorization() also registered explicitly, since Relay (unlike Api/Subscribe) has no AddControllers() to bring that in transitively (caught in review; verified by actually scaffolding, building, and running the host).
  • Security: coreex-api/coreex-relay/coreex-subscribe no longer override HealthCheckOptions.AreDetailedEndpointsEnabled to true — they now inherit the library's secure-by-default behavior. Existing Health_Detailed test coverage is preserved via a CoreEx.AspNetCore.HealthChecks config section in each template's appsettings.unittest.json (test-only; the generated app itself stays secure). The same change was applied to all 7 Contoso sample hosts for consistency.
  • Fixed an inverted #if implement-sqlserver/implement-postgres guard on the Npgsql log-suppression entry in coreex-api/coreex-subscribe (copy-paste drift from coreex-relay, which had it correct) — regression-tested via two new validate-template-pack.ps1 scenarios.
  • Removed dead/unreachable template blocks: an implement-servicebus conditional in coreex-api (which has no messaging-provider parameter at all) and misspelled, unused FusionCache/Redis log config in coreex-relay (which has no such packages).
  • Fixed docker-compose.yml's project name only being lower-cased (not kebab-cased) for dotted project names — rejected by podman. Added validate-template-pack.ps1 coverage for this.
  • Added the missing .claude/commands/coreex-scaffold.md wrapper so /coreex-scaffold actually works in Claude Code (previously only worked in Copilot Chat despite being documented as available in both) — aligned every doc that referenced it (getting-started.md, consumer-instructions/README.md, CoreEx.Template/README.md).

Response to Copilot review

Copilot flagged four issues on this PR; all addressed:

  • coreex-relay's enabled UseAuthorization() had no AddAuthorization() behind it — real startup crash, fixed and verified by actually running the scaffolded host (see CoreEx.Template section above).
  • coreex-api/coreex-relay/coreex-subscribe opted into detailed health-check endpoints by default, undermining the library's new secure-by-default posture — fixed for both templates and samples (see CoreEx.Template section above).
  • tests/CoreEx.AspNetCore.Test.Api/Controllers/OtherController.cs extended Controller instead of ControllerBase (pre-existing, unrelated to this PR's changes, but cheap to fix) — now ControllerBase.

CoreEx.Validation

  • ValueFormatter always honors the provided FormatProvider.
  • PropertyContext.RefreshFromEntity() added to fix struct value sync in rule chains.
  • ComparePropertyRule/DecimalRule correctly handle numeric overflow as a validation error instead of an unhandled exception.
  • CompareValuesRule's overrideValueWhereMatched bug fixed and overrides now propagate correctly.
  • MandatoryRule/NullNoneEmptyRule dispose enumerators from non-collection IEnumerable sources.
  • ValidatingInlineValidator now uses .ConfigureAwait(false) consistently.

Verification

Every package's fixes were verified with dotnet build/dotnet test (full suites green), and the highest-priority/highest-risk fixes used revert-and-reproduce (confirm the regression test fails against the pre-fix code, then reapply). CoreEx.Template was additionally verified via tools/validate-template-pack.ps1 (14/14 scenarios passing, rebuilt from source) and manual scaffold+inspect for the security and doc fixes. The Relay authorization fix was verified by scaffolding a full coreex + coreex-relay solution, building it, and actually running it — confirmed clean startup, /health/live → 200, /health/live/detailed → 404 (secure by default), and /hosted-services/all/status reachable with the expected unsecured-warning logged. Full solution build (CoreEx.sln) passes with 0 warnings/errors.

🤖 Generated with Claude Code

- ValueFormatter: always use provided FormatProvider for string.Format
- PropertyContext: add RefreshFromEntity() to fix struct value sync in rule chains
- ComparePropertyRule: wrap OverflowException as InvalidCastException
- CompareValuesRule: fix overrideValueWhereMatched bug, propagate overrides
- DecimalRule: handle decimal.CreateChecked OverflowException as validation error
- MandatoryRule/NullNoneEmptyRule: dispose enumerators from non-collection IEnumerable
- ValidationExtensions: materialize allowed enum values, add regex ReDoS remarks
- ValidatingInlineValidator: ensure .ConfigureAwait(false) for async
- Add regression/unit tests for bounds, misconfig, disposal, exceptions, formatting, and override propagation
- Improves correctness, robustness, and resource management
- Distinguish CancellationToken vs. unrelated cancellations in event subscriber/publisher; only host shutdowns now bubble up.
- EventFormatter now applies InvariantCulture casing for Title/Source; added remarks and regression tests (e.g., Turkish "I").
- SubscribeAttribute and SubscribedBase glob-matching now use RegexOptions.CultureInvariant for deterministic case-insensitive matching; regression tests added.
- EventSubscriberMetrics now classifies all IEventSubscriberException outcomes and records "subscribed" tag for SubscribedManager.
- Removed AddAssignableFrom overloads from ErrorHandler; clarified XML docs.
- Removed debug event payload logging from EventPublisherBase (now test-only via EventPublisherDecorator).
- EventPublisherDecorator supports optional debug logging for tests.
- Added/updated unit tests for all above behaviors.
- Minor cleanups: null/empty checks, ordering, comments, and global usings.
- Fixed ServiceBusReceiver/SessionReceiver StopAsync to avoid OnStopAsync if never started; ensured all semaphore waits use .ConfigureAwait(false).
- Improved ServiceBusErrorClassifier: handle SessionCannotBeLocked as info, not lock-lost; added tests.
- Suppressed broker error descriptions for dead-lettered messages to avoid log duplication.
- Refactored DI registration for receivers/subscribers to prevent key confusion and resolve WithKeyedSubscriber(...).WithHostedService() bug.
- Changed session assignment for events without partition key to use "$none" (not GUID), bounding session growth and preserving order; added logging and tests.
- Ensured CloudEvent trace context and identity attributes are preserved in Binary-mode round-trip, even when includeAttributes is false; added regression tests.
- Hardened circuit-breaker and catastrophic error pause/resume logic to log failures instead of unobserved task exceptions.
- Updated comments, fixed doc remarks, and added/updated unit tests for all new and regression scenarios.
- Qualify all tags via ICacheKeyProvider to prevent cross-tenant/domain invalidation when sharing IFusionCache.
- FusionHybridCache.ConfigureEntryOptions now accepts both HybridCacheEntryOptions and FusionCacheEntryOptions, enabling richer configuration.
- AddFusionHybridCache supports an optional configure callback for DI-time configuration.
- Add/extend unit tests for tag qualification, entry options configuration, and DI callback behavior.
- Health check detailed endpoints are now disabled by default for security; opt-in and securing guidance added, with warnings if enabled unsafely.
- Paging logic uses long arithmetic to prevent overflow in next/prev links.
- Idempotency: Set-Cookie headers excluded from cache, request body hashed in chunks, only relevant headers overwritten on replay, tracing tags set post-validation.
- Web API: PATCH endpoints enforce correct media type, improved cancellation/exception handling, delete behavior configurable, GraphQL errors include codes.
- Usings consolidated in GlobalUsing.cs.
- Docs updated for new health check defaults and security.
- Regression tests added for all new behaviors and edge cases.
Add optional Action<OpenApiOptions> to AddCoreExConfiguration for custom JsonSerializerOptions propagation to schema generation. Update AcceptsAttribute handling to set OpenApiRequestBody.IsRequired based on IsOptional. Use indexer assignment for OpenAPI headers/content for idempotency. Correct documentation for ProducesNotFoundProblemAttribute (404) and QueryAttribute.SupportsFilter (default true). Add POST endpoint (optional-body) to OtherController for AcceptsAttribute demo. Add integration/unit tests for OpenAPI request body requiredness and JsonSerializerOptions flow.
Improved CoreEx query filter and order-by parsing:
- Fixed argument placeholder renumbering to prevent collisions.
- QueryFilterParser now errors on duplicate fields; supports 32/36-char Guids.
- Enforced stricter token validation in logical/function expressions.
- QueryOrderByParser enforces direction allow-lists and fixes default formatting.
- Added comprehensive tests for filters, order-by, ref-data fields, and edge cases.
- Updated docs and project references.
- `GetIdentifier<TId>` now converts boxed values using `TId.Parse`, supporting variable-supplied types (e.g., `long` to `int`, `string` to `Guid`).
- Added comprehensive tests for identifier conversion and error cases.
- Filter translator consults `QueryFilterParser` for quoting, ensuring correct OData syntax for types like `Guid`, `DateTime`, etc.
- Unquoted "Other" values are now injection-safe (no spaces, parentheses, or commas).
- Improved error messages for invalid boolean filter usage.
- Debug logging omits sensitive filter/order-by text by default; opt-in with `EnableSensitiveDataLogging`.
- PageInfo fields in connection results are now case-insensitive.
- Introspection schema builder detects and rejects CLR type name collisions.
- Float parsing prefers `decimal` for precision, falling back to `double` if needed.
- Updated tests and docs to cover new behaviors and edge cases.
Aggregate<TId, TSelf> now throws if AddEvent or ClearEvents are called on a read-only aggregate. EntityBase explicit IIdentifierCore.Id/IdType implementations throw NotSupportedException. The Remove method now fires the Mutated event before making the entity read-only, matching documentation. AggregateTests expanded to cover Remove return values, event order, and read-only enforcement for AddEvent/ClearEvents. These changes improve mutation safety and test coverage.
Introduce `TextJsonName` on `[ReferenceData]` to allow custom JSON property names for the "Text" property. The code generator now emits the `RefDataText` property only when `Text = true` (default), and applies the custom JSON name if provided. Update `PropertyModel` and `ContractModel` to support these options. Handlebars templates now conditionally emit the property and its attributes. Add unit tests to verify omission and custom naming behavior.
Added CoreEx.UnitTesting.Test.Unit project with full solution wiring and comprehensive unit tests for event expectations, JSON data reader, person entity helpers, validation extensions, and AwesomeAssertions. Improved event expectation configuration with new AssertWithValue factory overload, better path handling, and clearer error messages. Updated docs to clarify event assertion APIs and usage. Fixed minor issues including typos, comments, Service Bus test reliability, and validation error handling. Ensured all tests use correct hosts and DI patterns.
- Clarified `ref-data.yaml` placement and updated outputs table with exact file names/locations and default folders.
- Documented new `ApiGenerator` and clarified generator responsibilities in README.
- Fixed duplicate `IdType` assignment in `EntityConfig`.
- Updated repository interface template to use `EntitiesWithRepository`.
- Enhanced documentation for configuration and generator class roles.
Replaces "app-name-lower" with "app-name-kebab-case" for service naming in docker-compose.yml and template.json. Adds "DotToKebabCase" and "KebabCase" transformations to template.json for consistent kebab-case formatting. Updates docker-compose.yml to use the new variable.
Updated XML docs for MapHealthChecks and MapHostedServices to clarify that only the absence of the configuration delegate is checked, not enforcement of authentication/authorization. Added explicit warnings recommending delegate usage for security. MapHostedServices now logs a runtime warning if groupConfigure is not supplied, alerting developers that hosted service endpoints will be accessible anonymously. This aligns with the health check endpoint warning pattern.
Added .claude/commands/coreex-scaffold.md and updated CoreEx.Template to support /coreex-scaffold in Claude Code and Copilot Chat. Clarified documentation in README and getting-started guides. Fixed appsettings.Development.json template to only include Npgsql log suppression for Postgres, not SQL Server. Added regression tests to validate correct log config gating. Enabled app.UseAuthorization() by default in Program.cs.
Copilot AI lite review requested due to automatic review settings August 8, 2026 14:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Repository-wide hardening and doc/reality alignment across CoreEx packages, focusing on fixing concrete behavioral bugs, tightening security defaults, and adding regression coverage to prevent regressions in core primitives used by many packages.

Changes:

  • Fixes multiple correctness issues across validation, querying, eventing, Service Bus receiving, and ASP.NET Core WebApi behaviors.
  • Tightens security posture and operational robustness (health-check/hosted-service endpoint handling, idempotency replay safety, circuit-breaker pause/resume error visibility).
  • Adds/extends regression test coverage (including a new dedicated CoreEx.UnitTesting.Test.Unit project) and updates templates/docs/instructions to match runtime behavior.

Reviewed changes

Copilot reviewed 190 out of 190 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/CoreEx.Validation.Test.Unit/ValidatorTests.cs Adds regression coverage for explicit format-provider behavior under localization.
tests/CoreEx.Validation.Test.Unit/Rules/NullNoneEmptyRuleTests.cs Adds regression test ensuring enumerators are disposed for non-collection IEnumerable.
tests/CoreEx.Validation.Test.Unit/Rules/MandatoryRuleTests.cs Adds regression test ensuring enumerators are disposed for non-collection IEnumerable.
tests/CoreEx.Validation.Test.Unit/Rules/EnumRuleTests.cs Adds regression test ensuring allowed-values IEnumerable is enumerated once at config time.
tests/CoreEx.Validation.Test.Unit/Rules/DictionaryRuleTests.cs Adds misconfiguration tests for min/max count validation.
tests/CoreEx.Validation.Test.Unit/Rules/DecimalRuleTests.cs Adds regression tests for overflow/NaN/Infinity handling in precision/scale validation.
tests/CoreEx.Validation.Test.Unit/Rules/CompareValuesRuleTests.cs Adds regression tests for override behavior and chained-rule propagation.
tests/CoreEx.Validation.Test.Unit/Rules/ComparePropertyRuleTests.cs Adds regression test for overflow handling and consistent exception wrapping.
tests/CoreEx.Validation.Test.Unit/Rules/CollectionRuleTests.cs Adds misconfiguration tests for min/max count validation.
tests/CoreEx.Validation.Test.Unit/Rules/BetweenRuleTests.cs Adds regression coverage for exclusive-between semantics.
tests/CoreEx.Validation.Test.Unit/CommonValidatorTests.cs Extends coverage for common validators (success + error cases).
tests/CoreEx.UnitTesting.Test.Unit/EntryPoint.cs New unit-test host entrypoint for CoreEx.UnitTesting package verification.
tests/CoreEx.UnitTesting.Test.Unit/CoreEx.UnitTesting.Test.Unit.csproj New test project definition for CoreEx.UnitTesting package.
tests/CoreEx.RefData.Test.Unit/ReferenceDataAttributeCodeGenTests.cs Adds tests for [ReferenceData] Text/TextJsonName codegen behavior.
tests/CoreEx.Data.Test.Unit/CoreEx.Data.Test.Unit.csproj Adds CoreEx.RefData reference to support new/updated test scenarios.
tests/CoreEx.Data.GraphQL.Test.Unit/Internal/GraphQLArgsMapperTests.cs Updates tests to new BuildQueryArgs(args, filterParser) signature.
tests/CoreEx.Azure.Messaging.ServiceBus.Test.Unit/Subscribers/ProductSubscriber.cs Adjusts subscriber to exercise cancellation classification + result behaviors.
tests/CoreEx.Azure.Messaging.ServiceBus.Test.Unit/CoreEx.Azure.Messaging.ServiceBus.Test.Unit.csproj Adds CoreEx.UnitTesting reference for new test/assertion usage.
tests/CoreEx.AspNetCore.Test.Unit/WebApiTestsBase.MergePatchWithResult.cs Updates merge-patch content-type error messaging assertion.
tests/CoreEx.AspNetCore.Test.Unit/WebApiTestsBase.MergePatch.cs Updates merge-patch messaging + adds explicit rejection test for application/json.
tests/CoreEx.AspNetCore.Test.Unit/WebApiTestsBase.GetWithResult.cs Adds regression test preventing paging-link overflow for large $skip.
tests/CoreEx.AspNetCore.Test.Unit/WebApiTestsBase.Exceptions.cs Adds regression tests for “own token” vs unrelated-token cancellation handling.
tests/CoreEx.AspNetCore.Test.Unit/WebApiTestsBase.Delete.cs Adds regression test for configurable delete not-found conversion behavior.
tests/CoreEx.AspNetCore.Test.Unit/OtherApiTests.cs Adds regression coverage for AcceptsAttribute requestBody required/optional in Swagger JSON.
tests/CoreEx.AspNetCore.Test.Unit/NSwagExtensionsTests.cs New unit tests ensuring custom JsonSerializerOptions flow into schema generation.
tests/CoreEx.AspNetCore.Test.Unit/ExecutionContextMiddlewareTests.cs New unit test ensuring headers aren’t mutated after response started.
tests/CoreEx.AspNetCore.Test.Api/Program.cs Ensures test host maps health checks with detailed endpoints explicitly enabled for coverage.
tests/CoreEx.AspNetCore.Test.Api/Controllers/OtherController.cs Adds optional-body endpoint for OpenAPI coverage; extends test controller surface.
src/CoreEx.Validation/ValidationExtensions.EnumRule.cs Avoids re-enumeration of allowed values by materializing once at configuration time.
src/CoreEx.Validation/ValidatingInlineValidator.cs Adds missing ConfigureAwait(false) consistency.
src/CoreEx.Validation/Rules/PropertyRuleBase.cs Refreshes property context from entity after rule execution to support overrides in chains.
src/CoreEx.Validation/Rules/NullNoneEmptyRule.cs Ensures enumerators are disposed when enumerating non-collection IEnumerable.
src/CoreEx.Validation/Rules/MandatoryRule.cs Ensures enumerators are disposed when enumerating non-collection IEnumerable.
src/CoreEx.Validation/Rules/DecimalRule.cs Converts overflow/NaN/Infinity into validation errors (not unhandled exceptions).
src/CoreEx.Validation/Rules/CompareValuesRule.cs Fixes override/no-match crash and ensures override uses matched value reliably.
src/CoreEx.Validation/Rules/ComparePropertyRule.cs Wraps OverflowException consistently as InvalidCastException for comparison compatibility.
src/CoreEx.Validation/PropertyContext.cs Adds RefreshFromEntity to sync struct context across chained rule invocations.
src/CoreEx.Validation/Abstractions/ValueFormatter.cs Ensures explicit IFormatProvider is honored for composite formatting.
src/CoreEx.UnitTesting/UnitTestExOneOffTestSetUp.cs Adjusts validation error extraction behavior for null text cases.
src/CoreEx.UnitTesting/UnitTestExExtensions.Validation.cs Removes incorrect/outdated XML doc entry.
src/CoreEx.UnitTesting/UnitTestExExtensions.ServiceBus.cs Increases receive wait time to avoid latency-induced message drops; fixes typo.
src/CoreEx.UnitTesting/UnitTestExExtensions.Events.cs Passes logger to EventPublisherDecorator.
src/CoreEx.UnitTesting/UnitTestExExpectations.Identifier.cs Fixes identifier expectation to use the correct read-only identifier interface/type info.
src/CoreEx.UnitTesting/UnitTestExExpectations.Events.cs Fixes request-state keying to use consistent suffix constant.
src/CoreEx.UnitTesting/UnitTestExExpectations.ETag.cs Uses read-only ETag interface for expectations.
src/CoreEx.UnitTesting/UnitTestExExpectations.ChangeLog.cs Fixes created/updated-by checks and empty-string expectation semantics.
src/CoreEx.UnitTesting/GlobalUsings.cs Removes incorrect global-usings file (renamed/consolidated).
src/CoreEx.UnitTesting/GlobalUsing.cs Consolidates/updates global usings (including logger availability).
src/CoreEx.Template/README.md Documents .claude/commands wrappers (including scaffold) emitted by template.
src/CoreEx.Template/content/CoreEx.Subscribe/src/app-name.Subscribe/Program.cs Updates template host health-check mapping and related behavior.
src/CoreEx.Template/content/CoreEx.Subscribe/src/app-name.Subscribe/appsettings.Development.json Fixes incorrect conditional guard for Npgsql logging configuration.
src/CoreEx.Template/content/CoreEx.Relay/src/app-name.Relay/Program.cs Updates relay template middleware/health-check mapping (notably authorization + detailed endpoints).
src/CoreEx.Template/content/CoreEx.Relay/src/app-name.Relay/appsettings.Development.json Removes unused log-level blocks and corrects ordering/conditions.
src/CoreEx.Template/content/CoreEx.Core/docker-compose.yml Fixes template compose project name transformation for dotted names (kebab-case).
src/CoreEx.Template/content/CoreEx.Core/.template.config/template.json Adds/uses kebab-case transform and dot-to-kebab transform for derived symbols.
src/CoreEx.Template/content/CoreEx.Api/src/app-name.Api/Program.cs Updates API template health-check mapping behavior for detailed endpoints.
src/CoreEx.Template/content/CoreEx.Api/src/app-name.Api/appsettings.Development.json Fixes conditional guard drift and removes dead/unreachable template logging blocks.
src/CoreEx.Events/Subscribing/SubscribedManager.cs Tightens cancellation classification to only treat cancellations from the receiver token as bubble-up.
src/CoreEx.Events/Subscribing/SubscribedBase.Static.cs Makes glob matching culture-invariant by default; clarifies intent in docs.
src/CoreEx.Events/Subscribing/SubscribeAttribute.cs Corrects match logic for explicit Regex vs glob pattern usage.
src/CoreEx.Events/Publishing/EventPublisherBase.cs Removes debug payload logging that could leak sensitive event data.
src/CoreEx.Events/GlobalUsing.cs Adds missing System.Globalization import used by culture-invariant casing.
src/CoreEx.Events/EventData.With.cs Fixes exclude-paths empty handling logic.
src/CoreEx.DomainDriven/EntityBase.cs Uses NotSupportedException for unsupported identifier members and fixes Remove mutation ordering.
src/CoreEx.DomainDriven/Aggregate.cs Enforces read-only guard on event mutation APIs.
src/CoreEx.Data/README.md Fixes API/documentation drift for IUnitOfWork and reference-data model properties.
src/CoreEx.Data/Querying/QueryFilterParserWriter.cs Fixes argument placeholder renumbering collisions and introduces regex-based renumbering.
src/CoreEx.Data/Querying/QueryFilterFieldConfigBase.cs Improves token validation and error messaging for boolean constants.
src/CoreEx.Data/Querying/Expressions/QueryFilterStringFunctionExpression.cs Adds stricter token validation for function expressions.
src/CoreEx.Data/Querying/Expressions/QueryFilterLogicalExpression.cs Fixes logical-expression token handling edge case.
src/CoreEx.Data/GlobalUsing.cs Adds regex namespace import required by new filter-writer logic.
src/CoreEx.Data/AGENTS.md Fixes unit-of-work transaction example to correctly flow CancellationToken.
src/CoreEx.Data.GraphQL/Internal/GraphQLConnectionResolver.cs Makes pageInfo field handling case-insensitive to match GraphQL expectations.
src/CoreEx.Data.GraphQL/Internal/GraphQLArgsMapper.cs Plumbs QueryFilterParser into where-translation to preserve correct quoting/typing behavior.
src/CoreEx.CodeGen/RefData/Templates/IRepository_cs.hbs Fixes template to emit repository members only for entities with repositories.
src/CoreEx.CodeGen/RefData/Config/EntityConfig.cs Removes duplicated IdType defaulting assignment.
src/CoreEx.CodeGen/README.md Updates docs to match actual generator responsibilities/split.
src/CoreEx.CodeGen/AGENTS.md Corrects example config and output mapping tables to match reality.
src/CoreEx.Caching.FusionCache/CoreExFusionCacheExtensions.DependencyInjection.cs Adds DI-time configure callback for FusionHybridCache construction.
src/CoreEx.Azure.Messaging.ServiceBus/ServiceBusReceiverResiliency.cs Prevents unobserved task exceptions from circuit-breaker pause/resume flow by logging failures.
src/CoreEx.Azure.Messaging.ServiceBus/ServiceBusReceiverInvoker.cs Guards resiliency pipeline against exception outcomes by converting to Result.Fail.
src/CoreEx.Azure.Messaging.ServiceBus/Abstractions/ServiceBusReceiverOptionsBase.cs Fixes/clarifies doc for UnhandledErrorHandling behavior.
src/CoreEx.Azure.Messaging.ServiceBus/Abstractions/ServiceBusReceiverBaseT.cs Improves cancellation handling and logs failures for catastrophic pause to avoid unobserved tasks.
src/CoreEx.Azure.Messaging.ServiceBus/Abstractions/ServiceBusMessageActionsBase.cs Centralizes truncation behavior via ServiceBusReceiverBase constant/logic.
src/CoreEx.Azure.Messaging.ServiceBus/Abstractions/ProcessSessionMessageEventArgsActions.cs Avoids dead-letter metadata exposure by not persisting stack traces into broker metadata.
src/CoreEx.Azure.Messaging.ServiceBus/Abstractions/ProcessMessageEventArgsActions.cs Avoids dead-letter metadata exposure by not persisting stack traces into broker metadata.
src/CoreEx.AspNetCore/OpenApiOptions.cs Fixes/clarifies XML doc for fields request-headers inclusion.
src/CoreEx.AspNetCore/Mvc/WebApiInvoker.cs Removes redundant file-level using after GlobalUsing consolidation.
src/CoreEx.AspNetCore/Mvc/WebApi.cs Removes redundant usings; uses constant for IncludeExceptionInProblemDetails config lookup.
src/CoreEx.AspNetCore/Mvc/QueryAttribute.cs Fixes SupportsFilter default remark to match actual default.
src/CoreEx.AspNetCore/Mvc/ProducesNotFoundProblemAttribute.cs Fixes remark to correctly state 404 rather than 200.
src/CoreEx.AspNetCore/Idempotency/IIdempotencyProvider.cs Removes redundant using after GlobalUsing consolidation.
src/CoreEx.AspNetCore/Idempotency/IdempotencyKey.cs Fixes replay header handling and hashes request bodies in chunks to avoid unbounded buffering.
src/CoreEx.AspNetCore/Http/WebApi.cs Removes redundant using after GlobalUsing consolidation.
src/CoreEx.AspNetCore/Http/AspNetCoreHttpExtensions.cs Removes redundant usings after GlobalUsing consolidation.
src/CoreEx.AspNetCore/HealthChecks/README.md Updates docs to reflect detailed endpoints being disabled by default.
src/CoreEx.AspNetCore/HealthChecks/HealthCheckOptions.cs Changes default for detailed endpoints to false (secure by default) and clarifies config invocation semantics.
src/CoreEx.AspNetCore/GlobalUsing.cs Consolidates usings into project GlobalUsing (incl. Mvc, Options, aliases).
src/CoreEx.AspNetCore/ExecutionContextMiddleware.cs Prevents header mutation after response start.
src/CoreEx.AspNetCore/CoreExAspNetCoreExtensions.OpenTelemetry.cs Removes redundant null-check and ensures correct fluent return.
src/CoreEx.AspNetCore/CoreExAspNetCoreExtensions.GraphQLLite.cs Adds GraphQL-lite error codes for syntax/query-required errors.
src/CoreEx.AspNetCore/CoreExAspNetCoreExtensions.DependencyInjection.cs Fixes doc typo for IdempotencyKeyMiddleware registration.
src/CoreEx.AspNetCore/AGENTS.md Documents new secure-by-default detailed health-check behavior and opt-in pattern.
src/CoreEx.AspNetCore/Abstractions/WebApiPagingResult.cs Prevents overflow in prev/next paging computations by using long arithmetic + clamping.
src/CoreEx.AspNetCore/Abstractions/WebApiBase.cs Makes delete not-found conversion configurable (settable).
src/CoreEx.AspNetCore/Abstractions/WebApi.MergePatch.cs Tightens merge-patch content-type enforcement and updates error messaging.
src/CoreEx.AspNetCore/Abstractions/WebApi.Delete.cs Adds missing ConfigureAwait(false) to async path.
src/CoreEx.AspNetCore/Abstractions/WebApi.cs Ensures own-token cancellation bubbles even when converting unhandled exceptions to ProblemDetails.
src/CoreEx.AspNetCore.NSwag/CoreExNSwagExtensions.DependencyInjection.cs Adds configuration callback to flow JsonSerializerOptions into schema generation.
samples/src/Contoso.Shopping.Subscribe/Program.cs Updates health-check mapping to explicitly opt into detailed endpoints.
samples/src/Contoso.Shopping.Relay/Program.cs Updates health-check mapping to explicitly opt into detailed endpoints.
samples/src/Contoso.Shopping.Api/Program.cs Updates health-check mapping to explicitly opt into detailed endpoints.
samples/src/Contoso.Products.Subscribe/Program.cs Updates health-check mapping to explicitly opt into detailed endpoints.
samples/src/Contoso.Products.Relay/Program.cs Updates health-check mapping to explicitly opt into detailed endpoints.
samples/src/Contoso.Products.Api/Program.cs Updates health-check mapping to explicitly opt into detailed endpoints.
samples/src/Contoso.Orders.Api/Program.cs Updates health-check mapping to explicitly opt into detailed endpoints.
gen/CoreEx.Generator/Templates/ReferenceData.cs.hb Adds conditional text property emission and optional JsonPropertyName override support.
gen/CoreEx.Generator/Templates/Contract.cs.hb Adds conditional text property emission and optional JsonPropertyName override support.
gen/CoreEx.Generator/PropertyModel.cs Adds HasRefDataTextJsonName and minor hash-code formatting fix.
gen/CoreEx.Generator/ContractModel.cs Implements [ReferenceData] Text/TextJsonName handling in model creation.
docs/getting-started.md Updates docs to reflect scaffold command availability in Claude Code too.
CoreEx.slnx Adds new CoreEx.UnitTesting.Test.Unit project to solution.
CoreEx.Core.Test.Parallel.slnf Adds new CoreEx.UnitTesting.Test.Unit project to core parallel test filter.
CoreEx.Core.slnf Adds new CoreEx.UnitTesting.Test.Unit project to core solution filter.
consumer-instructions/README.md Clarifies Claude Code command wrapper requirement for /coreex-scaffold.
.github/skills/coreex-test-api/references/workflow.md Documents the new AssertWithValue(valueFactory, ...) overload usage.
.github/instructions/coreex-event-subscribers.instructions.md Updates guidance snippet for secure-by-default detailed health checks.
.claude/commands/coreex-scaffold.md Adds missing Claude Code command wrapper for the solution scaffolder skill.
Suppressed comments (1)

src/CoreEx.Template/content/CoreEx.Relay/src/app-name.Relay/Program.cs:81

  • The relay template enables detailed health-check endpoints by default. Now that HealthCheckOptions.AreDetailedEndpointsEnabled defaults to false for security, scaffolds should not opt in to detailed endpoints unless they’re also secured (e.g. RequireAuthorization). Consider leaving the default (disabled) and documenting how to enable + secure when needed.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/CoreEx.AspNetCore.Test.Api/Controllers/OtherController.cs Outdated
Comment thread src/CoreEx.Template/content/CoreEx.Api/src/app-name.Api/Program.cs Outdated
Comment thread src/CoreEx.Template/content/CoreEx.Subscribe/src/app-name.Subscribe/Program.cs Outdated
… in templates/samples

- CoreEx.Template: Relay's Program.cs enabled UseAuthorization() without
  registering authorization services (no AddControllers() to bring them in
  transitively like Api/Subscribe) - crashed at startup. Added
  AddAuthorization() explicitly.
- CoreEx.Template + samples: removed the AreDetailedEndpointsEnabled = true
  override from all host Program.cs files so scaffolded/sample apps inherit
  the secure-by-default health check behavior; preserved existing
  Health_Detailed test coverage via a CoreEx.AspNetCore.HealthChecks
  config section in each affected test project's appsettings.unittest.json.
- tests/CoreEx.AspNetCore.Test.Api: OtherController now extends
  ControllerBase instead of Controller, matching sibling test controllers.
- CoreEx.CodeGen: reverted the IRepository_cs.hbs change from the previous
  commit - the interface-declares-all/implementation-declares-some
  asymmetry for repository: None entities is intentional (forces a manual
  partial-class implementation), not a bug.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 16:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 196 out of 196 changed files in this pull request and generated no new comments.

Suppressed comments (3)

src/CoreEx.UnitTesting/UnitTestExExtensions.ServiceBus.cs:32

  • CoreEx library code convention is to use ConfigureAwait(false) on awaited calls. These SDK awaits currently omit it, which can lead to unnecessary context captures in non-test consumers.

This issue also appears on line 79 of the same file.
src/CoreEx.UnitTesting/UnitTestExExtensions.ServiceBus.cs:83

  • CoreEx library code convention is to use ConfigureAwait(false) on awaited calls. These session receiver awaits currently omit it, which can lead to unnecessary context captures in non-test consumers.
    src/CoreEx.Azure.Messaging.ServiceBus/ServiceBusReceiverResiliency.cs:61
  • Use CoreEx's ambient clock (Runtime.UtcNow) instead of DateTimeOffset.UtcNow so pause/resume timestamps are ExecutionContext-aware and deterministic in tests.

@chullybun chullybun added this to the v4.0.0-preview-4 milestone Aug 8, 2026
@chullybun
chullybun merged commit ddd048f into main Aug 8, 2026
4 checks passed
@chullybun
chullybun deleted the coreex-review branch August 8, 2026 18:17
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.

2 participants