gov-scraper: 신청 체크리스트(apply-checklist.md) 추가
- docs/apply-checklist.md: 예비창업자 자격 + 현재 열린 공고 252건, 마감일 그룹별 체크박스 + URL - scripts/generate_checklist.js: DB에서 체크리스트 재생성(추적 대상 docs/에 출력) - 신청 완료 시 [x] 체크하며 진행, 스크립트로 갱신 가능 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
74
government/scripts/generate_checklist.js
Normal file
74
government/scripts/generate_checklist.js
Normal file
@@ -0,0 +1,74 @@
|
||||
// 예비창업자 자격 + 현재 열린 공고를 마감일 그룹별 체크리스트(Markdown)로 생성.
|
||||
// git 추적 대상인 docs/apply-checklist.md 에 저장 → 신청 완료 시 [x] 체크하며 진행.
|
||||
// 실행: LD_LIBRARY_PATH=$ORACLE_IC_LIB_DIR node scripts/generate_checklist.js
|
||||
import { writeFile } 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_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 region(title) {
|
||||
const m = /^\[([^\]]{1,8})\]/.exec(title);
|
||||
return m ? `\`${m[1]}\` ` : '';
|
||||
}
|
||||
function ymd(d) {
|
||||
return d ? new Date(d).toISOString().slice(0, 10) : '';
|
||||
}
|
||||
function line(x) {
|
||||
const dtag = x.DLEFT === 9999 ? '상시' : `D-${x.DLEFT}`;
|
||||
const deadline = x.DLEFT === 9999 ? '상시/예산소진' : ymd(x.APPLY_END);
|
||||
const cat = x.CATEGORY ? `[${x.CATEGORY}] ` : '';
|
||||
const title = x.TITLE.replace(/\s+/g, ' ').trim();
|
||||
return `- [ ] **${dtag}** (${deadline}) ${region(x.TITLE)}${cat}[${title}](${x.DETAIL_URL}) — ${x.AGENCY || ''}`;
|
||||
}
|
||||
|
||||
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 buckets = {
|
||||
'🔴 이번 주 마감 (D-0 ~ D-7)': (d) => d <= 7,
|
||||
'🟡 2주 내 (D-8 ~ D-14)': (d) => d >= 8 && d <= 14,
|
||||
'🟢 여유 (D-15 이상)': (d) => d >= 15 && d !== 9999,
|
||||
'⏳ 상시 접수 (마감 압박 없음)': (d) => d === 9999,
|
||||
};
|
||||
|
||||
const today = new Date().toISOString().slice(0, 10);
|
||||
const out = [];
|
||||
out.push('# 정부지원사업 신청 체크리스트');
|
||||
out.push('');
|
||||
out.push(`> 생성일: ${today} · 대상: **예비창업자 자격 + 현재 신청 가능** 공고 (총 ${rows.length}건)`);
|
||||
out.push('> 신청을 마치면 `[ ]` → `[x]` 로 체크하세요. 갱신: `LD_LIBRARY_PATH=$ORACLE_IC_LIB_DIR node scripts/generate_checklist.js`');
|
||||
out.push('> ⚠️ 마감 "시각"과 정확한 자격요건은 각 공고 원문에서 반드시 확인하세요.');
|
||||
out.push('');
|
||||
|
||||
for (const [title, pred] of Object.entries(buckets)) {
|
||||
const group = rows.filter((x) => pred(x.DLEFT));
|
||||
if (group.length === 0) continue;
|
||||
out.push(`## ${title} — ${group.length}건`);
|
||||
out.push('');
|
||||
for (const x of group) out.push(line(x));
|
||||
out.push('');
|
||||
}
|
||||
|
||||
const path = new URL('../docs/apply-checklist.md', import.meta.url);
|
||||
await writeFile(path, out.join('\n'), 'utf8');
|
||||
console.log(`생성: ${rows.length}건 → government/docs/apply-checklist.md`);
|
||||
Reference in New Issue
Block a user