341 lines
12 KiB
Markdown
341 lines
12 KiB
Markdown
|
|
# SWP.Core - Technical Documentation
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
SWP.Core is a modular .NET 9.0 enterprise application framework designed for multi-tenant SaaS applications. The system provides a comprehensive foundation for building scalable applications with advanced configuration management, security, telemetry, and database operations.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
### High-Level Architecture
|
||
|
|
|
||
|
|
The system follows a layered architecture with clear separation of concerns:
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────┐
|
||
|
|
│ Application Layer │
|
||
|
|
├─────────────────────────────────────────┤
|
||
|
|
│ Core Library │
|
||
|
|
│ ┌─────────────┬─────────────────────┐ │
|
||
|
|
│ │ Command/ │ Configuration │ │
|
||
|
|
│ │ Query │ Management │ │
|
||
|
|
│ ├─────────────┼─────────────────────┤ │
|
||
|
|
│ │ Security & │ Telemetry & │ │
|
||
|
|
│ │ Encryption │ Logging │ │
|
||
|
|
│ ├─────────────┼─────────────────────┤ │
|
||
|
|
│ │ Database │ Module Registry │ │
|
||
|
|
│ │ Operations │ (Autofac) │ │
|
||
|
|
│ └─────────────┴─────────────────────┘ │
|
||
|
|
├─────────────────────────────────────────┤
|
||
|
|
│ Database Layer │
|
||
|
|
│ ┌─────────────────────────────────────┐ │
|
||
|
|
│ │ PostgreSQL with Row Level Security │ │
|
||
|
|
│ │ Multi-tenant Schema Management │ │
|
||
|
|
│ └─────────────────────────────────────┘ │
|
||
|
|
└─────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
### Technology Stack
|
||
|
|
|
||
|
|
- **Framework**: .NET 9.0
|
||
|
|
- **Database**: PostgreSQL with Insight.Database
|
||
|
|
- **DI Container**: Autofac
|
||
|
|
- **Testing**: MSTest + Shouldly
|
||
|
|
- **Telemetry**: Application Insights + Seq
|
||
|
|
- **Security**: Sodium.Core for encryption
|
||
|
|
- **Configuration**: Custom multi-provider system
|
||
|
|
|
||
|
|
## Core Components
|
||
|
|
|
||
|
|
### 1. Configuration Management System
|
||
|
|
|
||
|
|
**Location**: `Core/Configurations/`
|
||
|
|
|
||
|
|
The system implements a sophisticated multi-provider configuration system that supports:
|
||
|
|
|
||
|
|
- **JSON Configuration Provider**: File-based configuration
|
||
|
|
- **Smart Configuration Provider**: Database-backed configuration with caching
|
||
|
|
- **Hierarchical Configuration**: Nested configuration with path-based access
|
||
|
|
|
||
|
|
**Key Classes**:
|
||
|
|
- [`ConfigurationBuilder`](Core/Configurations/ConfigurationBuilder.cs): Main builder for configuration providers
|
||
|
|
- [`SmartConfigProvider`](Core/Configurations/SmartConfigProvider/SmartConfigProvider.cs): Database-backed configuration
|
||
|
|
- [`PostgresConfigurationRepository`](Core/Configurations/SmartConfigProvider/Repositories/PostgresConfigurationRepository.cs): PostgreSQL storage
|
||
|
|
|
||
|
|
**Usage Example**:
|
||
|
|
```csharp
|
||
|
|
var config = new ConfigurationBuilder()
|
||
|
|
.AddProvider(new JsonConfigProvider("appsettings.json"))
|
||
|
|
.AddProvider(new SmartConfigProvider(connectionString))
|
||
|
|
.Build();
|
||
|
|
|
||
|
|
var connectionString = config.GetConnectionString("DefaultConnection");
|
||
|
|
var feature = config.Get<FeatureConfig>("Feature");
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Database Operations
|
||
|
|
|
||
|
|
**Location**: `Core/Database/`
|
||
|
|
|
||
|
|
Provides a robust database abstraction layer with:
|
||
|
|
|
||
|
|
- **Connection Factory Pattern**: [`IDbConnectionFactory`](Core/Database/ConnectionFactory/IDbConnectionFactory.cs)
|
||
|
|
- **Operation Scoping**: [`DatabaseScope`](Core/Database/DatabaseScope.cs) for transaction and telemetry management
|
||
|
|
- **Telemetry Integration**: Automatic performance tracking
|
||
|
|
|
||
|
|
**Key Classes**:
|
||
|
|
- [`SqlOperations`](Core/Database/SqlOperations.cs): Main database operations class
|
||
|
|
- [`PostgresConnectionFactory`](Core/Database/ConnectionFactory/PostgresConnectionFactory.cs): PostgreSQL connection management
|
||
|
|
|
||
|
|
**Usage Example**:
|
||
|
|
```csharp
|
||
|
|
var result = await _sqlOperations.ExecuteAsync(async conn =>
|
||
|
|
{
|
||
|
|
return await conn.QueryAsync<User>("SELECT * FROM users WHERE id = @id", new { id });
|
||
|
|
}, "GetUserById");
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Security & Encryption
|
||
|
|
|
||
|
|
**Location**: `Core/MultiKeyEncryption/`, `Core/ISecureTokenizer.cs`
|
||
|
|
|
||
|
|
Implements enterprise-grade security features:
|
||
|
|
|
||
|
|
- **Multi-Key Encryption**: [`MasterKey`](Core/MultiKeyEncryption/MasterKey.cs) for key management
|
||
|
|
- **Secure Connection Strings**: [`SecureConnectionString`](Core/MultiKeyEncryption/SecureConnectionString.cs)
|
||
|
|
- **Token Security**: [`SecureTokenizer`](Core/SecureTokenizer.cs) using Sodium.Core
|
||
|
|
|
||
|
|
**Features**:
|
||
|
|
- SHA-256 based token generation
|
||
|
|
- Secure password hashing
|
||
|
|
- Connection string encryption
|
||
|
|
- Key rotation support
|
||
|
|
|
||
|
|
### 4. Command/Query Pattern
|
||
|
|
|
||
|
|
**Location**: `Core/CommandQueries/`
|
||
|
|
|
||
|
|
Implements a lightweight command/query pattern without MediatR:
|
||
|
|
|
||
|
|
- **Base Command**: [`Command`](Core/CommandQueries/Command.cs) with correlation tracking
|
||
|
|
- **Command Interface**: [`ICommand`](Core/CommandQueries/ICommand.cs)
|
||
|
|
- **Response Handling**: [`CommandResponse`](Core/CommandQueries/CommandResponse.cs)
|
||
|
|
- **Problem Details**: [`ProblemDetails`](Core/CommandQueries/ProblemDetails.cs) for error handling
|
||
|
|
|
||
|
|
### 5. Telemetry & Logging
|
||
|
|
|
||
|
|
**Location**: `Core/Telemetry/`, `Core/SeqLogging/`
|
||
|
|
|
||
|
|
Comprehensive observability solution:
|
||
|
|
|
||
|
|
- **Application Insights Integration**: [`TelemetryExtensions`](Core/Telemetry/TelemetryExtensions.cs)
|
||
|
|
- **Seq Logging**: [`SeqLogger`](Core/SeqLogging/SeqLogger.cs) for structured logging
|
||
|
|
- **Custom Telemetry Channel**: [`SeqTelemetryChannel`](Core/Telemetry/SeqTelemetryChannel.cs)
|
||
|
|
- **Background Processing**: [`SeqBackgroundService`](Core/SeqLogging/SeqBackgroundService.cs)
|
||
|
|
|
||
|
|
**Features**:
|
||
|
|
- Structured logging with correlation IDs
|
||
|
|
- Performance metrics collection
|
||
|
|
- Exception tracking with full stack traces
|
||
|
|
- Custom enrichers for metadata
|
||
|
|
|
||
|
|
### 6. Module Registry (Dependency Injection)
|
||
|
|
|
||
|
|
**Location**: `Core/ModuleRegistry/`
|
||
|
|
|
||
|
|
Autofac-based modular dependency injection:
|
||
|
|
|
||
|
|
- **Security Module**: [`SecurityModule`](Core/ModuleRegistry/SecurityModule.cs)
|
||
|
|
- **Telemetry Module**: [`TelemetryModule`](Core/ModuleRegistry/TelemetryModule.cs)
|
||
|
|
- **Seq Logging Module**: [`SeqLoggingModule`](Core/ModuleRegistry/SeqLoggingModule.cs)
|
||
|
|
- **Database Module**: [`DbPostgreSqlModule`](Core/Database/ModuleRegistry/DbPostgreSqlModule.cs)
|
||
|
|
|
||
|
|
## Database Schema
|
||
|
|
|
||
|
|
### Multi-Tenant Architecture
|
||
|
|
|
||
|
|
The system implements a sophisticated multi-tenant architecture using PostgreSQL:
|
||
|
|
|
||
|
|
**Core Tables** (in identity schema):
|
||
|
|
- **users**: User authentication and profile data
|
||
|
|
- **organizations**: Tenant/organization management
|
||
|
|
- **user_organizations**: Many-to-many relationship with PIN codes
|
||
|
|
|
||
|
|
**Security Features**:
|
||
|
|
- **Row Level Security (RLS)**: Automatic tenant isolation
|
||
|
|
- **Schema-based Separation**: Each tenant can have dedicated schemas
|
||
|
|
- **Connection String Encryption**: Secure tenant database connections
|
||
|
|
|
||
|
|
**Example Schema Setup**:
|
||
|
|
```sql
|
||
|
|
-- From SetupIdentitySystem.cs
|
||
|
|
CREATE TABLE identity.users (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
email VARCHAR(256) NOT NULL UNIQUE,
|
||
|
|
password_hash VARCHAR(256) NOT NULL,
|
||
|
|
security_stamp VARCHAR(36) NOT NULL,
|
||
|
|
email_confirmed BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
|
||
|
|
-- RLS Policy
|
||
|
|
CREATE POLICY organization_access ON identity.organizations
|
||
|
|
USING (id IN (
|
||
|
|
SELECT organization_id
|
||
|
|
FROM identity.user_organizations
|
||
|
|
WHERE user_id = current_setting('app.user_id', TRUE)::INTEGER
|
||
|
|
));
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Strategy
|
||
|
|
|
||
|
|
**Location**: `Tests/`
|
||
|
|
|
||
|
|
Comprehensive testing approach using MSTest + Shouldly:
|
||
|
|
|
||
|
|
- **Unit Tests**: Component-level testing
|
||
|
|
- **Integration Tests**: Database and external service testing
|
||
|
|
- **Configuration Tests**: Multi-provider configuration validation
|
||
|
|
|
||
|
|
**Testing Principles**:
|
||
|
|
- Clear variable names for debugging
|
||
|
|
- Shouldly assertions for readable test failures
|
||
|
|
- Isolated test environments
|
||
|
|
- Mock-based testing for external dependencies
|
||
|
|
|
||
|
|
**Example Test Structure**:
|
||
|
|
```csharp
|
||
|
|
[TestMethod]
|
||
|
|
public void SecureTokenizer_Should_Generate_Valid_Token()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var tokenizer = new SecureTokenizer();
|
||
|
|
var inputText = "test-password";
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var generatedToken = tokenizer.TokenizeText(inputText);
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
generatedToken.ShouldNotBeNullOrEmpty();
|
||
|
|
generatedToken.Length.ShouldBe(64); // SHA-256 hex length
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
### Multi-Provider Configuration System
|
||
|
|
|
||
|
|
The system supports multiple configuration sources with hierarchical merging:
|
||
|
|
|
||
|
|
1. **JSON Files**: Traditional appsettings.json
|
||
|
|
2. **Database**: Dynamic configuration stored in PostgreSQL
|
||
|
|
3. **Environment Variables**: Runtime configuration
|
||
|
|
4. **Azure App Configuration**: Cloud-based configuration (planned)
|
||
|
|
|
||
|
|
**Configuration Structure**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"ConnectionStrings": {
|
||
|
|
"DefaultConnection": "Host=localhost;Database=app;..."
|
||
|
|
},
|
||
|
|
"ApplicationInsights": {
|
||
|
|
"ConnectionString": "InstrumentationKey=...",
|
||
|
|
"UseSeqLoggingTelemetryChannel": true
|
||
|
|
},
|
||
|
|
"SeqConfiguration": {
|
||
|
|
"IngestionEndpoint": "http://localhost:5341",
|
||
|
|
"Environment": "Development"
|
||
|
|
},
|
||
|
|
"Feature": {
|
||
|
|
"Enabled": true,
|
||
|
|
"RolloutPercentage": 25,
|
||
|
|
"AllowedUserGroups": ["beta"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Deployment & Operations
|
||
|
|
|
||
|
|
### Prerequisites
|
||
|
|
|
||
|
|
- .NET 9.0 Runtime
|
||
|
|
- PostgreSQL 12+
|
||
|
|
- Seq (for logging)
|
||
|
|
- Application Insights (for telemetry)
|
||
|
|
|
||
|
|
### Environment Setup
|
||
|
|
|
||
|
|
1. **Database Setup**: Run DDL scripts from `Database/Core/DDL/`
|
||
|
|
2. **Configuration**: Set up appsettings.json with connection strings
|
||
|
|
3. **Logging**: Configure Seq endpoint
|
||
|
|
4. **Telemetry**: Set Application Insights connection string
|
||
|
|
|
||
|
|
### Performance Considerations
|
||
|
|
|
||
|
|
- **Connection Pooling**: Managed by Npgsql
|
||
|
|
- **Async Operations**: All database operations are async
|
||
|
|
- **Telemetry Overhead**: Minimal impact with background processing
|
||
|
|
- **Configuration Caching**: Smart config provider includes caching
|
||
|
|
|
||
|
|
## Security Considerations
|
||
|
|
|
||
|
|
### Authentication & Authorization
|
||
|
|
|
||
|
|
- **Password Security**: SHA-256 hashing with security stamps
|
||
|
|
- **Token Management**: Secure token generation and validation
|
||
|
|
- **Multi-Tenant Isolation**: RLS policies prevent cross-tenant data access
|
||
|
|
|
||
|
|
### Data Protection
|
||
|
|
|
||
|
|
- **Connection String Encryption**: Sensitive connection data encrypted
|
||
|
|
- **Audit Trails**: Comprehensive logging of all operations
|
||
|
|
- **Input Validation**: FluentValidation integration
|
||
|
|
|
||
|
|
### Compliance
|
||
|
|
|
||
|
|
- **GDPR Ready**: User data management and deletion capabilities
|
||
|
|
- **Audit Logging**: Complete operation tracking
|
||
|
|
- **Data Encryption**: At-rest and in-transit encryption
|
||
|
|
|
||
|
|
## Extension Points
|
||
|
|
|
||
|
|
### Adding New Modules
|
||
|
|
|
||
|
|
1. Create new Autofac module inheriting from `Module`
|
||
|
|
2. Register services in `Load()` method
|
||
|
|
3. Add module to container builder
|
||
|
|
|
||
|
|
### Custom Configuration Providers
|
||
|
|
|
||
|
|
1. Implement `IConfigurationProvider`
|
||
|
|
2. Add to `ConfigurationBuilder`
|
||
|
|
3. Handle configuration merging strategy
|
||
|
|
|
||
|
|
### Custom Telemetry
|
||
|
|
|
||
|
|
1. Extend `TelemetryExtensions`
|
||
|
|
2. Add custom enrichers
|
||
|
|
3. Configure Application Insights processors
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Common Issues
|
||
|
|
|
||
|
|
1. **Database Connection**: Check PostgreSQL connection strings and user permissions
|
||
|
|
2. **Configuration Loading**: Verify JSON syntax and provider order
|
||
|
|
3. **Telemetry**: Ensure Application Insights and Seq endpoints are accessible
|
||
|
|
4. **Multi-Tenant**: Verify RLS policies and user context settings
|
||
|
|
|
||
|
|
### Debugging
|
||
|
|
|
||
|
|
- Enable detailed logging in Seq
|
||
|
|
- Use Application Insights for performance monitoring
|
||
|
|
- Check database query performance with PostgreSQL logs
|
||
|
|
- Validate configuration loading with debug output
|
||
|
|
|
||
|
|
## Future Roadmap
|
||
|
|
|
||
|
|
- Azure App Configuration integration
|
||
|
|
- Advanced caching strategies
|
||
|
|
- GraphQL API support
|
||
|
|
- Event sourcing capabilities
|
||
|
|
- Microservices decomposition support
|