You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- 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`).
18
18
- Provide incremental diffs (patches) rather than large rewrites; avoid unrelated refactors.
19
19
- Suggest and create focused tests (unit for domain/handlers, integration for endpoints/persistence) but do not let test generation block feature delivery.
20
20
@@ -74,7 +74,6 @@ Example transformation:
74
74
Before (template): `[Entity]CreateCommand` with route `api/[ModuleLower]/[EntityPlural]`
75
75
After (Customer in CoreModule): `CustomerCreateCommand` with route `api/core/customers`
76
76
77
-
78
77
## Process: Adding a New Domain Entity (Aggregate) End-to-End
79
78
80
79
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
90
89
Inputs: Business description of the new domain entity with all its state and functions.
91
90
Outputs: Aggregate class, supporting value objects/enumerations, domain events.
92
91
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.
Outputs: EF Core type configuration, DbContext update, repository registration (DI).
105
106
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).
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.
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.
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>();`.
0 commit comments