Journaling for all flights

This commit is contained in:
2025-12-18 07:34:19 -05:00
parent f3eb83665f
commit a2682314c9
16 changed files with 594 additions and 87 deletions

View File

@@ -1,5 +1,5 @@
from fastapi import APIRouter
from app.api.endpoints import auth, pprs, public, aircraft, airport, local_flights, departures, arrivals, circuits
from app.api.endpoints import auth, pprs, public, aircraft, airport, local_flights, departures, arrivals, circuits, journal
api_router = APIRouter()
@@ -9,6 +9,7 @@ api_router.include_router(local_flights.router, prefix="/local-flights", tags=["
api_router.include_router(departures.router, prefix="/departures", tags=["departures"])
api_router.include_router(arrivals.router, prefix="/arrivals", tags=["arrivals"])
api_router.include_router(circuits.router, prefix="/circuits", tags=["circuits"])
api_router.include_router(journal.router, prefix="/journal", tags=["journal"])
api_router.include_router(public.router, prefix="/public", tags=["public"])
api_router.include_router(aircraft.router, prefix="/aircraft", tags=["aircraft"])
api_router.include_router(airport.router, prefix="/airport", tags=["airport"])

View File

@@ -87,7 +87,16 @@ async def update_arrival(
detail="Arrival record not found"
)
arrival = crud_arrival.update(db, db_obj=db_arrival, obj_in=arrival_in)
# Get user IP from request
user_ip = request.client.host if request.client else None
arrival = crud_arrival.update(
db,
db_obj=db_arrival,
obj_in=arrival_in,
user=current_user.username,
user_ip=user_ip
)
# Send real-time update
if hasattr(request.app.state, 'connection_manager'):
@@ -112,11 +121,14 @@ async def update_arrival_status(
current_user: User = Depends(get_current_operator_user)
):
"""Update arrival status"""
client_ip = get_client_ip(request)
arrival = crud_arrival.update_status(
db,
arrival_id=arrival_id,
status=status_update.status,
timestamp=status_update.timestamp
timestamp=status_update.timestamp,
user=current_user.username,
user_ip=client_ip
)
if not arrival:
raise HTTPException(

View File

@@ -87,7 +87,16 @@ async def update_departure(
detail="Departure record not found"
)
departure = crud_departure.update(db, db_obj=db_departure, obj_in=departure_in)
# Get user IP from request
user_ip = request.client.host if request.client else None
departure = crud_departure.update(
db,
db_obj=db_departure,
obj_in=departure_in,
user=current_user.username,
user_ip=user_ip
)
# Send real-time update
if hasattr(request.app.state, 'connection_manager'):
@@ -112,11 +121,14 @@ async def update_departure_status(
current_user: User = Depends(get_current_operator_user)
):
"""Update departure status"""
client_ip = get_client_ip(request)
departure = crud_departure.update_status(
db,
departure_id=departure_id,
status=status_update.status,
timestamp=status_update.timestamp
timestamp=status_update.timestamp,
user=current_user.username,
user_ip=client_ip
)
if not departure:
raise HTTPException(

View File

@@ -0,0 +1,63 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app.api import deps
from app.crud.crud_journal import journal
from app.models.journal import EntityType
from app.schemas.journal import JournalEntryResponse, EntityJournalResponse
from typing import List
router = APIRouter(tags=["journal"])
@router.get("/{entity_type}/{entity_id}", response_model=EntityJournalResponse)
async def get_entity_journal(
entity_type: str,
entity_id: int,
limit: int = 100,
db: Session = Depends(deps.get_db),
current_user = Depends(deps.get_current_user)
):
"""
Get journal entries for a specific entity (PPR, LOCAL_FLIGHT, ARRIVAL, or DEPARTURE).
The journal is immutable - entries are created automatically by the backend
when changes are made. This endpoint is read-only.
Parameters:
- entity_type: One of 'PPR', 'LOCAL_FLIGHT', 'ARRIVAL', 'DEPARTURE'
- entity_id: The ID of the entity
- limit: Maximum number of entries to return (default 100)
"""
# Validate entity type
try:
entity = EntityType[entity_type.upper()]
except KeyError:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Invalid entity_type. Must be one of: {', '.join([e.value for e in EntityType])}"
)
entries = journal.get_entity_journal(db, entity, entity_id, limit=limit)
return EntityJournalResponse(
entity_type=entity_type,
entity_id=entity_id,
entries=entries,
total_entries=len(entries)
)
@router.get("/user/{username}", response_model=List[JournalEntryResponse])
async def get_user_journal(
username: str,
limit: int = 100,
db: Session = Depends(deps.get_db),
current_user = Depends(deps.get_current_user)
):
"""
Get all journal entries created by a specific user.
This endpoint is read-only and returns entries in reverse chronological order.
"""
entries = journal.get_user_journal(db, username, limit=limit)
return entries

View File

@@ -88,7 +88,16 @@ async def update_local_flight(
detail="Local flight record not found"
)
flight = crud_local_flight.update(db, db_obj=db_flight, obj_in=flight_in)
# Get user IP from request
user_ip = request.client.host if request.client else None
flight = crud_local_flight.update(
db,
db_obj=db_flight,
obj_in=flight_in,
user=current_user.username,
user_ip=user_ip
)
# Send real-time update
if hasattr(request.app.state, 'connection_manager'):
@@ -113,11 +122,14 @@ async def update_local_flight_status(
current_user: User = Depends(get_current_operator_user)
):
"""Update local flight status (LANDED, CANCELLED, etc.)"""
client_ip = get_client_ip(request)
flight = crud_local_flight.update_status(
db,
flight_id=flight_id,
status=status_update.status,
timestamp=status_update.timestamp
timestamp=status_update.timestamp,
user=current_user.username,
user_ip=client_ip
)
if not flight:
raise HTTPException(