diff options
Diffstat (limited to 'app/api/revalidate')
| -rw-r--r-- | app/api/revalidate/approval/route.ts | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/app/api/revalidate/approval/route.ts b/app/api/revalidate/approval/route.ts new file mode 100644 index 00000000..ed4da139 --- /dev/null +++ b/app/api/revalidate/approval/route.ts @@ -0,0 +1,101 @@ +import { revalidateTag } from 'next/cache'; +import { NextRequest, NextResponse } from 'next/server'; + +/** + * 결재 시스템 캐시 무효화 API + * + * 백그라운드 프로세스(폴링 서비스)에서 request 컨텍스트 없이 + * 캐시를 무효화하기 위한 API 라우트 + * + * 사용법: + * await fetch('/api/revalidate/approval', { + * method: 'POST', + * headers: { 'Content-Type': 'application/json' }, + * body: JSON.stringify({ tags: ['approval-logs'] }) + * }); + */ +export async function POST(request: NextRequest) { + try { + const body = await request.json(); + const { tags, secret } = body; + + // 선택적 보안: 환경 변수로 시크릿 키 검증 + // 내부 서버에서만 호출되므로 필수는 아님 + if (process.env.REVALIDATION_SECRET && secret !== process.env.REVALIDATION_SECRET) { + return NextResponse.json( + { success: false, message: 'Invalid secret' }, + { status: 401 } + ); + } + + // 캐시 태그 무효화 + if (Array.isArray(tags)) { + for (const tag of tags) { + revalidateTag(tag); + console.log(`[Cache Revalidation] Tag revalidated: ${tag}`); + } + } else if (typeof tags === 'string') { + revalidateTag(tags); + console.log(`[Cache Revalidation] Tag revalidated: ${tags}`); + } + + return NextResponse.json({ + success: true, + revalidated: true, + tags: Array.isArray(tags) ? tags : [tags], + timestamp: new Date().toISOString(), + }); + } catch (error) { + console.error('[Cache Revalidation] Error:', error); + return NextResponse.json( + { + success: false, + message: error instanceof Error ? error.message : 'Revalidation failed', + }, + { status: 500 } + ); + } +} + +// GET 요청으로도 사용 가능 (개발/테스트용) +export async function GET(request: NextRequest) { + const { searchParams } = new URL(request.url); + const tag = searchParams.get('tag'); + const secret = searchParams.get('secret'); + + if (process.env.REVALIDATION_SECRET && secret !== process.env.REVALIDATION_SECRET) { + return NextResponse.json( + { success: false, message: 'Invalid secret' }, + { status: 401 } + ); + } + + if (!tag) { + return NextResponse.json( + { success: false, message: 'Tag parameter is required' }, + { status: 400 } + ); + } + + try { + revalidateTag(tag); + console.log(`[Cache Revalidation] Tag revalidated: ${tag}`); + + return NextResponse.json({ + success: true, + revalidated: true, + tag, + timestamp: new Date().toISOString(), + }); + } catch (error) { + console.error('[Cache Revalidation] Error:', error); + return NextResponse.json( + { + success: false, + message: error instanceof Error ? error.message : 'Revalidation failed', + }, + { status: 500 } + ); + } +} + |
