검색 K
밝은/어두운 배경
밝은/어두운 배경
게시물 정보
모든 핸들러는 Vercel Serverless Function으로 배포됩니다. 로컬 개발 시에는 scripts/api-server.ts가 동일한 경로로 Express 서버를 제공합니다.
인증: rss-register, my-feeds, rss-withdraw는 withAuth 미들웨어를 사용합니다. 요청 본문에 folderName과 password를 반드시 포함해야 합니다.
CORS: 허용 오리진은 _middleware.ts의 ALLOWED_ORIGINS에서 관리합니다.
http://localhost:5173
https://briefingk.vercel.app
https://briefingk.kro.kr/api/rss-register 피드 등록을 신청합니다. 최대 10개 피드를 배치로 신청할 수 있습니다.
{
"folderName": "policy-news",
"password": "...",
"feeds": [
{
"feedUrl": "https://example.com/rss",
"feedTitle": "예시 피드",
"sourceLink": "https://example.com",
"scope": "all"
}
],
"message": "신청자 메모 (선택)"
}| 필드 | 필수 | 설명 |
|---|---|---|
feeds[].feedUrl | ✓ | RSS 피드 URL |
feeds[].feedTitle | ✓ | 피드 표시 이름 (파일명 변환 후 저장) |
feeds[].sourceLink | ✓ | 원본 웹사이트 URL |
feeds[].scope | — | all(기본) · today · 3days · weekly |
message | — | 운영자에게 전달할 메모 |
withAuth — folderName + password 검증isScraperLocked)validateFeedUrl — 5초 타임아웃)feed_requests 배치 INSERT (batch_id 공유)sendAdminBatchEmail)| 상태 코드 | 의미 |
|---|---|
| 200 | 신청 접수 완료 |
| 400 | 필수 항목 누락 · 형식 오류 · 건수 초과 |
| 401 | 인증 실패 |
| 409 | 중복 피드 |
| 423 | 스크래퍼 실행 중 (잠시 후 재시도) |
/api/review 운영자가 피드 등록 신청을 승인하거나 반려합니다. 이메일 내 링크로 호출되므로 GET 방식입니다.
GET /api/review?id=123&action=approve&token=abc...
GET /api/review?id=123&action=reject&reason=unreachable&token=abc...GET /api/review?batchId=uuid&action=approve&token=abc...
GET /api/review?batchId=uuid&action=reject&reason=invalid_format&token=abc...| 파라미터 | 설명 |
|---|---|
id | 단건 처리 시 feed_requests.id |
batchId | 배치 처리 시 UUID |
action | approve 또는 reject |
reason | 반려 사유 키. unreachable · inappropriate · invalid_format |
token | 일회성 review_token |
token_used_at IS NULL)consumeReviewToken — 토큰 소진 + 상태 업데이트approveFeedRequest — registered_feeds UPSERTsendBatchResultEmail 발송 (중복 방지 guard)triggerScraper 호출| 상태 코드 | 의미 |
|---|---|
| 200 | 처리 완료 (텍스트 응답) |
| 400 | 파라미터 누락 |
| 410 | 이미 처리됨 또는 유효하지 않은 토큰 |
동시 요청 방어:
token_used_at IS NULL조건으로 동일 토큰의 중복 처리를 방지합니다. 결과 이메일은result_sent_at컬럼 UPDATE RETURNING으로 단 한 번만 발송됩니다.
/api/my-feeds 인증된 사용자의 활성 피드 목록을 반환합니다.
{
"folderName": "policy-news",
"password": "..."
}{
"ok": true,
"feeds": [
{
"feed_id": "policy-news-a1b2c3d4",
"folder_name": "policy-news",
"feed_url": "https://example.com/rss",
"feed_title": "예시 피드",
"source_link": "https://example.com",
"scope": "all",
"include_image": false,
"meta_display": true,
"registered_at": "2026-06-01T09:00:00Z"
}
]
}/api/rss-withdraw 등록된 피드의 철회를 신청합니다.
{
"folderName": "policy-news",
"password": "...",
"feedUrls": [
"https://example.com/rss"
]
}withAuth — 인증registered_feeds에서 active 피드 존재 여부 확인withdraw_requests에서 이미 신청 중인 항목 확인withdraw_requests INSERT + 토큰 생성sendWithdrawAdminEmail)| 상태 코드 | 의미 |
|---|---|
| 200 | 철회 신청 접수 완료 |
| 400 | 필수 항목 누락 또는 대상 피드 없음 |
| 401 | 인증 실패 |
| 409 | 이미 철회 신청 중인 피드 |
| 423 | 스크래퍼 실행 중 |
/api/withdraw-review 운영자가 피드 철회 신청을 확인하거나 거부합니다.
GET /api/withdraw-review?action=confirm&token=abc...
GET /api/withdraw-review?action=reject&token=abc...GET /api/withdraw-review?action=confirm&token=abc...&folderName=policy-news
GET /api/withdraw-review?action=reject&token=abc...&folderName=policy-newsfolderName이 있으면 해당 폴더의 모든 pending 철회 신청을 일괄 처리합니다.
consumeWithdrawToken — 토큰 소진 + 상태 업데이트deactivateFeed — CTE로 registered_feeds 비활성화 + feed_requests 상태 갱신을 원자적 처리sendWithdrawResultEmail 발송triggerScraper 호출| 상태 코드 | 의미 |
|---|---|
| 200 | 처리 완료 (텍스트 응답) |
| 400 | 파라미터 누락 |
| 410 | 이미 처리됨 또는 유효하지 않은 토큰 |