Skip to content

Modernize ref-data querying, fix alias resolution, add coreex-graphql skill - #174

Merged
chullybun merged 5 commits into
mainfrom
refdata-query
Jul 29, 2026
Merged

Modernize ref-data querying, fix alias resolution, add coreex-graphql skill#174
chullybun merged 5 commits into
mainfrom
refdata-query

Conversation

@chullybun

Copy link
Copy Markdown
Collaborator

Summary

This branch moves reference data off its bespoke codes/textPattern filter onto the same QueryArgsConfig/dynamic-LINQ pipeline used elsewhere, adds a pluggable IReferenceDataQuery, bulk-exposes reference data through GraphQL, and fixes two bugs found during review — plus adds a new AI-enablement skill for CoreEx.Data.GraphQL.

Bug fixes

  • ReferenceDataOrchestrator.GetNamedAsync silently dropped a type's primary name once it had an alias. Fixed by adding a reverse _typeToName map; ReplaceNames now resolves input via _nameToType (accepts both primary and alias names) and normalizes output via _typeToName. Added matching ReferenceDataOrchestratorTests coverage.
  • Updated CoreEx.Data.GraphQL AGENTS.md/README.mdAddReferenceDataQueries exposes every ref-data type known to the orchestrator, not just types with an AlternateNames entry.

New: coreex-graphql AI skill

  • New L1 skill (.github/skills/coreex-graphql/SKILL.md + references/workflow.md) and matching .github/prompts/coreex-graphql.prompt.md, covering first-time AddCoreExGraphQLLite/MapCoreExGraphQLLite wiring, entity query/get root registration, bulk reference-data exposure, and recording enablement in a host's AGENTS.md.
  • Amended the coreex-api skill to offer a matching GraphQL root after scaffolding a query endpoint, when the host already has GraphQL enabled.
  • Pointed coreex-host-setup/coreex-api-controllers instructions at the new skill instead of prose-only guidance.
  • Registered the skill in the copilot-instructions.md / coreex-ai-workflows.md catalogs and wired it into CoreEx.Template.csproj's CopyTemplateAiContext packing target so dotnet new coreex-ai ships it.

Validation

  • dotnet build src/CoreEx.Template/CoreEx.Template.csproj -c Release — succeeds; verified the packed .nupkg contains the new coreex-graphql prompt/skill files under content/CoreEx.Ai/.github/....
  • dotnet build CoreEx.sln -c Release — 0 errors, 0 warnings.

Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com

chullybun and others added 3 commits July 29, 2026 10:10
ReferenceDataOrchestrator now supports QueryAsync<TRef> with dynamic LINQ-based filtering, ordering, and paging via QueryArgs and PagingArgs, replacing static codes/text/inactive filters. Controller endpoints and generated templates use the new querying model, removing DataMap and legacy GetWithFilterAsync. GraphQLLiteOptions and WebApiOptionsBase updated for friendly names and query support. Tests updated for new syntax and behaviors. New files define query configuration and implementation.
- Add non-generic QueryAsync(Type, ...) to ReferenceDataOrchestrator/IReferenceDataQuery for runtime ref-data queries.
- Refactor ReferenceDataQuery for per-type QueryArgsConfig selection; fallback to default config.
- Auto-register ReferenceDataQuery.Default in AddReferenceDataOrchestrator for OData-style filtering/paging.
- Update API controller/host setup docs to use new QueryAsync methods.
- Document AddReferenceDataQueries DI extension for GraphQL bulk registration.
- Update GraphQLEngine/GraphQLLiteOptions to use non-generic QueryAsync for ref-data roots.
- Enforce single alternate name per provider for ref-data types.
- Add tests for QueryAsync(Type, ...), per-type config, and duplicate name enforcement.
- Update READMEs for new query, DI, and GraphQL features.
…skill

- ReferenceDataOrchestrator: fix GetNamedAsync silently dropping a type's
  primary name once it had an alias by adding a reverse _typeToName map;
  ReplaceNames now resolves input via _nameToType (accepts both primary
  and alias names) and normalizes output via _typeToName.
- Add matching ReferenceDataOrchestratorTests coverage.
- Update CoreEx.Data.GraphQL AGENTS.md/README to reflect that
  AddReferenceDataQueries exposes every ref-data type known to the
  orchestrator, not just types with an AlternateNames entry.

- Add new coreex-graphql L1 skill (SKILL.md + references/workflow.md)
  and matching coreex-graphql.prompt.md, covering first-time
  AddCoreExGraphQLLite/MapCoreExGraphQLLite wiring, entity query/get
  root registration, bulk reference-data exposure, and recording
  enablement in a host's AGENTS.md.
- Amend coreex-api skill to offer a matching GraphQL root after
  scaffolding a query endpoint on a host with GraphQL already enabled.
- Point coreex-host-setup/coreex-api-controllers instructions at the
  new skill instead of prose-only guidance.
- Register coreex-graphql in the copilot-instructions.md and
  coreex-ai-workflows.md skill catalogs, and wire it into
  CoreEx.Template.csproj's CopyTemplateAiContext packing target so
  dotnet new coreex-ai ships it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 29, 2026 20:54

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

This PR modernizes reference-data querying to use the same QueryArgsConfig/dynamic-LINQ pipeline as the rest of CoreEx, fixes reference-data alias/primary-name resolution in ReferenceDataOrchestrator.GetNamedAsync, expands GraphQL-lite to bulk-expose reference data, and ships a new coreex-graphql AI skill (prompt + packaging) to standardize GraphQL-lite enablement/wiring in API hosts.

Changes:

  • Replace bespoke ref-data codes/textPattern filtering with ReferenceDataOrchestrator.QueryAsync(...) backed by a pluggable IReferenceDataQuery (ReferenceDataQuery.Default + ReferenceDataQueryArgsConfig.Default).
  • Fix alternate-name handling so primary type names remain resolvable while results normalize to the canonical external name; add/extend unit + sample tests for the new behavior.
  • Add GraphQL-lite bulk reference-data root registration (AddReferenceDataQueries) and author a new coreex-graphql skill/prompt, then wire it into the AI catalogs and template packing.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/CoreEx.RefData.Test.Unit/ReferenceDataOrchestratorTests.cs Updates/refactors tests to cover new QueryAsync path, per-type config selector, and alias/primary naming behavior.
tests/CoreEx.Data.GraphQL.Test.Unit/GraphQLLiteOptionsTests.cs Adds coverage for bulk ref-data GraphQL root registration and exclusions.
tests/CoreEx.AspNetCore.Test.Unit/ReferenceDataApi_TestsBase.cs Updates ref-data API tests to use $filter-style query strings via WithQuery(...)/include-inactive semantics.
tests/CoreEx.AspNetCore.Test.Api/Services/ReferenceDataService.cs Cleans up test provider implementation imports.
tests/CoreEx.AspNetCore.Test.Api/Services/PersonService2.cs Aligns query service signature to accept nullable PagingArgs.
tests/CoreEx.AspNetCore.Test.Api/Services/PersonService.cs Aligns query service signature to accept nullable PagingArgs.
tests/CoreEx.AspNetCore.Test.Api/Program.cs Updates minimal API ref-data endpoint to use QueryAsync and ro.QueryArgs/ro.PagingArgs.
tests/CoreEx.AspNetCore.Test.Api/Controllers/ReferenceDataController.cs Updates MVC ref-data controller to use QueryAsync and ro.QueryArgs/ro.PagingArgs.
src/CoreEx/RefData/ReferenceDataOrchestrator.cs Implements alias/primary normalization maps, adds RegisterQuery + QueryAsync APIs, and fixes GetNamedAsync canonical naming.
src/CoreEx/RefData/README.md Documents new QueryAsync + IReferenceDataQuery strategy capabilities and naming semantics.
src/CoreEx/RefData/IReferenceDataProvider.cs Adds AlternateNames support for providers.
src/CoreEx/RefData/Abstractions/IReferenceDataQuery.cs Introduces the query strategy interface used by ReferenceDataOrchestrator.QueryAsync.
src/CoreEx/Extensions.HttpRequestMessage.cs Adds request helpers for include-text / include-inactive query flags.
src/CoreEx.Template/CoreEx.Template.csproj Ensures the new coreex-graphql prompt/skill content is packaged by the template.
src/CoreEx.RefData/ReferenceDataQueryArgsConfig.cs Adds default ref-data query config (filter/orderby) for the new query pipeline.
src/CoreEx.RefData/README.md Documents default ref-data querying behavior and how to customize per type.
src/CoreEx.RefData/GlobalUsing.cs Adds CoreEx.Data querying dependencies needed by the new ref-data query implementation.
src/CoreEx.RefData/CoreExReferenceDataExtensions.DependencyInjection.cs Auto-registers ReferenceDataQuery.Default when an orchestrator factory doesn’t supply one.
src/CoreEx.RefData/CoreEx.RefData.csproj Adds a project reference to CoreEx.Data to support querying.
src/CoreEx.RefData/AGENTS.md Documents ReferenceDataQuery.Default auto-registration and per-type config customization.
src/CoreEx.RefData/Abstractions/ReferenceDataQuery.cs Implements the default dynamic-LINQ backed ref-data query strategy.
src/CoreEx.Data.GraphQL/README.md Updates docs to reflect bulk ref-data exposure behavior and naming rules.
src/CoreEx.Data.GraphQL/GraphQLLiteOptions.cs Adds AddQuery(Type, ...) and AddReferenceDataQueries(...) bulk ref-data root registration.
src/CoreEx.Data.GraphQL/GraphQLEngine.cs Routes schema execution and query/item root execution through the invoker for tracing/consistency.
src/CoreEx.Data.GraphQL/GlobalUsing.cs Adds System.Linq.Expressions (currently needs re-sorting).
src/CoreEx.Data.GraphQL/AGENTS.md Documents bulk ref-data root registration and naming rules for GraphQL-lite.
src/CoreEx.CodeGen/RefData/Templates/Service_cs.hbs Generates provider AlternateNames to support stable external naming.
src/CoreEx.CodeGen/RefData/Templates/Controller_cs.hbs Updates generated ref-data controllers to use QueryAsync and includes query/paging metadata.
src/CoreEx.AspNetCore/Abstractions/WebApiOptionsBase.cs Makes PagingArgs nullable when not specified; retains QueryArgs parsing.
samples/tests/Contoso.Products.Test.Api/HostTests.ReferenceData.cs Expands sample tests around multi-name query normalization/deduping.
samples/src/Contoso.Shopping.Application/ReferenceDataService.g.cs Updates generated sample ref-data service to emit alternate-name mappings.
samples/src/Contoso.Shopping.Api/Controllers/ReferenceDataController.g.cs Updates generated sample ref-data controllers to QueryAsync and removes old mapping/filter patterns.
samples/src/Contoso.Products.Application/ReferenceDataService.g.cs Updates generated sample ref-data service to emit alternate-name mappings.
samples/src/Contoso.Products.Api/Program.cs Adds bulk ref-data GraphQL roots via AddReferenceDataQueries.
samples/src/Contoso.Products.Api/Controllers/ReferenceDataController.g.cs Updates generated sample ref-data controllers to QueryAsync.
samples/src/Contoso.Orders.Application/ReferenceDataService.cs Adds AlternateNames to the Orders ref-data provider.
samples/src/Contoso.Orders.Api/Controllers/ReferenceDataController.cs Updates Orders ref-data endpoint to QueryAsync.
.github/skills/coreex-graphql/SKILL.md Introduces the new coreex-graphql skill documentation and usage rules.
.github/skills/coreex-graphql/references/workflow.md Adds detailed workflow steps and guardrails for GraphQL-lite enablement.
.github/skills/coreex-api/SKILL.md Updates coreex-api skill to optionally hand off to coreex-graphql when GraphQL is already enabled.
.github/prompts/coreex-graphql.prompt.md Adds the Copilot prompt wrapper for the new skill.
.github/instructions/coreex-host-setup.instructions.md Updates host setup guidance to reference the new coreex-graphql skill and ref-data querying defaults.
.github/instructions/coreex-api-controllers.instructions.md Updates controller guidance for ref-data endpoints to use QueryAsync + [Query]/[Paging] metadata.
.github/coreex-ai-workflows.md Registers coreex-graphql in the L1 skills catalog count/list.
.github/copilot-instructions.md Registers coreex-graphql in the repo’s Copilot instructions catalog.

Comment thread src/CoreEx.Data.GraphQL/GraphQLLiteOptions.cs Outdated
Comment thread src/CoreEx.Data.GraphQL/GraphQLEngine.cs Outdated
Comment thread src/CoreEx.Data.GraphQL/GlobalUsing.cs
Comment thread tests/CoreEx.AspNetCore.Test.Api/Program.cs Outdated
…sync, use params Type[] for excludeTypes, fix using-order, add Query/Paging OpenAPI metadata to ref-data query endpoints

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 29, 2026 21:14

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 45 out of 45 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (4)

tests/CoreEx.Data.GraphQL.Test.Unit/GraphQLLiteOptionsTests.cs:93

  • CreateOrchestratorServiceProvider disposes providerServiceProvider (using var) even though the created ReferenceDataOrchestrator retains that IServiceProvider for later scope creation. This leaves the orchestrator backed by a disposed provider, which can cause ObjectDisposedException if any future test (or refactor) calls into orchestrator methods that require ServiceProvider (e.g. GetByType* / QueryAsync).
    src/CoreEx/RefData/ReferenceDataOrchestrator.cs:128
  • When an alternate name equals an already-registered name for the same type (e.g. the provider mistakenly sets AlternateNames to ("DummyRefData", typeof(DummyRefData))), the primary is not null branch hits continue without populating _nameMappings / _typeToName. Because the later primary-name mapping loop skips types that appear in AlternateNames, this leaves the type with no definitive external-name mapping, so GetAlternateNameMappings() omits it and ReplaceNames can’t normalize it.
    src/CoreEx.CodeGen/RefData/Templates/Controller_cs.hbs:21
  • The generated ref-data controller actions drop cancellation propagation: they don’t accept a CancellationToken and don’t pass cancellationToken: into _webApi.GetAsync(...). This conflicts with the repo’s controller convention of taking a trailing token and flowing it through to the WebApi helper and downstream calls.
    [Query(supportsOrderBy: true), Paging(supportsCount: true)]
    public Task<IActionResult> Get{{Plural}}Async() => _webApi.GetAsync(Request, (ro, ct) => ReferenceDataOrchestrator.Current.QueryAsync<{{Name}}>(ro.QueryArgs, ro.PagingArgs, ct));

src/CoreEx.CodeGen/RefData/Templates/Controller_cs.hbs:26

  • GetNamedAsync in the template also omits the standard trailing CancellationToken and doesn’t pass it to _webApi.GetAsync(...), so generated controllers won’t honor request cancellation.
    [HttpGet]
    [ProducesResponseType(typeof(ReferenceDataMultiDictionary), 200)]
    public Task<IActionResult> GetNamedAsync([FromQuery] string[] name) => _webApi.GetAsync(Request, (ro, ct) => ReferenceDataOrchestrator.Current.GetNamedAsync(name, ro.IsIncludeInactive, ct));

ReferenceDataController methods now accept a CancellationToken and pass it to _webApi.GetAsync, enabling request cancellation. Updated Controller_cs.hbs template to generate these signatures for future codegen consistency.
Copilot AI review requested due to automatic review settings July 29, 2026 22:09
@chullybun chullybun added the enhancement New feature or request label Jul 29, 2026
@chullybun chullybun added this to the v4.0.0-preview-3 milestone Jul 29, 2026

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 45 out of 45 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (3)

tests/CoreEx.RefData.Test.Unit/ReferenceDataOrchestratorTests.cs:361

  • This test claims it uses a per-type config that "only allows filtering on Code", but new ReferenceDataQueryArgsConfig() also enables filtering on Text. As written, the assertion would still pass even if the per-type selector were ignored (because the default config behaves the same). Use a truly code-only QueryArgsConfig and assert that a text filter is rejected to prove the selector is applied.
    src/CoreEx.CodeGen/RefData/Templates/Controller_cs.hbs:22
  • The codegen controller template takes a required CancellationToken parameter. Across CoreEx controllers the convention is CancellationToken cancellationToken = default so callers aren’t forced to supply one and the signature matches the rest of the repo’s controller examples.
    [Query(supportsOrderBy: true), Paging(supportsCount: true)]
    public Task<IActionResult> Get{{Plural}}Async(CancellationToken cancellationToken)
        => _webApi.GetAsync(Request, (ro, ct) => ReferenceDataOrchestrator.Current.QueryAsync<{{Name}}>(ro.QueryArgs, ro.PagingArgs, ct), cancellationToken: cancellationToken);

src/CoreEx.CodeGen/RefData/Templates/Controller_cs.hbs:28

  • The codegen controller template’s GetNamedAsync signature should also follow the repo controller convention of CancellationToken cancellationToken = default as the trailing optional parameter.
    [HttpGet]
    [ProducesResponseType(typeof(ReferenceDataMultiDictionary), 200)]
    public Task<IActionResult> GetNamedAsync([FromQuery] string[] name, CancellationToken cancellationToken)
        => _webApi.GetAsync(Request, (ro, ct) => ReferenceDataOrchestrator.Current.GetNamedAsync(name, ro.IsIncludeInactive, ct), cancellationToken: cancellationToken);

Comment thread tests/CoreEx.Data.GraphQL.Test.Unit/GraphQLLiteOptionsTests.cs
@chullybun
chullybun merged commit 770bb78 into main Jul 29, 2026
4 checks passed
@chullybun
chullybun deleted the refdata-query branch July 29, 2026 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants