Release v4.0.0-preview-3 - #178
Merged
Merged
Conversation
- Standardized GraphQL argument handling with `args.GetIdentifier<TId>()` in all samples and instructions.
- Documented named `cancellationToken` requirement for repository paging methods to prevent parameter binding errors.
- Clarified reference data field naming: always use the contract's navigation property, not `{Name}Code`.
- Added CQRS read service/controller scaffolding gate to ensure repository query methods exist first.
- Warned against inventing CoreEx API member names; provided resolution order for correct usage.
- Updated AI skill catalog refresh guidance to require client restart after skill changes.
- Improved clarity and consistency across docs, quick-references, and workflows.
- Bumped version to `4.0.0-preview-3`.
Contributor
There was a problem hiding this comment.
Pull request overview
Publishes v4.0.0-preview-3 by bumping the shared version and applying a final clarification pass across the CoreEx docs/AI guidance (GraphQL-lite usage, query/paging conventions, CQRS scaffolding gates, and docs-sync guardrails).
Changes:
- Bump
Version.propsto4.0.0-preview-3. - Clarify/query sample patterns (notably GraphQL-lite identifier handling and named
cancellationTokenfor paging helpers). - Tighten AI skill/instruction guidance (CQRS read-service gating, ref-data field naming, “don’t invent API member names”, docs-sync restart reminder).
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| Version.props | Version bump to 4.0.0-preview-3. |
| src/CoreEx.EntityFrameworkCore/AGENTS.md | EF Core usage guide updates (CRUD + mapped model + paging/query sample). |
| src/CoreEx.Data/AGENTS.md | Query/paging sample updated to include paging + named cancellationToken. |
| src/CoreEx.Data.GraphQL/README.md | GraphQL-lite docs updated to use GetIdentifier<TId>() in AddGet. |
| src/CoreEx.Data.GraphQL/AGENTS.md | GraphQL-lite AI usage guide aligned with GetIdentifier<TId>(). |
| samples/docs/hosts-layer.md | Sample host docs aligned with current GraphQL-lite root registration pattern. |
| docs/capabilities.md | Capabilities docs aligned with current GraphQL-lite registration guidance. |
| .github/skills/coreex-repository/SKILL.md | Repository skill clarifications (ref-data nav property naming; named cancellationToken). |
| .github/skills/coreex-repository/references/workflow.md | Repository workflow guidance expanded (ref-data field rule; named cancellationToken). |
| .github/skills/coreex-graphql/SKILL.md | GraphQL skill guidance tightened (identifier arg handling; usage rules). |
| .github/skills/coreex-graphql/references/workflow.md | GraphQL workflow examples updated to GetIdentifier<TId>(). |
| .github/skills/coreex-docs-sync/SKILL.md | Docs-sync skill clarifies reporting + client restart when skill set changes. |
| .github/skills/coreex-docs-sync/README.md | Docs-sync README adds restart note after skill add/remove/rename. |
| .github/skills/coreex-app-service/SKILL.md | App-service skill adds CQRS gating: require repo query methods first. |
| .github/skills/coreex-app-service/references/workflow.md | App-service workflow adds “stop-and-check” CQRS guidance. |
| .github/skills/coreex-api/SKILL.md | API skill adds CQRS gating: create read service before read controllers. |
| .github/skills/coreex-api/references/workflow.md | API workflow adds explicit “do not skip” read-service gate. |
| .github/instructions/coreex-repositories.instructions.md | Repository instruction clarifications (named token; ref-data field naming; mapper call patterns). |
| .github/instructions/coreex-host-setup.instructions.md | Host setup instructions updated for GraphQL-lite guidance. |
| .github/instructions/coreex-conventions.instructions.md | Conventions expanded (named token guidance; “don’t invent member names” resolution order). |
| .github/copilot-instructions.md | Adds CPM note about spike/reflection projects inside the repo tree. |
Suppressed comments (1)
.github/skills/coreex-graphql/references/workflow.md:65
- GetIdentifier validates presence and type (cast) but does not perform type conversion; the comment currently implies conversion.
// GetIdentifier<TId> reads/converts the named argument (default "id") and throws an ArgumentException, mapped by the engine to ARGUMENT_ERROR, if missing/empty/wrong-typed.
.AddGet<{Entity}>("{entity}", (args, ct) => CoreEx.ExecutionContext.GetRequiredService<I{Entity}ReadService>().GetAsync(args.GetIdentifier<string>(), ct));
… sample type mismatch - GetIdentifier<TId> validates presence/type (casts to TId); it does not convert between types. Corrected wording across README/AGENTS.md/docs/skills/instructions that implied conversion (8 occurrences). - src/CoreEx.EntityFrameworkCore/AGENTS.md QueryAsync sample: return type ItemsResult<ProductLite> was inconsistent with ProductMapper.From.Map(m), which returns Product for an IBiDirectionMapper<Product, ProductModel>. Fixed return type to ItemsResult<Product> and added a note on projecting inline for a reduced Lite contract. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…, and video-scope note - Step 11: Add an Employee query endpoint via /coreex-api skill (paging, LastName EQ/StartsWith, Gender filter, LastName/FirstName/Id default ordering). - Step 12: Add GraphQL query support via /coreex-graphql skill. - Added 'Going further (optional)' divider after step 10 to distinguish the core walkthrough from these extensions. - Added a grouped table of contents (setup / core walkthrough / going further / reference). - Noted the walk-through video covers steps 1-10 only. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated no new comments.
Suppressed comments (2)
.github/skills/coreex-graphql/SKILL.md:54
name = "id"is not valid C# named-argument syntax (it should bename: "id"). As written, this example won’t compile if someone copies it verbatim.
- Use `args.GetIdentifier<TId>(name = "id")` inside an `AddGet<T>` resolver to validate the identifier argument's presence and type (it casts to `TId`, it does not convert) — it throws an `ArgumentException` (mapped to `ARGUMENT_ERROR`) if missing/empty/wrong-typed. Do not reach for `args.TryGetValue(...)` directly — `GraphQLLiteArgs` is not a dictionary; use `args.Arguments.TryGetValue(...)` only for non-identifier arguments.
src/CoreEx.Data.GraphQL/README.md:92
- This README correctly states that
GetIdentifier<TId>casts (doesn’t convert). However, the API XML docs onGraphQLLiteArgs.GetIdentifier<TId>currently say it “converts”/“convertible”, which contradicts this guidance and can confuse consumers reading IntelliSense. Consider updatingsrc/CoreEx.Data.GraphQL/GraphQLLiteArgs.csto match the actual behavior (cast-only).
// GetIdentifier<TId> validates the named argument (default "id") for presence and type (it casts to TId, it does not convert) and throws an ArgumentException - mapped by the engine to an ARGUMENT_ERROR GraphQL error - if
// it is missing, empty, or the wrong type, instead of an unhandled KeyNotFoundException/NullReferenceException surfacing as an opaque EXECUTION_ERROR.
.AddGet<Product>("product", (args, ct) => CoreEx.ExecutionContext.GetRequiredService<IProductReadService>().GetAsync(args.GetIdentifier<string>(), ct));
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
Publishes v4.0.0-preview-3. All milestone work is already on
main; this branch adds a final documentation/instructions clarification pass and bumpsVersion.propsto4.0.0-preview-3(commit 27d729f).Milestone
v4.0.0-preview-3milestone — 5/5 closed.QueryArgsConfiginto reusable per-entity classes, add query AI-enablement docsCoreEx.Data.GraphQL(GraphQL-lite) query bridgecoreex-graphqlskillJsonElementStringConverter: non-genericIConverteroverloads use swapped/wrong castsTwo additional PRs merged into
mainin this same cycle, not tagged to the milestone but part of this release's scope:JsonElementStringConverternon-genericIConverterswapped casts (closes JsonElementStringConverter: non-generic IConverter overloads use swapped/wrong casts #175)Testing summary (AI-assisted validation)
Every PR in this cycle was built/validated through iterative AI-agent review before merge, not just a single pass — #172 in particular went through "several rounds of independent/automated review" that caught real bugs (culture-sensitive float parsing, silent long→int overflow, duplicate alias last-wins bugs, a pre-existing unrelated
JsonFilterprefix-matching bug, etc.) before merge. Aggregate results reported across the individual PRs:CoreEx.Test.Unit: 705–735/735 passing (net8.0 / net9.0 / net10.0) depending on PR baseline; full suite green onmain.CoreEx.Data.Test.Unit: 120/120 passing (net8.0 / net9.0 / net10.0).CoreEx.Data.GraphQL.Test.Unit: 118/118 passing (net8.0 / net9.0 / net10.0).Contoso.Products.Test.ApiGraphQL-lite integration tests: 7/7 passing, including spec-compliant introspection.Contoso.Shopping.Test.Unit/Contoso.Shopping.Test.Subscribe: 48/48 and 15/15 passing, now restored to CI solution filters (Add omitted Shopping tests to CI filters #173).JsonFilterprefix bug inside feat: add CoreEx.Data.GraphQL (GraphQL-lite) query bridge #172) rather than only via pre-written specs — i.e. the AI review loop was exercised as a genuine defect-finding pass, not rubber-stamping.CoreEx.slnfull solution build: 0 errors, 0 warnings, all target frameworks.This branch's own change (27d729f)
Documentation/instruction clarifications discovered while doing the above AI-assisted work, folded back into the AI workflow assets so future sessions don't repeat the same mistakes:
args.GetIdentifier<TId>()) across samples/instructions.cancellationTokenrequirement for repository paging methods (prevents parameter-binding errors).{Name}Code).Version.propsto4.0.0-preview-3.Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com