4.9 KiB
4.9 KiB
CLAUDE.md - SoaFE Tournament Portal
Overview
This application is a tournament organization portal for the Secrets of a Fallen Empire (SoaFE) mod for Star Wars: Empire at War: Forces of Corruption.
Tech Stack
- .NET 10, Blazor Interactive WebAssembly
- Entity Framework Core 10 with PostgreSQL
- Radzen Blazor Components for UI layout and components (MCP server:
radzen.mcp) - FluentValidation for validating models
Project Structure
src/Client/-- Client-side components, pages, and layoutssrc/Core/-- Abstractions, components, and utilities used by bothsrc/Client/andsrc/Serversrc/Data/-- Entity Framework Core, ORM models, DB functions, migrations, and enumssrc/Server/-- API, Server-side components, pages, and services
Commands
- Build:
dotnet build - Run:
dotnet run --project src/Server - Add Migration:
dotnet ef migrations add <Name> -p "src/Data" -s "src/Server" - Update Database:
dotnet ef database update -p "src/Data" -s "src/Server" - Format:
dotnet format
Architecture Rules
- The
src/Client/WebAssembly project houses most all layouts, pages, and components - The
src/Server/project houses server-side rendered components and API endpoints - The
src/Core/project houses reusable component abstractions, controls, and services that are frequently reused throughout the solution - When designing views, use
#radzen_searchto search the Radzen UI component documentation - The
src/Data/project contains all of the Entity Framework Core models, database contexts, function definitions, view definitions, and migration scripts - All database access goes through an Entity Framework Core DbContext without repository pattern
- All .NET NuGet packages should use version
$(DotNetVersion)(defined inDirectory.Build.props) where available, with a fallback to the latest compatible version - UI strings are defined in resource files (
.resx) -- no hard coding of any strings that are displayed on the interface - Major app features are organized into
Features/<Name>/with the following organization substructure:Dialogs/-- Components that are only meant to be used in a dialog modalExtensions/-- Contains extensions (i.e.ServiceCollectionExtensions.cs) to extend the application to use services within this featureModels/-- Record type models used by the views in this featurePages/-- Routable componentsServices/-- DI Services (i.e. validators) used by this featureShared/-- Non-routable or dialog components used by this feature
- Layout components are implemented in
Layout - Root pages (e.g. home page) are implemented in
Features/Home - Shared components across all features are implemented in
Features/Shared - When writing component code-behind files, organize in the following order
- Parameters Region (public parameters, private cascading parameters, private dependency injections)
- State Region (private state fields, private or protected lambdas)
- Lifecycle Region (SetParametersAsync, OnInitialized/OnInitializedAsync, OnParametersSet/OnParametersSetAsync, OnFirstRender/OnFirstRenderAsync, Dispose)
- Mutators Region (any private methods that modifies component state or performs an action)
- Callbacks Region (any private methods that are wired up to controls as an EventCallback; callbacks should only call a mutator)
- Anything else (refrain from using public methods, but put them at the bottom if necessary)
Code Conventions
Naming
- Routable pages:
[Name]Index,[Name]Detail - Dialogs:
[Name]Dialog - Components:
[Name]Form,[Name]Grid,[Name]DropDown - DTO Models:
[Name]Model - Validators:
[Name]Validator - Component code-behind:
[Component].razor.cs - Enums:
E[Name].cs
Patterns We Use
- DTO models are record type and inherit
Feature - File-scoped namespaces
- Always pass
CancellationTokento async methods where available - Code-behind files for Blazor components;
@codeblocks in.razorfiles only for reusable RenderFragments - Resource
.resxfiles for UI strings unique to components _Imports.razorfile with a@namespacedefinition for any folder that contains components- ORM models implement
IEntityTypeConfiguration<T>and define explicit column names and ordering consistent with PostgreSQL naming conventions - Explicit projection of ORM models into DTO models
- One file per type
Patters We DO NOT Use
- Primary constructors
- Repository patterns
- AutoMapper, Mapster, etc.
- Hard-coded strings for UI elements
- Multiple types in a file or nested classes
Validation
- All feature models should have a validator that inherits
AbstractValidator<T>with validation rules for applicable fields - Validators are automatically ran by forms including the
<FluentValidator />component - Validators that include async rules must use
<FluentValidator AsyncMode />in edit forms