mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-07-14 18:15:56 -04:00
- Replace `tmdbProviderId` (single int) with a many-to-many `platformTmdbProviders` join table so one platform entry can map to multiple TMDB provider IDs (e.g. a single "Max" platform covers several regional TMDB IDs) - Add `isSubscription` flag to platforms to distinguish subscription services from transactional ones, replacing the old `displayOrder` field in API responses - Add `getPlatformTmdbIds` / `getPlatformTmdbIdMap` helpers in `@sofa/core/platforms` and thread them through discover, explore, and platform list procedures - Replace `providerId: number` with `platformId: string` (UUID) in discover input schema so the client never needs to resolve TMDB IDs - Add `scripts/sync-tmdb-providers.ts` script to pull live provider data from TMDB and update `platforms.json` - Split native title detail availability into separate "Stream" and "Buy or Rent" sections matching the web pattern - Add two new DB migrations for the join table and platform schema changes
101 lines
2.8 KiB
TypeScript
101 lines
2.8 KiB
TypeScript
import { asc, desc, eq, inArray } from "drizzle-orm";
|
|
|
|
import { db } from "../client";
|
|
import { platformTmdbIds, platforms, userPlatforms } from "../schema";
|
|
|
|
export function getUserPlatformIds(userId: string): string[] {
|
|
return db
|
|
.select({ platformId: userPlatforms.platformId })
|
|
.from(userPlatforms)
|
|
.where(eq(userPlatforms.userId, userId))
|
|
.all()
|
|
.map((r) => r.platformId);
|
|
}
|
|
|
|
export function getUserPlatforms(userId: string) {
|
|
return db
|
|
.select({
|
|
id: platforms.id,
|
|
name: platforms.name,
|
|
logoPath: platforms.logoPath,
|
|
urlTemplate: platforms.urlTemplate,
|
|
isSubscription: platforms.isSubscription,
|
|
})
|
|
.from(userPlatforms)
|
|
.innerJoin(platforms, eq(userPlatforms.platformId, platforms.id))
|
|
.where(eq(userPlatforms.userId, userId))
|
|
.orderBy(desc(platforms.isSubscription), asc(platforms.name))
|
|
.all();
|
|
}
|
|
|
|
export function setUserPlatforms(userId: string, platformIds: string[]): void {
|
|
db.transaction((tx) => {
|
|
tx.delete(userPlatforms).where(eq(userPlatforms.userId, userId)).run();
|
|
if (platformIds.length > 0) {
|
|
tx.insert(userPlatforms)
|
|
.values(platformIds.map((platformId) => ({ userId, platformId })))
|
|
.onConflictDoNothing()
|
|
.run();
|
|
}
|
|
});
|
|
}
|
|
|
|
export function getAllPlatforms() {
|
|
return db
|
|
.select()
|
|
.from(platforms)
|
|
.orderBy(desc(platforms.isSubscription), asc(platforms.name))
|
|
.all();
|
|
}
|
|
|
|
export function hasUserPlatforms(userId: string): boolean {
|
|
return (
|
|
db
|
|
.select({ platformId: userPlatforms.platformId })
|
|
.from(userPlatforms)
|
|
.where(eq(userPlatforms.userId, userId))
|
|
.limit(1)
|
|
.get() != null
|
|
);
|
|
}
|
|
|
|
export function platformIdsExist(platformIds: string[]): boolean {
|
|
if (platformIds.length === 0) return true;
|
|
const unique = [...new Set(platformIds)];
|
|
const found = db
|
|
.select({ id: platforms.id })
|
|
.from(platforms)
|
|
.where(inArray(platforms.id, unique))
|
|
.all();
|
|
return found.length === unique.length;
|
|
}
|
|
|
|
export function getTmdbProviderIdsForPlatform(platformId: string): number[] {
|
|
return db
|
|
.select({ tmdbProviderId: platformTmdbIds.tmdbProviderId })
|
|
.from(platformTmdbIds)
|
|
.where(eq(platformTmdbIds.platformId, platformId))
|
|
.all()
|
|
.map((r) => r.tmdbProviderId);
|
|
}
|
|
|
|
export function getTmdbProviderIdsByPlatformIds(platformIds: string[]): Map<string, number[]> {
|
|
if (platformIds.length === 0) return new Map();
|
|
const rows = db
|
|
.select({
|
|
platformId: platformTmdbIds.platformId,
|
|
tmdbProviderId: platformTmdbIds.tmdbProviderId,
|
|
})
|
|
.from(platformTmdbIds)
|
|
.where(inArray(platformTmdbIds.platformId, platformIds))
|
|
.all();
|
|
|
|
const map = new Map<string, number[]>();
|
|
for (const row of rows) {
|
|
const arr = map.get(row.platformId) ?? [];
|
|
arr.push(row.tmdbProviderId);
|
|
map.set(row.platformId, arr);
|
|
}
|
|
return map;
|
|
}
|