12 KiB
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: Main builder for configuration providersSmartConfigProvider: Database-backed configurationPostgresConfigurationRepository: PostgreSQL storage
Usage Example:
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 - Operation Scoping:
DatabaseScopefor transaction and telemetry management - Telemetry Integration: Automatic performance tracking
Key Classes:
SqlOperations: Main database operations classPostgresConnectionFactory: PostgreSQL connection management
Usage Example:
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:
MasterKeyfor key management - Secure Connection Strings:
SecureConnectionString - Token Security:
SecureTokenizerusing 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:
Commandwith correlation tracking - Command Interface:
ICommand - Response Handling:
CommandResponse - Problem Details:
ProblemDetailsfor error handling
5. Telemetry & Logging
Location: Core/Telemetry/, Core/SeqLogging/
Comprehensive observability solution:
- Application Insights Integration:
TelemetryExtensions - Seq Logging:
SeqLoggerfor structured logging - Custom Telemetry Channel:
SeqTelemetryChannel - Background Processing:
SeqBackgroundService
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 - Telemetry Module:
TelemetryModule - Seq Logging Module:
SeqLoggingModule - Database Module:
DbPostgreSqlModule
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:
-- 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:
[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:
- JSON Files: Traditional appsettings.json
- Database: Dynamic configuration stored in PostgreSQL
- Environment Variables: Runtime configuration
- Azure App Configuration: Cloud-based configuration (planned)
Configuration Structure:
{
"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
- Database Setup: Run DDL scripts from
Database/Core/DDL/ - Configuration: Set up appsettings.json with connection strings
- Logging: Configure Seq endpoint
- 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
- Create new Autofac module inheriting from
Module - Register services in
Load()method - Add module to container builder
Custom Configuration Providers
- Implement
IConfigurationProvider - Add to
ConfigurationBuilder - Handle configuration merging strategy
Custom Telemetry
- Extend
TelemetryExtensions - Add custom enrichers
- Configure Application Insights processors
Troubleshooting
Common Issues
- Database Connection: Check PostgreSQL connection strings and user permissions
- Configuration Loading: Verify JSON syntax and provider order
- Telemetry: Ensure Application Insights and Seq endpoints are accessible
- 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