Initial commit: SWP.Core enterprise framework with multi-tenant architecture, configuration management, security, telemetry and comprehensive test suite

This commit is contained in:
Janus C. H. Knudsen 2025-08-02 22:16:39 +02:00
commit 5275a75502
87 changed files with 6140 additions and 0 deletions

344
NAMING_CONVENTION.md Normal file
View file

@ -0,0 +1,344 @@
# SWP.Core Naming Convention
Dette dokument definerer de officielle naming conventions for SWP.Core projektet baseret på analyse af eksisterende kodebase og .NET bedste praksis.
## Generelle Principper
1. **Konsistens**: Følg samme mønster gennem hele kodebasen
2. **Læsbarhed**: Navne skal være selvforklarende og beskrivende
3. **Sprogovervejelser**: Brug engelsk for al kode og kommentarer
4. **Undgå forkortelser**: Brug fulde ord frem for forkortelser
## 1. Namespace Naming
### Standard Format
```csharp
SWP.Core.[FeatureArea].[SubArea]
```
### Regler
- **PascalCase** for alle segmenter
- Brug `SWP.Core` som rod prefix (ikke `PlanTempus.Core`)
- Hierarkisk struktur afspejler folder struktur
- Maksimalt 4 niveauer dybt for læsbarhed
### Eksempler
```csharp
// ✅ Korrekt
SWP.Core.CommandQueries
SWP.Core.Configurations.SmartConfigProvider
SWP.Core.Database.ConnectionFactory
SWP.Core.Entities.Users
SWP.Core.X.TDD.Security
// ❌ Forkert
PlanTempus.Core.CommandQueries // Forkert prefix
SWP.core.commandqueries // Forkert casing
SWP.Core.Cfg.SmartCfgProv // Forkortelser
```
## 2. Class Naming
### Regler
- **PascalCase** for alle klasser
- Beskrivende navne der afspejler klassens ansvar
- Suffixes for specielle typer
### Class Type Suffixes
| Type | Suffix | Eksempel |
|------|--------|----------|
| Abstract classes | (ingen) | `Command` |
| Interfaces | `I` prefix | `ISecureTokenizer` |
| Exceptions | `Exception` | `ConfigurationException` |
| Factories | `Factory` | `PostgresConnectionFactory` |
| Services | `Service` | `UserService` |
| Extensions | `Extensions` | `TelemetryExtensions` |
| Modules (Autofac) | `Module` | `SecurityModule` |
| Configuration | `Configuration` eller `Options` | `SeqConfiguration`, `SmartConfigOptions` |
| Tests | `Tests` | `SecureTokenizerTests` |
### Eksempler
```csharp
// ✅ Korrekt
public class SecureTokenizer : ISecureTokenizer
public class PostgresConnectionFactory : IDbConnectionFactory
public abstract class Command : ICommand
public class ConfigurationException : Exception
// ❌ Forkert
public class secureTokenizer // Forkert casing
public class Factory // For generisk
public class SecureTokenizerImpl // Undgå "Impl" suffix
```
## 3. Interface Naming
### Regler
- **PascalCase** med `I` prefix
- Beskriver capability eller kontrakt
- Undgå `Interface` suffix
### Eksempler
```csharp
// ✅ Korrekt
public interface ISecureTokenizer
public interface IDbConnectionFactory
public interface IConfigurationRepository
// ❌ Forkert
public interface SecureTokenizer // Mangler I prefix
public interface ISecureTokenizerInterface // Redundant suffix
```
## 4. Method Naming
### Regler
- **PascalCase** for alle metoder
- Begynd med verbum der beskriver handlingen
- Async metoder skal have `Async` suffix
### Naming Patterns
| Pattern | Eksempel |
|---------|----------|
| Action methods | `TokenizeText()`, `VerifyToken()` |
| Factory methods | `Create()`, `Build()` |
| Async methods | `LogAsync()`, `CreateAsync()` |
| Boolean methods | `IsValid()`, `CanExecute()`, `HasPermission()` |
### Eksempler
```csharp
// ✅ Korrekt
public string TokenizeText(string word)
public async Task<bool> VerifyTokenAsync(string hash, string word)
public bool IsValidFormat(string input)
// ❌ Forkert
public string tokenize_text(string word) // Forkert casing
public async Task<bool> VerifyToken(string hash, string word) // Mangler Async suffix
public bool ValidFormat(string input) // Mangler verbum
```
## 5. Property Naming
### Regler
- **PascalCase** for alle properties
- Brug substantiver eller substantiv-sætninger
- Auto-properties anbefales
### Eksempler
```csharp
// ✅ Korrekt
public Guid CorrelationId { get; set; }
public required string Email { get; set; }
public DateTime CreatedDate { get; set; }
public bool IsActive { get; set; }
// ❌ Forkert
public Guid correlationId { get; set; } // Forkert casing
public string GetEmail() { get; set; } // Metode navngivning
```
## 6. Field Naming
### Private Fields
- **camelCase** med underscore prefix `_`
- Beskrivende navne
### Constants
- **PascalCase** for public constants
- **camelCase** med underscore prefix for private constants
### Readonly Fields
- Som private fields med underscore prefix
### Eksempler
```csharp
// ✅ Korrekt
private readonly IHttpClient _httpClient;
private const int _saltSize = 16;
public const string DefaultConnectionString = "...";
private static readonly string _defaultEncoding = "UTF-8";
// ❌ Forkert
private readonly IHttpClient httpClient; // Mangler underscore
private const int SALT_SIZE = 16; // Forkert casing for private
public const string default_connection = "..."; // Forkert casing for public
```
## 7. Parameter Naming
### Regler
- **camelCase** for alle parametre
- Beskrivende navne der afspejler parameterens formål
- Undgå single-letter navne (undtagen type parametre)
### Eksempler
```csharp
// ✅ Korrekt
public bool VerifyToken(string hashedToken, string plainTextPassword)
public void Configure(IServiceCollection services, string connectionString)
public async Task<T> ExecuteAsync<T>(CancellationToken cancellationToken)
// ❌ Forkert
public bool VerifyToken(string s1, string s2) // Ikke beskrivende
public void Configure(string ConnString) // Forkert casing
public async Task<T> ExecuteAsync<T>(CancellationToken ct) // Forkortelse
```
## 8. File og Folder Naming
### Files
- **PascalCase** der matcher hovedklassen i filen
- En hovedklasse per fil (undtagen interne/helper klasser)
### Folders
- **PascalCase** der afspejler namespace struktur
- Brug plural for samlinger af entities (f.eks. `Users`, `Configurations`)
### Eksempler
```
✅ Korrekt
/Core/CommandQueries/Command.cs
/Core/Entities/Users/User.cs
/Core/Configurations/SmartConfigProvider/SmartConfigProvider.cs
/Tests/Security/SecureTokenizerTests.cs
❌ Forkert
/Core/command-queries/command.cs
/Core/entities/users/user.cs
/Tests/security/secure_tokenizer_tests.cs
```
## 9. Test Naming
### Test Classes
- Klassenavn + `Tests` suffix
- Samme namespace som den testede klasse + `.X.TDD`
### Test Methods
- Format: `[MethodName]_Should[ExpectedBehavior]_[Condition]`
- Eller: `[MethodName]_[Condition]_[ExpectedBehavior]`
### Test Projects
- Format: `[ProjectName].X.TDD`
### Eksempler
```csharp
// ✅ Korrekt
namespace SWP.Core.X.TDD.Security;
[TestClass]
public class SecureTokenizerTests
{
[TestMethod]
public void TokenizeText_ShouldReturnDifferentTokens_ForSamePassword()
[TestMethod]
public void VerifyToken_WithValidPassword_ShouldReturnTrue()
[TestMethod]
public void VerifyToken_WithNullInput_ShouldThrowException()
}
// ❌ Forkert
public class TestSecureTokenizer // Forkert prefix
public void TokenizeTextTest() // Ikke beskrivende
public void Test1() // Ikke beskrivende
```
## 10. Configuration og Database Naming
### Configuration Keys
- **PascalCase** for hver sektion
- Hierarkisk med kolon separator
- Logisk gruppering
### Database vs C# Mapping
- **Database**: snake_case for kolonner
- **C#**: PascalCase for properties
- Brug mapping hvor nødvendigt
### Eksempler
```json
// ✅ Korrekt configuration
{
"Database": {
"ConnectionString": "...",
"CommandTimeout": 30
},
"Logging": {
"Level": "Information",
"Providers": {
"Seq": {
"Url": "http://localhost:5341"
}
}
}
}
```
```sql
-- ✅ Database (snake_case)
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(255),
password_hash VARCHAR(255),
created_at TIMESTAMP
);
```
```csharp
// ✅ C# Entity (PascalCase)
public class User
{
public int Id { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public DateTime CreatedAt { get; set; }
}
```
## 11. Specielle Konventioner
### Generic Type Parameters
- Single letters: `T`, `TKey`, `TValue`
- Beskrivende hvis nødvendigt: `TEntity`, `TRequest`, `TResponse`
### Event Handlers
- Format: `On[EventName]` eller `Handle[EventName]`
### Extension Methods
- Første parameter skal være `this`
- Metoder i statiske klasser med `Extensions` suffix
### Async/Await
- Altid `Async` suffix for async metoder
- Brug `CancellationToken cancellationToken` som sidste parameter
## 12. Undtagelser fra Konventioner
### Acceptable Forkortelser
- `Id` (frem for Identifier)
- `Url` (frem for UniformResourceLocator)
- `Http` (frem for HyperTextTransferProtocol)
- `Json` (frem for JavaScriptObjectNotation)
- `Sql` (frem for StructuredQueryLanguage)
### Kendte Patterns
- `DTO` suffix for Data Transfer Objects
- `CRUD` i kommentarer og dokumentation
- `API` for Application Programming Interface
## Implementering
1. **Gradvis migration**: Ret eksisterende kode gradvist ved ændringer
2. **Code reviews**: Håndhæv conventions i code reviews
3. **Linting**: Konfigurer analyzers til at håndhæve konventioner
4. **Dokumentation**: Hold denne guide opdateret
## Værktøjer
- **EditorConfig**: Konfigurer formatting regler
- **StyleCop**: Håndhæv naming conventions
- **SonarQube**: Code quality og consistency checks
- **Visual Studio**: Code analysis og suggestions