import { IS_PLATFORM } from 'common' import { NextResponse } from 'next/server' import { InternalServerError } from '@/lib/api/apiHelpers' import { getActiveIncidents, type IncidentCache } from '@/lib/api/incident-status' import { createAdminClient } from '@/lib/api/briven-admin' /** * Cache on CDN for 5 minutes * Allow serving stale content for 1 minute while revalidating */ const CACHE_CONTROL_SETTINGS = 'public, s-maxage=300, stale-while-revalidate=60' async function fetchIncidentCache(incidentIds: Array): Promise> { const cacheMap = new Map() if (incidentIds.length === 0) return cacheMap const briven = createAdminClient() try { const { data, error } = await briven .from('incident_status_cache') .select('incident_id, affected_regions, affects_project_creation') .in('incident_id', incidentIds) if (error) { console.error('Failed to fetch incident_status_cache: %O', error) return cacheMap } for (const row of data ?? []) { cacheMap.set(row.incident_id, { affected_regions: row.affected_regions ?? null, affects_project_creation: row.affects_project_creation, }) } } catch (error) { console.error('Unexpected error fetching incident_status_cache: %O', error) } return cacheMap } export async function OPTIONS() { if (!IS_PLATFORM) return new Response(null, { status: 404 }) return new Response(null, { status: 204, headers: { Allow: 'GET, HEAD, OPTIONS', }, }) } export async function HEAD() { if (!IS_PLATFORM) return new Response(null, { status: 404 }) return new Response(null, { status: 200, headers: { 'Cache-Control': CACHE_CONTROL_SETTINGS }, }) } export async function GET() { if (!IS_PLATFORM) return new Response(null, { status: 404 }) try { const allIncidents = await getActiveIncidents() const bannerIncidents = allIncidents.filter( (incident) => incident.impact !== 'maintenance' && incident.metadata?.dashboard_metadata?.show_banner === true ) const cacheMap = await fetchIncidentCache(bannerIncidents.map((i) => i.id)) const enrichedIncidents = bannerIncidents.map((incident) => ({ ...incident, cache: cacheMap.get(incident.id) ?? null, })) return NextResponse.json(enrichedIncidents, { headers: { 'Cache-Control': CACHE_CONTROL_SETTINGS }, }) } catch (error) { let errorCode = 500 const headers = new Headers() if (error instanceof InternalServerError) { if (typeof error.details?.status === 'number') errorCode = error.details.status if (errorCode === 420) errorCode = 429 if (errorCode === 429 && typeof error.details?.retryAfter === 'string') { headers.set('Retry-After', error.details.retryAfter) } console.error('Failed to fetch active StatusPage incidents: %O', { message: error.message, details: error.details, }) } else { console.error('Unexpected error fetching active StatusPage incidents: %O', error) } return NextResponse.json( { error: 'Unable to fetch incidents at this time' }, { status: errorCode, headers } ) } }