← back to Nineoh Guide
apps/web/app/api/shows/route.ts
56 lines
import { NextResponse } from "next/server";
import { pool } from "@/lib/db";
export const dynamic = "force-dynamic";
/**
* Show list for the show selector (web + Expo). Multi-show support: the guide
* covers the ORIGINAL "Beverly Hills, 90210" (1990) and the 2008 reboot "90210".
* The ORIGINAL is returned FIRST so the client defaults to it.
*
* Each show now includes a `showInfo` object with:
* - description: the full original description text
* - seasonCount, episodeCount: computed from the seasons/episodes tables
* - premiereDate, finaleDate: ISO date strings (or null)
* - disclaimerText: the show's disclaimer from the DB
*/
export async function GET() {
try {
const { rows } = await pool.query(
`select s.id,
s.canonical_title,
s.display_title,
s.description_original,
s.disclaimer_text,
count(distinct se.id)::int as season_count,
count(distinct ep.id)::int as episode_count,
to_char(min(ep.air_date), 'YYYY-MM-DD') as premiere_date,
to_char(max(ep.air_date), 'YYYY-MM-DD') as finale_date
from shows s
left join seasons se on se.show_id = s.id
left join episodes ep on ep.show_id = s.id
group by s.id, s.canonical_title, s.display_title,
s.description_original, s.disclaimer_text
order by (s.canonical_title = 'beverly-hills-90210') desc,
s.created_at asc`
);
const shows = rows.map((r) => ({
id: r.id as string,
canonicalTitle: r.canonical_title as string,
displayTitle: r.display_title as string,
showInfo: {
description: r.description_original as string,
seasonCount: r.season_count as number,
episodeCount: r.episode_count as number,
premiereDate: r.premiere_date as string | null,
finaleDate: r.finale_date as string | null,
disclaimerText: r.disclaimer_text as string,
},
}));
return NextResponse.json({ shows });
} catch (err) {
console.error("[api/shows] DB error:", err);
return NextResponse.json({ shows: [] }, { status: 500 });
}
}