[기획/설계 문서] - CONTENT/ARCHITECTURE_EBAY_PARTS_TOOL.md: 3-tier 아키텍처 설계서 - CONTENT/ebay-tool-proposal.html: 공식 제안서 (3단 패키지 120/198/330만원) - CONTENT/ebay-tool-questionnaire.html: 사전 요구사항 질문지 (17항목) [관리자 문서 뷰어] - admin/documents/page.tsx: 프로젝트 문서 카드 목록 + iframe 미리보기 - api/admin/documents/[filename]: 인증 기반 HTML 문서 서빙 API - AdminSidebar: "프로젝트 문서" 메뉴 추가 [MVP 스캐폴딩] - tools/ebay-parts/page.tsx: 품번 입력 → 5탭 결과 UI (Mock 데이터) - api/tools/ebay-parts/search: POST 검색 API (Mock 반환) - Sidebar: "이베이 부품 검색" 메뉴 추가 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { readFile } from 'fs/promises';
|
|
import path from 'path';
|
|
import { verifyAdminTokenNode } from '@/lib/admin-auth';
|
|
import { cookies } from 'next/headers';
|
|
|
|
export const runtime = 'nodejs';
|
|
|
|
const ALLOWED_FILES = [
|
|
'ebay-tool-proposal.html',
|
|
'ebay-tool-questionnaire.html',
|
|
];
|
|
|
|
async function checkAuth() {
|
|
const cookieStore = await cookies();
|
|
const token = cookieStore.get('admin_token')?.value;
|
|
return token && verifyAdminTokenNode(token);
|
|
}
|
|
|
|
export async function GET(
|
|
request: Request,
|
|
{ params }: { params: Promise<{ filename: string }> }
|
|
) {
|
|
if (!(await checkAuth())) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const { filename } = await params;
|
|
|
|
if (!ALLOWED_FILES.includes(filename)) {
|
|
return NextResponse.json({ error: 'Not found' }, { status: 404 });
|
|
}
|
|
|
|
try {
|
|
const filePath = path.join(process.cwd(), 'CONTENT', filename);
|
|
const content = await readFile(filePath, 'utf-8');
|
|
|
|
return new NextResponse(content, {
|
|
headers: { 'Content-Type': 'text/html; charset=utf-8' },
|
|
});
|
|
} catch {
|
|
return NextResponse.json({ error: 'File not found' }, { status: 404 });
|
|
}
|
|
}
|