diff --git a/api/src/db/schema.ts b/api/src/db/schema.ts index 90614c1..297783b 100644 --- a/api/src/db/schema.ts +++ b/api/src/db/schema.ts @@ -1,7 +1,5 @@ -import { integer, text, sqliteTable, sqliteView } from "drizzle-orm/sqlite-core"; -import { eq, sql } from "drizzle-orm"; +import { integer, text, sqliteTable } from "drizzle-orm/sqlite-core"; -// Tables export const attraction = sqliteTable('attraction', { id: integer().primaryKey({ autoIncrement: true }), name: text().notNull(), @@ -25,7 +23,7 @@ export const logbook = sqliteTable('logbook', { realWaittime: integer() }) -export const notificationMethod = sqliteTable('notification_method', { +export const notificationMethod = sqliteTable('notification', { id: integer().primaryKey({ autoIncrement: true }), webhookUrl: text().notNull(), shownName: text().notNull(), @@ -44,24 +42,4 @@ export const user = sqliteTable('user', { id: integer().primaryKey({ autoIncrement: true }), username: text().notNull(), isActive: integer({ mode: 'boolean' }).default(false) -}) - -// Views -export const subscribedThemeparks = sqliteView('subscribed_themeparks').as((qb) => - qb.selectDistinct({ - apiName: sql`themepark.api_name`.as('api_name') - }).from(attractionNotification) - .innerJoin(attraction, eq(attractionNotification.attractionId, attraction.id)) - .innerJoin(themepark, eq(attraction.themeparkId, themepark.id)) -); - -export const attractionSubscriptions = sqliteView('attraction_subscriptions').as((qb) => - qb.selectDistinct({ - attractionApiCode: sql`attraction.api_code`.as('attraction_api_code'), - themeparkApiName: sql`themepark.api_name`.as('themepark_api_name'), - webhookUrl: sql`notification_method.webhook_url`.as('webhook_url') - }).from(attractionNotification) - .innerJoin(attraction, eq(attractionNotification.attractionId, attraction.id)) - .innerJoin(themepark, eq(attraction.themeparkId, themepark.id)) - .innerJoin(notificationMethod, eq(attractionNotification.notificationMethodId, notificationMethod.id)) -); \ No newline at end of file +}) \ No newline at end of file diff --git a/api/src/jobs/update-attraction-list.ts b/api/src/jobs/update-attraction-list.ts index 0a9c38b..a97f8c7 100644 --- a/api/src/jobs/update-attraction-list.ts +++ b/api/src/jobs/update-attraction-list.ts @@ -1,22 +1,62 @@ import { getDbEnv } from '../db/client' import { attraction, themepark } from '../db/schema' import { inArray } from 'drizzle-orm' -import { Attraction } from '../types/attraction' -import { ThemeparkSelect } from '../types/themepark' +import httpRequest from '../lib/http-request' import asyncBatchJob from '../lib/async-batch-job' -import fetchAttractions from '../lib/fetch-attractions' -type ThemeparkAPI = Pick; +interface AttractionImport { + code: string, + name: string, +} + +interface AttractionType { + name: string, + apiCode: string, + themeparkId: number +} + +interface Themepark { + apiName: string, + id: number +} + +/** + * Fetching the attractions from a specified park + * @param park API Code for request themepark + * @param endpoint Endpoint where to fetch data from (default: https://api.wartezeiten.app/v1/parks) + * @param lang Language used for API request + * @returns Interface with attraction code & name + */ +async function fetchAttractions( + park: string, + endpoint: string = "https://api.wartezeiten.app/v1/parks", + lang: string = 'de' +): Promise{ + try{ + const headers = { + 'language':lang, + 'park':park + }; + + const result = await httpRequest(endpoint, { + headers: headers + }); + return result; + } + catch(e){ + throw new Error(`Failed to fetch attractions: ${e}`); + } +} /** * Return an object of all themeparks saved in the database * @param env DB Connection * @returns Object of themeparks with api name & id from internal DB */ -async function getThemeparks(env: Env): Promise{ +async function getThemeparks(env: Env): Promise{ try{ const db = getDbEnv(env); - const themeparks: ThemeparkAPI[] = await db.select({ + const themeparks: Themepark[] = await db.select({ apiName: themepark.apiName, id: themepark.id }).from(themepark); @@ -34,13 +74,13 @@ async function getThemeparks(env: Env): Promise{ * @param parks Object of themeparks to get attractions from * @returns Object of attractions */ -async function getAttractionsByParks(env: Env, parks: ThemeparkAPI[]): Promise{ +async function getAttractionsByParks(env: Env, parks: Themepark[]): Promise{ try{ const db = getDbEnv(env); const parkIds: number[] = parks.map(p => p.id); - const attractions: Attraction[] = await db.select({ + const attractions: AttractionType[] = await db.select({ name: attraction.name, apiCode: attraction.apiCode, themeparkId: attraction.themeparkId @@ -60,7 +100,7 @@ async function getAttractionsByParks(env: Env, parks: ThemeparkAPI[]): Promise{ +async function importAttractionsByParks(env: Env, parks: Themepark[]): Promise{ try{ const db = getDbEnv(env); diff --git a/api/src/lib/fetch-attractions.ts b/api/src/lib/fetch-attractions.ts deleted file mode 100644 index c83e7e1..0000000 --- a/api/src/lib/fetch-attractions.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { AttractionImport } from '../types/attraction' -import httpRequest from '../lib/http-request' - -/** - * Fetching the attractions from a specified park - * @param park API Code for request themepark - * @param endpoint Endpoint where to fetch data from (default: https://api.wartezeiten.app/v1/parks) - * @param lang Language used for API request - * @returns Interface with attraction code & name - */ -export default async function fetchAttractions( - park: string, - endpoint: string = "https://api.wartezeiten.app/v1/waitingtimes", - lang: string = 'de' -): Promise{ - try{ - const headers = { - 'language':lang, - 'park':park - }; - - const result = await httpRequest(endpoint, { - headers: headers - }); - return result; - } - catch(e){ - throw new Error(`Failed to fetch attractions: ${e}`); - } -} \ No newline at end of file diff --git a/api/src/types/attraction-subscriptions.ts b/api/src/types/attraction-subscriptions.ts deleted file mode 100644 index a5e6b70..0000000 --- a/api/src/types/attraction-subscriptions.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { attractionSubscriptions } from '../db/schema'; - -export type AttractionSubscription = typeof attractionSubscriptions.$inferSelect; \ No newline at end of file diff --git a/api/src/types/attraction.ts b/api/src/types/attraction.ts index 0d76170..11c4438 100644 --- a/api/src/types/attraction.ts +++ b/api/src/types/attraction.ts @@ -2,21 +2,4 @@ import { type InferSelectModel, type InferInsertModel } from 'drizzle-orm'; import { attraction } from '../db/schema'; export type Attraction = InferInsertModel -export type AttractionSelect = InferSelectModel - -// API Response format -export interface AttractionImport { - code: string, - name: string, - waitingtime: number, - status: "opened" | "virtualqueue" | "maintenance" | "closedice" | "closedweather" | "closed" -} - -// Waittime comparison -export interface AttractionChanges { - apiCode: string, - name: string, - waittime: number, - hasChanged: boolean, - increased: boolean -} \ No newline at end of file +export type AttractionSelect = InferSelectModel \ No newline at end of file diff --git a/api/src/types/attraction-notification.ts b/api/src/types/attractionNotification.ts similarity index 100% rename from api/src/types/attraction-notification.ts rename to api/src/types/attractionNotification.ts diff --git a/api/src/types/notification-method.ts b/api/src/types/notificationMethod.ts similarity index 100% rename from api/src/types/notification-method.ts rename to api/src/types/notificationMethod.ts diff --git a/api/src/types/subscribed-themeparks.ts b/api/src/types/subscribed-themeparks.ts deleted file mode 100644 index 085c524..0000000 --- a/api/src/types/subscribed-themeparks.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { subscribedThemeparks } from '../db/schema'; - -export type SubscribedThemeparks = typeof subscribedThemeparks.$inferSelect; \ No newline at end of file