All files / web/src/app/api/admin/page-spots/status route.ts

0% Statements 0/84
0% Branches 0/1
0% Functions 0/1
0% Lines 0/84

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                                                                                                                                                                         
import { existsSync, statSync } from 'fs'
import { join } from 'path'
import { NextResponse } from 'next/server'
import { withAuth } from '@/lib/auth/withAuth'
import { getAllPageSpotGroups } from '@/lib/page-spots/spotDefinitions'
import { loadPageSpotConfig, spotImageExists, spotImageUrl } from '@/lib/page-spots/loadSpotConfig'
import { IMAGE_PROVIDERS } from '@/lib/tasks/blog-image-generate'
import { getSpotComponentList } from '@/lib/page-spots/spotComponentList'

const CONTENT_DIR = join(process.cwd(), 'content', 'page-spots')
const PUBLIC_DIR = join(process.cwd(), 'public', 'page-spots')

/**
 * GET /api/admin/page-spots/status
 *
 * Returns all pages/spots with their config state, image/html existence,
 * available providers, and component list.
 */
export const GET = withAuth(
  async () => {
    const groups = getAllPageSpotGroups()

    const pages = groups.map((group) => {
      const configMap = loadPageSpotConfig(group.pageId)

      const spots = group.spots.map((def) => {
        const config = configMap[def.id] ?? null

        let imageUrl: string | null = null
        let imageSizeBytes: number | undefined
        let htmlExists = false

        if (config?.type === 'generated' && spotImageExists(group.pageId, def.id)) {
          imageUrl = spotImageUrl(group.pageId, def.id)
          const imgPath = join(PUBLIC_DIR, group.pageId, `${def.id}.png`)
          if (existsSync(imgPath)) {
            imageSizeBytes = statSync(imgPath).size
          }
        }

        if (config?.type === 'html') {
          const htmlPath = join(CONTENT_DIR, group.pageId, `${def.id}.html`)
          htmlExists = existsSync(htmlPath)
        }

        return {
          id: def.id,
          label: def.label,
          description: def.description,
          aspectRatio: def.aspectRatio ?? null,
          config,
          imageUrl,
          imageSizeBytes,
          htmlExists,
        }
      })

      return {
        pageId: group.pageId,
        label: group.label,
        spots,
      }
    })

    const providers = IMAGE_PROVIDERS.map((p) => {
      const hasKey =
        'envKeyAlt' in p
          ? !!(process.env[p.envKey] || process.env[p.envKeyAlt!])
          : !!process.env[p.envKey]

      return {
        id: p.id,
        name: p.name,
        available: hasKey,
        models: p.models.map((m) => ({ id: m.id, name: m.name })),
      }
    })

    const components = getSpotComponentList()

    return NextResponse.json({ pages, providers, components })
  },
  { role: 'admin' }
)