https://github.com/bvandewe/starter-app
An opinionated FastAPI template showcasing Clean architecture DDD, CQRS, OAuth2/OIDC with RBAC, CloudEvents, OTEL and pluggable infrastructure, implementing Neuroglia Python Framework
https://github.com/bvandewe/starter-app
cqrs cqrs-pattern ddd ddd-example fastapi-template full-stack-web-development otel-supported rbac starter-template
Last synced: 3 months ago
JSON representation
An opinionated FastAPI template showcasing Clean architecture DDD, CQRS, OAuth2/OIDC with RBAC, CloudEvents, OTEL and pluggable infrastructure, implementing Neuroglia Python Framework
- Host: GitHub
- URL: https://github.com/bvandewe/starter-app
- Owner: bvandewe
- License: apache-2.0
- Created: 2025-11-07T22:17:57.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2025-12-16T07:46:08.000Z (4 months ago)
- Last Synced: 2025-12-19T19:49:59.417Z (4 months ago)
- Topics: cqrs, cqrs-pattern, ddd, ddd-example, fastapi-template, full-stack-web-development, otel-supported, rbac, starter-template
- Language: Python
- Homepage: https://bvandewe.github.io/starter-app
- Size: 2.38 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Starter App - Neuroglia WebApplication
[](https://www.python.org/downloads/)
[](https://python-poetry.org/)
[](https://fastapi.tiangolo.com)
[](https://github.com/neuroglia-io/python-framework)
[](LICENSE)
[](https://bvandewe.github.io/starter-app/)
[](https://github.com/psf/black)
[](https://github.com/astral-sh/ruff)
[](https://docs.pytest.org/)
[](htmlcov/index.html)
[](docker-compose.yml)
[](https://www.keycloak.org/)
[](https://www.mongodb.com/)
[](https://redis.io/)
An opinionated Neuroglia FastAPI template showcasing multi-subapp architecture (API + UI), CQRS, RBAC, OAuth2/OIDC, and pluggable infrastructure:
- π¨ **SubApp Pattern**: Clean separation between API and UI concerns
- π **OAuth2/OIDC Authentication**: Keycloak integration with Backend-for-Frontend pattern
- π΄ **Redis Session Store**: Distributed sessions for horizontal scaling in Kubernetes
- π‘οΈ **RBAC**: Role-based access control at the application layer
- π **CQRS Pattern**: Command Query Responsibility Segregation
- π― **Clean Architecture**: Domain-driven design with clear boundaries

## ποΈ Architecture
This application follows the **Simple UI** sample pattern from Neuroglia, implementing:
- **API SubApp** (`/api`): RESTful JSON endpoints with JWT authentication
- **UI SubApp** (`/`): Bootstrap 5 SPA with Parcel bundler
- **Domain Layer**: Task entities with repository pattern
- **Application Layer**: CQRS commands/queries with RBAC handlers
- **Integration Layer**: In-memory and MongoDB (motor) repositories (ready for PostgreSQL/Redis/...)
### Project Structure
```
starter-app/
βββ src/
β βββ main.py # FastAPI app factory entry point
β βββ api/ # API sub-app (mounted at /api)
β β βββ controllers/ # Route controllers
β β βββ dependencies.py # Shared dependency helpers (auth, user)
β β βββ services/ # API-specific service utilities (e.g. OpenAPI config)
β βββ application/ # Application layer (CQRS, mapping, settings)
β β βββ settings.py
β β βββ commands/ # Write operations
β β βββ queries/ # Read operations
β β βββ events/ # Domain/application events (placeholder)
β β βββ mapping/ # Object mapping profiles
β β βββ services/ # Cross-cutting services (logger, etc.)
β βββ domain/ # Pure domain model
β β βββ entities/ # Aggregate/entity classes (task, etc.)
β β βββ repositories/ # Repository interfaces (ports)
β βββ infrastructure/ # Technical adapters implementing ports
β β βββ session_store.py # Session store implementations (in-memory/redis)
β βββ integration/ # Concrete adapters / in-memory repos
β β βββ models/
β β βββ repositories/
β βββ observability/ # Metrics, tracing, logging integration points
β β βββ metrics.py
β βββ ui/ # Frontend build + controller sub-app
β β βββ controllers/ # UI route(s)
β β βββ src/ # Parcel source (scripts, styles)
β β βββ package.json # Frontend dependencies
βββ tests/ # Pytest suites (unit/integration)
β βββ test_rename_integrity.py # Ensures no leftover starter branding post-rename
βββ scripts/
β βββ rename_project.py # Automated project rebranding utility
βββ docs/ # MkDocs documentation source
βββ deployment/ # Deployment & Keycloak realm config assets
βββ notes/ # Design / architecture scratchpad docs
βββ static/ # Published frontend bundle (built UI assets)
βββ Makefile # Developer automation commands
βββ docker-compose.yml # Local service orchestration
βββ Dockerfile # Application container build
βββ pyproject.toml # Python dependencies & tool config (Poetry)
βββ README.md # This file
```
## π Quick Start
### Prerequisites
- Python 3.11+
- Poetry
- Node.js 20+ (for UI build)
- Docker & Docker Compose (optional)
### Quick Setup (Recommended)
Use the Makefile for easy setup and management:
```bash
# Complete setup for new developers
make setup
# Run locally
make run
# Or run with Docker
make up
# See all available commands
make help
```
### Manual Local Development
1. **Install Python dependencies:**
```bash
poetry install
```
2. **Install frontend dependencies and build UI:**
```bash
make install-ui
make build-ui
```
3. **Run the application:**
```bash
make run
```
4. **Access the application:**
- Application: http://localhost:8000/
- API Documentation: http://localhost:8000/api/docs
### Frontend Development Mode
For hot-reload during UI development:
```bash
# Terminal 1: Watch and rebuild frontend assets
make dev-ui
# Terminal 2: Start backend with hot-reload
make run
```
### Docker Development
Run the complete stack with Docker Compose using the **Makefile** (recommended):
```bash
# Copy environment variables (first time only)
cp .env.example .env
# Build and start services
make up
# View logs
make logs
# Stop services
make down
# Rebuild from scratch
make rebuild
```
Or use docker-compose directly:
```bash
# Start all services
docker-compose up
# Or run in background
docker-compose up -d
```
This will start:
- β
Starter App App (http://localhost:8020)
- β
MongoDB (localhost:8022) and Mongo Express (http://localhost:8023)
- β
Keycloak (http://localhost:8021)
- β
OpenTelemetry Collector
- β
UI Builder (auto-rebuild)
- β
Redis (localhost:6379)
- β
Event Player (http://localhost:8024)
## π₯ Test Users
The application includes test users with different roles:
| Username | Password | Role | Access Level |
|----------|----------|------|--------------|
| admin | test | admin | All tasks |
| manager | test | manager | Department tasks |
| user | test | user | Only assigned tasks |
See [deployment/keycloak/starter-app-realm-export.json](./deployment/keycloak/starter-app-realm-export.json)
## π Authentication & RBAC
### JWT Authentication
- **Stateless**: No server-side sessions required
- **Token Storage**: localStorage (not cookies)
- **Expiration**: 24 hours (configurable)
- **Claims**: username, user_id, roles, department
### Role-Based Access Control
Authorization happens in the **application layer** (handlers), not controllers:
- **Admin**: Can view and manage all tasks, can delete tasks
- **Manager**: Can view tasks in their department
- **User**: Can only view their assigned tasks
Example RBAC logic in `GetTasksQueryHandler`:
```python
if "admin" in user_roles:
tasks = await self.task_repository.get_all_async()
elif "manager" in user_roles:
tasks = await self.task_repository.get_by_department_async(department)
else:
tasks = await self.task_repository.get_by_assignee_async(user_id)
```
## π οΈ Configuration
### Environment Variables
Create a `.env` file (or use `.env.example`):
```bash
# Application server
APP_HOST=127.0.0.1 # Override only if you must expose the API externally
APP_PORT=8080
# Keycloak OAuth2/OIDC
KEYCLOAK_SERVER_URL=http://keycloak:8080
KEYCLOAK_REALM=starter-app
KEYCLOAK_CLIENT_ID=portal-web-app
# Redis Session Storage (for production horizontal scaling)
REDIS_ENABLED=false # Set to true for production
REDIS_URL=redis://redis:6379/0
REDIS_KEY_PREFIX=session:
# Database
MONGODB_PASSWORD=neuroglia123
```
### Redis Session Store
The application supports two session storage backends:
**Development (default)**: `InMemorySessionStore`
- β‘ Fast, no external dependencies
- β οΈ Sessions lost on restart
- β Not suitable for multiple instances
**Production**: `RedisSessionStore`
- π΄ Distributed, shared across pods
- π Enables horizontal scaling in Kubernetes
- πͺ Sessions survive pod restarts
- β° Auto-expiring via Redis TTL
To enable Redis for production:
```bash
# In .env file
REDIS_ENABLED=true
```
See `notes/REDIS_SESSION_STORE.md` for detailed documentation on:
- Kubernetes deployment strategies
- Redis configuration options
- Testing horizontal scaling
- Security best practices
### VS Code Setup
The project includes VS Code settings for:
- β
Automatic Poetry venv activation
- β
Python formatter (Black)
- β
Import organization
- β
Pytest integration
## π Documentation
### API Documentation
Once running, visit http://localhost:8020/api/docs for interactive API documentation.
### Project Documentation
Comprehensive documentation is available in the `docs/` directory and online:
- **Online**: https://bvandewe.github.io/starter-app
- **Local**: Run `make docs-serve` and visit http://127.0.0.1:8000
#### Documentation Topics
- [**Getting Started**](https://bvandewe.github.io/starter-app/getting-started/installation/) - How to install and run the application.
- [**Architecture**](https://bvandewe.github.io/starter-app/architecture/overview/) - CQRS pattern, dependency injection, design patterns
- [**Security**](https://bvandewe.github.io/starter-app/security/authentication-flows/) - Dual auth system (session + JWT), OAuth2/OIDC, RBAC
- [**Development**](https://bvandewe.github.io/starter-app/development/makefile-reference/) - Makefile reference, workflow, testing
- [**Deployment**](https://bvandewe.github.io/starter-app/deployment/docker-environment/) - Docker environment, deployment, configuration
- [**Troubleshooting**](https://bvandewe.github.io/starter-app/troubleshooting/common-issues/) - Common issues, known bugs, solutions
#### Documentation Commands
```bash
# Install documentation dependencies
make docs-install
# Serve documentation locally with live reload
make docs-serve
# Build documentation site
make docs-build
# Deploy to GitHub Pages (maintainers only)
make docs-deploy
```
### Key Endpoints
#### Authentication
- `POST /api/auth/login` - Login and get JWT token
#### Tasks
- `GET /api/tasks` - Get tasks (role-filtered)
- `POST /api/tasks` - Create new task
- `PUT /api/tasks/{task_id}` - Update task (with authorization)
All task endpoints require `Authorization: Bearer {token}` header.
## οΏ½οΈ Makefile Commands
The project includes a comprehensive Makefile for easy development workflow management:
### Docker Commands
- `make build` - Build Docker image
- `make dev` - Build and start Docker services with logs
- `make rebuild` - Rebuild services from scratch (no cache)
- `make up` - Start services in background
- `make down` - Stop and remove services
- `make restart` - Restart all services
- `make logs` - Show logs from all services
- `make clean` - Stop services and remove volumes β οΈ
### Local Development Commands
- `make setup` - Complete setup for new developers (install + build)
- `make install` - Install Python dependencies with Poetry
- `make install-ui` - Install Node.js dependencies
- `make build-ui` - Build frontend assets
- `make dev-ui` - Start UI dev server with hot-reload
- `make run` - Run application locally with auto-reload
- `make run-debug` - Run with debug logging
### Testing & Quality Commands
- `make test` - Run tests
- `make test-cov` - Run tests with coverage report
- `make lint` - Run linting checks
- `make format` - Format code with Black
### Utility Commands
- `make clean` - Clean up caches and generated files
- `make clean-all` - Clean everything including Docker volumes
- `make status` - Show current environment status
- `make info` - Display project information and URLs
- `make env-check` - Check environment requirements
- `make help` - Display all available commands
**Example Workflow:**
```bash
# New developer setup
make setup
# Start local development
make run
# Or use Docker
make docker-up
make docker-logs
# Stop Docker services
make docker-down
```
## οΏ½π Related Documentation
- [Neuroglia Python Framework](https://bvandewe.github.io/pyneuro/)
- [Simple UI Sample](https://bvandewe.github.io/pyneuro/samples/simple-ui/)
- [RBAC Guide](https://bvandewe.github.io/pyneuro/guides/rbac-authorization/)
- [OAuth & JWT Reference](https://bvandewe.github.io/pyneuro/references/oauth-oidc-jwt/)
## π§ͺ Testing
```bash
# Run tests
poetry run pytest
```
## πͺ Pre-Commit Hooks
Automated formatting, linting, and security checks run before you commit to keep the codebase consistent.
### What's Included
- Trailing whitespace / EOF / merge conflict checks
- Black (Python formatting) + isort (imports)
- Flake8 (lint) and optional Ruff/extra rules if enabled
- Prettier for JS/TS/CSS/HTML/JSON/YAML/Markdown
- Markdownlint (auto-fix basic style issues)
- Yamllint (with relaxed config)
- Bandit (Python security scanning)
- Detect-Secrets (prevents committing secrets)
### Setup
```bash
poetry add --group dev pre-commit
poetry run pre-commit install --install-hooks
poetry run pre-commit run --all-files # Run on entire repo once
```
If you later update hooks:
```bash
poetry run pre-commit autoupdate
```
### Enforcing Consistency
CI should run:
```bash
poetry run pre-commit run --all-files
```
### DCO Reminder
Pre-commit does not enforce DCO; ensure commits include:
```
Signed-off-by: Your Name
```
Use `git commit -s` to auto-add this line.
## π Rebranding / Forking as a New Project
You can turn this repository into a new project quickly without manually hunting for every
`starter-app` occurrence.
### Option 1: Built-in Rename Script (Recommended)
Run a dry run first:
```bash
python scripts/rename_project.py --new-name "Acme Tasks" --dry-run
```
Apply the changes:
```bash
python scripts/rename_project.py --new-name "Acme Tasks"
```
This will replace variants:
- `starter-app` (slug)
- `starter_app` (snake)
- `Starter App` (title)
- `StarterApp` (Pascal)
- `STARTER_APP` (UPPER_SNAKE)
- `Starter App API`
Optional flags:
```bash
# Also adjust Keycloak realm/client identifiers (you must reconfigure Keycloak manually afterward)
python scripts/rename_project.py --new-name "Acme Tasks" --update-keycloak
# Limit to certain folders
python scripts/rename_project.py --new-name "Acme Tasks" --include src docs
# Override derived name styles explicitly
python scripts/rename_project.py --new-name "Acme Tasks" \
--slug acme-tasks --snake acme_tasks --pascal AcmeTasks --upper ACME_TASKS
```
Post-rename checklist:
1. Rename the repository folder and remote (e.g., `git remote set-url origin ...`).
2. Adjust Docker image tags / compose service names if needed.
3. Update Keycloak realm + client IDs if `--update-keycloak` was used.
4. Search for any remaining branding (e.g., README examples, docs URLs).
5. Run tests: `poetry run pytest -q`.
6. Rebuild UI assets: `make build-ui`.
### Option 2: GitHub Template Repo
Using GitHub's builtβin Template feature lets you create a clean copy of the repository without forking the full commit history. Workflow:
1. Maintainer: In the original repo, go to Settings β General β Enable "Template repository".
2. Consumer: Click "Use this template" (instead of Fork). GitHub scaffolds a brandβnew repo with the current contents (no upstream remote linkage).
3. In your new repo clone, run the rename script (Option 1) to apply your branding and identifiers.
4. Update any secrets / realms (Keycloak) and run tests.
Why combine both? The template feature handles repository creation & initial history isolation; the rename script performs systematic text/style replacements so you don't miss lingering `starter-app` variants. If you skip the script, manual edits are errorβprone (especially mixed case variants and service identifiers).
### Option 3: Cookiecutter (Future)
You can evolve this into a Cookiecutter template for parameter prompts. A future `cookiecutter.json` might include: app_name, slug, docker_image, keycloak_realm, enable_redis, etc.
### Verify No Leftover Names
Run the rename integrity test (after the script has been applied and test added):
```bash
poetry run pytest -k rename_integrity -q
```
If it fails, it lists files containing residual references.
### Run with coverage
```bash
poetry run pytest --cov=. --cov-report=html
```
## π¦ Deployment
### Production Checklist
- [ ] Change `JWT_SECRET_KEY` to a strong random value
- [ ] Set `DEBUG=False` in settings
- [ ] Configure proper database (MongoDB/PostgreSQL)
- [ ] Set up Keycloak for production OAuth/OIDC
- [ ] Configure CORS for production domains
- [ ] Set up proper logging and monitoring
- [ ] Use environment-specific `.env` files
### Docker Production Build
```bash
docker build -t starter-app:latest .
docker run -p 8000:8000 starter-app:latest
```
## π€ Contributing
This project follows the Neuroglia Python Framework patterns. See the [development guide](https://bvandewe.github.io/pyneuro/guides/local-development/) for more information.
## π License
Licensed under the Apache License, Version 2.0. See `LICENSE` for the full text.
Copyright Β© 2025 Starter App Contributors.
You may not use this project except in compliance with the License. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
---
Built with β€οΈ using [Neuroglia Python Framework](https://github.com/bvandewe/pyneuro)