# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Codex is a CQRS-based ASP.NET Core 8.0 Web API using the OpenHarbor.CQRS framework with a modular architecture powered by PoweredSoft modules. ## .NET Version Policy **IMPORTANT**: This project uses .NET 8.0 LTS and should NOT be upgraded to .NET 9 or later versions without explicit approval. All projects must target `net8.0`. ## Docker Setup (Recommended) This project uses Docker containers for PostgreSQL and Ollama: ```bash # Start all services (PostgreSQL + Ollama) docker-compose up -d # Verify containers are running docker ps # Apply database migrations dotnet ef database update --project Codex.Dal --connection "Host=localhost;Database=codex;Username=postgres;Password=postgres" # Stop services docker-compose down # Reset database (CAUTION: deletes all data) docker-compose down -v docker-compose up -d dotnet ef database update --project Codex.Dal --connection "Host=localhost;Database=codex;Username=postgres;Password=postgres" ``` **Services**: - **PostgreSQL**: localhost:5432 (codex/postgres/postgres) - **Ollama**: localhost:11434 **Important**: If you have a local PostgreSQL running on port 5432, stop it first: ```bash brew services stop postgresql@14 # or your PostgreSQL version ``` ### Ollama Model Management ```bash # Pull a lightweight model for testing (1.6GB) docker exec codex-ollama ollama pull phi # List downloaded models docker exec codex-ollama ollama list # Test Ollama is working curl http://localhost:11434/api/tags ``` ## Building and Running ```bash # Build the solution dotnet build # Run the API dotnet run --project Codex.Api/Codex.Api.csproj # Run tests (when test projects are added) dotnet test ``` The API runs on: - HTTP: http://localhost:5246 - HTTPS: https://localhost:7108 - Swagger UI (Development only): http://localhost:5246/swagger ## Architecture ### CQRS Pattern This application strictly follows the Command Query Responsibility Segregation (CQRS) pattern: - **Commands**: Handle write operations (create, update, delete). Execute business logic and persist data. - **Queries**: Handle read operations. Always use `.AsNoTracking()` for read-only operations. ### Module System The application uses PoweredSoft's module system (`IModule`) to organize features. Each module registers its services in the `ConfigureServices` method. **Module Registration Flow**: 1. Create feature-specific modules (CommandsModule, QueriesModule, DalModule) 2. Register all modules in `AppModule` 3. Register `AppModule` in `Program.cs` via `services.AddModule()` ### Project Structure - **Codex.Api**: API layer with controllers, Program.cs, and AppModule - **Codex.CQRS**: Commands, queries, and business logic - **Codex.Dal**: Data access layer with DbContext, entities, and query provider infrastructure ## Commands Commands perform write operations and follow a strict 3-part structure: **1. Command Definition** (record) ```csharp public record MyCommand { // Properties } ``` **2. Handler Implementation** (implements `ICommandHandler`) ```csharp public class MyCommandHandler(DbContext dbContext) : ICommandHandler { public async Task HandleAsync(MyCommand command, CancellationToken cancellationToken = default) { // Business logic } } ``` **3. Validation** (extends `AbstractValidator`) ```csharp public class MyCommandValidator : AbstractValidator { public MyCommandValidator() { // FluentValidation rules } } ``` **Registration**: All three components go in a single file and are registered together: ```csharp services.AddCommand(); ``` ## Queries ### Single Value Queries Return a specific value (e.g., health check, lookup): ```csharp public record MyQuery { } public class MyQueryHandler : IQueryHandler { public Task HandleAsync(MyQuery query, CancellationToken cancellationToken = default) { // Return single value } } // Registration services.AddQuery(); ``` ### Paginated Queries Return queryable lists with automatic filtering, sorting, pagination, and aggregates: ```csharp // 1. Define the item structure public record MyQueryItem { // Properties for each list item } // 2. Implement IQueryableProviderOverride public class MyQueryableProvider(DbContext dbContext) : IQueryableProviderOverride { public Task> GetQueryableAsync(object query, CancellationToken cancellationToken = default) { var result = dbContext.MyTable .AsNoTracking() // ALWAYS use AsNoTracking for queries .Select(x => new MyQueryItem { /* mapping */ }); return Task.FromResult(result); } } // Registration services.AddDynamicQuery() .AddQueryableProviderOverride(); ``` **IMPORTANT**: Paginated queries return `IQueryable`. The framework handles actual query execution, pagination, filtering, and sorting. ## Data Access Layer Setup The DAL requires specific infrastructure files for the CQRS query system to work properly: ### Required Files 1. **IQueryableProviderOverride.cs**: Interface for custom query providers 2. **ServiceCollectionExtensions.cs**: Extension to register query provider overrides 3. **DefaultQueryableProvider.cs**: Default provider that checks for overrides 4. **InMemoryQueryableHandlerService.cs**: Handler for in-memory queryables 5. **DalModule.cs**: Module to register DAL services All code examples for these files are in `.context/dal-context.md`. ### DbContext Create your DbContext with EF Core and use migrations for schema management: ```bash # Add a new migration dotnet ef migrations add --project Codex.Dal # Update database dotnet ef database update --project Codex.Dal ``` ### OpenAPI Documentation Export After adding or modifying commands/queries with XML documentation: ```bash # Build and export OpenAPI specification dotnet build ./export-openapi.sh # This generates docs/openapi.json for frontend integration ``` ## API Configuration (Program.cs) Required service registrations: ```csharp // PoweredSoft & CQRS builder.Services.AddPoweredSoftDataServices(); builder.Services.AddPoweredSoftEntityFrameworkCoreDataServices(); builder.Services.AddPoweredSoftDynamicQuery(); builder.Services.AddDefaultCommandDiscovery(); builder.Services.AddDefaultQueryDiscovery(); // Validation builder.Services.AddFluentValidation(); // Module registration builder.Services.AddModule(); // Controllers with OpenHarbor CQRS integration var mvcBuilder = builder.Services .AddControllers() .AddJsonOptions(jsonOptions => { jsonOptions.JsonSerializerOptions.Converters.Insert(0, new JsonStringEnumConverter()); }); mvcBuilder.AddOpenHarborCommands(); mvcBuilder.AddOpenHarborQueries() .AddOpenHarborDynamicQueries(); ``` **Note**: Controllers (not minimal APIs) are required for OpenHarbor CQRS integration. ## Key Dependencies - **OpenHarbor.CQRS**: CQRS framework core - **OpenHarbor.CQRS.AspNetCore.Mvc**: MVC integration for commands/queries - **OpenHarbor.CQRS.DynamicQuery.AspNetCore**: Dynamic query support - **OpenHarbor.CQRS.FluentValidation**: FluentValidation integration - **PoweredSoft.Module.Abstractions**: Module system - **PoweredSoft.Data.EntityFrameworkCore**: Data access abstractions - **PoweredSoft.DynamicQuery**: Dynamic query engine - **FluentValidation.AspNetCore**: Validation ## Development Guidelines 1. **Query Performance**: Always use `.AsNoTracking()` for read-only queries 2. **File Organization**: Place command/handler/validator in the same file 3. **Validation**: All commands must have validators (even if empty) 4. **Modules**: Group related commands/queries into feature modules 5. **XML Documentation**: Add XML comments to all commands/queries for OpenAPI generation 6. **OpenAPI Export**: Run `./export-openapi.sh` after API changes to update frontend specs 7. **CORS**: Configure allowed origins in appsettings for different environments 8. **HTTPS**: Only enforced in non-development environments # 🔒 MANDATORY CODING STANDARDS ## Strict Typing - NO EXCEPTIONS See [.claude-docs/strict-typing.md](.claude-docs/strict-typing.md) for complete typing requirements. --- ## 🗣️ Response Protocol See [.claude-docs/response-protocol.md](.claude-docs/response-protocol.md) for complete protocol details. --- ## 📡 Frontend Integration See [.claude-docs/frontend-api-integration.md](.claude-docs/frontend-api-integration.md) for complete API integration specifications for frontend teams.