Skip to content

Add coreex-aggregate skill (DDD domain objects)#162

Merged
chullybun merged 10 commits into
mainfrom
skills/coreex-aggregate
Jul 1, 2026
Merged

Add coreex-aggregate skill (DDD domain objects)#162
chullybun merged 10 commits into
mainfrom
skills/coreex-aggregate

Conversation

@chullybun

Copy link
Copy Markdown
Collaborator

Summary

Adds the coreex-aggregate skill for adding/modifying DDD domain objects (aggregate roots, child entities, value objects) built on CoreEx.DomainDriven, per the L1 skills inventory in #151.

Intentionally domain-agnostic — unlike sample-anchored skills (coreex-adapter, coreex-subscriber), this skill uses generic {Aggregate}/{ChildEntity}/{ValueObject} placeholders throughout rather than referencing samples/src/Contoso.Shopping.Domain/ directly, per explicit direction for this skill.

What's included

  • .github/skills/coreex-aggregate/SKILL.md — entry point: when to use / not use, quick reference, key references (instructions files + actual CoreEx.DomainDriven source, not samples)
  • .github/skills/coreex-aggregate/references/workflow.md — full workflow:
    • Phase 0 — confirm a Domain layer is actually warranted (skip for CRUD-oriented domains)
    • Phase 1 — interview to branch into aggregate root / entity / value object
    • Step 1 — Aggregate Root pattern (Aggregate<TId,TSelf>, CreateNew/CreateFrom, OnCheckCanMutate/OnMutate)
    • Step 2 — Child Entity pattern (Entity<TId,TSelf>, internal mutation methods, consumer-authored Clone(PersistenceState) helper)
    • Step 3 — Value Object pattern (sealed record, invariants in init accessors)
    • Unit Testing Aggregates — new section generalizing samples/tests/Contoso.Shopping.Test.Unit/Domains/BasketTests.cs: aggregates have no injected dependencies (beyond reference data), making them the best unit-test target in the codebase for both happy-path and business-rule-rejection coverage
    • Guard Helpers Reference, PersistenceState Reference (with actual transition nuances — New stays New on Modify, Remove is terminal + read-only), Integration Events (not domain events) rationale, Guardrails
  • .github/prompts/coreex-aggregate.prompt.md/coreex-aggregate prompt bridge
  • Wired into src/CoreEx.Template/CoreEx.Template.csproj

Key rules captured

  • Constructor always private; CreateNew(...)/CreateFrom(...) are the only public construction paths
  • Modify(...)/Remove(...) are the only mutation paths — Remove(...) is terminal (sets Removed + MakeReadOnly(), no restore path)
  • Child-entity mutation methods are internal, never public
  • OnCheckCanMutate() guard failures throw the exception carried by the failed Result (typically BusinessException); other mutation methods may instead return a failed Result directly (e.g. not-found) — tests need to assert each correctly
  • No async I/O in domain classes — ever
  • No native domain-event dispatch (MediatR-style) — only coarse integration events via Aggregate<TId,TSelf>.Events, forwarded by the Application layer
  • Aggregate unit tests (WithGenericTester<EntryPoint> + Test.Scoped(...)) cover mutation logic that request-validator tests structurally cannot reach

Validation

  • Self-reviewed via rubber-duck sub-agent twice (once for the base skill, once for the added testing section) — each pass caught real accuracy issues before commit (child-entity factory visibility, ThrowOnError() overstatement, PersistenceState transition nuances, Clone() mislabeling, a nonexistent Runtime.Clock API reference, an overbroad "always throws" claim, an overstated validator claim, and overly narrow reference-data wiring guidance) — all fixed
  • dotnet build src/CoreEx.Template/CoreEx.Template.csproj -c Release — 0 warnings, 0 errors

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

chullybun and others added 9 commits June 30, 2026 10:52
…cing skills

coreex-db-migration and coreex-refdata skills had decision tables keyed
on Contoso domain names (Products/Shopping/Orders) rather than the
consumer's actual database type choice. Replace with generic
PostgreSQL vs SQL Server rows and 'check Program.cs' guidance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds the coreex-aggregate skill for DDD domain objects (aggregate
root, entity, value object) built on CoreEx.DomainDriven. Kept
domain-agnostic per request (generic {Aggregate}/{Entity}/{ValueObject}
placeholders) rather than tied to the Contoso.Shopping.Domain sample.

- .github/skills/coreex-aggregate/SKILL.md - entry point: when to use,
  quick reference, interview-driven branching (aggregate root vs entity
  vs value object)
- .github/skills/coreex-aggregate/references/workflow.md - full workflow:
  Phase 0 (confirm Domain layer warranted), Phase 1 interview, Step 1-3
  patterns, PersistenceState transition rules, guard helpers, integration
  events (not domain events), guardrails
- .github/prompts/coreex-aggregate.prompt.md - prompt bridge
- Wired into CoreEx.Template.csproj

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds a 'Unit Testing Aggregates' section to workflow.md, generalized
from samples/tests/Contoso.Shopping.Test.Unit/Domains/BasketTests.cs.
Aggregates have no injected dependencies (beyond reference data), making
them ideal traditional unit-test targets for both happy-path and
guard-rejection logic.

Covers: WithGenericTester<EntryPoint> + Test.Scoped(...) pattern, arranging
via CreateFrom, invoking mutation methods directly, asserting
OnCheckCanMutate guard failures as thrown BusinessException vs other
methods returning a failed Result, reference-data test wiring, and how
this differs from (and doesn't replace) request-validator tests.

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

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

Adds a new coreex-aggregate skill to guide developers in creating/modifying DDD domain objects (aggregate roots, child entities, value objects) using CoreEx.DomainDriven, and wires the skill assets into the template packaging so they ship with generated .github/ AI assets.

Changes:

  • Added .github/skills/coreex-aggregate/ skill entrypoint plus a detailed workflow reference (including aggregate unit testing guidance).
  • Added a /coreex-aggregate prompt bridge under .github/prompts/.
  • Updated src/CoreEx.Template/CoreEx.Template.csproj to copy/pack the new prompt + skill files.

Reviewed changes

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

File Description
src/CoreEx.Template/CoreEx.Template.csproj Includes the new coreex-aggregate prompt/skill files in the AI content pack and copy steps.
.github/skills/coreex-aggregate/SKILL.md Introduces the coreex-aggregate skill (scope, quick reference, and links to authoritative references).
.github/skills/coreex-aggregate/references/workflow.md Provides the end-to-end workflow for aggregates/entities/value objects and aggregate unit testing guidance.
.github/prompts/coreex-aggregate.prompt.md Adds the agent-mode prompt wrapper to invoke the skill consistently.

Comment thread .github/skills/coreex-aggregate/references/workflow.md
Comment thread .github/skills/coreex-aggregate/references/workflow.md
Comment thread .github/skills/coreex-aggregate/references/workflow.md Outdated
Comment thread .github/skills/coreex-aggregate/references/workflow.md Outdated
Comment thread .github/skills/coreex-aggregate/references/workflow.md Outdated
- Introduce {NewIdExpression} placeholder instead of hard-coding
  Runtime.NewId() in the aggregate root / child entity examples, since
  Runtime.NewId() always returns string and would be wrong/misleading
  for a Guid (or other) {IdType}. Rules now explain to pick
  Runtime.NewId() vs Runtime.NewGuid() based on the actual id type.
- Corrected the Test.Scoped(...) rationale: Runtime.NewId()/NewGuid()
  resolve via IdentifierGenerator.Current and do not need an ambient
  ExecutionContext; only Runtime.UtcNow and reference-data validity
  checks (ThrowIfInactive) do.
- Replaced quoted "{id}" literals in the unit-test examples with an
  unquoted {id} placeholder so the pattern doesn't imply string-only
  identifiers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@chullybun chullybun added the enhancement New feature or request label Jul 1, 2026
@chullybun chullybun added this to the v4.0.0-preview-2 milestone Jul 1, 2026
@chullybun chullybun merged commit fe8a551 into main Jul 1, 2026
4 of 5 checks passed
@chullybun chullybun deleted the skills/coreex-aggregate branch July 1, 2026 22:00
@chullybun chullybun restored the skills/coreex-aggregate branch July 1, 2026 22:01
@chullybun chullybun deleted the skills/coreex-aggregate branch July 1, 2026 22:02
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