feat: Space Booking System - MVP complet

Sistem web pentru rezervarea de birouri și săli de ședință
cu flux de aprobare administrativă.

Stack: FastAPI + Vue.js 3 + SQLite + TypeScript

Features implementate:
- Autentificare JWT + Self-registration cu email verification
- CRUD Spații, Utilizatori, Settings (Admin)
- Calendar interactiv (FullCalendar) cu drag-and-drop
- Creare rezervări cu validare (durată, program, overlap, max/zi)
- Rezervări recurente (săptămânal)
- Admin: aprobare/respingere/anulare cereri
- Admin: creare directă rezervări (bypass approval)
- Admin: editare orice rezervare
- User: editare/anulare rezervări proprii
- Notificări in-app (bell icon + dropdown)
- Notificări email (async SMTP cu BackgroundTasks)
- Jurnal acțiuni administrative (audit log)
- Rapoarte avansate (utilizare, top users, approval rate)
- Șabloane rezervări (booking templates)
- Atașamente fișiere (upload/download)
- Conflict warnings (verificare disponibilitate real-time)
- Integrare Google Calendar (OAuth2)
- Suport timezone (UTC storage + user preference)
- 225+ teste backend

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-02-09 17:51:29 +00:00
commit df4031d99c
113 changed files with 24491 additions and 0 deletions

View File

@@ -0,0 +1 @@
"""Utilities module."""

View File

@@ -0,0 +1,79 @@
"""Timezone utilities for converting between UTC and user timezones."""
from datetime import datetime
from typing import Optional
import pytz
from dateutil import parser
def convert_to_utc(dt: datetime, from_timezone: str = "UTC") -> datetime:
"""Convert datetime from user timezone to UTC.
Args:
dt: Datetime to convert (naive or aware)
from_timezone: IANA timezone name (e.g., "Europe/Bucharest")
Returns:
Naive datetime in UTC
"""
if dt.tzinfo is None:
# Naive datetime, assume it's in user timezone
tz = pytz.timezone(from_timezone)
dt = tz.localize(dt)
# Convert to UTC
return dt.astimezone(pytz.UTC).replace(tzinfo=None)
def convert_from_utc(dt: datetime, to_timezone: str = "UTC") -> datetime:
"""Convert datetime from UTC to user timezone.
Args:
dt: Datetime in UTC (naive or aware)
to_timezone: IANA timezone name (e.g., "Europe/Bucharest")
Returns:
Timezone-aware datetime in target timezone
"""
if dt.tzinfo is None:
# Add UTC timezone if naive
dt = pytz.UTC.localize(dt)
# Convert to target timezone
tz = pytz.timezone(to_timezone)
return dt.astimezone(tz)
def format_datetime_tz(dt: datetime, timezone: str = "UTC", format_str: str = "%Y-%m-%d %H:%M %Z") -> str:
"""Format datetime with timezone abbreviation.
Args:
dt: Datetime in UTC (naive or aware)
timezone: IANA timezone name for display
format_str: Format string (default includes timezone abbreviation)
Returns:
Formatted datetime string with timezone
"""
dt_tz = convert_from_utc(dt, timezone)
return dt_tz.strftime(format_str)
def get_available_timezones():
"""Get list of common timezones for user selection."""
common_timezones = [
"UTC",
"Europe/Bucharest",
"Europe/London",
"Europe/Paris",
"Europe/Berlin",
"Europe/Amsterdam",
"America/New_York",
"America/Los_Angeles",
"America/Chicago",
"America/Denver",
"Asia/Tokyo",
"Asia/Shanghai",
"Asia/Dubai",
"Australia/Sydney",
]
return common_timezones