No description
- HTML 49.3%
- Python 48.9%
- JavaScript 0.8%
- Dockerfile 0.8%
- CSS 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
Build & Publish Nightly Container / Build & Publish Container (:nightly) (push) Successful in 10s
Reviewed-on: #2 |
||
| .forgejo/workflows | ||
| app | ||
| data | ||
| tests | ||
| .dockerignore | ||
| .env | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| README.md | ||
| requirements.txt | ||
Spesen Portal
A modern, containerized web application for registering and managing volunteer expense reimbursements ("Spesen") for small volunteer-based non-profit organizations.
🌟 Key Features
- OpenID Connect (OIDC) Authentication: Exclusively authenticates against your Identity Provider (Keycloak, Authentik, Zitadel, Google Workspace, Azure AD, etc.).
- User Auto-Provisioning: Users are automatically provisioned and synchronized on login with their
username,display_name, andemail. - Payout Information Management: Seamlessly stores and allows updating of each volunteer's IBAN and Postal Address, with automatic IBAN grouping formatting.
- Admin Privilege Mapping: Admin status is derived dynamically from the OIDC
groupsclaim (groupscontains'admin'). - Refund Requests:
- Expense Name / Title, Amount (CHF/EUR/etc.), and Destination / Vendor.
- Receipt image/document upload directly from mobile phone camera (
capture="environment") or desktop drag-and-drop (JPG, PNG, WEBP, PDF). - Linked to the submitting volunteer and categorized by an admin-defined Project.
- Volunteer view of all their requests and live status (
pending,completed).
- Admin & Treasurer Features:
- Comprehensive view of all refund requests across all volunteers.
- Direct visibility into volunteer IBAN and postal address for one-click payment processing.
- Mark requests as Completed with optional payment references / audit notes.
- Financial Project Overview: All requests sorted by project with individual and grand totals for pending, completed, and overall amounts.
- Project Management: Create and manage projects (activate/archive).
- CSV Export: Export all records for bookkeepers and financial audits.
- Email Notifications:
- Dispatched automatically via SMTP when a new refund request is registered (alert to treasurer + confirmation to volunteer).
- Dispatched automatically to the volunteer when their refund is marked as completed and paid out.
- Graceful dev fallback if SMTP is unconfigured.
- Docker-Ready: Packaged with a lightweight
Dockerfileanddocker-compose.ymlwith persistent storage for SQLite data and receipts.
🚀 Quick Start with Docker
1. Clone or Navigate to the App Directory
cd /home/edward/.gemini/antigravity/scratch/spesen-app
2. Configure Environment Variables
Copy the template configuration file:
cp .env.example .env
Edit .env to configure your OIDC provider and SMTP settings. (For quick local testing without an external IdP, leave ENABLE_DEV_LOGIN=true).
3. Build & Run with Docker Compose
docker compose up -d --build
The web app is now available at: 👉 http://localhost:8000
🔐 OpenID Connect (OIDC) Configuration
The application uses standard OIDC Authorization Code Flow with PKCE.
Configure the following variables in .env:
OIDC_DISCOVERY_URL="https://auth.example.org/realms/nonprofit/.well-known/openid-configuration"
OIDC_CLIENT_ID="spesen-client"
OIDC_CLIENT_SECRET="your-client-secret"
OIDC_SCOPES="openid profile email groups"
OIDC_ADMIN_GROUP="admin"
Redirect URI
In your Identity Provider's client settings, set the Allowed Redirect URI to:
http://<your-domain-or-localhost:8000>/auth/oidc/callback
Admin Privilege Determination
Admin rights are granted if the user's OIDC token or userinfo contains:
groups: containing'admin'(e.g.["admin", "volunteers"]or comma-delimited"admin,volunteers")- Or fallback:
group: "admin",roles: ["admin"], or Keycloakrealm_access.roles: ["admin"].
📧 Email Notifications Setup
Configure your organization's SMTP server in .env:
SMTP_ENABLED=true
SMTP_HOST="smtp.example.org"
SMTP_PORT=587
SMTP_USER="spesen@example.org"
SMTP_PASSWORD="your-secure-password"
SMTP_FROM="spesen@example.org"
SMTP_FROM_NAME="Nonprofit Spesen Portal"
SMTP_STARTTLS=true
ADMIN_NOTIFICATION_EMAIL="treasurer@example.org"
When Emails are Sent:
- New Request Created:
- Treasurer: Receives full expense details, project name, amount, volunteer name, IBAN, and a direct review link.
- Volunteer: Receives submission confirmation.
- Request Completed:
- Volunteer: Receives notification that their refund has been processed, the amount paid, payment reference/notes, and the destination IBAN.
📂 Project Structure
spesen-app/
├── app/
│ ├── config.py # App settings and environment loading
│ ├── database.py # SQLAlchemy database connection and session
│ ├── models.py # User, Project, and RefundRequest database models
│ ├── auth.py # OIDC authentication, claims extraction, auto-provisioning
│ ├── mailer.py # SMTP email dispatcher with HTML templates
│ ├── main.py # FastAPI application setup and middlewares
│ ├── routes/
│ │ ├── auth.py # Login, OIDC exchange, logout, dev demo login
│ │ ├── requests.py # Volunteer refund requests (list, create, detail)
│ │ ├── admin.py # Admin project overview, all requests, complete, projects, CSV export
│ │ ├── profile.py # User profile, IBAN & address management
│ │ └── receipts.py # Secure receipt image & PDF serving with auth checks
│ ├── templates/ # Responsive Jinja2 templates styled with Tailwind CSS
│ └── static/ # Static CSS and JS assets (drag-and-drop, IBAN auto-format)
├── tests/ # Pytest test suite (13 passing tests)
├── Dockerfile # Production Dockerfile
├── docker-compose.yml # Multi-container orchestration with persistent storage
├── .env.example # Documented environment variables template
└── requirements.txt # Python dependencies
🧪 Running Automated Tests
To run the test suite locally:
source .venv/bin/activate
PYTHONPATH=. pytest -v tests
Tests verify:
- OIDC claim extraction and auto-provisioning
- Group-based admin detection
- User IBAN and address persistence
- Volunteer request isolation and receipt authorization
- Admin overview calculations (totals grouped by project)
- Admin completion workflow and notes
- Email notification triggers
- CSV accounting exports