- government/ Node 데몬: Open API 우선 + HTML 보조 + 디스커버리 전략 - Strategy 패턴 소스 어댑터: KStartupApiSource(공공데이터 Open API), GenericHtmlSource(config 기반) - sundol 3단계 폴백 크롤러(cheerio→Jina→Playwright CDP) Node 재구현, sundol-chrome(9222) 재사용 - Oracle thick 모드(Instant Client + sso 지갑) 접속, gov_source/gov_opportunity 적재(중복제거) - K-Startup 29,017건 + 중기부(mss) 30건 적재 검증, PM2 gov-daemon 등록(60분 주기) - 기업마당(bizinfo)은 자체 crtfcKey 발급 대기 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
3.4 KiB
MySQL
55 lines
3.4 KiB
MySQL
-- 정부지원사업 스크래퍼 스키마
|
|
-- 기존 sundol 컨벤션 준수: snake_case 테이블, RAW(16) id(SYS_GUID()), TIMESTAMP(SYSTIMESTAMP)
|
|
-- 실행: SQLcl 에서 @government/db/schema.sql
|
|
|
|
-- ============================================================
|
|
-- gov_source : 공고 소스(사이트) 목록. Strategy 어댑터가 이 행을 읽어 동작한다.
|
|
-- ============================================================
|
|
CREATE TABLE gov_source (
|
|
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
|
code VARCHAR2(50) NOT NULL, -- 어댑터 식별자 (예: kstartup, bizinfo, smes)
|
|
name VARCHAR2(200) NOT NULL, -- 표시명
|
|
base_url VARCHAR2(500), -- 기준 URL
|
|
type VARCHAR2(20) NOT NULL, -- API | HTML
|
|
config CLOB, -- 어댑터 설정(JSON): endpoint, params, selectors 등
|
|
active NUMBER(1) DEFAULT 1 NOT NULL, -- 1=활성, 0=비활성
|
|
last_crawled_at TIMESTAMP,
|
|
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
|
CONSTRAINT gov_source_code_uq UNIQUE (code),
|
|
CONSTRAINT gov_source_type_ck CHECK (type IN ('API', 'HTML')),
|
|
CONSTRAINT gov_source_active_ck CHECK (active IN (0, 1))
|
|
);
|
|
|
|
-- ============================================================
|
|
-- gov_opportunity : 수집된 공고. (source_code, external_id) 로 중복 제거.
|
|
-- external_id 는 항상 채운다. HTML 소스는 detail_url 해시로 채운다.
|
|
-- ============================================================
|
|
CREATE TABLE gov_opportunity (
|
|
id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
|
|
source_id RAW(16) NOT NULL,
|
|
source_code VARCHAR2(50) NOT NULL, -- 비정규화(조회 편의)
|
|
external_id VARCHAR2(200) NOT NULL, -- 소스 고유 키(pbancSn 등) 또는 detail_url 해시
|
|
title VARCHAR2(1000 CHAR) NOT NULL,
|
|
agency VARCHAR2(300 CHAR), -- 소관/주관기관
|
|
category VARCHAR2(200 CHAR), -- 지원분야
|
|
target VARCHAR2(1000 CHAR), -- 지원대상
|
|
apply_start DATE,
|
|
apply_end DATE,
|
|
detail_url VARCHAR2(1000),
|
|
body_text CLOB, -- 상세 본문(스크랩)
|
|
raw_json CLOB, -- 원본 API/스크랩 데이터
|
|
status VARCHAR2(20) DEFAULT 'LISTED' NOT NULL, -- LISTED | DETAILED | CLOSED | ERROR
|
|
list_collected_at TIMESTAMP, -- 목록 수집 시각
|
|
detail_collected_at TIMESTAMP, -- 상세 수집 시각
|
|
created_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL,
|
|
CONSTRAINT gov_opp_source_fk FOREIGN KEY (source_id) REFERENCES gov_source (id),
|
|
CONSTRAINT gov_opp_dedup_uq UNIQUE (source_code, external_id),
|
|
CONSTRAINT gov_opp_status_ck CHECK (status IN ('LISTED', 'DETAILED', 'CLOSED', 'ERROR'))
|
|
);
|
|
|
|
CREATE INDEX gov_opp_status_ix ON gov_opportunity (status);
|
|
CREATE INDEX gov_opp_apply_end_ix ON gov_opportunity (apply_end);
|
|
CREATE INDEX gov_opp_source_ix ON gov_opportunity (source_id);
|