From 14d3ad6150ee23bd8bd48f0b850b2c7671a3fcdd Mon Sep 17 00:00:00 2001 From: Juan Alvarado Date: Wed, 13 Mar 2024 18:57:13 -0400 Subject: [PATCH] Remove dead code --- src/server/application.ts | 23 ---- src/server/context.ts | 5 +- src/server/domain/Episode.ts | 45 ------- src/server/repositories/episodesRepository.ts | 127 ------------------ src/server/services/episodesService.ts | 90 ------------- 5 files changed, 3 insertions(+), 287 deletions(-) delete mode 100644 src/server/application.ts delete mode 100644 src/server/domain/Episode.ts delete mode 100644 src/server/repositories/episodesRepository.ts delete mode 100644 src/server/services/episodesService.ts diff --git a/src/server/application.ts b/src/server/application.ts deleted file mode 100644 index b534d9e..0000000 --- a/src/server/application.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { inferAsyncReturnType } from "@trpc/server"; -import { createDbConnection } from "./db"; -import { createEpisodesRepo } from "./repositories/episodesRepository"; -import { createEpisodesService } from "./services/episodesService"; - -type ISoulectorApp = inferAsyncReturnType; - -export async function createApp() { - const db = await createDbConnection(); - const episodesRepo = createEpisodesRepo(db); - const episodesService = createEpisodesService(episodesRepo, db); - return { db, episodesService }; -} - -let app: ISoulectorApp; - -export async function getApp() { - if (app) { - return app; - } - - return await createApp(); -} diff --git a/src/server/context.ts b/src/server/context.ts index 9304361..26642b8 100644 --- a/src/server/context.ts +++ b/src/server/context.ts @@ -1,6 +1,6 @@ -import { getApp } from "@/server/application"; import * as trpc from "@trpc/server"; import * as trpcNext from "@trpc/server/adapters/next"; +import { createDbConnection } from "./db"; // eslint-disable-next-line @typescript-eslint/no-empty-interface interface CreateContextOptions { @@ -12,7 +12,8 @@ interface CreateContextOptions { * This is useful for testing when we don't want to mock Next.js' request/response */ export async function createContextInner(_opts: CreateContextOptions) { - return getApp(); + const db = await createDbConnection(); + return { db }; } export type Context = trpc.inferAsyncReturnType; diff --git a/src/server/domain/Episode.ts b/src/server/domain/Episode.ts deleted file mode 100644 index e498bab..0000000 --- a/src/server/domain/Episode.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { v4 } from "uuid"; -import { invariant } from "../crosscutting/errorTypes"; - -export interface IEntity { - id: string; - createdAt: Date; - updatedAt: Date; -} - -export interface IEpisode extends IEntity { - name: string; - sourceUrl: string; - artworkUrl: string; - duration: number; - releaseDate: Date; - source: "MIXCLOUD" | "SOUNDCLOUD"; -} - -interface EpisodeOpts { - name: string; - sourceUrl: string; - artworkUrl: string; - duration: number; - releaseDate: Date; - source: IEpisode["source"]; -} - -export function createNewEpisode(opts: EpisodeOpts): Readonly { - invariant( - opts.source === "MIXCLOUD" || opts.source === "SOUNDCLOUD", - `Unrecognized source: ${opts.source}` - ); - - return { - id: v4(), - updatedAt: new Date(), - createdAt: new Date(), - name: opts.name, - sourceUrl: opts.sourceUrl, - artworkUrl: opts.artworkUrl, - duration: opts.duration, - releaseDate: opts.releaseDate, - source: opts.source, - }; -} diff --git a/src/server/repositories/episodesRepository.ts b/src/server/repositories/episodesRepository.ts deleted file mode 100644 index 75e30ee..0000000 --- a/src/server/repositories/episodesRepository.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { Collection, Db } from "mongodb"; -import { IEpisode } from "../domain/Episode"; - -export interface IDbEntity { - _id: string; - created_at: Date; - updated_at: Date; -} - -interface DbEpisode extends IDbEntity { - name: string; - artwork_url: string; - duration: number; - release_date: Date; - source_url: string; - source: string; -} - -export class EpisodesRepo { - private collection: Collection; - - constructor(private db: Db) { - this.collection = this.db.collection("episodes"); - } - - async getAllEpisodes(): Promise { - const cursor = this.collection - .find() - .sort({ release_date: -1 }) - .map(fromDbEpisode); - const episodes = await cursor.toArray(); - cursor.close(); - return episodes; - } - - async existManyByUrl( - urls: string[] - ): Promise<{ url: string; exists: boolean }[]> { - const cursor = this.collection.find({ source_url: { $in: urls } }); - const existingEpisodes = await cursor.toArray(); - - cursor.close(); - - const existingUrls = existingEpisodes.map((e) => e.source_url); - - return urls.map((newUrl) => { - return { - url: newUrl, - exists: existingUrls.includes(newUrl), - }; - }); - } - - async getEpisodesByUrl(urls: string[]) { - const cursor = this.collection - .find({ source_url: { $in: urls } }) - .map(fromDbEpisode); - cursor.close(); - - const episodes = await cursor.toArray(); - return episodes; - } - - async getLatestEpisode(): Promise { - const cursor = this.collection - .find({}) - .sort({ release_date: -1 }) - .limit(1) - .map(fromDbEpisode); - const eps = await cursor.toArray(); - - cursor.close(); - - if (eps.length === 1) { - return eps[0]; - } - return null; - } - - async saveEpisode(episode: IEpisode): Promise { - const dbEp = toDbEpisode(episode); - - await this.collection.updateOne( - { _id: episode.id }, - { $set: dbEp }, - { upsert: true } - ); - } - - async insertMany(episodes: IEpisode[]): Promise { - const dbEps = episodes.map(toDbEpisode); - const insertRes = await this.collection.insertMany(dbEps); - return dbEps.length === insertRes.insertedCount; - } -} - -export function createEpisodesRepo(db: Db) { - return new EpisodesRepo(db); -} - -function fromDbEpisode(dbEp: DbEpisode): IEpisode { - return { - id: dbEp._id, - name: dbEp.name, - artworkUrl: dbEp.artwork_url, - releaseDate: dbEp.release_date, - source: dbEp.source === "MIXCLOUD" ? "MIXCLOUD" : "SOUNDCLOUD", - sourceUrl: dbEp.source_url, - createdAt: dbEp.created_at, - updatedAt: dbEp.updated_at, - duration: dbEp.duration, - }; -} - -function toDbEpisode(ep: IEpisode): DbEpisode { - return { - _id: ep.id, - source: ep.source, - created_at: ep.createdAt, - updated_at: ep.updatedAt, - name: ep.name, - source_url: ep.sourceUrl, - artwork_url: ep.artworkUrl, - duration: ep.duration, - release_date: ep.releaseDate, - }; -} diff --git a/src/server/services/episodesService.ts b/src/server/services/episodesService.ts deleted file mode 100644 index 38523da..0000000 --- a/src/server/services/episodesService.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Db } from "mongodb"; -import { SoundCloudApiClient } from "../crosscutting/soundCloudApiClient"; -import { createNewEpisode } from "../domain/Episode"; -import { EpisodesRepo } from "../repositories/episodesRepository"; - -export class EpisodesService { - private scClient: SoundCloudApiClient; - - constructor(private episodesRepo: EpisodesRepo, private db: Db) { - this.scClient = new SoundCloudApiClient(); - } - - async getAllEpisodes() { - return this.episodesRepo.getAllEpisodes(); - } - - async getLatestEpisode() { - return this.episodesRepo.getLatestEpisode(); - } - - async migrateTracksToEpisodes() { - type DBTrack = { - _id: string; - source: string; - created_time: string; - name: string; - url: string; - picture_large: string; - duration: number; - }; - - const tracksCollection = this.db.collection("tracks"); - const oldTracks = await tracksCollection.find({}).toArray(); - - const migratedEpisodes = oldTracks.map((ot) => - createNewEpisode({ - name: ot.name, - duration: ot.duration, - artworkUrl: ot.picture_large, - source: ot.source === "SOUNDCLOUD" ? "SOUNDCLOUD" : "MIXCLOUD", - releaseDate: new Date(ot.created_time), - sourceUrl: ot.url, - }) - ); - - return this.episodesRepo.insertMany(migratedEpisodes); - } - - async syncSoulectionFromSoundcloud() { - const soulectionRadioSessionsPlaylistId = "8025093"; - - // get soulection episodes from soundcloud - const scTrackDtos = await this.scClient - .getPlaylistInfo(soulectionRadioSessionsPlaylistId) - .then((res) => res.tracks); - - const existsRes = await this.episodesRepo.existManyByUrl( - scTrackDtos.map((dto) => dto.permalink_url) - ); - - const missingEpUsrls = existsRes - .filter((res) => !res.exists) - .map((r) => r.url); - - const missingDtos = scTrackDtos.filter((dto) => - missingEpUsrls.includes(dto.permalink_url) - ); - - const eps = missingDtos.map((dto) => - createNewEpisode({ - name: dto.title, - artworkUrl: dto.artwork_url, - duration: dto.duration, - releaseDate: new Date(dto.created_at), - source: "SOUNDCLOUD", - sourceUrl: dto.permalink_url, - }) - ); - - if (eps.length > 0) { - return await this.episodesRepo.insertMany(eps); - } - - return []; - } -} - -export function createEpisodesService(episodeRepo: EpisodesRepo, db: Db) { - return new EpisodesService(episodeRepo, db); -}