Many more states WIP

This commit is contained in:
2026-03-25 13:16:36 -04:00
parent eb2321ef40
commit 9867156334
14 changed files with 351 additions and 128 deletions
@@ -18,20 +18,20 @@ depends_on = None
def upgrade() -> None:
# Add GROUND and LOCAL to local_flights status enum
op.execute("ALTER TABLE local_flights MODIFY COLUMN status ENUM('BOOKED_OUT','GROUND','DEPARTED','LOCAL','CIRCUIT','LANDED','CANCELLED')")
op.execute("ALTER TABLE local_flights MODIFY COLUMN status ENUM('BOOKED_OUT','GROUND','DEPARTED','LOCAL','CIRCUIT','CIRCUIT_DOWNWIND','CIRCUIT_BASE','CIRCUIT_FINAL','LANDED','CANCELLED')")
# Add timestamp columns to local_flights
op.add_column('local_flights', sa.Column('contact_dt', sa.DateTime(), nullable=True))
op.add_column('local_flights', sa.Column('takeoff_dt', sa.DateTime(), nullable=True))
# Add GROUND and ARRIVED to arrivals status enum
op.execute("ALTER TABLE arrivals MODIFY COLUMN status ENUM('BOOKED_IN','LANDED','GROUND','LOCAL','CIRCUIT','ARRIVED','CANCELLED')")
op.execute("ALTER TABLE arrivals MODIFY COLUMN status ENUM('BOOKED_IN','INBOUND','LANDED','GROUND','LOCAL','CIRCUIT','CIRCUIT_DOWNWIND','CIRCUIT_BASE','CIRCUIT_FINAL','ARRIVED','CANCELLED')")
# Add timestamp column to arrivals
op.add_column('arrivals', sa.Column('arrived_dt', sa.DateTime(), nullable=True))
# Add GROUND and LOCAL to departures status enum
op.execute("ALTER TABLE departures MODIFY COLUMN status ENUM('BOOKED_OUT','GROUND','DEPARTED','LOCAL','CANCELLED')")
op.execute("ALTER TABLE departures MODIFY COLUMN status ENUM('BOOKED_OUT','GROUND','DEPARTED','LOCAL','CIRCUIT','CIRCUIT_DOWNWIND','CIRCUIT_BASE','CIRCUIT_FINAL','LANDED','CANCELLED')")
# Add timestamp columns to departures
op.add_column('departures', sa.Column('contact_dt', sa.DateTime(), nullable=True))
+2 -2
View File
@@ -38,12 +38,12 @@ async def create_arrival(
current_user: User = Depends(get_current_operator_user)
):
"""Create a new arrival record"""
arrival = crud_arrival.create(db, obj_in=arrival_in, created_by=current_user.username)
arrival = crud_arrival.create(db, obj_in=arrival_in, created_by=current_user.username, submitted_via=arrival_in.submitted_via)
# Send real-time update via WebSocket
if hasattr(request.app.state, 'connection_manager'):
await request.app.state.connection_manager.broadcast({
"type": "arrival_booked_in",
"type": "arrival_inbound",
"data": {
"id": arrival.id,
"registration": arrival.registration,
+1 -1
View File
@@ -39,7 +39,7 @@ async def create_local_flight(
current_user: User = Depends(get_current_operator_user)
):
"""Create a new local flight record (book out)"""
flight = crud_local_flight.create(db, obj_in=flight_in, created_by=current_user.username)
flight = crud_local_flight.create(db, obj_in=flight_in, created_by=current_user.username, submitted_via="ADMIN")
# Send real-time update via WebSocket
if hasattr(request.app.state, 'connection_manager'):
+4 -4
View File
@@ -97,11 +97,11 @@ async def get_public_arrivals(db: Session = Depends(get_db)):
# Add booked-in arrivals
booked_in_arrivals = crud_arrival.get_multi(db, limit=1000)
for arrival in booked_in_arrivals:
# Only include BOOKED_IN and LANDED arrivals
if arrival.status not in (ArrivalStatus.BOOKED_IN, ArrivalStatus.LANDED):
# Only include BOOKED_IN, INBOUND and LANDED arrivals
if arrival.status not in (ArrivalStatus.BOOKED_IN, ArrivalStatus.INBOUND, ArrivalStatus.LANDED):
continue
# For BOOKED_IN, only include those created today
if arrival.status == ArrivalStatus.BOOKED_IN:
# For BOOKED_IN and INBOUND, only include those created today
if arrival.status in (ArrivalStatus.BOOKED_IN, ArrivalStatus.INBOUND):
if not (today_start <= arrival.created_dt < today_end):
continue
# For LANDED, only include those landed today
+3 -4
View File
@@ -56,7 +56,7 @@ async def public_book_local_flight(
notes=flight_in.notes,
)
flight = crud_local_flight.create(db, obj_in=flight_create, created_by="PUBLIC_PILOT")
flight = crud_local_flight.create(db, obj_in=flight_create, created_by="PUBLIC_PILOT", submitted_via="PUBLIC")
# Update with submission source and pilot email
db.query(type(flight)).filter(type(flight).id == flight.id).update({
@@ -181,11 +181,10 @@ async def public_book_arrival(
notes=arrival_in.notes,
)
arrival = crud_arrival.create(db, obj_in=arrival_create, created_by="PUBLIC_PILOT")
arrival = crud_arrival.create(db, obj_in=arrival_create, created_by="PUBLIC_PILOT", submitted_via="PUBLIC")
# Update with submission source and pilot email
# Update with 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()
+25 -5
View File
@@ -24,7 +24,17 @@ class CRUDArrival:
query = db.query(Arrival)
if status:
query = query.filter(Arrival.status == status)
if status == ArrivalStatus.CIRCUIT:
# Special case: when requesting CIRCUIT status, return all circuit-related statuses
circuit_statuses = [
ArrivalStatus.CIRCUIT,
ArrivalStatus.CIRCUIT_DOWNWIND,
ArrivalStatus.CIRCUIT_BASE,
ArrivalStatus.CIRCUIT_FINAL
]
query = query.filter(Arrival.status.in_(circuit_statuses))
else:
query = query.filter(Arrival.status == status)
if date_from:
query = query.filter(func.date(Arrival.created_dt) >= date_from)
@@ -35,23 +45,33 @@ class CRUDArrival:
return query.order_by(desc(Arrival.created_dt)).offset(skip).limit(limit).all()
def get_arrivals_today(self, db: Session) -> List[Arrival]:
"""Get today's arrivals (booked in or landed)"""
"""Get today's arrivals (booked in, inbound or landed)"""
today = date.today()
return db.query(Arrival).filter(
and_(
func.date(Arrival.created_dt) == today,
or_(
Arrival.status == ArrivalStatus.BOOKED_IN,
Arrival.status == ArrivalStatus.INBOUND,
Arrival.status == ArrivalStatus.LANDED
)
)
).order_by(Arrival.created_dt).all()
def create(self, db: Session, obj_in: ArrivalCreate, created_by: str) -> Arrival:
def create(self, db: Session, obj_in: ArrivalCreate, created_by: str, submitted_via: str = "ADMIN") -> Arrival:
from app.models.arrival import SubmissionSource
# Set initial status based on submission source
initial_status = ArrivalStatus.BOOKED_IN
if submitted_via == SubmissionSource.ADMIN:
initial_status = ArrivalStatus.INBOUND
db_obj = Arrival(
**obj_in.dict(),
**obj_in.dict(exclude={'submitted_via'}),
created_by=created_by,
status=ArrivalStatus.BOOKED_IN
status=initial_status,
submitted_via=submitted_via
)
db.add(db_obj)
db.commit()
+22 -3
View File
@@ -26,7 +26,17 @@ class CRUDLocalFlight:
query = db.query(LocalFlight)
if status:
query = query.filter(LocalFlight.status == status)
if status == LocalFlightStatus.CIRCUIT:
# Special case: when requesting CIRCUIT status, return all circuit-related statuses
circuit_statuses = [
LocalFlightStatus.CIRCUIT,
LocalFlightStatus.CIRCUIT_DOWNWIND,
LocalFlightStatus.CIRCUIT_BASE,
LocalFlightStatus.CIRCUIT_FINAL
]
query = query.filter(LocalFlight.status.in_(circuit_statuses))
else:
query = query.filter(LocalFlight.status == status)
if flight_type:
query = query.filter(LocalFlight.flight_type == flight_type)
@@ -74,11 +84,20 @@ class CRUDLocalFlight:
)
).order_by(LocalFlight.created_dt).all()
def create(self, db: Session, obj_in: LocalFlightCreate, created_by: str) -> LocalFlight:
def create(self, db: Session, obj_in: LocalFlightCreate, created_by: str, submitted_via: str = "ADMIN") -> LocalFlight:
from app.models.local_flight import SubmissionSource
# Set initial status based on submission source
initial_status = LocalFlightStatus.BOOKED_OUT
if submitted_via == SubmissionSource.ADMIN:
initial_status = LocalFlightStatus.GROUND
db_obj = LocalFlight(
**obj_in.dict(),
created_by=created_by,
status=LocalFlightStatus.BOOKED_OUT
status=initial_status,
submitted_via=submitted_via
)
db.add(db_obj)
db.commit()
+5 -1
View File
@@ -11,10 +11,14 @@ class SubmissionSource(str, Enum):
class ArrivalStatus(str, Enum):
BOOKED_IN = "BOOKED_IN"
INBOUND = "INBOUND"
LANDED = "LANDED"
GROUND = "GROUND"
LOCAL = "LOCAL"
CIRCUIT = "CIRCUIT"
CIRCUIT_DOWNWIND = "CIRCUIT_DOWNWIND"
CIRCUIT_BASE = "CIRCUIT_BASE"
CIRCUIT_FINAL = "CIRCUIT_FINAL"
ARRIVED = "ARRIVED"
CANCELLED = "CANCELLED"
@@ -28,7 +32,7 @@ class Arrival(Base):
callsign = Column(String(16), nullable=True)
pob = Column(Integer, nullable=False)
in_from = Column(String(4), nullable=False, index=True)
status = Column(SQLEnum(ArrivalStatus), default=ArrivalStatus.BOOKED_IN, nullable=False, index=True)
status = Column(SQLEnum(ArrivalStatus), default=ArrivalStatus.INBOUND, nullable=False, index=True)
notes = Column(Text, nullable=True)
created_dt = Column(DateTime, server_default=func.now(), nullable=False, index=True)
eta = Column(DateTime, nullable=True, index=True)
+3
View File
@@ -21,6 +21,9 @@ class LocalFlightStatus(str, Enum):
DEPARTED = "DEPARTED"
LOCAL = "LOCAL"
CIRCUIT = "CIRCUIT"
CIRCUIT_DOWNWIND = "CIRCUIT_DOWNWIND"
CIRCUIT_BASE = "CIRCUIT_BASE"
CIRCUIT_FINAL = "CIRCUIT_FINAL"
LANDED = "LANDED"
CANCELLED = "CANCELLED"
+5
View File
@@ -6,10 +6,14 @@ from enum import Enum
class ArrivalStatus(str, Enum):
BOOKED_IN = "BOOKED_IN"
INBOUND = "INBOUND"
LANDED = "LANDED"
GROUND = "GROUND"
LOCAL = "LOCAL"
CIRCUIT = "CIRCUIT"
CIRCUIT_DOWNWIND = "CIRCUIT_DOWNWIND"
CIRCUIT_BASE = "CIRCUIT_BASE"
CIRCUIT_FINAL = "CIRCUIT_FINAL"
ARRIVED = "ARRIVED"
CANCELLED = "CANCELLED"
@@ -48,6 +52,7 @@ class ArrivalBase(BaseModel):
class ArrivalCreate(ArrivalBase):
eta: Optional[datetime] = None
submitted_via: Optional[SubmissionSource] = SubmissionSource.ADMIN
class ArrivalUpdate(BaseModel):
+3
View File
@@ -16,6 +16,9 @@ class LocalFlightStatus(str, Enum):
DEPARTED = "DEPARTED"
LOCAL = "LOCAL"
CIRCUIT = "CIRCUIT"
CIRCUIT_DOWNWIND = "CIRCUIT_DOWNWIND"
CIRCUIT_BASE = "CIRCUIT_BASE"
CIRCUIT_FINAL = "CIRCUIT_FINAL"
LANDED = "LANDED"
CANCELLED = "CANCELLED"