refactor: rename Catalogs to ServiceCatalogs - Phase 1a (Domain + Inf…#19
refactor: rename Catalogs to ServiceCatalogs - Phase 1a (Domain + Inf…#19
Conversation
…rastructure) - Renamed Domain layer: entities, value objects, repositories, events - Renamed Infrastructure layer: DbContext, migrations, repositories - Updated namespaces to MeAjudaAi.Modules.ServiceCatalogs - Updated solution file to reference new paths - Updated Shared validation constants Files: 32 (Domain + Infrastructure layers) Phase: 1a of 3 Next: Phase 1b will add Application + API layers
|
Warning Rate limit exceeded@frigini has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 5 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (7)
WalkthroughThe pull request renames the Catalogs module to ServiceCatalogs across the solution structure and introduces a complete new ServiceCatalogs module with domain entities (Service, ServiceCategory), value objects, domain events, repositories, EF Core persistence layer with initial migrations, and infrastructure wiring. Changes
Sequence DiagramsequenceDiagram
participant Client
participant Handler
participant Domain as Service/Category<br/>(Domain)
participant Repo as Repository
participant DbContext as DbContext
participant Events as Domain Events
Note over Client,Events: Service Creation Flow
Client->>Handler: CreateServiceCommand
Handler->>Domain: Service.Create(categoryId, name, ...)
Domain->>Domain: Validate inputs
Domain->>Events: Emit ServiceCreatedDomainEvent
Domain-->>Handler: Service instance
Handler->>Repo: AddAsync(service)
Repo->>DbContext: Add + SaveChangesAsync
DbContext-->>Repo: Persisted
Repo-->>Handler: ✓
Handler-->>Client: Success
Note over Domain,Events: Service State Transitions
Domain->>Domain: Activate/Deactivate/Update
Domain->>Domain: Conditional validation
Domain->>Events: Emit corresponding event
Domain->>DbContext: Mark as updated
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
src/Modules/ServiceCatalogs/Domain/Exceptions/CatalogDomainException.cs (1)
1-12: CatalogDomainException is appropriate; optionally add full standard ctorsThe sealed exception with
messageandmessage + innerExceptionis enough for domain validation scenarios. If your analyzer rules or guidelines expect the full .NET exception pattern, consider later adding the parameterless and serialization constructors to avoid diagnostics and support cross-boundary serialization, but it’s not required for typical in-process domain use.src/Modules/ServiceCatalogs/Infrastructure/MeAjudaAi.Modules.ServiceCatalogs.Infrastructure.csproj (1)
1-33: Infrastructure project wiring looks good; double‑check package version strategyTargeting
net9.0, enabling nullable/implicit usings, wiringShared/Application/Domainreferences, and exposing internals to the tests project all look consistent with the rest of the module layout.For
EFCore.NamingConventions, if you’re not already using central package management (e.g.,Directory.Packages.props), it’s worth pinning an explicit Version here to keep builds reproducible across environments.src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (1)
1-32: ServiceId value object is consistent and robustValidation, factory methods, equality components, ToString, and implicit conversions all match the established pattern (e.g., ServiceCategoryId) and are suitable for use as an aggregate key and EF mapping.
If you want to tighten the type a bit further, you could mark
ServiceIdassealed(as it’s a value object not intended for inheritance):-public class ServiceId : ValueObject +public sealed class ServiceId : ValueObjectsrc/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContextFactory.cs (1)
1-55: Design‑time DbContext factory is well structured; just ensure Npgsql extensions are in scopeThe factory is nicely documented, enforces the required
ServiceCatalogs_DB_CONNECTIONconfiguration, and configures the migrations history table andSplitQuerybehavior consistently with theServiceCatalogsDbContextschema.One thing to double‑check: this relies on the Npgsql
UseNpgsqlextension method and related EF Core APIs being available in scope (typically via a reference toNpgsql.EntityFrameworkCore.PostgreSQLand an appropriateusing/ global using). If you don’t already have a global using for the Npgsql namespace, consider adding an explicitusingin this file soUseNpgsqland its options lambda resolve cleanly.src/Modules/ServiceCatalogs/Infrastructure/Extensions.cs (1)
33-67: Align connection string resolution withDapperConnectionto avoid divergenceHere you resolve connection strings only via named connection strings (
DefaultConnection,ServiceCatalogs,meajudaai-db) and then fall back to a hard-coded test connection when none are found.DapperConnection.GetConnectionString(PostgresOptions?)instead relies onPostgresOptions.ConnectionString(likely bound fromPostgres:ConnectionString) plus the same test fallback and error message.This means EF and Dapper can silently diverge: Dapper can work (options bound from
Postgres:ConnectionString) while EF fails because no named connection string is present. Consider centralizing this resolution (e.g., a shared helper that both EF and Dapper use) or at least including thePostgresOptions‑based path here so both stacks obey the same precedence rules.src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/CatalogsDbContextModelSnapshot.cs (1)
13-141: Snapshot matches the current model and migrationsThe model snapshot accurately reflects the
ServiceCatalogsDbContextmodel (schema, tables, columns, indexes, and FK behavior) and is in sync with the Designer/migration. No functional issues here. If you care about consistency, you might eventually rename the file toServiceCatalogsDbContextModelSnapshot.cs, but that’s cosmetic only.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (31)
MeAjudaAi.sln(1 hunks)src/Modules/ServiceCatalogs/Domain/Entities/Service.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceActivatedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceCategoryChangedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceCreatedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceDeactivatedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceUpdatedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryActivatedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryCreatedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryDeactivatedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryUpdatedDomainEvent.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Exceptions/CatalogDomainException.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/MeAjudaAi.Modules.ServiceCatalogs.Domain.csproj(1 hunks)src/Modules/ServiceCatalogs/Domain/Repositories/IServiceCategoryRepository.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/Repositories/IServiceRepository.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs(1 hunks)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Extensions.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/MeAjudaAi.Modules.ServiceCatalogs.Infrastructure.csproj(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Configurations/ServiceCategoryConfiguration.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Configurations/ServiceConfiguration.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.Designer.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/CatalogsDbContextModelSnapshot.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Repositories/ServiceCategoryRepository.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Repositories/ServiceRepository.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs(1 hunks)src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContextFactory.cs(1 hunks)src/Shared/Constants/ValidationConstants.cs(1 hunks)src/Shared/Constants/ValidationMessages.cs(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (25)
src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryCreatedDomainEvent.cs (3)
src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (3)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/Catalogs/Domain/Events/ServiceCategoryDomainEvents.cs (2)
ServiceCategoryCreatedDomainEvent(6-7)ServiceCategoryUpdatedDomainEvent(9-10)
src/Modules/ServiceCatalogs/Infrastructure/Extensions.cs (5)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs (1)
ServiceCatalogsDbContext(10-24)src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContextFactory.cs (1)
ServiceCatalogsDbContext(30-54)src/Shared/Database/DapperConnection.cs (1)
GetConnectionString(11-22)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Repositories/ServiceCategoryRepository.cs (1)
ServiceCategoryRepository(8-73)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Repositories/ServiceRepository.cs (1)
ServiceRepository(8-121)
src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceUpdatedDomainEvent.cs (3)
src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (3)
Service(13-159)Service(45-45)Service(55-76)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (4)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)src/Modules/Catalogs/Domain/Events/ServiceDomainEvents.cs (1)
ServiceUpdatedDomainEvent(9-10)
src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceCreatedDomainEvent.cs (4)
src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (3)
Service(13-159)Service(45-45)Service(55-76)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (4)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/Catalogs/Domain/Events/ServiceDomainEvents.cs (1)
ServiceCreatedDomainEvent(6-7)
src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryActivatedDomainEvent.cs (3)
src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (3)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/Catalogs/Domain/Events/ServiceCategoryDomainEvents.cs (2)
ServiceCategoryActivatedDomainEvent(12-13)ServiceCategoryDeactivatedDomainEvent(15-16)
src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryDeactivatedDomainEvent.cs (3)
src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (3)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/Catalogs/Domain/Events/ServiceCategoryDomainEvents.cs (2)
ServiceCategoryDeactivatedDomainEvent(15-16)ServiceCategoryActivatedDomainEvent(12-13)
src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (3)
src/Shared/Domain/ValueObject.cs (1)
ValueObject(3-32)src/Shared/Time/UuidGenerator.cs (1)
UuidGenerator(8-33)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (2)
IEnumerable(23-26)ToString(28-28)
src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryUpdatedDomainEvent.cs (3)
src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (3)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/Catalogs/Domain/Events/ServiceCategoryDomainEvents.cs (1)
ServiceCategoryUpdatedDomainEvent(9-10)
src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (3)
src/Shared/Domain/ValueObject.cs (1)
ValueObject(3-32)src/Shared/Time/UuidGenerator.cs (1)
UuidGenerator(8-33)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (2)
IEnumerable(23-26)ToString(28-28)
src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceActivatedDomainEvent.cs (3)
src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (3)
Service(13-159)Service(45-45)Service(55-76)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (4)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)src/Modules/Catalogs/Domain/Events/ServiceDomainEvents.cs (1)
ServiceActivatedDomainEvent(12-13)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.cs (2)
src/Modules/Catalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.cs (2)
MeAjudaAi(6-118)Up(12-104)src/Modules/Catalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.Designer.cs (1)
DbContext(14-145)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Configurations/ServiceCategoryConfiguration.cs (3)
src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (3)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Configurations/ServiceConfiguration.cs (1)
Configure(10-76)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)
src/Modules/ServiceCatalogs/Domain/Repositories/IServiceCategoryRepository.cs (2)
src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (3)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs (6)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContextFactory.cs (1)
ServiceCatalogsDbContext(30-54)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.Designer.cs (1)
DbContext(14-145)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/CatalogsDbContextModelSnapshot.cs (1)
DbContext(13-142)src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (3)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (3)
Service(13-159)Service(45-45)Service(55-76)src/Modules/Catalogs/Infrastructure/Persistence/CatalogsDbContext.cs (1)
CatalogsDbContext(10-24)
src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceCategoryChangedDomainEvent.cs (4)
src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (3)
Service(13-159)Service(45-45)Service(55-76)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (4)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/Catalogs/Domain/Events/ServiceDomainEvents.cs (1)
ServiceCategoryChangedDomainEvent(18-22)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/CatalogsDbContextModelSnapshot.cs (3)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.Designer.cs (1)
DbContext(14-145)src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs (1)
ServiceCatalogsDbContext(10-24)src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContextFactory.cs (1)
ServiceCatalogsDbContext(30-54)
src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceDeactivatedDomainEvent.cs (2)
src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (3)
Service(13-159)Service(45-45)Service(55-76)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (4)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContextFactory.cs (1)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs (1)
ServiceCatalogsDbContext(10-24)
src/Modules/ServiceCatalogs/Domain/Repositories/IServiceRepository.cs (4)
src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (3)
Service(13-159)Service(45-45)Service(55-76)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (5)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)IEnumerable(23-26)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (5)
IEnumerable(23-26)ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/Catalogs/Domain/Repositories/IServiceRepository.cs (1)
IServiceRepository(9-69)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Repositories/ServiceCategoryRepository.cs (4)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs (1)
ServiceCatalogsDbContext(10-24)src/Modules/ServiceCatalogs/Domain/Repositories/IServiceCategoryRepository.cs (7)
Task(16-16)Task(23-23)Task(30-30)Task(38-38)Task(45-45)Task(52-52)Task(59-59)src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (4)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)Update(68-80)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)
src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (5)
src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (6)
ValidateName(139-146)ValidateDescription(148-152)ValidateDisplayOrder(154-158)Update(81-93)Activate(117-124)Deactivate(130-137)src/Shared/Domain/BaseEntity.cs (2)
AddDomainEvent(22-22)MarkAsUpdated(24-24)src/Modules/ServiceCatalogs/Domain/Exceptions/CatalogDomainException.cs (3)
CatalogDomainException(6-12)CatalogDomainException(8-8)CatalogDomainException(10-11)src/Shared/Constants/ValidationConstants.cs (2)
ValidationConstants(9-79)CatalogLimits(69-78)
src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (6)
src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (4)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (9)
ServiceCategory(13-127)ServiceCategory(37-37)ServiceCategory(46-63)ValidateName(107-114)ValidateDescription(116-120)ValidateDisplayOrder(122-126)Update(68-80)Activate(85-92)Deactivate(98-105)src/Modules/ServiceCatalogs/Domain/Exceptions/CatalogDomainException.cs (3)
CatalogDomainException(6-12)CatalogDomainException(8-8)CatalogDomainException(10-11)src/Shared/Domain/BaseEntity.cs (2)
AddDomainEvent(22-22)MarkAsUpdated(24-24)src/Shared/Constants/ValidationConstants.cs (2)
ValidationConstants(9-79)CatalogLimits(69-78)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Repositories/ServiceRepository.cs (5)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs (1)
ServiceCatalogsDbContext(10-24)src/Modules/ServiceCatalogs/Domain/Repositories/IServiceRepository.cs (9)
Task(16-16)Task(23-23)Task(30-30)Task(37-37)Task(45-45)Task(54-54)Task(62-62)Task(69-69)Task(76-76)src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (4)
Service(13-159)Service(45-45)Service(55-76)Update(81-93)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (5)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)IEnumerable(23-26)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (5)
IEnumerable(23-26)ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Configurations/ServiceConfiguration.cs (4)
src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (3)
Service(13-159)Service(45-45)Service(55-76)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Configurations/ServiceCategoryConfiguration.cs (1)
Configure(10-59)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceId.cs (4)
ServiceId(9-32)ServiceId(13-18)ServiceId(20-20)ServiceId(21-21)src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (4)
ServiceCategoryId(9-32)ServiceCategoryId(13-18)ServiceCategoryId(20-20)ServiceCategoryId(21-21)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.Designer.cs (5)
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/CatalogsDbContextModelSnapshot.cs (1)
DbContext(13-142)src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs (1)
ServiceCatalogsDbContext(10-24)src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContextFactory.cs (1)
ServiceCatalogsDbContext(30-54)src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.cs (1)
InitialCreate(9-117)src/Modules/Catalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.Designer.cs (3)
DbContext(14-145)BuildTargetModel(19-144)b(29-82)
🔇 Additional comments (31)
src/Shared/Constants/ValidationMessages.cs (1)
80-83: Doc summary now matches ServiceCatalogs module namingThe updated summary correctly reflects the ServiceCatalogs module without affecting behavior. No further changes needed here.
src/Shared/Constants/ValidationConstants.cs (1)
66-70: ValidationConstants summary aligned with ServiceCatalogs namingThe summary text now matches the ServiceCatalogs terminology and leaves the constants behavior untouched. Looks good.
src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryDeactivatedDomainEvent.cs (1)
1-7: ServiceCategoryDeactivatedDomainEvent matches existing domain event conventionsThe event shape (keyed by
CategoryId.Value,Version: 1) is consistent with the other ServiceCategory events and the aggregate’sDeactivatemethod. No issues spotted.src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryActivatedDomainEvent.cs (1)
1-7: ServiceCategoryActivatedDomainEvent is consistent with the ServiceCategory event suiteThis event cleanly follows the same pattern as the other ServiceCategory domain events (Id + version), so wiring from
Activate()should behave as expected.src/Modules/ServiceCatalogs/Domain/MeAjudaAi.Modules.ServiceCatalogs.Domain.csproj (1)
1-19: ServiceCatalogs.Domain project configuration is clean and layered correctlyThe domain project targeting
net9.0, depending only onShared, and exposing internals to the tests assembly aligns well with the intended architecture. No changes suggested here.src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceUpdatedDomainEvent.cs (1)
1-7: ServiceUpdatedDomainEvent correctly represents Service updatesThe event definition matches the pattern used by the
Serviceaggregate (Id+ fixed version) and aligns with the previous Catalogs events. Looks solid.src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryCreatedDomainEvent.cs (1)
1-7: ServiceCategoryCreated event mirrors the previous Catalogs event correctlyUsings, namespace, payload, and DomainEvent key all align with the existing pattern; this is a clean relocation/rename with no behavioral change.
src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceCreatedDomainEvent.cs (1)
1-7: ServiceCreated event is correctly modeled around the Service aggregateThe event shape (ServiceId + CategoryId) and use of ServiceId.Value as the DomainEvent key are consistent with the existing Catalogs implementation and the Service.Create factory.
src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceActivatedDomainEvent.cs (1)
1-7: ServiceActivated event wiring looks correctThe event’s payload and use of
ServiceId.Valueas the DomainEvent identifier match the activation logic inService.Activate()and the previous Catalogs event.src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceDeactivatedDomainEvent.cs (1)
1-7: ServiceDeactivated event is consistent with activation and legacy behaviorShape and keying match the Catalogs version and the
Service.Deactivate()method, keeping the lifecycle event pattern coherent.src/Modules/ServiceCatalogs/Domain/Events/ServiceCategory/ServiceCategoryUpdatedDomainEvent.cs (1)
1-7: ServiceCategoryUpdated event cleanly mirrors the old Catalogs eventCorrectly carries only the
CategoryIdand usesCategoryId.Valueas the DomainEvent key, matching theServiceCategory.Update()behavior.src/Modules/ServiceCatalogs/Domain/Events/Service/ServiceCategoryChangedDomainEvent.cs (1)
1-10: ServiceCategoryChanged event correctly captures the category transitionIncluding both old and new category IDs with
ServiceId.Valueas the DomainEvent key matches theService.ChangeCategorybehavior and the legacy event, so consumers can react with full context.src/Modules/ServiceCatalogs/Infrastructure/Extensions.cs (1)
24-95: Overall infrastructure wiring looks consistent and cohesiveDbContext registration, repository registrations, and command/query handler wiring are coherent and align with the new ServiceCatalogs module structure and migrations. Nothing blocking here.
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.cs (1)
12-116: Migration matches the new schema and domain modelThe
InitialCreatemigration cleanly recreates the previous structure under theServiceCatalogsschema: table shapes, constraints, and indexes are consistent with the Designer and model snapshot. Up/Down are symmetric and look correct.src/Modules/ServiceCatalogs/Infrastructure/Persistence/ServiceCatalogsDbContext.cs (1)
7-23: DbContext configuration is minimal and correctDefault schema, DbSets, and
ApplyConfigurationsFromAssemblyall line up with the migrations and EF configurations. This is a clean, conventional DbContext for the module.src/Modules/ServiceCatalogs/Domain/ValueObjects/ServiceCategoryId.cs (1)
9-32: Strongly-typed ID implementation looks solidNon-empty Guid enforcement, value-based equality, factory methods, and implicit conversions are all coherent and consistent with the existing
ServiceIdpattern.src/Modules/ServiceCatalogs/Infrastructure/Persistence/Configurations/ServiceCategoryConfiguration.cs (1)
8-59: ServiceCategory EF configuration matches domain and migrationsTable name, value-object Id conversion, max lengths, required flags, and index names all align with
ServiceCategoryvalidations and theInitialCreatemigration. IgnoringDomainEventsis appropriate.src/Modules/ServiceCatalogs/Infrastructure/Persistence/Migrations/20251117205349_InitialCreate.Designer.cs (1)
12-144: Migration designer is consistent with model configurationThe model snapshot for
ServiceandServiceCategory(schema, columns, max lengths, indexes, and FK constraint) matches the explicit configurations and theInitialCreatemigration. No manual edits needed here.src/Modules/ServiceCatalogs/Domain/Repositories/IServiceCategoryRepository.cs (1)
6-59: ServiceCategory repository interface is cohesive and matches domain needsMethod set (lookups, listing with
activeOnly, existence check, and basic CRUD) is clear and aligns with theServiceCategoryaggregate and the EF implementation.src/Modules/ServiceCatalogs/Infrastructure/Persistence/Configurations/ServiceConfiguration.cs (1)
8-75: Service EF configuration is consistent and well‑indexedMappings (value-object keys, required fields, max lengths) and index/relationship setup match the
Service/ServiceCategorydomain model and the migration. IgnoringDomainEventsis correct.src/Modules/ServiceCatalogs/Infrastructure/Persistence/Repositories/ServiceCategoryRepository.cs (1)
25-36: UseAsNoTrackingforGetAllAsyncread query
GetAllAsynccurrently uses a tracked query, while other read methods useAsNoTracking. For consistency and to avoid unnecessary tracking for list scenarios, consider:- var query = context.ServiceCategories.AsQueryable(); + var query = context.ServiceCategories + .AsNoTracking();[ suggest_recommended_refactor ]
src/Modules/ServiceCatalogs/Domain/Repositories/IServiceRepository.cs (1)
6-83: Service repository interface cleanly models required queries and commandsAPI shape (ID/name/category queries,
activeOnlyfilters, existence/count helpers, and CRUD) is coherent and matches theServiceRepositoryimplementation and domain semantics.src/Modules/ServiceCatalogs/Domain/Entities/ServiceCategory.cs (1)
9-126: ServiceCategory aggregate invariants and events look solidValidation rules match
ValidationConstantsand EF config, state changes are idempotent, and each mutation correctly marks the entity as updated and emits the appropriate domain event. This is a clear and consistent DDD aggregate.MeAjudaAi.sln (1)
152-168: LGTM! Solution file correctly updated for module rename.The project references have been properly renamed from
CatalogstoServiceCatalogsacross all layers (Domain, Application, Infrastructure, API, Tests) with paths updated accordingly. GUIDs are correctly preserved, ensuring existing project references and build configurations remain intact.src/Modules/ServiceCatalogs/Domain/Entities/Service.cs (7)
1-7: LGTM! Imports and namespace correctly configured.The using statements include all necessary dependencies (domain events, exceptions, value objects, shared constants, and domain base classes), and the namespace correctly reflects the renamed ServiceCatalogs module structure.
13-42: LGTM! Well-designed aggregate root with proper encapsulation.The entity follows DDD best practices:
- Sealed class prevents inheritance
- Private setters protect invariants
- Navigation property supports lazy loading
- Comprehensive XML documentation
The
null!initialization on Line 18 is an acceptable pattern for EF Core compatibility with non-nullable reference types, as the Create factory method ensures proper initialization.
55-76: LGTM! Factory method correctly enforces domain invariants.The Create method properly:
- Validates all inputs before construction
- Initializes with a new ServiceId
- Sets sensible defaults (IsActive = true)
- Trims string inputs to prevent whitespace issues
- Emits ServiceCreatedDomainEvent with both service and category identifiers
81-93: LGTM! Update method follows proper domain patterns.The method correctly validates inputs, updates properties with trimmed values, marks the entity as updated, and emits the appropriate domain event.
98-112: LGTM! Category change logic is well-implemented.The method correctly:
- Validates the new categoryId
- Avoids no-op changes with early return
- Stores the old categoryId for the domain event
- Invalidates the Category navigation property (Line 108) to ensure EF Core reloads it when needed
- Emits a comprehensive domain event with both old and new identifiers
The comparison on Line 103 could optionally use
CategoryId == newCategoryIdsince ValueObject implements equality, but the explicit.Valuecomparison is clear and correct.
117-137: LGTM! Activation state management is properly implemented.Both methods correctly:
- Use early returns to prevent no-op state changes and duplicate events
- Update the IsActive flag appropriately
- Mark the entity as updated
- Emit the corresponding domain events
The documentation clearly explains the business rules around service deactivation.
139-158: LGTM! Validation logic is thorough and consistent.The validation methods correctly:
- Enforce required fields (Name)
- Validate string lengths after trimming (preventing whitespace padding issues)
- Check business rules (non-negative DisplayOrder)
- Use shared validation constants for consistency
- Provide clear error messages including actual limits
- Handle optional fields appropriately (Description)
The approach is consistent with the ServiceCategory entity validation pattern.
src/Modules/ServiceCatalogs/Infrastructure/Persistence/Repositories/ServiceRepository.cs
Show resolved
Hide resolved
…uild Code review fixes: - Add null/empty guard in ServiceRepository.GetByIdsAsync to prevent NullReferenceException - Add parameterless constructor to CatalogDomainException for full .NET pattern - Mark ServiceId as sealed (value object not intended for inheritance) - Add explicit Npgsql using in ServiceCatalogsDbContextFactory - Align connection string resolution with DapperConnection (include Postgres:ConnectionString) Phase 1a preparation: - Remove Application layer references from Infrastructure project - Remove Application project reference from Infrastructure.csproj - Remove command/query handler registrations from Extensions.cs - Remove Application, API and Tests projects from solution file - Add note about handlers being added in Phase 1b Build verified successfully.
…rastructure)
Files: 32 (Domain + Infrastructure layers)
Phase: 1a of 3
Next: Phase 1b will add Application + API layers
Summary by CodeRabbit
New Features
Chores