검색 K
밝은/어두운 배경
밝은/어두운 배경
게시물 정보
피드 등록과 철회 전체 흐름을 파트 통합 관점에서 설명합니다.
1. 신청자가 프론트엔드 신청 폼 제출
↓
2. 파트 2 API가 registered_feeds에 행 삽입 (active = false)
↓
3. 관리자가 검토 후 승인 → active = true 로 업데이트
↓
4. 다음 스크래퍼 실행 시 fetchActiveFeeds()가 해당 피드를 포함
↓
5. RSS 수집 → JSON 저장 → Markdown 생성프론트엔드 신청 없이 관리자가 직접 피드를 추가하는 경우:
INSERT INTO registered_feeds (
feed_url,
feed_title,
folder_name,
source_link,
scope,
include_image,
meta_display,
active
) VALUES (
'https://example.com/rss', -- RSS 피드 URL
'예시 피드', -- 표시 이름 (Markdown 파일명으로 사용)
'policy-news', -- VitePress 폴더명 (영문 소문자, 하이픈)
'https://example.com', -- 원본 웹사이트 URL
'all', -- 수집 범위: all | today | 3days | weekly
false, -- 대표 이미지 추출 여부
true, -- 발행일/저자/카테고리 표시 여부
true -- 즉시 활성화
);folder_name: 영문 소문자와 하이픈만 사용합니다. 동일한 folderName끼리는 VitePress에서 같은 섹션으로 묶입니다.
scope: 피드 발행 빈도와 모니터링 목적에 따라 선택합니다. 자세한 기준은 설정 가이드를 참고합니다.
include_image: 피드 원본에 이미지가 포함되어 있고 Markdown에 표시하고 싶을 때 true로 설정합니다. 이미지가 없는 피드에 true로 설정해도 무방합니다(이미지 없으면 건너뜀).
meta_display: 발행일·저자·카테고리 정보 블록을 Markdown에 표시할지 결정합니다. 저자 정보가 없는 피드에는 false를 권장합니다.
피드 Markdown 상단에 로고를 표시하려면:
src/{folderName}/logo-assets/ 에 추가합니다.logo_name 컬럼에 파일명을 입력합니다.UPDATE registered_feeds
SET logo_name = 'example-logo.png'
WHERE feed_url = 'https://example.com/rss';스크래퍼 실행 후 다음을 확인합니다.
✓ JSON 파일 생성 여부: src/_data/{year}/{MM}/{urlToFileName}.json
✓ Markdown 파일 생성 여부: src/{folderName}/{year}/{MM}/{feedTitle}.md
✓ 폴더 인덱스 생성 여부: src/{folderName}/index.md
✓ 연도 인덱스 생성 여부: src/{folderName}/{year}/index.md1. 철회 요청 접수 (신청자 또는 관리자)
↓
2. 파트 2 API 또는 관리자 직접 DB 업데이트
→ active = false, withdrawn_at = NOW()
↓
3. 다음 스크래퍼 실행 시 fetchInactiveFeeds()가 해당 피드를 포함
↓
4. cleanupService.ts가 관련 파일 삭제
→ src/{folderName}/{year}/{MM}/{feedTitle}.md 삭제
→ 해당 URL을 참조하는 active 피드가 없으면 JSON도 삭제
↓
5. 빈 디렉토리 자동 정리UPDATE registered_feeds
SET active = false,
withdrawn_at = NOW()
WHERE feed_url = 'https://example.com/rss'
AND folder_name = 'policy-news';주의:
withdrawn_at을NULL로 두면 고아 파일 정리 대상에서 제외됩니다. 파일 정리를 원하면 반드시withdrawn_at = NOW()를 함께 설정합니다.
예: https://example.com/rss가 policy-news와 env-watch 두 folderName에 등록되어 있고 policy-news만 철회하는 경우:
-- policy-news만 철회
UPDATE registered_feeds
SET active = false, withdrawn_at = NOW()
WHERE feed_url = 'https://example.com/rss' AND folder_name = 'policy-news';이 경우 env-watch의 active 피드가 남아 있으므로 JSON 파일은 삭제되지 않습니다. policy-news 관련 Markdown 파일만 삭제됩니다.
철회된 피드를 다시 활성화하는 경우:
UPDATE registered_feeds
SET active = true,
withdrawn_at = NULL -- 반드시 NULL로 초기화
WHERE feed_url = 'https://example.com/rss'
AND folder_name = 'policy-news';withdrawn_at = NULL로 초기화하지 않으면, 재활성화해도 다음 스크래퍼 실행 시 고아 파일 정리 대상으로 다시 잡힙니다.
재활성화 후 첫 스크래퍼 실행 시:
feed_url 접근 가능 여부 브라우저로 확인folder_name 영문 소문자·하이픈만 사용scope 발행 빈도에 맞게 설정active = true 확인logo_name 설정active = false, withdrawn_at = NOW() 함께 설정이메일이 발송되지 않았거나 링크가 만료된 경우 DB를 직접 조작합니다.
-- 1. 대상 행 확인
SELECT id, batch_id, folder_name, feed_url, feed_title, source_link, scope
FROM feed_requests
WHERE status = 'pending' AND folder_name = 'policy-news';
-- 2. 토큰 소진 + 상태 업데이트
UPDATE feed_requests
SET token_used_at = NOW(),
reviewed_at = NOW(),
status = 'approved'
WHERE id = <id> AND token_used_at IS NULL;
-- 3. registered_feeds에 등록
INSERT INTO registered_feeds (
feed_id, folder_name, feed_url, feed_title, source_link, scope, active
) VALUES (
'policy-news-' || substr(gen_random_uuid()::text, 1, 8),
'policy-news',
'https://example.com/rss',
'예시 피드',
'https://example.com',
'all',
true
)
ON CONFLICT (folder_name, feed_url) DO UPDATE
SET active = true,
withdrawn_at = NULL,
registered_at = NOW();수동 승인 후 스크래퍼가 자동으로 반영하도록 GitHub Actions에서 rss-scraper 워크플로우를 수동 실행합니다.
UPDATE feed_requests
SET token_used_at = NOW(),
reviewed_at = NOW(),
status = 'rejected',
rejected_reason = 'RSS URL에 접근할 수 없습니다.'
WHERE id = <id> AND token_used_at IS NULL;새 folderName 계정을 생성할 때 사용합니다.
---
date: 2026-06-08
writers: claude.ai
description: 비밀번호 해시 생성
pageClass: sysDocs
tags:
- 기술 문서
- 운영 매뉴얼
- claude.ai
- 비밀번호 해시 생성
---
# 비밀번호 해시 생성
<div aria-hidden="true" class="aria-hidden">
:::info 게시물 정보
- 작성일: <Date />
- 글쓴이: <Writers />
- 주제어: <TagLinks />
:::
</div>
tsx scripts/hash-password.ts <비밀번호>
---
date: 2026-06-08
writers: claude.ai
description: → password_hash: $2b$12$...
pageClass: sysDocs
tags:
- 기술 문서
- 운영 매뉴얼
- claude.ai
- → password_hash: $2b$12$...
---
# → password_hash: $2b$12$...
<div aria-hidden="true" class="aria-hidden">
:::info 게시물 정보
- 작성일: <Date />
- 글쓴이: <Writers />
- 주제어: <TagLinks />
:::
</div>INSERT INTO users (folder_name, password_hash, email)
VALUES ('new-folder', '$2b$12$...', 'user@example.com');비밀번호는 공백만으로 구성할 수 없습니다.
hash-password.ts가 이를 검증하고 종료합니다.