287 lines
12 KiB
Markdown
287 lines
12 KiB
Markdown
# AGENTS.md
|
|
|
|
This file provides guidance to Codex when working with code in this repository.
|
|
|
|
## Development Commands
|
|
|
|
### Building
|
|
- **Build entire solution**: `dotnet build Centron.sln`
|
|
- **Build specific project**: `dotnet build src/centron/Centron.WPF.UI/Centron.WPF.UI.csproj`
|
|
- **Build for Release**: `dotnet build Centron.sln -c Release`
|
|
|
|
### Testing
|
|
- **Run all tests**: `dotnet test Centron.sln`
|
|
- **Run specific test project**: `dotnet test tests/backend/Centron.Tests.BL/Centron.Tests.BL.csproj`
|
|
- **Run integration tests**: `dotnet test tests/Centron.Tests.Integration/Centron.Tests.Integration.csproj`
|
|
- **Run end-to-end tests**: `dotnet test tests/Centron.Tests.EndToEnd/Centron.Tests.EndToEnd.csproj`
|
|
|
|
### Using Centron.Scripts Build System
|
|
The project uses a custom build system via Centron.Scripts for complete builds:
|
|
|
|
```bash
|
|
cd scripts/Centron.Scripts
|
|
dotnet run -- <target>
|
|
```
|
|
|
|
Available targets:
|
|
- `clean` - Clean artifacts and bin/obj directories
|
|
- `setup-versioning` - Set up version information
|
|
- `build-web-service` - Build the web service components
|
|
- `build-centron-net` - Build the WPF client application
|
|
- `run-tests` - Execute all test suites
|
|
- `create-installers` - Build MSI installers
|
|
|
|
### Publishing
|
|
- **Publish WPF UI**: `dotnet publish src/centron/Centron.WPF.UI/Centron.WPF.UI.csproj -c Release -r win-x64 --self-contained`
|
|
- **Publish Web Service**: `dotnet publish src/webservice/Centron.Host.WindowsService/Centron.Host.WindowsService.csproj -c Release -r win-x64 --self-contained`
|
|
|
|
## Project Architecture
|
|
|
|
### High-Level Structure
|
|
This is a .NET 8 enterprise application with a multi-layered architecture:
|
|
|
|
```
|
|
src/
|
|
├── apis/ - External API integrations (FinAPI, GLS, Shipcloud, etc.)
|
|
├── backend/ - Core business logic layer
|
|
│ ├── Centron.BL/ - Business Logic layer
|
|
│ ├── Centron.Common/ - Common utilities and helpers
|
|
│ ├── Centron.DAO/ - Data Access Objects (NHibernate)
|
|
│ ├── Centron.Entities/ - Domain entities
|
|
│ ├── Centron.Gateway/ - External service gateways
|
|
│ └── Centron.Interfaces/ - Service interfaces
|
|
├── centron/ - WPF client application
|
|
│ ├── Centron.WPF.UI/ - Main WPF application
|
|
│ └── Centron.WPF.UI.Extension/ - UI extensions
|
|
├── shared/ - Shared components and controls
|
|
│ ├── Centron.Core/ - Core shared functionality
|
|
│ ├── Centron.Controls/ - Custom UI controls
|
|
│ └── Centron.Controls.Preview/ - Preview controls
|
|
└── webservice/ - Web service components
|
|
├── Centron.Host/ - Web service host
|
|
├── Centron.Host.Console/ - Console host
|
|
├── Centron.Host.WindowsService/ - Windows service host
|
|
├── Centron.WebServices.Core/ - Web service core
|
|
└── c-entron.misc.ConnectionManager/ - Connection management
|
|
```
|
|
|
|
### Data Access Pattern
|
|
The application uses a dual data access pattern supporting both direct database access and web service communication:
|
|
|
|
#### ILogic Interface Pattern
|
|
All data operations use the ILogic interface accessed through ClassContainer:
|
|
```csharp
|
|
var result = await ClassContainer
|
|
.Instance
|
|
.WithInstance((IAccountContractsLogic logic) => logic.GetAccountContracts(filter))
|
|
.ThrowIfError();
|
|
```
|
|
|
|
#### Dual Implementation Requirements
|
|
Every module MUST implement both:
|
|
1. **ILogic Interface** - Defines the contract
|
|
2. **BLLogic Class** - Direct database access via NHibernate
|
|
3. **WSLogic Class** - Web service access via REST API
|
|
|
|
### Technology Stack
|
|
- **.NET 8** - Primary framework
|
|
- **WPF** - Desktop UI framework
|
|
- **NHibernate** - ORM for database access
|
|
- **DevExpress 24.2.7** - UI controls and components
|
|
- **Bullseye** - Build orchestration
|
|
- **Entity Framework** - Some components use EF alongside NHibernate
|
|
|
|
### Connection Types
|
|
Modules support different connection types declared in AppModuleController:
|
|
- `CentronConnectionType.CentronWebServices` - Uses WSLogic implementation
|
|
- `CentronConnectionType.SqlServer` - Uses BLLogic implementation
|
|
|
|
## Development Guidelines
|
|
|
|
### Language Requirements
|
|
- All user-facing content must be in German (primary market)
|
|
- Support for English through localization files
|
|
- Use German resource files (LocalizedStrings.resx) and English (LocalizedStrings.en.resx)
|
|
|
|
### File Encoding
|
|
- All C# source files (*.cs) must use UTF-8 with BOM
|
|
- All XAML files (*.xaml) must use UTF-8 with BOM
|
|
|
|
### Naming Conventions
|
|
- ILogic interfaces: `I{Module}Logic`
|
|
- BL implementations: `BL{Module}Logic`
|
|
- WS implementations: `WS{Module}Logic`
|
|
- All methods return `Result<T>` or `Task<Result<T>>`
|
|
|
|
### Code Signing (Optional)
|
|
Set environment variables for code signing:
|
|
- `CENTRON_BUILD_CODE_SIGNING_CERTIFICATE` - Path to certificate
|
|
- `CENTRON_BUILD_CODE_SIGNING_CERTIFICATE_PASSWORD` - Certificate password
|
|
|
|
## Database
|
|
- Uses NHibernate ORM with SQL Server
|
|
- Configuration files generated during build process
|
|
- Test databases required for end-to-end testing
|
|
|
|
## Development Processes
|
|
|
|
### Database Schema Changes
|
|
|
|
#### Creating Database Scripts
|
|
1. **Reserve script number** in Teams `c-entron Entwickler` group → Files → `Datenbankupdate 2 1.xlsx`
|
|
2. **Create script class** at `src/backend/Centron.BL/Administration/Scripts/ScriptMethods/Scripts/ScriptMethod{number}.cs`
|
|
3. **Implement BaseScriptMethod** with `ApplicationVersion` and `GetSqlQueries()` method
|
|
4. **Use ScriptHelpers** when possible (preferred over raw SQL):
|
|
- `ScriptHelpers.AddColumnIfNotExists()`
|
|
- `ScriptHelpers.AddTableIfNotExists()`
|
|
- `ScriptHelpers.AddRightIfNotExists()`
|
|
- `ScriptHelpers.AddIndexIfNotExists()`
|
|
- `ScriptHelpers.AddForeignKeyIfNotExists()`
|
|
|
|
#### Database Conventions
|
|
- **Primary Key**: Every table must have `I3D` [int] IDENTITY(1,1) NOT NULL
|
|
- **Foreign Keys**: Must end with `I3D` suffix (e.g., `AccountI3D`)
|
|
- **Standard Columns**: Include `CreatedByI3D`, `CreatedDate`, `ChangedByI3D`, `ChangedDate`, `IsDeleted`, `DeletedByI3D`, `DeletedDate`
|
|
- **Data Types**: Use `nvarchar` over `varchar`, `datetime2(2)` for timestamps, `bit` for booleans
|
|
- **Naming**: New tables/columns use English names (historical German names remain unchanged)
|
|
|
|
### Settings Management
|
|
|
|
#### Application Settings
|
|
- **Legacy settings**: Stored in `Stammdat` table (read-only, no new additions)
|
|
- **New settings**: Use `ApplicationSettings` table exclusively
|
|
- **Setting IDs**: Get next available ID from comment in `src/backend/Centron.Interfaces/Administration/Settings/ApplicationSettingID.cs`
|
|
- **Descriptions**: Add to `ApplicationSettingDefinitions.cs`
|
|
|
|
#### Adding New Settings
|
|
1. Check next available ID in `ApplicationSettingID.cs`
|
|
2. Add enum value with new ID
|
|
3. Update "Next Centron Settings ID" comment
|
|
4. Add description in `ApplicationSettingDefinitions.cs`
|
|
5. Create group setting classes for accessing settings
|
|
6. Use `AppSettingsBL.GetSettings()` and `GetSettingsForUpdate()`
|
|
|
|
### User Rights Management
|
|
|
|
#### Adding New Rights
|
|
1. **Open** `UserRightsConst.cs` to get next I3D
|
|
2. **Create script** using `ScriptHelpers.AddRightIfNotExists()`:
|
|
```csharp
|
|
yield return ScriptHelpers.AddRightIfNotExists(
|
|
UserRightsConst.Sales.Customer.Helpdesk.SHOW_HOURLYSURCHARGERATES,
|
|
UserRightsConst.Sales.Customer.Helpdesk.ID,
|
|
"German display name",
|
|
"German description");
|
|
```
|
|
3. **Add constant** to `UserRightsConst.cs`
|
|
|
|
### Web Service Development
|
|
|
|
#### Creating Web Service Methods (Full Stack)
|
|
1. **BL Layer**: Create method in `{Entity}BL.cs` returning `Result<T>`
|
|
2. **WebServiceBL**: Create `{Entity}WebServiceBL.cs` with DTO↔Entity conversion
|
|
3. **RestService**: Add method to `CentronRestService.cs` accepting `Request<T>` and returning `Response<T>`
|
|
4. **Interface**: Add method signature to `ICentronRestService.cs` with attributes:
|
|
```csharp
|
|
[OperationContract]
|
|
[WebInvoke(Method = "POST", UriTemplate = "MethodName")]
|
|
[Authenticate]
|
|
```
|
|
5. **Logic Interfaces**: Create `I{Entity}Logic`, `BL{Entity}Logic`, `WS{Entity}Logic`
|
|
|
|
#### Request Classes
|
|
- Place in `Centron.WebServices.Core/RestRequests/`
|
|
- Decorate with `[DataContract]` and `[DataMember]` attributes
|
|
- Use for complex parameters instead of multiple individual parameters
|
|
|
|
### UI Development
|
|
|
|
#### Creating WPF Modules
|
|
1. **AppModuleController**: Implement `ICentronAppModuleController`
|
|
2. **View**: Create `UserControl` inheriting from `BaseModule`
|
|
3. **ViewModel**: Inherit from `BindableBase`
|
|
4. **Ribbon**: Implement `IRibbonControlModule` interface variations
|
|
5. **Registration**: Add to `ModuleRegistration.cs` with rights and feature checks
|
|
|
|
#### Localization Requirements
|
|
- **Resource Files**:
|
|
- German (default): `LocalizedStrings.resx`
|
|
- English: `LocalizedStrings.en.resx`
|
|
- **XAML Usage**: `{x:Static properties:LocalizedStrings.KeyName}`
|
|
- **Code Usage**: Direct access via `LocalizedStrings.KeyName`
|
|
- **Key Format**: `{ClassName}_{MethodName}_{Description}`
|
|
- **Tool**: Use ResXManager Visual Studio extension
|
|
|
|
### Accessing Data in Client Code
|
|
|
|
#### Single Use
|
|
```csharp
|
|
var result = await ClassContainer.Instance
|
|
.WithInstance((IEntityLogic logic) => logic.GetEntity(id))
|
|
.ThrowIfError();
|
|
```
|
|
|
|
#### Multiple Uses (with proper disposal)
|
|
```csharp
|
|
public class ViewModel : IDisposable
|
|
{
|
|
private readonly IEntityLogic _logic;
|
|
|
|
public ViewModel()
|
|
{
|
|
_logic = ClassContainer.Instance.GetInstance<IEntityLogic>();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
ClassContainer.Instance.ReleaseInstance(_logic);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Documentation
|
|
|
|
### Creating Documentation
|
|
When adding new documentation to the project:
|
|
|
|
1. **Choose the right location** within the existing `docs/` structure:
|
|
- `docs/getting-started/` - Beginner guides and introductory material
|
|
- `docs/guides/development/` - Development task guides
|
|
- `docs/guides/database/` - Database-related guides
|
|
- `docs/guides/ui/` - UI development guides
|
|
- `docs/guides/services/` - Web services guides
|
|
- `docs/reference/architecture/` - Architecture specifications
|
|
- `docs/reference/database/` - Database reference documentation
|
|
- `docs/reference/receipts/` - Receipts system documentation
|
|
- `docs/reference/security/` - Security documentation
|
|
- `docs/operations/` - Operational procedures
|
|
|
|
2. **Name the file appropriately** using kebab-case (e.g., `actionprice-system.md`)
|
|
|
|
3. **Create the file** with UTF-8 with BOM encoding, using proper Markdown format
|
|
|
|
4. **Update navigation** in `docs/README.md`:
|
|
- Add a new entry with a link to your documentation file
|
|
- Follow the existing pattern and place in appropriate section
|
|
|
|
5. **Update the Solution File** (`Centron.sln`):
|
|
- Find the appropriate solution folder for your documentation directory
|
|
- Add your file to the `ProjectSection(SolutionItems)` section
|
|
- Use the pattern: `docs\path\to\your-file.md = docs\path\to\your-file.md`
|
|
|
|
### Documentation Standards
|
|
- Use UTF-8 with BOM encoding for all documentation files
|
|
- Start with a `#` heading that clearly describes the content
|
|
- Use proper Markdown formatting for headings, lists, code blocks, etc.
|
|
- Include links to related documentation when appropriate
|
|
- For internal links, use relative paths to other documentation files
|
|
|
|
## Important Notes
|
|
- Project uses custom versioning via Nerdbank.GitVersioning
|
|
- Build artifacts placed in `/artifacts` directory
|
|
- Integration with Azure DevOps for CI/CD
|
|
- Automatic ticket integration with c-entron ticket system
|
|
- Supports both standalone and web service deployment modes
|
|
- Always test database scripts before committing
|
|
- Use German for all user-facing text with English translations
|
|
- Follow dual implementation pattern (BL + WS) for all data access |