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
This commit is contained in:
179
README.md
Normal file
179
README.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user