Files
org-parking/README.md
Stefano Manfredi c74a0ed350 Initial commit: Parking Manager
Features:
- Manager-centric parking spot management
- Fair assignment algorithm (parking/presence ratio)
- Presence tracking calendar
- Closing days (specific & weekly recurring)
- Guarantees and exclusions
- Authelia/LLDAP integration for SSO

Stack:
- FastAPI backend
- SQLite database
- Vanilla JS frontend
- Docker deployment
2025-11-26 23:37:50 +00:00

180 lines
5.3 KiB
Markdown

# Parking Manager
A manager-centric parking spot management application with fair assignment algorithm.
## Features
- **Manager-centric model**: Managers own parking spots, not offices
- **Fair assignment algorithm**: Users with lowest parking/presence ratio get priority
- **Presence tracking**: Calendar-based presence marking (present/remote/absent)
- **Closing days**: Support for specific dates and weekly recurring closures
- **Guarantees & exclusions**: Per-user parking rules
- **Authelia/LLDAP integration**: SSO authentication with group-based roles
## Architecture
```
├── app/
│ ├── routes/ # API endpoints
│ │ ├── auth.py # Authentication + holidays
│ │ ├── users.py # User management
│ │ ├── offices.py # Office CRUD
│ │ ├── managers.py # Manager rules (closing days, guarantees)
│ │ ├── presence.py # Presence marking
│ │ └── parking.py # Parking assignments
│ └── config.py # Application configuration
├── database/
│ ├── models.py # SQLAlchemy ORM models
│ └── connection.py # Database setup
├── services/
│ ├── auth.py # JWT + password handling
│ ├── parking.py # Fair assignment algorithm
│ ├── holidays.py # Public holiday calculation
│ └── notifications.py # Email notifications (TODO: scheduler)
├── frontend/
│ ├── pages/ # HTML pages
│ ├── js/ # JavaScript modules
│ └── css/ # Stylesheets
└── main.py # FastAPI application entry
```
## Quick Start (Development)
```bash
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Run development server
python main.py
```
Access at http://localhost:8000
## Docker Deployment
```bash
# Build image
docker build -t parking-manager .
# Run with environment variables
docker run -d \
-p 8000:8000 \
-v ./data:/app/data \
-e SECRET_KEY=your-secret-key \
-e AUTHELIA_ENABLED=true \
parking-manager
```
Or use Docker Compose:
```bash
docker compose up -d
```
## Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `SECRET_KEY` | JWT signing key | Random (dev only) |
| `HOST` | Bind address | `0.0.0.0` |
| `PORT` | Server port | `8000` |
| `DATABASE_URL` | SQLite path | `sqlite:///data/parking.db` |
| `AUTHELIA_ENABLED` | Enable Authelia SSO | `false` |
| `ALLOWED_ORIGINS` | CORS origins | `*` |
### SMTP (Notifications - Optional)
| Variable | Description |
|----------|-------------|
| `SMTP_HOST` | SMTP server hostname |
| `SMTP_PORT` | SMTP port (default: 587) |
| `SMTP_USER` | SMTP username |
| `SMTP_PASSWORD` | SMTP password |
| `SMTP_FROM` | From email address |
## Authentication
### Standalone Mode
Built-in JWT authentication with bcrypt password hashing. Users register/login via `/login` and `/register`.
### Authelia Mode
When `AUTHELIA_ENABLED=true`, the app trusts Authelia headers:
- `Remote-User`: User email/username
- `Remote-Name`: Display name
- `Remote-Groups`: Comma-separated group list
Group mapping:
- `parking-admins` → admin role
- `parking-managers` → manager role
- Others → employee role
## User Roles
| Role | Permissions |
|------|-------------|
| **admin** | Full access, manage users/offices |
| **manager** | Manage assigned offices, set rules |
| **employee** | Mark own presence, view calendar |
## API Endpoints
### Authentication
- `POST /api/auth/login` - Login
- `POST /api/auth/register` - Register (standalone mode)
- `POST /api/auth/logout` - Logout
- `GET /api/auth/me` - Current user info
- `GET /api/auth/holidays/{year}` - Public holidays
### Users
- `GET /api/users` - List users (admin)
- `POST /api/users` - Create user (admin)
- `PUT /api/users/{id}` - Update user (admin)
- `DELETE /api/users/{id}` - Delete user (admin)
- `GET /api/users/me/profile` - Own profile
- `PUT /api/users/me/settings` - Own settings
### Offices
- `GET /api/offices` - List offices
- `POST /api/offices` - Create office (admin)
- `PUT /api/offices/{id}` - Update office (admin)
- `DELETE /api/offices/{id}` - Delete office (admin)
### Managers
- `GET /api/managers` - List managers
- `GET /api/managers/{id}` - Manager details
- `PUT /api/managers/{id}/settings` - Update parking quota (admin)
- `GET/POST/DELETE /api/managers/{id}/closing-days` - Specific closures
- `GET/POST/DELETE /api/managers/{id}/weekly-closing-days` - Recurring closures
- `GET/POST/DELETE /api/managers/{id}/guarantees` - Parking guarantees
- `GET/POST/DELETE /api/managers/{id}/exclusions` - Parking exclusions
### Presence
- `POST /api/presence/mark` - Mark presence
- `POST /api/presence/mark-bulk` - Bulk mark
- `GET /api/presence/my-presences` - Own presences
- `GET /api/presence/team` - Team calendar (manager/admin)
### Parking
- `GET /api/parking/assignments/{date}` - Day's assignments
- `GET /api/parking/my-assignments` - Own assignments
- `POST /api/parking/manual-assign` - Manual assignment
- `POST /api/parking/reassign-spot` - Reassign spot
## Fairness Algorithm
Parking spots are assigned based on a fairness ratio:
```
ratio = parking_days / office_days
```
Users with the lowest ratio get priority. Guaranteed users are always assigned first.
## License
MIT