검색 K
밝은/어두운 배경
밝은/어두운 배경
게시물 정보
등록 신청과 철회 신청 각각의 상태 전이를 설명합니다.
사용자 API 운영자
│ │ │
│── POST /api/rss-register ─>│ │
│ │ feed_requests INSERT │
│ │ status = 'pending' │
│ │── sendAdminBatchEmail ────>│
│<── 200 신청 접수 ───────────│ │
│ │ (이메일 링크 클릭)
│ │<── GET /api/review ────────│
│ │ consumeReviewToken │
│ │ status = 'approved'/'rejected'
│ │ │
│ │ [approved 시] │
│ │ approveFeedRequest │
│ │ registered_feeds UPSERT │
│ │ active = true │
│ │ │
│ │ triggerScraper ────────────────> GitHub Actions
│<── sendBatchResultEmail ───│ │| 상태 | 의미 | 전이 조건 |
|---|---|---|
pending | 검토 대기 중 | 신청 접수 시 초기값 |
approved | 승인 완료 | 운영자 승인 링크 클릭 |
rejected | 반려 | 운영자 반려 링크 클릭 |
withdrawn | 철회됨 | 피드 철회 확인 시 자동 전이 |
철회된 피드를 재신청하면 uq_active_request 부분 인덱스 조건(status IN ('pending', 'approved'))에서 벗어나 있으므로 새 행이 INSERT됩니다. 승인 시 registered_feeds는 ON CONFLICT DO UPDATE로 복구됩니다.
사용자 API 운영자
│ │ │
│── POST /api/rss-withdraw ─>│ │
│ │ withdraw_requests INSERT │
│ │ status = 'pending' │
│ │── sendWithdrawAdminEmail ─>│
│<── 200 신청 접수 ───────────│ │
│ │ (이메일 링크 클릭)
│ │<── GET /api/withdraw-review│
│ │ consumeWithdrawToken │
│ │ status = 'confirmed'/'rejected'
│ │ │
│ │ [confirmed 시] │
│ │ deactivateFeed (CTE) │
│ │ registered_feeds.active = false
│ │ registered_feeds.withdrawn_at = NOW()
│ │ feed_requests.status = 'withdrawn'
│ │ │
│ │ triggerScraper ────────────────> GitHub Actions
│<── sendWithdrawResultEmail ─│ │| 상태 | 의미 | 전이 조건 |
|---|---|---|
pending | 검토 대기 중 | 신청 접수 시 초기값 |
confirmed | 철회 확인 완료 | 운영자 확인 링크 클릭 |
rejected | 철회 거부 | 운영자 거부 링크 클릭 |
deactivateFeed 원자성 보장 CTE 단일 쿼리로 두 테이블을 동시에 갱신합니다. 순차 실행 시 feed_requests.status = 'approved' 상태가 남아 uq_active_request 제약으로 재신청이 차단되는 문제를 방지합니다.
WITH deactivate AS (
UPDATE registered_feeds SET active = false, withdrawn_at = NOW()
WHERE folder_name = $1 AND feed_url = $2
RETURNING folder_name, feed_url
)
UPDATE feed_requests SET status = 'withdrawn'
WHERE folder_name = $1 AND feed_url = $2 AND status = 'approved'등록 신청과 철회 신청 모두 단건과 배치 처리를 동일한 엔드포인트에서 지원합니다.
| 구분 | 등록 | 철회 |
|---|---|---|
| 배치 식별자 | batchId (UUID) | folderName |
| 배치 완료 기준 | 배치 내 pending 행 없음 | folderName의 pending 행 없음 |
| 결과 이메일 | 배치 완료 시 1회 | 배치 완료 시 1회 |
| 중복 발송 방지 | result_sent_at UPDATE RETURNING | pending_count 확인 |
운영자 이메일에는 두 가지 버튼이 있습니다.
두 버튼 모두 동일한 엔드포인트를 사용하며, 쿼리 파라미터로 단건/배치를 구분합니다.
운영자가 동일한 이메일 링크를 두 번 클릭하거나, 전체 처리와 개별 처리를 동시에 실행하는 상황에 대비합니다.
토큰 소진: token_used_at IS NULL 조건의 UPDATE RETURNING으로 한 번만 처리됩니다.
결과 이메일 중복 방지: result_sent_at IS NULL 조건의 UPDATE RETURNING으로 한 요청만 이메일 발송 책임을 가집니다.
배치 내 일부 동시 처리: 배치 처리 중 단건도 함께 처리될 수 있으나, updated === 0인 행은 건너뛰어 안전하게 처리됩니다.