BeanShare is a Clean Architecture information system for managing office coffee consumption, built with .NET 10, Blazor Server, and .NET MAUI. It tracks purchases, logs user consumption, generates settlements, and provides analytics with PostgreSQL and OpenID Connect support.
- Multi-User Spaces: Create and manage multiple coffee-sharing spaces
- Stock Management: Track coffee purchases and inventory levels
- Consumption Tracking: Log individual coffee consumption with presets
- Automated Settlements: Generate fair cost-sharing reports using weighted average costing
- Multi-Currency Support: Handle purchases and settlements in different currencies with automatic exchange rate updates
- Authentication: Support for Keycloak OIDC, JWT tokens, and OAuth providers
- Cross-Platform: Web application (Blazor Server) and mobile app (.NET MAUI)
- Document Export: Generate settlement reports in PDF and Excel formats
- Email Notifications: Send settlement notifications to space members
BeanShare follows Clean Architecture principles with clear separation of concerns:
BeanShare/
├── src/
│ ├── Core/
│ │ ├── BeanShare.Domain/ # Entities, Value Objects, Domain Services
│ │ └── BeanShare.Application/ # Use Cases, DTOs, Interfaces
│ ├── Infrastructure/
│ │ ├── BeanShare.Infrastructure/ # Exchange Rates, Documents
│ │ ├── BeanShare.Infrastructure.Persistence/ # EF Core, Repositories
│ │ ├── BeanShare.Infrastructure.Identity/ # Authentication
│ │ └── BeanShare.Infrastructure.Communication/ # Email Service
│ └── Presentation/
│ ├── BeanShare.Api/ # FastEndpoints API
│ ├── BeanShare.BlazorWeb/ # Blazor Server Web App
│ ├── BeanShare.Maui/ # Mobile App
│ └── BeanShare.SharedUi/ # Shared Razor Components
└── tests/
├── BeanShare.Application.Tests/ # Application Layer Tests
├── BeanShare.Infrastructure.Tests/ # Infrastructure Tests
├── BeanShare.Tests.Unit/ # Domain Unit Tests
└── BeanShare.Tests.Integration/ # Integration Tests
- .NET 10.0 SDK
- PostgreSQL 14+
- (Optional) Keycloak for OIDC authentication
- (Optional) OpenExchangeRates API key for currency conversion
-
Clone the repository
git clone <repository-url> cd BeanShare
-
Configure environment variables
cp .env.example .env # Edit .env with your local configuration -
Set up the database
# Create PostgreSQL database createdb beanshare # Update connection string in .env ConnectionStrings__DefaultConnection="Host=localhost;Database=beanshare;Username=postgres;Password=yourpassword"
-
Run the API
cd src/Presentation/BeanShare.Api dotnet run -
Run the Web Application
cd src/Presentation/BeanShare.BlazorWeb dotnet run -
Access the application
- Web App: http://localhost:5126
- API: http://localhost:5247
- Swagger: http://localhost:5247/swagger
For quick testing without setting up PostgreSQL:
{
"UseMockServices": true,
"UseMockAuthentication": true
}Add these to appsettings.Development.json and run the application.
Development with Nix:
nix develop # enter dev shell (.NET 10, git)
nix run .#updateDeps # refresh NuGet lockfile (nix/deps.json)
cp .env.oidc.local.example .env.oidc.local # optional: enable local OIDC for dev-container
nix run .#dev-container -- up # build/load/run dev container in DockerRun the development container for the services.beanshare-blazorweb NixOS module in Docker:
# build and start
nix run .#dev-container -- up
# open a shell in the running container
nix run .#dev-container -- exec
# connect over SSH (nixos@localhost:2222, password: nixos)
nix run .#dev-container -- ssh
# inspect and stop it
nix run .#dev-container -- status
nix run .#dev-container -- downThis workflow:
- builds a NixOS container image via
dockerTools(no project Dockerfile) - enables
services.beanshare-blazorweb,services.beanshare-api, and nginx inside the container - loads and starts it under Docker with systemd
- exposes SSH on
localhost:2222and a single HTTP endpoint on0.0.0.0:5000 - serves the Blazor web app on
http://localhost:5000/and the API onhttp://localhost:5000/api/ - mounts
.env.oidc.localinto the container when present, so local OIDC secrets stay out of git - supports
up,exec,down,ps,status, andsshsubcommands viadev-container
When deploying the NixOS modules directly, import self.nixosModules.beanshareCommon alongside the web and API modules. It provides shared defaults for:
services.beanshare.database.*for the common PostgreSQL connection and local data directoryservices.beanshare.storage.uploadsRootPathfor the shared avatar upload filesystem path
- Deployment Guide - Full deployment guide with infrastructure setup
- Configuration Guide - Complete guide to all configuration options
- Production Deployment Checklist - Step-by-step deployment checklist
- CSS Architecture - UI styling and theming guide
- Architecture - System architecture and design decisions
BeanShare uses environment variables for sensitive configuration. See CONFIGURATION.md for detailed information.
ConnectionStrings__DefaultConnection- PostgreSQL connection stringJwt__Secret- JWT signing secret (minimum 32 characters)OpenExchangeRates__AppId- API key from openexchangerates.org
- Keycloak OIDC settings
- Email (SMTP) settings
- .NET 10.0 SDK
- Docker Desktop
# 1. Start PostgreSQL + Keycloak
docker compose up -d
# 2. Run the API (auto-creates database and seeds demo data)
cd src/Presentation/BeanShare.Api
dotnet run
# 3. In another terminal, run the web app
cd src/Presentation/BeanShare.BlazorWeb
dotnet run- Web App: http://localhost:5126
- API / Swagger: http://localhost:5247/swagger
- Keycloak Admin: http://localhost:8080 (admin / admin)
Login with any demo user (password: password123):
john.smith@beanshare.dev(Admin)sarah.johnson@beanshare.com(Member)test@beanshare.com(Member)
See PRODUCTION-DEPLOYMENT.md for production deployment and TEST.md for local setup.
- Local Testing Guide - Development setup & local testing
- Production Deployment - Production deployment guide
- Configuration Guide - All configuration options
- Architecture - System architecture and design decisions
- API Documentation - REST API reference
- User Guide - End-user documentation
- CSS Architecture - UI styling and theming
See CONFIGURATION.md for all options and PRODUCTION-DEPLOYMENT.md for production setup.
- PostgreSQL connection string
- Keycloak realm URL and client secrets
- JWT signing secret (minimum 32 characters)
- OpenExchangeRates API key (currency conversion)
- SMTP credentials (email notifications)
- OAuth providers (Google, Facebook)
BeanShare supports multiple authentication methods:
-
Keycloak OIDC (Recommended for production)
- Enterprise-grade authentication
- OAuth 2.0 / OpenID Connect
- Single sign-on support
- User federation
-
OAuth Providers
- Google OAuth
- Facebook OAuth
See CONFIGURATION.md for setup instructions.
- .NET 10 - Application framework
- Entity Framework Core - ORM
- PostgreSQL - Database
- FastEndpoints - API framework
- MediatR - CQRS pattern
- Mapster - Object mapping
- Blazor Server - Web application framework
- .NET MAUI - Mobile application framework
- Bootstrap 5 - UI framework
- Font Awesome - Icons
- Keycloak - Authentication (optional)
- OpenExchangeRates - Currency conversion
- SMTP - Email notifications
- xUnit - Testing framework
- FluentAssertions - Test assertions
- Moq - Mocking library
- QuestPDF - PDF generation
- ClosedXML - Excel generation
# Run all tests
dotnet test
# Run specific test project
dotnet test tests/BeanShare.Application.Tests
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"# Build API
cd src/Presentation/BeanShare.Api
dotnet publish -c Release -o ./publish
# Build Web App
cd src/Presentation/BeanShare.BlazorWeb
dotnet publish -c Release -o ./publish
# Build MAUI (Windows)
cd src/Presentation/BeanShare.Maui
dotnet publish -f net10.0-windows10.0.19041.0 -c Release
# Build MAUI (Android)
dotnet publish -f net10.0-android -c ReleaseSee PRODUCTION_DEPLOYMENT_CHECKLIST.md for complete deployment guide. See TEST.md for local setup and PRODUCTION-DEPLOYMENT.md for production deployment.
BeanShare.Domain - Enterprise business rules
Aggregates/- Domain aggregates (Space, CoffeeStock, Settlement)Entities/- Domain entitiesValueObjects/- Value objects (Money, Currency, Weight)Services/- Domain services (CostingPolicy)Specifications/- Query specifications
BeanShare.Application - Application business rules
Features/- Use cases organized by feature (CQRS pattern)Abstractions/- Repository and service interfacesServices/- Application servicesConstants/- Application constantsCommon/- Shared DTOs and results
BeanShare.Infrastructure - External services implementation
Services/- Currency exchange, document generationDependencyInjection.cs- Service registration
BeanShare.Infrastructure.Persistence - Data access
Configurations/- EF Core entity configurationsRepositories/- Repository implementationsSeeds/- Database seeding
BeanShare.Infrastructure.Identity - Authentication
- JWT token generation
- Password hashing
- OAuth integration
BeanShare.Infrastructure.Communication - Email service
- SMTP email sending
- Email templates
BeanShare.Api - REST API
Endpoints/- FastEndpoints definitionsFilters/- Request/response filtersMiddleware/- Custom middleware
BeanShare.BlazorWeb - Web application
Components/- Razor componentsEndpoints/- Account endpoints (login/register)Services/- UI services
BeanShare.Maui - Mobile application
Components/- Mobile-specific componentsServices/- Platform-specific servicesPlatforms/- Platform-specific code
BeanShare.SharedUi - Shared components
- Reusable Razor components
- Shared CSS and assets
- Follow Clean Architecture principles
- Write unit tests for new features
- Update documentation as needed
- Follow C# coding conventions
- Use meaningful commit messages
This project is licensed under the GNU Affero General Public License v3.0.
Authored by Oliver Golec as a diploma thesis at the Faculty of Information Technology, Brno University of Technology (VUT FIT), under the supervision of Ing. Jan Pluskal, Ph.D.
For issues and questions, create an issue in the repository.