Files
sundol/government/scripts/export_eligible_csv.js
joungmin cdce7b86bb gov-scraper: 마스터 사업계획서 + 공고 매칭/추출 스크립트 추가
- docs/business-plans.md: Tasteby/Lyricsy/Parents Story 3개 앱 PSST 사업계획서 초안
- scripts/match.js: 앱별 주제 키워드 매칭 조회
- scripts/eligible.js: 예비창업자 자격 + 현재 열린 공고 목록
- scripts/export_eligible_csv.js: 신청 추적용 CSV(exports/) 생성
- exports/ gitignore

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 07:24:39 +00:00

69 lines
2.3 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 예비창업자 자격 + 현재 열린 공고 전체를 CSV 로 내보낸다(신청 추적용).
// 실행: LD_LIBRARY_PATH=$ORACLE_IC_LIB_DIR node scripts/export_eligible_csv.js
import { writeFile, mkdir } from 'node:fs/promises';
import { withConnection, closePool, oracledb } from '../src/db.js';
const SQL = `
SELECT * FROM (
SELECT title, category, agency, source_code, detail_url, apply_start, apply_end,
CASE WHEN apply_end IS NULL THEN 9999 ELSE (apply_end - TRUNC(SYSDATE)) END AS dleft,
ROW_NUMBER() OVER (PARTITION BY title ORDER BY CASE source_code WHEN 'kstartup' THEN 1 WHEN 'bizinfo' THEN 2 ELSE 3 END) rn
FROM gov_opportunity
WHERE (apply_end IS NULL OR apply_end >= TRUNC(SYSDATE))
AND (
target LIKE '%' || :k1 || '%' OR target LIKE '%' || :k2 || '%'
OR DBMS_LOB.INSTR(body_text, :k1) > 0 OR DBMS_LOB.INSTR(body_text, :k2) > 0
)
)
WHERE rn = 1
ORDER BY dleft ASC, source_code`;
function csvCell(v) {
if (v == null) return '';
const s = String(v).replace(/"/g, '""').replace(/\r?\n/g, ' ');
return `"${s}"`;
}
function ymd(d) {
return d ? new Date(d).toISOString().slice(0, 10) : '';
}
function region(title) {
const m = /^\[([^\]]{1,8})\]/.exec(title);
return m ? m[1] : '';
}
const rows = await withConnection(async (conn) => {
const r = await conn.execute(
SQL,
{ k1: '예비창업', k2: '예비 창업' },
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
return r.rows;
});
await closePool();
const header = ['신청완료', 'D-day', '마감일', '지역', '분야', '주관기관', '소스', '제목', '링크'];
const lines = [header.map(csvCell).join(',')];
for (const x of rows) {
lines.push(
[
'',
x.DLEFT === 9999 ? '상시' : `D-${x.DLEFT}`,
x.DLEFT === 9999 ? '상시/예산소진' : ymd(x.APPLY_END),
region(x.TITLE),
x.CATEGORY || '',
x.AGENCY || '',
x.SOURCE_CODE,
x.TITLE,
x.DETAIL_URL || '',
]
.map(csvCell)
.join(',')
);
}
await mkdir(new URL('../exports/', import.meta.url), { recursive: true });
const out = new URL('../exports/eligible_opportunities.csv', import.meta.url);
// 엑셀 한글 깨짐 방지 BOM
await writeFile(out, '' + lines.join('\n'), 'utf8');
console.log(`내보냄: ${rows.length}건 → government/exports/eligible_opportunities.csv`);