1- import { rdsGetMultiple } from "@sk/db/redis" ;
1+ import { rdsGetMultiple , rdsGetSingle } from "@sk/db/redis" ;
22import type { StaticAirport } from "@sk/types/db" ;
33import type {
44 PilotDelta ,
@@ -13,6 +13,71 @@ import type {
1313import { haversineDistance } from "./utils/helpers.js" ;
1414
1515const TAXI_TIME_MS = 5 * 60 * 1000 ;
16+ const PILOT_RATINGS = [
17+ {
18+ id : 0 ,
19+ short_name : "NEW" ,
20+ long_name : "Basic Member" ,
21+ } ,
22+ {
23+ id : 1 ,
24+ short_name : "PPL" ,
25+ long_name : "Private Pilot License" ,
26+ } ,
27+ {
28+ id : 3 ,
29+ short_name : "IR" ,
30+ long_name : "Instrument Rating" ,
31+ } ,
32+ {
33+ id : 7 ,
34+ short_name : "CMEL" ,
35+ long_name : "Commercial Multi-Engine License" ,
36+ } ,
37+ {
38+ id : 15 ,
39+ short_name : "ATPL" ,
40+ long_name : "Airline Transport Pilot License" ,
41+ } ,
42+ {
43+ id : 31 ,
44+ short_name : "FI" ,
45+ long_name : "Flight Instructor" ,
46+ } ,
47+ {
48+ id : 63 ,
49+ short_name : "FE" ,
50+ long_name : "Flight Examiner" ,
51+ } ,
52+ ] ;
53+ const MILITARY_RATINGS = [
54+ {
55+ id : 0 ,
56+ short_name : "M0" ,
57+ long_name : "No Military Rating" ,
58+ } ,
59+ {
60+ id : 1 ,
61+ short_name : "M1" ,
62+ long_name : "Military Pilot License" ,
63+ } ,
64+ {
65+ id : 3 ,
66+ short_name : "M2" ,
67+ long_name : "Military Instrument Rating" ,
68+ } ,
69+ {
70+ id : 7 ,
71+ short_name : "M3" ,
72+ long_name : "Military Multi-Engine Rating" ,
73+ } ,
74+ {
75+ id : 15 ,
76+ short_name : "M4" ,
77+ long_name : "Military Mission Ready Pilot" ,
78+ } ,
79+ ] ;
80+
1681let cached : PilotLong [ ] = [ ] ;
1782let deleted : string [ ] = [ ] ;
1883let updated : PilotShort [ ] = [ ] ;
@@ -23,7 +88,7 @@ export async function mapPilots(latestVatsimData: VatsimData): Promise<PilotLong
2388 updated = [ ] ;
2489 added = [ ] ;
2590
26- const pilotsLong : PilotLong [ ] = latestVatsimData . pilots . map ( ( pilot ) => {
91+ const pilotsLongPromises : Promise < PilotLong > [ ] = latestVatsimData . pilots . map ( async ( pilot ) => {
2792 const id = `${ pilot . cid } _${ pilot . callsign } _${ pilot . logon_time } ` ;
2893 const cachedPilot = cached . find ( ( c ) => c . id === id ) ;
2994
@@ -59,9 +124,9 @@ export async function mapPilots(latestVatsimData: VatsimData): Promise<PilotLong
59124 aircraft : pilot . flight_plan ?. aircraft_short || "A320" ,
60125 name : pilot . name ,
61126 server : pilot . server ,
62- pilot_rating : pilot . pilot_rating ,
63- military_rating : pilot . military_rating ,
64- flight_plan : mapPilotFlightPlan ( pilot . flight_plan ) ,
127+ pilot_rating : PILOT_RATINGS . find ( ( r ) => r . id === pilot . pilot_rating ) ?. short_name || "NEW" ,
128+ military_rating : MILITARY_RATINGS . find ( ( r ) => r . id === pilot . military_rating ) ?. short_name || "M0" ,
129+ flight_plan : await mapPilotFlightPlan ( pilot . flight_plan ) ,
65130 route : `${ pilot . flight_plan ?. departure || "N/A" } -- ${ pilot . flight_plan ?. arrival || "N/A" } ` ,
66131 logon_time : new Date ( pilot . logon_time ) ,
67132 times : null ,
@@ -76,6 +141,8 @@ export async function mapPilots(latestVatsimData: VatsimData): Promise<PilotLong
76141 return pilotLong ;
77142 } ) ;
78143
144+ const pilotsLong = await Promise . all ( pilotsLongPromises ) ;
145+
79146 // Fetch airport coordinates for flight time estimation and store in PilotLong to minimize DB access
80147 const icaos = getUniqueAirports ( pilotsLong ) ;
81148 const airports = ( await rdsGetMultiple ( "static_airport" , icaos ) ) as ( StaticAirport | null ) [ ] ;
@@ -149,11 +216,11 @@ function calculateVerticalSpeed(current: PilotLong, cache: PilotLong | undefined
149216 return Math . round ( vs ) ;
150217}
151218
152- function mapPilotFlightPlan ( fp ?: VatsimPilotFlightPlan ) : PilotFlightPlan | null {
219+ async function mapPilotFlightPlan ( fp ?: VatsimPilotFlightPlan ) : Promise < PilotFlightPlan | null > {
153220 if ( ! fp ) return null ;
154221 return {
155222 flight_rules : fp . flight_rules === "I" ? "IFR" : "VFR" ,
156- ac_reg : extractAircraftRegistration ( fp . remarks ) ,
223+ ac_reg : await extractAircraftRegistration ( fp . remarks ) ,
157224 departure : { icao : fp . departure } ,
158225 arrival : { icao : fp . arrival } ,
159226 alternate : { icao : fp . alternate } ,
@@ -167,9 +234,27 @@ function mapPilotFlightPlan(fp?: VatsimPilotFlightPlan): PilotFlightPlan | null
167234 } ;
168235}
169236
170- function extractAircraftRegistration ( remarks : string ) : string | null {
237+ async function extractAircraftRegistration ( remarks : string ) : Promise < string | null > {
171238 const match = remarks . match ( / R E G \/ ( [ A - Z 0 - 9 ] + ) / i) ;
172- return match ?. [ 1 ] ?? null ;
239+ if ( ! match ?. [ 1 ] ) return null ;
240+ const reg = match [ 1 ] . toUpperCase ( ) ;
241+
242+ let aircraft = await rdsGetSingle ( `fleet:${ reg } ` ) ;
243+ if ( aircraft ) return reg ;
244+
245+ if ( reg . length > 1 ) {
246+ const format1 = `${ reg [ 0 ] } -${ reg . slice ( 1 ) } ` ;
247+ aircraft = await rdsGetSingle ( `fleet:${ format1 } ` ) ;
248+ if ( aircraft ) return format1 ;
249+ }
250+
251+ if ( reg . length > 2 ) {
252+ const format2 = `${ reg . slice ( 0 , 2 ) } -${ reg . slice ( 2 ) } ` ;
253+ aircraft = await rdsGetSingle ( `fleet:${ format2 } ` ) ;
254+ if ( aircraft ) return format2 ;
255+ }
256+
257+ return reg ;
173258}
174259
175260function mapPilotTimes ( current : PilotLong , cache : PilotLong | undefined , vatsimPilot : VatsimPilot ) : PilotTimes | null {
0 commit comments