Files
josh 548c7ae09e feat: initial project scaffold with CI/CD and Docker deployment
Next.js 15 + Tailwind CSS v4 week calendar showing Six Flags park hours.
Scrapes the internal CloudFront API, stores results in SQLite.
Includes Dockerfile (Debian/Playwright-compatible), docker-compose, and
Gitea Actions pipeline that builds and pushes to the container registry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 00:48:09 -04:00

60 lines
1.6 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { PARKS } from "@/lib/parks";
import { openDb, getMonthCalendar } from "@/lib/db";
import type { Park } from "@/lib/scrapers/types";
export interface ParksApiResponse {
parks: Park[];
calendar: Record<string, boolean[]>;
month: string;
daysInMonth: number;
}
function getDaysInMonth(year: number, month: number): number {
return new Date(year, month, 0).getDate();
}
function parseMonthParam(
monthParam: string | null
): { year: number; month: number } | null {
if (!monthParam) return null;
const match = monthParam.match(/^(\d{4})-(\d{2})$/);
if (!match) return null;
const year = parseInt(match[1], 10);
const month = parseInt(match[2], 10);
if (month < 1 || month > 12) return null;
return { year, month };
}
export async function GET(request: NextRequest): Promise<NextResponse> {
const monthParam = request.nextUrl.searchParams.get("month");
const parsed = parseMonthParam(monthParam);
if (!parsed) {
return NextResponse.json(
{ error: "Invalid or missing ?month=YYYY-MM parameter" },
{ status: 400 }
);
}
const { year, month } = parsed;
const daysInMonth = getDaysInMonth(year, month);
const db = openDb();
const calendar = getMonthCalendar(db, year, month);
db.close();
const response: ParksApiResponse = {
parks: PARKS,
calendar,
month: `${year}-${String(month).padStart(2, "0")}`,
daysInMonth,
};
return NextResponse.json(response, {
headers: {
"Cache-Control": "public, s-maxage=3600, stale-while-revalidate=86400",
},
});
}