from typing import List from fastapi import APIRouter, Depends, HTTPException, status, Request from sqlalchemy.orm import Session from app.api.deps import get_db from app.core.config import settings from app.schemas.public_book import ( PublicLocalFlightCreate, PublicCircuitCreate, PublicDepartureCreate, PublicArrivalCreate, ) from app.schemas.local_flight import LocalFlight as LocalFlightSchema from app.schemas.circuit import Circuit as CircuitSchema from app.schemas.departure import Departure as DepartureSchema from app.schemas.arrival import Arrival as ArrivalSchema from app.crud.crud_local_flight import local_flight as crud_local_flight from app.crud.crud_circuit import crud_circuit from app.crud.crud_departure import departure as crud_departure from app.crud.crud_arrival import arrival as crud_arrival from app.models.local_flight import SubmissionSource from app.models.departure import SubmissionSource as DepartureSubmissionSource from app.models.arrival import SubmissionSource as ArrivalSubmissionSource router = APIRouter() def check_public_booking_enabled(): """Check if public booking is enabled""" if not settings.allow_public_booking: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Public booking is currently disabled" ) @router.post("/local-flights", response_model=LocalFlightSchema) async def public_book_local_flight( request: Request, flight_in: PublicLocalFlightCreate, db: Session = Depends(get_db), ): """Book a local flight via public portal""" check_public_booking_enabled() # Create the flight with public submission source from app.schemas.local_flight import LocalFlightCreate flight_create = LocalFlightCreate( registration=flight_in.registration, type=flight_in.type, callsign=flight_in.callsign, pob=flight_in.pob, flight_type=flight_in.flight_type, duration=flight_in.duration, etd=flight_in.etd, notes=flight_in.notes, ) flight = crud_local_flight.create(db, obj_in=flight_create, created_by="PUBLIC_PILOT") # Update with submission source and pilot email db.query(type(flight)).filter(type(flight).id == flight.id).update({ type(flight).submitted_via: SubmissionSource.PUBLIC, type(flight).pilot_email: flight_in.pilot_email, }) db.commit() db.refresh(flight) # Send real-time update via WebSocket if available if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "local_flight_booked_out", "data": { "id": flight.id, "registration": flight.registration, "flight_type": flight.flight_type.value, "status": flight.status.value, "submitted_via": "PUBLIC" } }) return flight @router.post("/circuits", response_model=CircuitSchema) async def public_record_circuit( request: Request, circuit_in: PublicCircuitCreate, db: Session = Depends(get_db), ): """Record a circuit (touch and go) via public portal""" check_public_booking_enabled() from app.schemas.circuit import CircuitCreate circuit_create = CircuitCreate( local_flight_id=circuit_in.local_flight_id, circuit_timestamp=circuit_in.circuit_timestamp, ) circuit = crud_circuit.create(db, obj_in=circuit_create) # Send real-time update via WebSocket if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "circuit_recorded", "data": { "id": circuit.id, "local_flight_id": circuit.local_flight_id, "circuit_timestamp": circuit.circuit_timestamp.isoformat(), "submitted_via": "PUBLIC" } }) return circuit @router.post("/departures", response_model=DepartureSchema) async def public_book_departure( request: Request, departure_in: PublicDepartureCreate, db: Session = Depends(get_db), ): """Book a departure via public portal""" check_public_booking_enabled() from app.schemas.departure import DepartureCreate departure_create = DepartureCreate( registration=departure_in.registration, type=departure_in.type, callsign=departure_in.callsign, pob=departure_in.pob, out_to=departure_in.out_to, etd=departure_in.etd, notes=departure_in.notes, ) departure = crud_departure.create(db, obj_in=departure_create, created_by="PUBLIC_PILOT") # Update with submission source and pilot email db.query(type(departure)).filter(type(departure).id == departure.id).update({ type(departure).submitted_via: DepartureSubmissionSource.PUBLIC, type(departure).pilot_email: departure_in.pilot_email, }) db.commit() db.refresh(departure) # Send real-time update via WebSocket if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "departure_booked_out", "data": { "id": departure.id, "registration": departure.registration, "status": departure.status.value, "submitted_via": "PUBLIC" } }) return departure @router.post("/arrivals", response_model=ArrivalSchema) async def public_book_arrival( request: Request, arrival_in: PublicArrivalCreate, db: Session = Depends(get_db), ): """Book an arrival via public portal""" check_public_booking_enabled() from app.schemas.arrival import ArrivalCreate arrival_create = ArrivalCreate( registration=arrival_in.registration, type=arrival_in.type, callsign=arrival_in.callsign, pob=arrival_in.pob, in_from=arrival_in.in_from, eta=arrival_in.eta, notes=arrival_in.notes, ) arrival = crud_arrival.create(db, obj_in=arrival_create, created_by="PUBLIC_PILOT") # Update with submission source and pilot email db.query(type(arrival)).filter(type(arrival).id == arrival.id).update({ type(arrival).submitted_via: ArrivalSubmissionSource.PUBLIC, type(arrival).pilot_email: arrival_in.pilot_email, }) db.commit() db.refresh(arrival) # Send real-time update via WebSocket if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "arrival_booked_in", "data": { "id": arrival.id, "registration": arrival.registration, "status": arrival.status.value, "submitted_via": "PUBLIC" } }) return arrival