217 lines
4.4 KiB
Python
217 lines
4.4 KiB
Python
from pydantic import BaseModel, EmailStr, validator
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
from enum import Enum
|
|
|
|
|
|
class PPRStatus(str, Enum):
|
|
NEW = "NEW"
|
|
CONFIRMED = "CONFIRMED"
|
|
CANCELED = "CANCELED"
|
|
LANDED = "LANDED"
|
|
DELETED = "DELETED"
|
|
DEPARTED = "DEPARTED"
|
|
|
|
|
|
class UserRole(str, Enum):
|
|
ADMINISTRATOR = "ADMINISTRATOR"
|
|
OPERATOR = "OPERATOR"
|
|
READ_ONLY = "READ_ONLY"
|
|
|
|
|
|
class PPRBase(BaseModel):
|
|
ac_reg: str
|
|
ac_type: str
|
|
ac_call: Optional[str] = None
|
|
captain: str
|
|
fuel: Optional[str] = None
|
|
in_from: str
|
|
eta: datetime
|
|
pob_in: int
|
|
out_to: Optional[str] = None
|
|
etd: Optional[datetime] = None
|
|
pob_out: Optional[int] = None
|
|
email: Optional[EmailStr] = None
|
|
phone: Optional[str] = None
|
|
notes: Optional[str] = None
|
|
|
|
@validator('ac_reg')
|
|
def validate_registration(cls, v):
|
|
if not v or len(v.strip()) == 0:
|
|
raise ValueError('Aircraft registration is required')
|
|
return v.strip().upper()
|
|
|
|
@validator('pob_in')
|
|
def validate_pob_in(cls, v):
|
|
if v is not None and v < 0:
|
|
raise ValueError('POB inbound must be non-negative')
|
|
return v
|
|
|
|
@validator('pob_out')
|
|
def validate_pob_out(cls, v):
|
|
if v is not None and v < 0:
|
|
raise ValueError('POB outbound must be non-negative')
|
|
return v
|
|
|
|
|
|
class PPRCreate(PPRBase):
|
|
pass
|
|
|
|
|
|
class PPRUpdate(BaseModel):
|
|
ac_reg: Optional[str] = None
|
|
ac_type: Optional[str] = None
|
|
ac_call: Optional[str] = None
|
|
captain: Optional[str] = None
|
|
fuel: Optional[str] = None
|
|
in_from: Optional[str] = None
|
|
eta: Optional[datetime] = None
|
|
pob_in: Optional[int] = None
|
|
out_to: Optional[str] = None
|
|
etd: Optional[datetime] = None
|
|
pob_out: Optional[int] = None
|
|
email: Optional[EmailStr] = None
|
|
phone: Optional[str] = None
|
|
notes: Optional[str] = None
|
|
|
|
|
|
class PPRStatusUpdate(BaseModel):
|
|
status: PPRStatus
|
|
timestamp: Optional[datetime] = None
|
|
|
|
|
|
class PPRInDBBase(PPRBase):
|
|
id: int
|
|
status: PPRStatus
|
|
landed_dt: Optional[datetime] = None
|
|
departed_dt: Optional[datetime] = None
|
|
created_by: Optional[str] = None
|
|
submitted_dt: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class PPR(PPRInDBBase):
|
|
pass
|
|
|
|
|
|
class PPRPublic(BaseModel):
|
|
"""Public schema for arrivals/departures board - excludes sensitive data"""
|
|
id: int
|
|
status: PPRStatus
|
|
ac_reg: str
|
|
ac_type: str
|
|
ac_call: Optional[str] = None
|
|
in_from: str
|
|
eta: datetime
|
|
out_to: Optional[str] = None
|
|
etd: Optional[datetime] = None
|
|
landed_dt: Optional[datetime] = None
|
|
departed_dt: Optional[datetime] = None
|
|
submitted_dt: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class PPRInDB(PPRInDBBase):
|
|
pass
|
|
|
|
|
|
# User schemas
|
|
class UserBase(BaseModel):
|
|
username: str
|
|
role: UserRole = UserRole.READ_ONLY
|
|
|
|
|
|
class UserCreate(UserBase):
|
|
password: str
|
|
|
|
|
|
class UserUpdate(BaseModel):
|
|
username: Optional[str] = None
|
|
password: Optional[str] = None
|
|
role: Optional[UserRole] = None
|
|
|
|
|
|
class ChangePassword(BaseModel):
|
|
"""Schema for admin-initiated password changes"""
|
|
password: str
|
|
|
|
|
|
class UserInDBBase(UserBase):
|
|
id: int
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class User(UserInDBBase):
|
|
pass
|
|
|
|
|
|
class UserInDB(UserInDBBase):
|
|
password: str
|
|
|
|
|
|
# Authentication schemas
|
|
class Token(BaseModel):
|
|
access_token: str
|
|
token_type: str
|
|
expires_in: int # Token expiry in seconds
|
|
|
|
|
|
class TokenData(BaseModel):
|
|
username: Optional[str] = None
|
|
|
|
|
|
# Journal schemas
|
|
class JournalBase(BaseModel):
|
|
ppr_id: int
|
|
entry: str
|
|
user: str
|
|
ip: str
|
|
|
|
|
|
class JournalCreate(JournalBase):
|
|
pass
|
|
|
|
|
|
class Journal(JournalBase):
|
|
id: int
|
|
entry_dt: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# Airport schemas
|
|
class AirportBase(BaseModel):
|
|
icao: str
|
|
iata: Optional[str] = None
|
|
name: str
|
|
country: str
|
|
|
|
|
|
class Airport(AirportBase):
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# Aircraft schemas
|
|
class AircraftBase(BaseModel):
|
|
icao24: Optional[str] = None
|
|
registration: Optional[str] = None
|
|
manufacturer_icao: Optional[str] = None
|
|
type_code: Optional[str] = None
|
|
manufacturer_name: Optional[str] = None
|
|
model: Optional[str] = None
|
|
clean_reg: Optional[str] = None
|
|
|
|
|
|
class Aircraft(AircraftBase):
|
|
id: int
|
|
|
|
class Config:
|
|
from_attributes = True |