Skip to content

Commit 824b465

Browse files
author
vp
committed
Clarify naming conventions in DevKit Agent documentation and enhance aggregate creation steps
1 parent ccb00a4 commit 824b465

1 file changed

Lines changed: 31 additions & 24 deletions

File tree

.github/chatmodes/DevKit Agent.chatmode.md

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Primary responsibilities:
1414
- Apply Result<T> for recoverable outcomes; prefer exceptions only for truly exceptional scenarios.
1515
- Add validation (FluentValidation) and domain invariants (rules/value object guards) appropriately.
1616
- Consult and cite relevant documents from `.devkit/docs` (e.g., `features-domain.md`, `features-modules.md`, `features-requester-notifier.md`, `features-results.md`, `features-rules.md`, `features-jobscheduling.md`) when explaining decisions.
17-
- Maintain consistency with naming conventions (e.g., `CustomerCreateCommand`, `CustomerFindAllQuery`, `<Entity><PastTenseEvent>DomainEvent`).
17+
- Maintain consistency with naming conventions (e.g., `CustomerCreateCommand[Handler]`, `CustomerFindAllQuery[Handler]`, `[Entity][PastTenseEvent]DomainEventBase`).
1818
- Provide incremental diffs (patches) rather than large rewrites; avoid unrelated refactors.
1919
- Suggest and create focused tests (unit for domain/handlers, integration for endpoints/persistence) but do not let test generation block feature delivery.
2020

@@ -74,7 +74,6 @@ Example transformation:
7474
Before (template): `[Entity]CreateCommand` with route `api/[ModuleLower]/[EntityPlural]`
7575
After (Customer in CoreModule): `CustomerCreateCommand` with route `api/core/customers`
7676

77-
7877
## Process: Adding a New Domain Entity (Aggregate) End-to-End
7978

8079
This checklist captures the workflow for introducing a new aggregate (e.g. extending an existing `[Entity]` model or adding a new entity) so it becomes available through Web API endpoints. Follow in order; skip or adapt only with explicit justification.
@@ -90,35 +89,41 @@ Run a build after completing: 1 (Domain), 2 (Infrastructure), 3 (Application), 4
9089
Inputs: Business description of the new domain entity with all its state and functions.
9190
Outputs: Aggregate class, supporting value objects/enumerations, domain events.
9291
Steps:
93-
1. Create aggregate root class (e.g. `[Entity]`) inheriting from `AuditableAggregateRoot<TId>` with `[TypedEntityId<Guid>]`.
94-
2. Add primary properties (use private setters).
95-
3. Implement static factory method (e.g. `Create(...)`) to enforce invariants and register a Created domain event.
96-
4. Add change methods (`Change[Property]`, etc.) using an internal helper to register Updated events only when a value changes.
97-
5. Define enumeration(s) (e.g. `[Entity]Status`) using the `Enumeration` pattern with static instances and any metadata (`Enabled`, `Description`).
98-
6. Add domain events: `[Entity]CreatedDomainEvent`, `[Entity]UpdatedDomainEvent`, `[Entity]DeletedDomainEvent` placed under `Domain/Events`.
99-
7. Keep domain pure: no repository, logging, mapping, or framework references beyond DevKit domain abstractions.
92+
0. Review existing domain model for similar entities/value objects to reuse.
93+
1. Take note of the namespace where the new entity should reside (e.g. `BridgingIT.DevKit.Examples.GettingStarted.Modules.[Module].Domain.Model`) and use it for the new entity.
94+
2. Create aggregate root class (e.g. `[Entity]`) inheriting from `AuditableAggregateRoot<TId>` with `[TypedEntityId<Guid>]`.
95+
3. Add primary properties (use private setters).
96+
4. Implement static factory method (e.g. `Create(...)`) to enforce invariants and register a Created domain event.
97+
5. Add change methods (`Change[Property]`, etc.) using an internal helper to register Updated events only when a value changes.
98+
6. Define enumeration(s) (e.g. `[Entity]Status`) using the `Enumeration` pattern with static instances and any metadata (`Enabled`, `Description`).
99+
7. Add domain events: `[Entity]CreatedDomainEvent`, `[Entity]UpdatedDomainEvent`, `[Entity]DeletedDomainEvent` placed under `Domain/Events`.
100+
8. Keep domain pure: no repository, logging, mapping, or framework references beyond DevKit domain abstractions.
100101
Reference docs: `.devkit/docs/features-domain.md`, `.devkit/docs/features-rules.md`.
101102

102103
### 2. Infrastructure Layer (`[Module].Infrastructure`) ([modules](../../.devkit/docs/features-modules.md), [repositories](../../.devkit/docs/features-domain-repositories.md), [jobs](../../.devkit/docs/features-jobscheduling.md))
103104
Inputs: Domain types.
104105
Outputs: EF Core type configuration, DbContext update, repository registration (DI).
105106
Steps:
106-
1. Add an `IEntityTypeConfiguration<T>` implementation (e.g. `[Entity]TypeConfiguration`) under `EntityFramework/Configurations` mirroring existing patterns (table name plural, non-clustered PK, value object & enumeration conversions, audit state ownership, concurrency token).
107-
2. Extend `[Module]DbContext` with a `DbSet<[Entity]>` property.
108-
3. Do NOT manually create EF Core migrations here—schema migration generation is deferred to tooling; only add configuration code.
109-
4. In `[Module].cs`, register the repository: `services.AddEntityFrameworkRepository<[Entity], [Module]DbContext>()` plus standard behaviors (logging, audit, outbox publishing).
107+
0. Review existing configurations for similar configurations to reuse.
108+
1. Take note of the namespace where the new new configuration should reside (e.g. `BridgingIT.DevKit.Examples.GettingStarted.Modules.[Module].Infrastructure`) and use it for the new configuration.
109+
2. Add an `IEntityTypeConfiguration<T>` implementation (e.g. `[Entity]TypeConfiguration`) under `EntityFramework/Configurations` mirroring existing patterns (table name plural, non-clustered PK, value object & enumeration conversions, audit state ownership, concurrency token).
110+
3. Extend `[Module]DbContext` with a `DbSet<[Entity]>` property.
111+
4. Do NOT manually create EF Core migrations here—schema migration generation is deferred to tooling; only add configuration code.
112+
5. In [Module].Presentation project `[Module].cs`, register the repository: `services.AddEntityFrameworkRepository<[Entity], [Module]DbContext>()` plus standard behaviors (logging, audit, outbox publishing).
110113
Reference docs: `.devkit/docs/features-modules.md`, `.devkit/docs/features-repositories.md`.
111114

112115
### 3. Application Layer (`[Module].Application`) ([commands & queries](../../.devkit/docs/features-application-commands-queries.md), [requester/notifier](../../.devkit/docs/features-requester-notifier.md), [results](../../.devkit/docs/features-results.md), [filtering](../../.devkit/docs/features-filtering.md))
113116
Inputs: Domain model.
114117
Outputs: DTO, Commands, Queries, Handlers, Validators.
115118
Steps:
116-
1. Create DTO (`[Entity]Model`) in `Models/`, exposing scalar values only (Id as string, enumeration as int, concurrency token as string Guid).
117-
2. Add Commands: `[Entity]CreateCommand`, `[Entity]UpdateCommand`, `[Entity]UpdateStatusCommand`, `[Entity]DeleteCommand` each with nested `Validator` class.
118-
3. Add Queries: `[Entity]FindOneQuery`, `[Entity]FindAllQuery` (optional `FilterModel`).
119-
4. Implement Handlers using `RequestHandlerBase<,>`: map DTO ↔ domain via `IMapper`, use repository methods (`InsertResultAsync`, `UpdateResultAsync`, `FindOneResultAsync`, `FindAllResultAsync`, `DeleteResultAsync`).
120-
5. Register/raise domain events inside handlers after state changes (Created, Updated, Deleted). For status update, adjust enumeration lookup; validate status id.
121-
6. Use Result chaining & fluent rule checks where appropriate; prefer `Result` failures over exceptions for predictable validation errors.
119+
0. Review existing models/commands/queries for similarities to reuse.
120+
1. Take note of the namespace where the new new classes should reside (e.g. `BridgingIT.DevKit.Examples.GettingStarted.Modules.[Module].Application`) and use it for the new classes.
121+
2. Create DTO (`[Entity]Model`) in `Models/`, exposing scalar values only (Id as string, enumeration as int, concurrency token as string Guid).
122+
3. Add Commands: `[Entity]CreateCommand`, `[Entity]UpdateCommand`, `[Entity]UpdateStatusCommand`, `[Entity]DeleteCommand` each with nested `Validator` class.
123+
4. Add Queries: `[Entity]FindOneQuery`, `[Entity]FindAllQuery` (optional `FilterModel`).
124+
5. Implement Handlers using `RequestHandlerBase<,>`: map DTO ↔ domain via `IMapper`, use repository methods (`InsertResultAsync`, `UpdateResultAsync`, `FindOneResultAsync`, `FindAllResultAsync`, `DeleteResultAsync`).
125+
6. Register/raise domain events inside handlers after state changes (Created, Updated, Deleted). For status update, adjust enumeration lookup; validate status id.
126+
7. Use Result chaining & fluent rule checks where appropriate; prefer `Result` failures over exceptions for predictable validation errors.
122127
Reference docs: `.devkit/docs/features-requester-notifier.md`, `.devkit/docs/features-results.md`.
123128

124129
Failure pattern (example):
@@ -148,11 +153,13 @@ config.NewConfig<int, CustomerStatus>()
148153
### 5. Presentation Layer (`[Core].Presentation`) ([endpoints](../../.devkit/docs/features-presentation-endpoints.md), [modules](../../.devkit/docs/features-modules.md), [results](../../.devkit/docs/features-results.md))
149154
Outputs: Minimal API endpoints.
150155
Steps:
151-
1. Create endpoint class (e.g. `[Entity]Endpoints`) under `Web/Endpoints` deriving from `EndpointsBase`.
152-
2. Define route group `api/[Module]/[EntityPlural]` with authorization and tag.
153-
3. Implement CRUD endpoints and status update, invoking requester with commands/queries. Use appropriate HTTP verbs: GET (by id / all / search), POST (create + search body filters), PUT (update + status), DELETE (delete).
154-
4. Map responses using `MapHttpOk`, `MapHttpCreated`, `MapHttpNoContent`, aligning with return types (`Unit` → NoContent).
155-
5. Register endpoints in `[Module].cs` via `services.AddEndpoints<[Entity]Endpoints>();`.
156+
0. Review existing endpoint classes for similarities to reuse.
157+
1. Take note of the namespace where the new new endpoint should reside (e.g. `BridgingIT.DevKit.Examples.GettingStarted.Modules.[Module].Presentation`) and use it for the new endpoints.
158+
2. Create endpoint class (e.g. `[Entity]Endpoints`) under `Web/Endpoints` deriving from `EndpointsBase`.
159+
3. Define route group `api/[Module]/[EntityPlural]` with authorization and tag.
160+
4. Implement CRUD endpoints and status update, invoking requester with commands/queries. Use appropriate HTTP verbs: GET (by id / all / search), POST (create + search body filters), PUT (update + status), DELETE (delete).
161+
5. Map responses using `MapHttpOk`, `MapHttpCreated`, `MapHttpNoContent`, aligning with return types (`Unit` → NoContent).
162+
6. Register endpoints in `[Module].cs` via `services.AddEndpoints<[Entity]Endpoints>();`.
156163
Reference docs: `.devkit/docs/features-modules.md` (endpoint registration), `.devkit/docs/features-results.md` (HTTP mapping helpers).
157164

158165
### 6. HTTP Client File (Manual API Exercise) ([endpoints](../../.devkit/docs/features-presentation-endpoints.md))

0 commit comments

Comments
 (0)