122 lines
5.2 KiB
Markdown
122 lines
5.2 KiB
Markdown
# 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 MediatR (source-generated)
|
|
- **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 [AGENTS.md](AGENTS.md).
|
|
|
|
## Requirements
|
|
|
|
- [.NET 10 SDK](https://dotnet.microsoft.com/)
|
|
- SQL Server (local instance, or the containerized one from `docker-compose.yml`)
|
|
|
|
## Running locally
|
|
|
|
From the `server/` folder:
|
|
|
|
```bash
|
|
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 database
|
|
- `ConnectionStrings:logDb` — Serilog SQL sink database
|
|
- `IdentitySettings` — `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):
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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 **MediatR**. Cross-cutting concerns (validation, metrics) are applied as MediatR 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
|
|
|
|
```bash
|
|
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](LICENSE.md).
|