From db263122a1b63e02d056630cd574f59b4819715e Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Fri, 26 Sep 2025 14:56:34 -0700 Subject: [PATCH] Refactor remaining methods in ApiBasedShuttleRepositoryLoader.ts to follow the same sub-procedure pattern --- .../ApiBasedShuttleRepositoryLoader.ts | 182 +++++++++++------- 1 file changed, 110 insertions(+), 72 deletions(-) diff --git a/src/loaders/shuttle/ApiBasedShuttleRepositoryLoader.ts b/src/loaders/shuttle/ApiBasedShuttleRepositoryLoader.ts index 29ad295..74d6c87 100644 --- a/src/loaders/shuttle/ApiBasedShuttleRepositoryLoader.ts +++ b/src/loaders/shuttle/ApiBasedShuttleRepositoryLoader.ts @@ -40,11 +40,37 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader } public async updateRouteDataForSystem() { - const systemId = this.passioSystemId; + try { + const json = await this.fetchRouteDataJson(); + const routes = this.constructRoutesFromJson(json); + if (routes !== null) { + await this.updateRouteDataInRepository(routes); + } else { + console.warn(`Route update failed for the following JSON: ${JSON.stringify(json)}`); + } + } catch(e: any) { + throw new ApiResponseError(e.message); + } + } + + private async updateRouteDataInRepository(routes: IRoute[]) { const routeIdsToPrune = await this.constructExistingEntityIdSet(async () => { return await this.repository.getRoutes(); }); + await Promise.all(routes.map(async (route) => { + await this.repository.addOrUpdateRoute(route); + routeIdsToPrune.delete(route.id); + })); + + await Promise.all(Array.from(routeIdsToPrune).map(async (routeId) => { + await this.repository.removeRouteIfExists(routeId); + })); + } + + private async fetchRouteDataJson() { + const systemId = this.passioSystemId; + const params = { getRoutes: "2", }; @@ -52,53 +78,63 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader const formDataJsonObject = { "systemSelected0": systemId, "amount": "1", - } + }; const formData = new FormData(); formData.set("json", JSON.stringify(formDataJsonObject)); const query = new URLSearchParams(params).toString(); - try { - const response = await fetch(`${this.baseUrl}?${query}`, { - method: "POST", - body: formData, + const response = await fetch(`${this.baseUrl}?${query}`, { + method: "POST", + body: formData, + }); + return await response.json(); + } + + private constructRoutesFromJson(json: any): IRoute[] | null { + if (typeof json.all === "object") { + return json.all.map((jsonRoute: any) => { + const constructedRoute: IRoute = { + name: jsonRoute.name, + color: jsonRoute.color, + id: jsonRoute.myid, + polylineCoordinates: [], + systemId: this.systemIdForConstructedData, + updatedTime: new Date(), + }; + return constructedRoute; }); - const json = await response.json(); + } - if (typeof json.all === "object") { - await Promise.all(json.all.map(async (jsonRoute: any) => { - const constructedRoute: IRoute = { - name: jsonRoute.name, - color: jsonRoute.color, - id: jsonRoute.myid, - polylineCoordinates: [], - systemId: this.systemIdForConstructedData, - updatedTime: new Date(), - }; + return null; + } - await this.repository.addOrUpdateRoute(constructedRoute); - - routeIdsToPrune.delete(constructedRoute.id); - })) - } - - await Promise.all(Array.from(routeIdsToPrune).map(async (routeId) => { - await this.repository.removeRouteIfExists(routeId); - })); + public async updateStopAndPolylineDataForRoutesInSystem() { + try { + const json = await this.fetchStopAndPolylineDataJson(); + await this.updateStopAndPolylineDataInRepository(json); } catch(e: any) { throw new ApiResponseError(e.message); } } - public async updateStopAndPolylineDataForRoutesInSystem() { - const passioSystemId = this.passioSystemId; - - // Fetch from the API - // Pass JSON output into two different methods to update repository + private async updateStopAndPolylineDataInRepository(json: any) { const stopIdsToPrune = await this.constructExistingEntityIdSet(async () => { return await this.repository.getStops(); }); + await this.updateStopDataForSystemAndApiResponse(json, stopIdsToPrune); + await this.updateOrderedStopDataForExistingStops(json); + await this.updatePolylineDataForExistingRoutesAndApiResponse(json); + + await Promise.all(Array.from(stopIdsToPrune).map(async (stopId) => { + await this.repository.removeStopIfExists(stopId); + })); + } + + private async fetchStopAndPolylineDataJson() { + const passioSystemId = this.passioSystemId; + const params = { getStops: "2", }; @@ -112,23 +148,11 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader const query = new URLSearchParams(params).toString(); - try { - const response = await fetch(`${this.baseUrl}?${query}`, { - method: "POST", - body: formData, - }); - const json = await response.json(); - - await this.updateStopDataForSystemAndApiResponse(json, stopIdsToPrune); - await this.updateOrderedStopDataForExistingStops(json); - await this.updatePolylineDataForExistingRoutesAndApiResponse(json); - - await Promise.all(Array.from(stopIdsToPrune).map(async (stopId) => { - await this.repository.removeStopIfExists(stopId); - })); - } catch(e: any) { - throw new ApiResponseError(e.message); - } + const response = await fetch(`${this.baseUrl}?${query}`, { + method: "POST", + body: formData, + }); + return await response.json(); } public async updateShuttleDataForSystem() { @@ -219,6 +243,24 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader } public async updateEtaDataForStopId(stopId: string) { + try { + const json = await this.fetchEtaDataJson(stopId); + const etas = this.constructEtasFromJson(json, stopId); + if (etas !== null) { + await this.updateEtaDataInRepository(etas); + } + } catch(e: any) { + throw new ApiResponseError(e.message); + } + } + + private async updateEtaDataInRepository(etas: IEta[]) { + await Promise.all(etas.map(async (eta) => { + await this.repository.addOrUpdateEta(eta); + })); + } + + private async fetchEtaDataJson(stopId: string) { const params = { eta: "3", stopIds: stopId, @@ -226,32 +268,28 @@ export class ApiBasedShuttleRepositoryLoader implements ShuttleRepositoryLoader const query = new URLSearchParams(params).toString(); - try { - const response = await fetch(`${this.baseUrl}?${query}`, { - method: "GET", + const response = await fetch(`${this.baseUrl}?${query}`, { + method: "GET", + }); + return await response.json(); + } + + private constructEtasFromJson(json: any, stopId: string): IEta[] | null { + if (json.ETAs && json.ETAs[stopId]) { + return json.ETAs[stopId].map((jsonEta: any) => { + const shuttleId: string = jsonEta.busId; + const eta: IEta = { + secondsRemaining: jsonEta.secondsSpent, + shuttleId: `${shuttleId}`, + stopId: stopId, + updatedTime: new Date(), + systemId: this.systemIdForConstructedData, + }; + return eta; }); - const json = await response.json(); - - if (json.ETAs && json.ETAs[stopId]) { - // Continue with the parsing - json.ETAs[stopId].forEach((jsonEta: any) => { - // Update cache - const shuttleId: string = jsonEta.busId; - - const eta: IEta = { - secondsRemaining: jsonEta.secondsSpent, - shuttleId: `${shuttleId}`, - stopId: stopId, - updatedTime: new Date(), - systemId: this.systemIdForConstructedData, - }; - - this.repository.addOrUpdateEta(eta); - }); - } - } catch(e: any) { - throw new ApiResponseError(e.message); } + + return null; } protected async updateStopDataForSystemAndApiResponse(