7.9 KiB
7.9 KiB
CLAUDE.md - Project Intelligence
Project Overview
Org-Parking is a manager-centric parking spot management system for organizations. It features fair parking assignment based on presence/parking ratio, supporting both standalone JWT authentication and Authelia/LLDAP SSO integration.
Technology Stack
- Backend: FastAPI + SQLAlchemy + SQLite
- Frontend: Vanilla JavaScript (no frameworks)
- Auth: JWT tokens + Authelia SSO support
- Containerization: Docker + Docker Compose
- Rate Limiting: slowapi
Architecture
app/
├── config.py → Configuration with logging and validation
└── routes/ → API endpoints (auth, users, managers, presence, parking)
services/ → Business logic (parking algorithm, auth, notifications)
database/ → SQLAlchemy models and connection
frontend/ → Static HTML pages + JS modules
utils/
├── auth_middleware.py → JWT/Authelia authentication
└── helpers.py → Shared utility functions
Build & Run Commands
# Development
SECRET_KEY=dev-secret-key python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
# Docker
docker compose up -d
# Dependencies
pip install -r requirements.txt
# Initialize test database
python create_test_db.py
Code Style & Conventions
Python
- FastAPI async patterns with
Depends()for dependency injection - Pydantic models for request/response validation
- SQLAlchemy ORM (no raw SQL)
- Use
generate_uuid()fromutils.helpersfor UUIDs - Use
config.loggerfor logging (not print statements) - Dates stored as TEXT in "YYYY-MM-DD" format
JavaScript
- ES6 modules with centralized API client (
/js/api.js) - Token stored in localStorage, auto-included in requests
- Utility functions in
/js/utils.js - Role-based navigation in
/js/nav.js
Authentication
- Dual mode: JWT tokens (standalone) or Authelia headers (SSO)
- LDAP users have
password_hash = None - Use helper:
is_ldap_user(user)fromutils.helpers
Utility Functions (utils/helpers.py)
from utils.helpers import (
generate_uuid, # Use instead of str(uuid.uuid4())
is_ldap_user, # Check if user is LDAP-managed
is_ldap_admin, # Check if user is LDAP admin
validate_password, # Returns list of validation errors
format_password_errors, # Format errors into user message
get_notification_default # Get setting value with default
)
Configuration (app/config.py)
Configuration is environment-based with required validation:
Required
SECRET_KEY- MUST be set (app exits if missing)
Security
RATE_LIMIT_REQUESTS- Requests per window (default: 5)RATE_LIMIT_WINDOW- Window in seconds (default: 60)
Email (org-stack pattern)
SMTP_ENABLED- Set totrueto enable SMTP sending- When disabled, emails are logged to
EMAIL_LOG_FILE - Follows org-stack pattern: direct send with file fallback
Logging
LOG_LEVEL- DEBUG, INFO, WARNING, ERROR (default: INFO)- Use
config.loggerfor all logging
Notifications (services/notifications.py)
Simplified notification service following org-stack pattern:
from services.notifications import (
send_email, # Direct send or file fallback
notify_parking_assigned, # When spot assigned
notify_parking_released, # When spot released
notify_parking_reassigned, # When spot reassigned
send_presence_reminder, # Weekly presence reminder
send_weekly_parking_summary, # Friday parking summary
send_daily_parking_reminder, # Daily parking reminder
run_scheduled_notifications # Called by cron/scheduler
)
Email Behavior
- If
SMTP_ENABLED=true: Send via SMTP - If SMTP fails or disabled: Log to
EMAIL_LOG_FILE - Never throws - always returns success/failure
Recent Improvements
Security Enhancements
- Required SECRET_KEY: App exits if not set
- Rate limiting: Login/register endpoints limited to 5 req/min
- Password validation: Requires uppercase, lowercase, number, 8+ chars
- Proper logging: All security events logged
Performance Optimizations
- Fixed N+1 queries in:
list_users()- Batch query for manager names and countslist_managers()- Batch query for managed user countsget_manager_guarantees()- Batch query for user namesget_manager_exclusions()- Batch query for user names
Code Consolidation
- Utility functions (
utils/helpers.py):generate_uuid()- Replaces 50+str(uuid.uuid4())callsis_ldap_user()- Replaces 4+ duplicated checksvalidate_password()- Consistent password validation
- Simplified notifications - Removed queue system, direct send
Logging Improvements
- Centralized logging via
config.logger - Replaced
print()with proper logging - Security events logged (login, password change, etc.)
API Quick Reference
Authentication
POST /api/auth/register- Create user (rate limited)POST /api/auth/login- Get JWT token (rate limited)GET /api/auth/me- Current user (JWT or Authelia)
Presence
POST /api/presence/mark- Mark single dayPOST /api/presence/mark-bulk- Mark multiple daysGET /api/presence/team- Team calendar with parking
Parking
POST /api/parking/manual-assign- Manager assigns spotPOST /api/parking/reassign-spot- Reassign existing spotGET /api/parking/eligible-users/{id}- Users for reassignment
Manager Settings
GET/POST/DELETE /api/managers/closing-daysGET/POST/DELETE /api/managers/weekly-closing-daysGET/POST/DELETE /api/managers/guaranteesGET/POST/DELETE /api/managers/exclusions
Development Notes
Adding a New Route
- Create file in
app/routes/ - Use
APIRouter(prefix="/api/...", tags=["..."]) - Register in
main.py:app.include_router(...) - Add auth dependency:
current_user: User = Depends(get_current_user) - Use
config.loggerfor logging - Use
generate_uuid()for new records
Database Changes
No migration system (Alembic) configured. Schema changes require:
- Update database/models.py
- Delete SQLite file or write manual migration
- Run
create_test_db.pyfor fresh database
Email Testing
With SMTP_ENABLED=false, check email log:
tail -f /tmp/parking-emails.log
Running Scheduled Notifications
Add to cron or systemd timer:
# Every 5 minutes
*/5 * * * * cd /path/to/org-parking && python -c "
from database.connection import get_db
from services.notifications import run_scheduled_notifications
db = next(get_db())
run_scheduled_notifications(db)
"
File Quick Links
| Purpose | File |
|---|---|
| Main entry | main.py |
| Configuration | app/config.py |
| Database models | database/models.py |
| Parking algorithm | services/parking.py |
| Notifications | services/notifications.py |
| Auth middleware | utils/auth_middleware.py |
| Utility helpers | utils/helpers.py |
| Frontend API client | frontend/js/api.js |
| CSS styles | frontend/css/styles.css |
| Docker config | compose.yml |
| Environment template | .env.example |
Deployment Notes
Remote Server
- Host:
rocketscale.it - User:
rocky - SSH:
ssh rocky@rocketscale.it - Project path:
/home/rocky/org-parking - Related project:
/home/rocky/org-stack(LLDAP, Authelia, etc.)
Environment Variables
Copy .env.example to .env and configure:
# Generate secure key
openssl rand -hex 32
Production Checklist
- Set strong
SECRET_KEY - Configure
ALLOWED_ORIGINS(not*) - Set
AUTHELIA_ENABLED=trueif using SSO - Configure SMTP or check email log file
- Set up notification scheduler (cron/systemd)