5.3 KiB
Balinyaar — Server (ASP.NET Core, Clean Architecture)
Backend API for the Balinyaar application. It is an ASP.NET Core (.NET 10) solution organized around Clean Architecture, with:
- CQRS via
martinothamar/Mediator(source-generated; not MediatR) - ASP.NET Core Identity with JWE (signed + encrypted JWT) and OTP authentication
- Dynamic, permission-based authorization
- EF Core persistence (SQL Server) with the Repository + Unit of Work patterns
- A modular gRPC plugin mounted via Application Parts
- Observability out of the box: Serilog, OpenTelemetry, Prometheus metrics, health checks
Looking for an architecture/file map to navigate the code? See CLAUDE.md (agent guide) and CONVENTIONS.md (coding rules).
Requirements
- .NET 10 SDK
- SQL Server (local instance, or the containerized one from
docker-compose.yml)
Running locally
From the server/ folder:
dotnet restore Baya.sln
dotnet build Baya.sln
dotnet run --project src/API/Baya.Web.Api/Baya.Web.Api.csproj
By default the API listens on https://localhost:5002 and serves Swagger UI at /swagger.
On startup the app applies EF Core migrations and seeds default users automatically, so a reachable database (see appsettings.json → ConnectionStrings) is required.
Configuration
Settings live in src/API/Baya.Web.Api/appsettings.json (+ appsettings.Development.json):
ConnectionStrings:SqlServer— main application databaseConnectionStrings:logDb— Serilog SQL sink databaseIdentitySettings—SecretKey(signing),Encryptkey(AES-128 encryption, exactly 16 chars),Issuer,Audience, token lifetimes
Running with Docker
Generate a development HTTPS certificate (used by the container):
dotnet dev-certs https -ep $env:USERPROFILE/.aspnet/https/baya.pfx -p Strong@Password
dotnet dev-certs https --trust
Build and start the API together with SQL Server 2022:
docker build -t bobby-baya -f Dockerfile .
docker-compose up -d
The compose stack exposes the API on http://localhost:5000 / https://localhost:5001 and SQL Server on localhost:1435.
Solution layout
src/
├── Core/
│ ├── Baya.Domain Entities + domain primitives (the core / "brain")
│ └── Baya.Application CQRS features, contracts (interfaces), MediatR pipeline
├── Infrastructure/
│ ├── Baya.Infrastructure.Persistence EF Core DbContext, configs, repositories, UoW, migrations
│ ├── Baya.Infrastructure.Identity Identity, JWE/JWT, OTP, dynamic permissions
│ ├── Baya.Infrastructure.CrossCutting Cross-cutting concerns (logging)
│ └── Baya.Infrastructure.Monitoring Health checks, OpenTelemetry, Prometheus
├── API/
│ ├── Baya.Web.Api Presentation: REST controllers, Program.cs (startup)
│ ├── Baya.WebFramework Reusable web config: base controller, filters, middleware, Swagger
│ └── Plugins/Baya.Web.Plugins.Grpc Self-contained gRPC plugin
├── Shared/
│ └── Baya.SharedKernel Shared extensions/helpers referenced by every layer
└── Tests/ xUnit test setup + Identity tests
The layers (why they exist)
Domain
The core of the project. Each entity may carry its own behavior. Entities derive from a common BaseEntity, which lets the persistence layer discover models via reflection to register them and drive migrations.
Application
Routes requests and defines the contracts (interfaces) the system depends on, without knowing their implementations. This is where CQRS lives: Commands and Queries are kept separate and dispatched to their handlers by Mediator (martinothamar/Mediator, source-generated). Cross-cutting concerns (validation, metrics) are applied as Mediator pipeline behaviors.
Infrastructure
Implements the contracts the Application layer declares — the parts needed to run in the real world:
- Persistence — the chosen database (SQL Server via EF Core). Repositories give self-describing, persistence-agnostic data access; Unit of Work keeps multi-step writes atomic and consistent.
- Identity — registration, authentication and authorization using ASP.NET Core Identity, with JWE tokens, OTP login, and a dynamic access-control system.
- CrossCutting — services used across the whole app, such as logging.
- Monitoring — health checks, distributed tracing/metrics, and Prometheus.
WebFramework
Keeps Program.cs thin by moving each piece of configuration into its own reusable class (filters, middleware, Swagger, API versioning, the base controller, etc.).
Web.Api
The presentation layer — an ASP.NET Core Web API exposing versioned REST controllers under Controllers/V1.
Web.Plugins.Grpc
A standalone module that adds gRPC endpoints to the same host via Application Parts, giving modularity (the "plugin" middle ground between a monolith and microservices) without a separate deployment. It registers its services and pipeline through extension methods called from Program.cs.
Tests
dotnet test Baya.sln
Each layer is designed to be testable in isolation; Baya.Tests.Setup provides the shared test scaffolding.
License
See LICENSE.md.