A modern .NET 9 full-stack platform built with Vertical Slice Architecture (VSA), multi-tenancy, and Blazor WebAssembly — designed for efficient AI-assisted feature development.
- Overview
- Architecture
- Key Features
- Technology Stack
- Getting Started
- Secrets and configuration (development)
- Project Structure
- Development Guide
- Deployment
- Contributing
- License
Krafter is a production-ready, enterprise-grade full-stack platform built with .NET 9, combining modern architectural patterns with cutting-edge technologies. It provides a solid foundation for building scalable, multi-tenant SaaS applications with rich user interfaces.
- 🏗️ Vertical Slice Architecture (VSA) - Backend organized by features, not layers
- 🌐 Hybrid Blazor - WebAssembly + Server rendering for optimal performance
- 🏢 Multi-Tenancy - Complete tenant isolation at the database level
- 🔐 Permission-Based Security - Fine-grained authorization with JWT
- ⚡ Real-Time Updates - SignalR integration for live notifications
- 📊 Observability - OpenTelemetry with Aspire orchestration
- 🎨 Modern UI - Radzen components with theming support
- Vertical Slice Architecture (VSA) - Features organized by business capability
- Clean Code - Single Responsibility, DRY, SOLID principles
- Auto-Registration - Handlers, services, and routes discovered via markers
- Response Pattern - Consistent
Response<T>wrapper for all operations
- JWT Authentication - Secure token-based authentication
- Google OAuth - External authentication integration
- Permission-Based Authorization - Fine-grained access control
- Multi-Tenancy - Complete tenant isolation at DB level
- Token Refresh - Automatic token rotation
- Blazor Hybrid - WebAssembly + Server rendering
- Radzen Components - 70+ professional UI components
- Theme Support - Light/Dark/Auto modes with WCAG compliance
- Responsive Design - Mobile and desktop optimized
- Code-Behind Pattern - Clean separation of markup and logic
- Kiota Client - Type-safe, auto-generated API client
- EF Core - PostgreSQL & MySQL support
- Multi-Database - Separate contexts for tenants, jobs, and main data
- Migrations - Code-first database schema management
- Soft Delete - Recoverable data deletion
- Background Jobs - TickerQ for async processing
- SignalR - Real-time bi-directional communication
- Redis Cache - Distributed caching support
- Pagination - Efficient data loading
- Debouncing - Optimized search and filtering
- .NET Aspire - Orchestration and service discovery
- OpenTelemetry - Distributed tracing and metrics
- Structured Logging - Comprehensive application logs
- Health Checks - Service health monitoring
- NUKE Build - Automated build pipeline
- Docker Support - Containerized deployment
- GitHub Actions - CI/CD automation
- Auto Deployment - Webhook-triggered updates
- .NET 9 - Latest .NET framework
- ASP.NET Core - Minimal APIs
- Entity Framework Core 9 - ORM
- ASP.NET Core Identity - User management
- FluentValidation - Input validation
- TickerQ - Background job processing
- SignalR - Real-time communication
- Blazor WebAssembly - Client-side SPA
- Blazor Server - Server-side rendering
- Radzen Blazor - UI component library
- Microsoft Kiota - API client generation
- Blazored LocalStorage - Browser storage
- FluentValidation.Blazor - Client-side validation
- Mapster - Object mapping
- .NET Aspire - Cloud-native orchestration
- OpenTelemetry - Observability
- Redis - Caching (optional)
- PostgreSQL / MySQL - Database
- Docker - Containerization
- NUKE - Build automation
- .NET 9 SDK
- Docker Desktop (optional)
- PostgreSQL or MySQL
- Visual Studio 2022 or VS Code
-
Clone the repository
git clone https://github.com/AditiKraft/Krafter.git cd Krafter -
Restore packages
dotnet restore
-
Run migrations
dotnet ef database update --project src/Backend --context KrafterContext dotnet ef database update --project src/Backend --context BackgroundJobsContext dotnet ef database update --project src/Backend --context TenantDbContext
-
Configure secrets and development configuration (required before running)
Key placeholders present in the repo (replace locally):
-
aspire/Krafter.Aspire.AppHost/appsettings.jsonParameters:postgresUsername={YOUR_POSTGRES_USERNAME}Parameters:postgresPassword={YOUR_POSTGRES_PASSWORD}
-
src/Backend/appsettings.jsonTickerQBasicAuth:Username={TICKERQ_BASIC_AUTH_USERNAME}TickerQBasicAuth:Password={TICKERQ_BASIC_AUTH_PASSWORD}SecuritySettings:JwtSettings:key={JWT_SIGNING_KEY}
-
src/UI/Krafter.UI.Web/appsettings.Development.jsonJwt:Key={JWT_SIGNING_KEY}(MUST be identical to backend JWT key)
-
src/UI/Krafter.UI.Web.Client/wwwroot/appsettings.jsonRemoteHostUrl={YOUR_BACKEND_HOST}Authentication:Google:ClientId={YOUR_GOOGLE_CLIENT_ID}
Important: The JWT signing key must be exactly the same for the Backend and the UI server host. This ensures tokens issued by the backend validate correctly during server-side rendering and prerendered Blazor scenarios.
-
Run with Aspire
dotnet run --project aspire/Krafter.Aspire.AppHost
-
Access the application
- Aspire Dashboard: https://localhost:17285
- Backend API: https://localhost:5199
- Swagger UI: https://localhost:5199/swagger
- Blazor UI: https://localhost:7291
-
Default Credentials
On first run, the application seeds a default admin account:
- Email:
[email protected] - Password:
Admin@123
⚠️ Important: Change the default password immediately in production!
Krafter/
├── aspire/ # Aspire orchestration
│ ├── Krafter.Aspire.AppHost/ # Orchestration host
│ └── Krafter.Aspire.ServiceDefaults/ # Shared configuration
├── src/
│ ├── Backend/ # ASP.NET Core API (VSA)
│ │ ├── Features/ # Vertical slices (Auth, Users, Roles, Tenants)
│ │ ├── Infrastructure/ # Persistence, Jobs, Multi-tenancy
│ │ ├── Common/ # Shared utilities, permissions
│ │ ├── Api/ # API configuration, middleware
│ │ └── Program.cs # Entry point
│ └── UI/
│ ├── Krafter.UI.Web.Client/ # Blazor WebAssembly
│ │ ├── Features/ # Feature-based UI components
│ │ ├── Infrastructure/ # Services, Auth, API clients
│ │ ├── Common/ # Shared components, models
│ │ └── Client/ # Auto-generated Kiota client
│ └── Krafter.UI.Web/ # Blazor Server host
├── build/ # NUKE build project
├── .github/ # GitHub Actions workflows
└── README.md # This file
For detailed structure, see .github/copilot-instructions.md
Backend (VSA Pattern):
- Create feature folder:
Features/<Feature>/ - Add operation files (e.g.,
Create<Feature>.cs,Get<Feature>s.cs) - Add entity to
Features/<Feature>/_Shared/<Entity>.cs - Update
KrafterContext.cswith newDbSet - Create EF configuration in
Infrastructure/Persistence/Configurations/ - Run migration:
dotnet ef migrations add Add<Feature> - Add permissions to
Common/Auth/Permissions/KrafterPermissions.cs
UI (Blazor):
- Create feature folder:
Features/<Feature>/ - Add list page:
<Feature>s.razor+<Feature>s.razor.cs - Add form dialog:
CreateOrUpdate<Feature>.razor+.razor.cs - Add route constant to
Common/Constants/KrafterRoute.cs - Update permissions in
Common/Permissions/KrafterPermissions.cs - Update
Infrastructure/Services/MenuService.csfor navigation - Regenerate Kiota client:
kiota update
For complete guidelines, see Development Workflow
# Build solution
dotnet build
# Run tests
dotnet test
# Create migration
dotnet ef migrations add <Name> --project src/Backend --context KrafterContext
dotnet ef migrations add <Name> --project src/Backend --context BackgroundJobsContext
dotnet ef migrations add <Name> --project src/Backend --context TenantDbContext
# Update database
dotnet ef database update --project src/Backend --context KrafterContext
dotnet ef database update --project src/Backend --context BackgroundJobsContext
dotnet ef database update --project src/Backend --context TenantDbContext
# Regenerate Kiota API client
cd src/UI/Krafter.UI.Web.Client
kiota updateBuild images:
dotnet publish src/Backend/Backend.csproj -c Release -p:PublishProfile=DefaultContainer
dotnet publish src/UI/Krafter.UI.Web/Krafter.UI.Web.csproj -c Release -p:PublishProfile=DefaultContainerThe project includes automated CI/CD pipelines that:
- Build and test on every push
- Create Docker images for
mainanddevbranches - Push images to GitHub Container Registry
- Trigger deployment webhooks
See .github/workflows for configuration.
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Follow the coding conventions in copilot-instructions.md
- Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Use Conventional Commits:
feat(scope): add new feature
fix(scope): fix bug
docs(scope): update documentation
refactor(scope): refactor code
test(scope): add tests
This project is licensed under the MIT License - see the LICENSE file for details.
- .NET Team - For the amazing .NET platform
- Radzen - For the excellent Blazor components
- Microsoft Kiota - For the API client generator
- NUKE Build - For the build automation framework
- Documentation: Copilot Instructions
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Built with ❤️ by Aditi Kraft
⭐ Star this repository if you find it helpful!