Instruction file imported from mohamedgamal17/Nexa (
.cursor/rules/naming-conventions.mdc). Copyright stays with the author.
Naming Conventions
Purpose
Keep identifiers consistent with existing Nexa modules so commands, endpoints, errors, and tests remain discoverable.
Repository-specific standards
| Artifact | Pattern | Example |
|---|---|---|
| Command | {Verb}{Entity}Command |
CreateCustomerCommand |
| Command handler | {Command}Handler |
CreateCustomerCommandHandler |
| Query | {Verb}{Entity}Query or List{Entity}Query |
ListUserTransfersQuery |
| Query handler | {Query}Handler |
ListUserTransfersQueryHandler |
| Validator | {Request}Validator nested or separate |
CreateCustomerCommandValidator |
| Endpoint | {Verb}{Entity}Endpoint |
CreateCustomerEndpoint |
| Route group | {Area}RoutingGroup / {Entity}EndpointGroup |
CustomerRoutingGroup |
| Consumer (MassTransit) | {Event}Consumer |
TransferCompletedIntegrationEventConsumer |
| Consumer tests | When_{scenario} fixture class |
When_transfer_completed_integration_event_consumed |
| Repository interface | I{Entity}Repository / I{Module}Repository<T> |
ITransferRepository |
| EF repository | {Entity}Repository |
TransferRepository |
| Response factory | I{Entity}ResponseFactory / {Entity}ResponseFactory |
CustomerResponseFactory |
| Module installer | {Module}ModuleInstaller |
TransactionsModuleInstaller |
| Module bootstrapper | {Module}ModuleBootStrapper |
AccountingModuleBootStrapper |
| DTO | {Entity}Dto |
CustomerDto |
| Error constants | {Area}ErrorConsts |
CustomerErrorConsts, GlobalErrorConsts |
| Error codes | camelCase via ToCamelCase() on const name |
userAlreadyHasCustomer |
| Integration event | {Entity}{PastTense}IntegrationEvent |
CustomerCreatedIntegrationEvent |
| Test method | Should_{expected_outcome} |
Should_create_user_customer |
| Test fixture | {Feature}TestFixture |
TransferTestFixture |
| Fake (tests) | Fake{Service} |
FakeWalletService |
| Bogus faker | {Entity}Faker |
WalletFaker |
Interfaces: I prefix (e.g. IRepository<T>, ISecurityContext).
No Async suffix on method names (use CreateCustomerAsync only when matching external SDK names).
Namespaces: mirror folder path under project root (e.g. Nexa.CustomerManagement.Application.Customers.Commands.CreateCustomer).
Required patterns
- One command/query class per file under
Commands/{Name}/orQueries/{Name}/. - Handler implements
IApplicationRequestHandler<TRequest, TResult>. - Endpoint generic args:
Endpoint<TRequest, TResponse>whereTRequestis often the MediatR command itself. - Place validators beside commands or in same file as nested class when small (see
CreateCustomerCommand.cs).
Forbidden patterns
Handlersuffix on commands (CreateCustomerCommandHandlerCommand).- Generic names:
Manager,Helper,Utilfor application services (prefer{Entity}Service,{Entity}Factory). - New error codes as raw strings in handlers when a
*ErrorConstsentry exists. - Renaming established typos in public API (
Faild,Reciver,Accoounting,BootStrapper) unless doing a dedicated refactor—match module spelling when extending.
Good examples from repository
// src/Modules/CustomerManagement/.../CreateCustomerCommand.cs
[Authorize]
public class CreateCustomerCommand : ICommand<CustomerDto> { }
public class CreateCustomerCommandValidator : AbstractValidator<CreateCustomerCommand> { }
// tests/.../CreateCustomerCommandHandlerTests.cs
public async Task Should_create_user_customer() { }
Bad examples from repository
// src/Modules/Transactions/.../CreateBankTrasnferEndpoint.cs — typo in type name; do not add new "Trasnfer" spellings
// src/Modules/CustomerManagement/.../GetUserReviewByIdEnpoint.cs — "Enpoint" typo
Enforcement guidance for AI generation
Mirror the nearest existing feature folder (e.g. Transfers/Commands/CreateNetworkTransfer/). Grep the module for {Entity} before inventing new names.
AI Generation Constraints
Must always: use Command/Query/Handler/Endpoint suffixes; define errors in *ErrorConsts as NexaError; use Dto suffix for API models in Shared.
Must never: introduce Controller suffix for FastEndpoints; use Exception in type names for non-exception result returns.
Architectural constraints: integration events live in *.Shared and end with IntegrationEvent when published cross-module.
Naming restrictions: follow Nexa.{Module}.{Layer} project and namespace roots.
Dependency restrictions: n/a
Testing expectations: test classes {ClassUnderTest}Tests or consumer specs When_{event}_consumed.