@@ -11,6 +11,7 @@ import crypto from 'crypto';
1111import { sql } from 'kysely' ;
1212import { incrementStat } from '../utils/statisticsCache.js' ;
1313import type { FlightsTable } from './types/connection/main/FlightsTable.js' ;
14+ import type { FlightLogsTable } from './types/connection/main/FlightLogsTable.js' ;
1415
1516function createUTCDate ( ) : Date {
1617 const now = new Date ( ) ;
@@ -188,6 +189,122 @@ export async function getFlightsBySession(sessionId: string) {
188189 }
189190}
190191
192+ export async function getFlightsByUser ( userId : string ) {
193+ try {
194+ const flights = await mainDb
195+ . selectFrom ( 'flights' )
196+ . selectAll ( )
197+ . where ( 'user_id' , '=' , userId )
198+ . orderBy ( 'created_at' , 'desc' )
199+ . execute ( ) ;
200+
201+ return flights . map ( ( flight ) => sanitizeFlightForClient ( flight ) ) ;
202+ } catch ( error ) {
203+ console . error ( `Error fetching flights for user ${ userId } :` , error ) ;
204+ return [ ] ;
205+ }
206+ }
207+
208+ export async function getFlightByIdForUser ( userId : string , flightId : string ) {
209+ try {
210+ const validFlightId = validateFlightId ( flightId ) ;
211+ const flight = await mainDb
212+ . selectFrom ( 'flights' )
213+ . selectAll ( )
214+ . where ( 'id' , '=' , validFlightId )
215+ . where ( 'user_id' , '=' , userId )
216+ . executeTakeFirst ( ) ;
217+
218+ return flight ? sanitizeFlightForClient ( flight ) : null ;
219+ } catch ( error ) {
220+ console . error ( `Error fetching flight ${ flightId } for user ${ userId } :` , error ) ;
221+ return null ;
222+ }
223+ }
224+
225+ export async function getFlightLogsForUser ( userId : string , flightId : string ) {
226+ try {
227+ const validFlightId = validateFlightId ( flightId ) ;
228+
229+ const ownedFlight = await mainDb
230+ . selectFrom ( 'flights' )
231+ . select ( [ 'id' , 'created_at' ] )
232+ . where ( 'id' , '=' , validFlightId )
233+ . where ( 'user_id' , '=' , userId )
234+ . executeTakeFirst ( ) ;
235+
236+ if ( ! ownedFlight ) {
237+ return { logs : [ ] , logsDiscardedDueToAge : false } ;
238+ }
239+
240+ const retentionThreshold = new Date (
241+ Date . now ( ) - 365 * 24 * 60 * 60 * 1000
242+ ) ;
243+ const logsDiscardedDueToAge = ! ! (
244+ ownedFlight . created_at && ownedFlight . created_at < retentionThreshold
245+ ) ;
246+
247+ const logs = await mainDb
248+ . selectFrom ( 'flight_logs' )
249+ . selectAll ( )
250+ . where ( 'flight_id' , '=' , validFlightId )
251+ . orderBy ( 'created_at' , 'desc' )
252+ . execute ( ) ;
253+
254+ return {
255+ logs : logs . map ( ( log : FlightLogsTable ) => ( {
256+ id : log . id ,
257+ action : log . action ,
258+ old_data : log . old_data ,
259+ new_data : log . new_data ,
260+ created_at : log . created_at ,
261+ } ) ) ,
262+ logsDiscardedDueToAge,
263+ } ;
264+ } catch ( error ) {
265+ console . error (
266+ `Error fetching flight logs for flight ${ flightId } and user ${ userId } :` ,
267+ error
268+ ) ;
269+ return { logs : [ ] , logsDiscardedDueToAge : false } ;
270+ }
271+ }
272+
273+ export async function claimFlightForUser (
274+ sessionId : string ,
275+ flightId : string ,
276+ acarsToken : string ,
277+ userId : string
278+ ) {
279+ const validSessionId = validateSessionId ( sessionId ) ;
280+ const validFlightId = validateFlightId ( flightId ) ;
281+
282+ const flight = await mainDb
283+ . selectFrom ( 'flights' )
284+ . select ( [ 'id' , 'user_id' , 'acars_token' ] )
285+ . where ( 'session_id' , '=' , validSessionId )
286+ . where ( 'id' , '=' , validFlightId )
287+ . executeTakeFirst ( ) ;
288+
289+ if ( ! flight ) return { ok : false , reason : 'not_found' as const } ;
290+ if ( flight . acars_token !== acarsToken )
291+ return { ok : false , reason : 'invalid_token' as const } ;
292+ if ( flight . user_id && flight . user_id !== userId )
293+ return { ok : false , reason : 'already_claimed' as const } ;
294+
295+ await mainDb
296+ . updateTable ( 'flights' )
297+ . set ( {
298+ user_id : userId ,
299+ updated_at : createUTCDate ( ) ,
300+ } )
301+ . where ( 'session_id' , '=' , validSessionId )
302+ . where ( 'id' , '=' , validFlightId )
303+ . execute ( ) ;
304+
305+ return { ok : true as const } ;
306+ }
307+
191308export async function validateAcarsAccess (
192309 sessionId : string ,
193310 flightId : string ,
@@ -418,7 +535,7 @@ export async function updateFlight(
418535 for ( const [ key , value ] of Object . entries ( updates ) ) {
419536 let dbKey = key ;
420537 if ( key === 'cruisingFL' ) dbKey = 'cruisingfl' ;
421- if ( key === 'clearedFL' ) dbKey = 'clearedfl' ;
538+ if ( key === 'clearedFL' ) dbKey = 'clearedfl' ;
422539 if ( allowedColumns . includes ( dbKey ) ) {
423540 dbUpdates [ dbKey ] = dbKey === 'clearance' ? String ( value ) : value ;
424541 }
0 commit comments