Improve the frontend 5
This commit is contained in:
377
services/external/app/registry/calendar_registry.py
vendored
Normal file
377
services/external/app/registry/calendar_registry.py
vendored
Normal file
@@ -0,0 +1,377 @@
|
||||
# services/external/app/registry/calendar_registry.py
|
||||
"""
|
||||
Calendar Registry - Pre-configured school calendars and local events
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Dict, Any
|
||||
from datetime import date
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class SchoolType(str, Enum):
|
||||
PRIMARY = "primary"
|
||||
SECONDARY = "secondary"
|
||||
UNIVERSITY = "university"
|
||||
|
||||
|
||||
@dataclass
|
||||
class HolidayPeriod:
|
||||
"""School holiday period definition"""
|
||||
name: str
|
||||
start_date: str # ISO format: "2024-12-20"
|
||||
end_date: str # ISO format: "2025-01-08"
|
||||
description: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SchoolHours:
|
||||
"""School operating hours configuration"""
|
||||
morning_start: str # "09:00"
|
||||
morning_end: str # "14:00"
|
||||
has_afternoon_session: bool # True/False
|
||||
afternoon_start: Optional[str] = None # "15:00" if has_afternoon_session
|
||||
afternoon_end: Optional[str] = None # "17:00" if has_afternoon_session
|
||||
|
||||
|
||||
@dataclass
|
||||
class CalendarDefinition:
|
||||
"""School calendar configuration for a specific city and school type"""
|
||||
calendar_id: str
|
||||
calendar_name: str
|
||||
city_id: str
|
||||
school_type: SchoolType
|
||||
academic_year: str # "2024-2025"
|
||||
holiday_periods: List[HolidayPeriod]
|
||||
school_hours: SchoolHours
|
||||
source: str
|
||||
enabled: bool = True
|
||||
|
||||
|
||||
class CalendarRegistry:
|
||||
"""Central registry of school calendars for forecasting"""
|
||||
|
||||
# Madrid Primary School Calendar 2024-2025 (Official Comunidad de Madrid - ORDEN 1177/2024)
|
||||
MADRID_PRIMARY_2024_2025 = CalendarDefinition(
|
||||
calendar_id="madrid_primary_2024_2025",
|
||||
calendar_name="Madrid Primary School Calendar 2024-2025",
|
||||
city_id="madrid",
|
||||
school_type=SchoolType.PRIMARY,
|
||||
academic_year="2024-2025",
|
||||
holiday_periods=[
|
||||
HolidayPeriod(
|
||||
name="Christmas Holiday",
|
||||
start_date="2024-12-21",
|
||||
end_date="2025-01-07",
|
||||
description="Official Christmas break - Comunidad de Madrid (Dec 21 - Jan 7)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="Easter Holiday (Semana Santa)",
|
||||
start_date="2025-04-11",
|
||||
end_date="2025-04-21",
|
||||
description="Official Easter break - Comunidad de Madrid (Apr 11-21)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="Summer Holiday",
|
||||
start_date="2025-06-21",
|
||||
end_date="2025-09-08",
|
||||
description="Summer vacation (Last day Jun 20, classes resume Sep 9)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="All Saints Long Weekend",
|
||||
start_date="2024-10-31",
|
||||
end_date="2024-11-03",
|
||||
description="October 31 - November 3 non-working days"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="February Long Weekend",
|
||||
start_date="2025-02-28",
|
||||
end_date="2025-03-03",
|
||||
description="February 28 - March 3 non-working days"
|
||||
),
|
||||
],
|
||||
school_hours=SchoolHours(
|
||||
morning_start="09:00",
|
||||
morning_end="14:00",
|
||||
has_afternoon_session=False
|
||||
),
|
||||
source="comunidad_madrid_orden_1177_2024",
|
||||
enabled=True
|
||||
)
|
||||
|
||||
# Madrid Secondary School Calendar 2024-2025 (Official Comunidad de Madrid - ORDEN 1177/2024)
|
||||
MADRID_SECONDARY_2024_2025 = CalendarDefinition(
|
||||
calendar_id="madrid_secondary_2024_2025",
|
||||
calendar_name="Madrid Secondary School Calendar 2024-2025",
|
||||
city_id="madrid",
|
||||
school_type=SchoolType.SECONDARY,
|
||||
academic_year="2024-2025",
|
||||
holiday_periods=[
|
||||
HolidayPeriod(
|
||||
name="Christmas Holiday",
|
||||
start_date="2024-12-21",
|
||||
end_date="2025-01-07",
|
||||
description="Official Christmas break - Comunidad de Madrid (Dec 21 - Jan 7)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="Easter Holiday (Semana Santa)",
|
||||
start_date="2025-04-11",
|
||||
end_date="2025-04-21",
|
||||
description="Official Easter break - Comunidad de Madrid (Apr 11-21)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="Summer Holiday",
|
||||
start_date="2025-06-21",
|
||||
end_date="2025-09-09",
|
||||
description="Summer vacation (Last day Jun 20, classes resume Sep 10)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="All Saints Long Weekend",
|
||||
start_date="2024-10-31",
|
||||
end_date="2024-11-03",
|
||||
description="October 31 - November 3 non-working days"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="February Long Weekend",
|
||||
start_date="2025-02-28",
|
||||
end_date="2025-03-03",
|
||||
description="February 28 - March 3 non-working days"
|
||||
),
|
||||
],
|
||||
school_hours=SchoolHours(
|
||||
morning_start="09:00",
|
||||
morning_end="14:00",
|
||||
has_afternoon_session=False
|
||||
),
|
||||
source="comunidad_madrid_orden_1177_2024",
|
||||
enabled=True
|
||||
)
|
||||
|
||||
# Madrid Primary School Calendar 2025-2026 (Official Comunidad de Madrid - ORDEN 1476/2025)
|
||||
MADRID_PRIMARY_2025_2026 = CalendarDefinition(
|
||||
calendar_id="madrid_primary_2025_2026",
|
||||
calendar_name="Madrid Primary School Calendar 2025-2026",
|
||||
city_id="madrid",
|
||||
school_type=SchoolType.PRIMARY,
|
||||
academic_year="2025-2026",
|
||||
holiday_periods=[
|
||||
HolidayPeriod(
|
||||
name="Christmas Holiday",
|
||||
start_date="2025-12-20",
|
||||
end_date="2026-01-07",
|
||||
description="Official Christmas break - Comunidad de Madrid (Dec 20 - Jan 7)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="Easter Holiday (Semana Santa)",
|
||||
start_date="2026-03-27",
|
||||
end_date="2026-04-06",
|
||||
description="Official Easter break - Comunidad de Madrid (Mar 27 - Apr 6)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="Summer Holiday",
|
||||
start_date="2026-06-21",
|
||||
end_date="2026-09-08",
|
||||
description="Summer vacation (classes resume Sep 9)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="October Long Weekend",
|
||||
start_date="2025-10-13",
|
||||
end_date="2025-10-13",
|
||||
description="October 13 non-working day (after Día de la Hispanidad)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="All Saints Long Weekend",
|
||||
start_date="2025-11-03",
|
||||
end_date="2025-11-03",
|
||||
description="November 3 non-working day (after All Saints)"
|
||||
),
|
||||
],
|
||||
school_hours=SchoolHours(
|
||||
morning_start="09:00",
|
||||
morning_end="14:00",
|
||||
has_afternoon_session=False
|
||||
),
|
||||
source="comunidad_madrid_orden_1476_2025",
|
||||
enabled=True
|
||||
)
|
||||
|
||||
# Madrid Secondary School Calendar 2025-2026 (Official Comunidad de Madrid - ORDEN 1476/2025)
|
||||
MADRID_SECONDARY_2025_2026 = CalendarDefinition(
|
||||
calendar_id="madrid_secondary_2025_2026",
|
||||
calendar_name="Madrid Secondary School Calendar 2025-2026",
|
||||
city_id="madrid",
|
||||
school_type=SchoolType.SECONDARY,
|
||||
academic_year="2025-2026",
|
||||
holiday_periods=[
|
||||
HolidayPeriod(
|
||||
name="Christmas Holiday",
|
||||
start_date="2025-12-20",
|
||||
end_date="2026-01-07",
|
||||
description="Official Christmas break - Comunidad de Madrid (Dec 20 - Jan 7)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="Easter Holiday (Semana Santa)",
|
||||
start_date="2026-03-27",
|
||||
end_date="2026-04-06",
|
||||
description="Official Easter break - Comunidad de Madrid (Mar 27 - Apr 6)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="Summer Holiday",
|
||||
start_date="2026-06-21",
|
||||
end_date="2026-09-09",
|
||||
description="Summer vacation (classes resume Sep 10)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="October Long Weekend",
|
||||
start_date="2025-10-13",
|
||||
end_date="2025-10-13",
|
||||
description="October 13 non-working day (after Día de la Hispanidad)"
|
||||
),
|
||||
HolidayPeriod(
|
||||
name="All Saints Long Weekend",
|
||||
start_date="2025-11-03",
|
||||
end_date="2025-11-03",
|
||||
description="November 3 non-working day (after All Saints)"
|
||||
),
|
||||
],
|
||||
school_hours=SchoolHours(
|
||||
morning_start="09:00",
|
||||
morning_end="14:00",
|
||||
has_afternoon_session=False
|
||||
),
|
||||
source="comunidad_madrid_orden_1476_2025",
|
||||
enabled=True
|
||||
)
|
||||
|
||||
# Registry of all calendars
|
||||
CALENDARS: List[CalendarDefinition] = [
|
||||
MADRID_PRIMARY_2024_2025,
|
||||
MADRID_SECONDARY_2024_2025,
|
||||
MADRID_PRIMARY_2025_2026,
|
||||
MADRID_SECONDARY_2025_2026,
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_all_calendars(cls) -> List[CalendarDefinition]:
|
||||
"""Get all calendars"""
|
||||
return cls.CALENDARS
|
||||
|
||||
@classmethod
|
||||
def get_enabled_calendars(cls) -> List[CalendarDefinition]:
|
||||
"""Get all enabled calendars"""
|
||||
return [cal for cal in cls.CALENDARS if cal.enabled]
|
||||
|
||||
@classmethod
|
||||
def get_calendar(cls, calendar_id: str) -> Optional[CalendarDefinition]:
|
||||
"""Get calendar by ID"""
|
||||
for cal in cls.CALENDARS:
|
||||
if cal.calendar_id == calendar_id:
|
||||
return cal
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_calendars_for_city(cls, city_id: str) -> List[CalendarDefinition]:
|
||||
"""Get all enabled calendars for a specific city"""
|
||||
return [
|
||||
cal for cal in cls.CALENDARS
|
||||
if cal.city_id == city_id and cal.enabled
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_calendar_for_city_and_type(
|
||||
cls,
|
||||
city_id: str,
|
||||
school_type: SchoolType,
|
||||
academic_year: Optional[str] = None
|
||||
) -> Optional[CalendarDefinition]:
|
||||
"""Get specific calendar for city, type, and optionally year"""
|
||||
for cal in cls.CALENDARS:
|
||||
if (cal.city_id == city_id and
|
||||
cal.school_type == school_type and
|
||||
cal.enabled and
|
||||
(academic_year is None or cal.academic_year == academic_year)):
|
||||
return cal
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def to_dict(cls, calendar: CalendarDefinition) -> Dict[str, Any]:
|
||||
"""Convert calendar definition to dictionary for JSON serialization"""
|
||||
return {
|
||||
"calendar_id": calendar.calendar_id,
|
||||
"calendar_name": calendar.calendar_name,
|
||||
"city_id": calendar.city_id,
|
||||
"school_type": calendar.school_type.value,
|
||||
"academic_year": calendar.academic_year,
|
||||
"holiday_periods": [
|
||||
{
|
||||
"name": hp.name,
|
||||
"start_date": hp.start_date,
|
||||
"end_date": hp.end_date,
|
||||
"description": hp.description
|
||||
}
|
||||
for hp in calendar.holiday_periods
|
||||
],
|
||||
"school_hours": {
|
||||
"morning_start": calendar.school_hours.morning_start,
|
||||
"morning_end": calendar.school_hours.morning_end,
|
||||
"has_afternoon_session": calendar.school_hours.has_afternoon_session,
|
||||
"afternoon_start": calendar.school_hours.afternoon_start,
|
||||
"afternoon_end": calendar.school_hours.afternoon_end,
|
||||
},
|
||||
"source": calendar.source,
|
||||
"enabled": calendar.enabled
|
||||
}
|
||||
|
||||
|
||||
# Local Events Registry for Madrid
|
||||
@dataclass
|
||||
class LocalEventDefinition:
|
||||
"""Local event that impacts demand"""
|
||||
event_id: str
|
||||
name: str
|
||||
city_id: str
|
||||
date: str # ISO format or "annual-MM-DD" for recurring
|
||||
impact_level: str # "low", "medium", "high"
|
||||
description: Optional[str] = None
|
||||
recurring: bool = False # True for annual events
|
||||
|
||||
|
||||
class LocalEventsRegistry:
|
||||
"""Registry of local events and festivals"""
|
||||
|
||||
MADRID_EVENTS = [
|
||||
LocalEventDefinition(
|
||||
event_id="madrid_san_isidro",
|
||||
name="San Isidro Festival",
|
||||
city_id="madrid",
|
||||
date="annual-05-15",
|
||||
impact_level="high",
|
||||
description="Madrid's patron saint festival - major citywide celebration",
|
||||
recurring=True
|
||||
),
|
||||
LocalEventDefinition(
|
||||
event_id="madrid_dos_de_mayo",
|
||||
name="Dos de Mayo",
|
||||
city_id="madrid",
|
||||
date="annual-05-02",
|
||||
impact_level="medium",
|
||||
description="Madrid regional holiday",
|
||||
recurring=True
|
||||
),
|
||||
LocalEventDefinition(
|
||||
event_id="madrid_almudena",
|
||||
name="Virgen de la Almudena",
|
||||
city_id="madrid",
|
||||
date="annual-11-09",
|
||||
impact_level="medium",
|
||||
description="Madrid patron saint day",
|
||||
recurring=True
|
||||
),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_events_for_city(cls, city_id: str) -> List[LocalEventDefinition]:
|
||||
"""Get all local events for a city"""
|
||||
if city_id == "madrid":
|
||||
return cls.MADRID_EVENTS
|
||||
return []
|
||||
Reference in New Issue
Block a user