Skip to content

Commit

Permalink
chore: seed a bigger variety of flights
Browse files Browse the repository at this point in the history
  • Loading branch information
johanohly committed Nov 22, 2024
1 parent 180eafe commit f0f50e2
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 54 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-svelte": "^2.44.1",
"factory.ts": "^1.4.2",
"globals": "^15.10.0",
"lucia": "^3.2.0",
"postcss": "^8.4.47",
Expand Down
53 changes: 46 additions & 7 deletions prisma/seed/flight.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,56 @@
import { format } from 'date-fns';
import { Sync as Factory } from 'factory.ts';
import { Kysely } from 'kysely';

import { createFlightPrimitive } from '../../src/lib/db/queries';
import { AIRPORTS } from '../../src/lib/data/airports';
import { createManyFlightsPrimitive } from '../../src/lib/db/queries';
import type { DB } from '../../src/lib/db/schema';
import type { CreateFlight } from '../../src/lib/db/types';
import { estimateFlightDuration } from '../../src/lib/utils/datetime';
import { distanceBetween } from '../../src/lib/utils/distance';

const routes = [
{ from: 'EGLL', to: 'KJFK' }, // London-Heathrow to New York-JFK
{ from: 'KMIA', to: 'OMDB' }, // Miami to Dubai
{ from: 'HECA', to: 'OEJN' }, // Cairo to Jeddah
{ from: 'VHHH', to: 'RCTP' }, // Hong Kong to Taipei-Taoyuan
{ from: 'OMDB', to: 'OERK' }, // Dubai to Riyadh
{ from: 'VTBS', to: 'RKSI' }, // Bangkok-Suvarnabhumi to Seoul-Incheon
];

const baseFlightFactory = Factory.makeFactory<CreateFlight>({
seats: [{ userId: 'PLACEHOLDER' }],
// @ts-expect-error - TS doesn't understand the modulo operation
from: Factory.each((i) => routes[i % routes.length].from),
// @ts-expect-error - TS doesn't understand the modulo operation
to: Factory.each((i) => routes[i % routes.length].to),
date: Factory.each(() =>
format(
new Date(Date.now() - Math.random() * 10 * 365 * 24 * 60 * 60 * 1000), // Random date within the last 10 years
'yyyy-MM-dd',
),
),
}).withDerivation2(['from', 'to'], 'duration', (fromIcao, toIcao) => {
const from = AIRPORTS.find((a) => a.ICAO === fromIcao);
const to = AIRPORTS.find((a) => a.ICAO === toIcao);
return from && to
? estimateFlightDuration(
distanceBetween([from.lon, from.lat], [to.lon, to.lat]) / 1000,
)
: 0;
});

export const seedFlight = async (db: Kysely<DB>, userId: string) => {
await createFlightPrimitive(db, {
const flights = baseFlightFactory.buildList(10, {
seats: [
{ userId, seat: 'window', seatNumber: '11F', seatClass: 'economy' },
{
userId,
seat: 'window',
seatNumber: '11F',
seatClass: 'economy',
},
],
from: 'EKCH',
to: 'ESSA',
date: format(new Date(), 'yyyy-MM-dd'),
duration: 70 * 60,
});

await createManyFlightsPrimitive(db, flights);
};
34 changes: 34 additions & 0 deletions src/lib/db/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { jsonArrayFrom } from 'kysely/helpers/postgres';
import type { DB } from './schema';
import type { CreateFlight } from './types';

import { db } from '$lib/db/index';

export const listFlightPrimitive = async (db: Kysely<DB>, userId: string) => {
return await db
.selectFrom('flight')
Expand Down Expand Up @@ -98,3 +100,35 @@ export const updateFlightPrimitive = async (
}
});
};

export const createManyFlightsPrimitive = async (
db: Kysely<DB>,
data: CreateFlight[],
) => {
await db.transaction().execute(async (trx) => {
const flights = await trx
.insertInto('flight')
.values(data.map(({ seats: _, ...rest }) => rest))
.returning('id')
.execute();

const seatData = flights.flatMap((flight, index) => {
const flightInput = data[index];

if (flightInput && flightInput.seats.length > 0) {
return flightInput.seats.map((seat) => ({
flightId: flight.id,
userId: seat.userId,
guestName: seat.guestName,
seat: seat.seat,
seatNumber: seat.seatNumber,
seatClass: seat.seatClass,
}));
}

return [];
});

await trx.insertInto('seat').values(seatData).execute();
});
};
5 changes: 2 additions & 3 deletions src/lib/import/jetlog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { z } from 'zod';
import { page } from '$app/stores';
import type { PlatformOptions } from '$lib/components/modals/settings/pages/import-page';
import type { CreateFlight, Seat } from '$lib/db/types';
import { parseCsv } from '$lib/utils';
import { distanceBetween, parseCsv } from '$lib/utils';
import { airlineFromIATA } from '$lib/utils/data/airlines';
import { airportFromICAO } from '$lib/utils/data/airports';
import { estimateFlightDuration, parseLocal, toUtc } from '$lib/utils/datetime';
Expand Down Expand Up @@ -115,8 +115,7 @@ export const processJetLogFile = async (
departure && arrival
? differenceInSeconds(arrival, departure)
: estimateFlightDuration(
{ lng: from.lon, lat: from.lat },
{ lng: to.lon, lat: to.lat },
distanceBetween([from.lat, from.lon], [to.lat, to.lon]) / 1000,
);

const seatClass =
Expand Down
43 changes: 6 additions & 37 deletions src/lib/server/routes/flight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { db } from '$lib/db';
import type { CreateFlight } from '$lib/db/types';
import {
createFlight,
createManyFlights,
deleteFlight,
listFlights,
} from '$lib/server/utils/flight';
Expand Down Expand Up @@ -102,50 +103,18 @@ export const flightRouter = router({
}),
createMany: authedProcedure
.input(z.custom<CreateFlight[]>())
.mutation(async ({ ctx: { user }, input }) => {
await db.transaction().execute(async (trx) => {
const flights = await trx
.insertInto('flight')
.values(input.map(({ seats, ...rest }) => rest))
.returning('id')
.execute();

const seatData = flights.flatMap((flight, index) => {
const flightInput = input[index];

if (
flightInput &&
flightInput.seats &&
flightInput.seats.length > 0
) {
return flightInput.seats.map((seat) => ({
flightId: flight.id,
userId: seat.userId || (seat.guestName ? null : user.id),
guestName: seat.guestName,
seat: seat.seat,
seatNumber: seat.seatNumber,
seatClass: seat.seatClass,
}));
} else {
return [];
}
});
if (seatData.length === 0) {
throw new Error('No seats provided');
}

return await trx.insertInto('seat').values(seatData).execute();
});
.mutation(async ({ input }) => {
await createManyFlights(input);
}),
exportJson: authedProcedure.query(async ({ ctx: { user } }) => {
const users = await db
.selectFrom('user')
.select(['id', 'displayName', 'username'])
.execute();
const res = await listFlights(user.id);
const flights = res.map(({ id, ...flight }) => ({
const flights = res.map(({ id: _, ...flight }) => ({
...flight,
seats: flight.seats.map(({ id, flightId, ...seat }) => ({
seats: flight.seats.map(({ id: _, flightId: __, ...seat }) => ({
...seat,
})),
}));
Expand All @@ -160,7 +129,7 @@ export const flightRouter = router({
}),
exportCsv: authedProcedure.query(async ({ ctx: { user } }) => {
const res = await listFlights(user.id);
const flights = res.map(({ id, seats, ...flight }) => {
const flights = res.map(({ id: _, seats, ...flight }) => {
const seat = seats.find((seat) => seat.userId === user.id);

return {
Expand Down
5 changes: 5 additions & 0 deletions src/lib/server/utils/flight.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { db } from '$lib/db';
import {
createFlightPrimitive,
createManyFlightsPrimitive,
getFlightPrimitive,
listFlightPrimitive,
updateFlightPrimitive,
Expand All @@ -26,3 +27,7 @@ export const deleteFlight = async (id: number) => {
export const updateFlight = async (id: number, data: CreateFlight) => {
return await updateFlightPrimitive(db, id, data);
};

export const createManyFlights = async (data: CreateFlight[]) => {
await createManyFlightsPrimitive(db, data);
};
7 changes: 1 addition & 6 deletions src/lib/utils/datetime/duration.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import type { LngLatLike } from 'maplibre-gl';

import { distanceBetween } from '$lib/utils';

export class Duration {
readonly days: number;
readonly hours: number;
Expand Down Expand Up @@ -31,8 +27,7 @@ export class Duration {
}
}

export const estimateFlightDuration = (from: LngLatLike, to: LngLatLike) => {
const distance = distanceBetween(from, to) / 1000;
export const estimateFlightDuration = (distance: number) => {
const durationHours = distance / 805 + 0.5; // 805 km/h is the average speed of a commercial jet, add 0.5 hours for takeoff and landing
return Math.round(durationHours * 3600);
};
5 changes: 4 additions & 1 deletion src/routes/api/flight/save/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
getFlight,
updateFlight,
} from '$lib/server/utils/flight';
import { distanceBetween } from '$lib/utils';
import { airportFromICAO } from '$lib/utils/data/airports';
import {
estimateFlightDuration,
Expand Down Expand Up @@ -108,7 +109,9 @@ export const POST: RequestHandler = async ({ locals, request }) => {
// if the airports are the same, the duration can't be calculated
const fromLonLat = { lon: fromAirport.lon, lat: fromAirport.lat };
const toLonLat = { lon: toAirport.lon, lat: toAirport.lat };
duration = estimateFlightDuration(fromLonLat, toLonLat);
duration = estimateFlightDuration(
distanceBetween(fromLonLat, toLonLat) / 1000,
);
}

const { flightNumber, aircraft, aircraftReg, airline, flightReason, note } =
Expand Down

0 comments on commit f0f50e2

Please sign in to comment.