Repository navigation
feat(funding): add funding:sync with automation settings and source freshness - #37
Merged
Merged
Conversation
Draft ADR 0006 (Proposed) for issue #5. Discovery from the K-Startup and Bizinfo Open APIs produces catalog drafts with reviewer UNASSIGNED; demotions (application end date passed, source changed, removed or closed) apply automatically; promotion to a current candidate still needs a human-reviewed catalog release. AI interpretation of announcement text stays out of scope. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
Rework the draft per the decision to automate both directions: funding:sync builds the catalog from the K-Startup and Bizinfo APIs and promotes non-loan announcements whose dates, stage and region come from structured fields. Industry and purpose UNKNOWN become pre-application checks instead of blocking. Loans and guarantees stay human-reviewed. Source failures keep the current release, and auto products drop out when syncs stop for more than three days. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
Support programs (grant, space, program) are automated from the K-Startup API. Policy loans and guarantees have no official API, so they are automated by crawling the SEMAS and Seoul Shinbo pages under explicit rules: robots.txt and terms checked per source, public pages only, once a day, no evasion when blocked. Repayment calculation is auto-promoted only when the page states a single fixed rate, term, grace and method; variable-rate loans stay non-calculable. Each track has its own promotion switch, and a failing source keeps its last products until they go stale after three days. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
Mark ADR 0006 Accepted with jhjh0512 as owner, and state that the follow-up doc changes in section 9 land with the implementation PRs (AGENTS.md section 7), not with this decision. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
…feat/funding-pre-application-checks
…hecks Per ADR 0006, industry and purpose are conditions no official source gives in structured form, so an UNKNOWN verdict on them no longer keeps a product out of the current candidates. They are added to manualChecks as "업종: ..." / "용도: ..." and counted in the candidate reason, while eligibilityVerdict stays UNKNOWN. An UNKNOWN business stage or region still means NEEDS_CONFIRMATION, and any FAIL still means NOT_ELIGIBLE. AGENTS.md section 3 item 8 now points to ADR 0006 for this case, and funding.md and the candidate group notes describe the new split. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
…feat/funding-pre-application-checks
Record the 2026-09-28 checks of real API responses, robots.txt and terms. K-Startup would surface 116 mostly unrelated current candidates for a Seoul pre-founder, so support programs are discovered through Bizinfo and promoted only by a person. Policy loans are crawled from the SEMAS policy fund site, including its notice list JSON to locate notice pages. Sbiz24's internal API is not used, and Seoul development funds stay human-managed because their terms exist only in HWP attachments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…feat/funding-pre-application-checks
…reshness Implements the source-agnostic half of ADR 0006 so a policy-fund crawler can plug in as a FundingSourceAdapter. - Catalog schema funding-catalog-v1.1.0 adds sourceRef on products and an automation block (policy loan and repayment promotion switches, blocked sources, per-source sync results). v1.0.0 releases stay readable with every switch off. The release stores automation in a new JSONB column. - Automated products (reviewer AUTO:funding-auto-v1) are judged by the source's last successful sync instead of nextReviewAt and drop to REVIEW_OVERDUE after three days. Blocked notices, automated support programs, and promotion switched off keep them in NEEDS_CONFIRMATION with the reason. The repayment switch gates repayment support, and the loan-assumption route now checks the evaluation instead of the product. - funding:sync collects per source, reuses immutable product versions when only dates change, keeps the previous products and last success date when a source fails (error, empty, drop below half, validation), lets a manual record override the same notice, and loads the merged catalog through the existing PENDING to ACTIVE loader. No source adapter is registered yet. - catalog.json moves to v1.1.0 as 2026-09-28.1 with both switches off; product versions are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
Base automatically changed from
feat/funding-pre-application-checks
to
main
September 28, 2026 14:28
Resolve AGENTS.md and eligibility.ts in favor of this branch: main holds the squashed #36 version, and this branch already contains #36 plus the #37 changes on the same lines. The merged tree is identical to ba3ac46. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
This was referenced Sep 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
관련: ADR 0006(#33) 2·4·5·6·7절. 별도 Issue는 없다.
#36 위에 쌓은 PR이다(#33 → #36 → 이 PR). 두 PR이 병합되면 GitHub가 base를 main으로 바꾸고, 그 뒤 main을 합쳐 diff를 정리한다. #33·#36보다 먼저 병합하지 않는다.
소진공 정책자금 크롤러 가운데 출처와 상관없는 절반이다. 이 작업 환경은 네트워크 정책 때문에
ols.semas.or.kr에 접속하지 못해, 실제 HTML이 필요한 수집기(파서)는 다음 PR로 나눴다. 이 PR은 수집기를FundingSourceAdapter로 꽂기만 하면 되도록 동기화·판정·저장을 준비한다.변경 내용
funding-catalog-v1.1.0sourceRef(출처·공고 식별자)를 추가했다. 기본값을 두지 않아서, 이 필드가 없는 기존 상품 버전의 저장 내용은 바뀌지 않는다.automation을 추가했다. 정책자금 자동 승격·상환 계산 자동 승격 스위치, 차단 목록, 출처별 동기화 결과를 담는다. 두 스위치는 기본으로 꺼져 있다.AUTO:…), 같은 공고를 가리키는 상품 두 개, 같은 출처의 동기화 결과 두 개. 자동 상품은 다음 검토일이 없어도 된다.funding_catalog_releases.automation(JSONB, nullable)을 추가하고, 적재기가 이 열을 저장한다.eligibility.ts,types.ts): 검수자가AUTO:funding-auto-v1인 상품에만 적용한다.REVIEW_OVERDUE이고, 사유에 출처와 마지막 성공일을 적는다.NEEDS_CONFIRMATION으로 두고 사유를 표시한다: 차단 목록의 공고, 지원사업(지원금·공간·프로그램) 자동 상품, 정책자금 자동 승격이 꺼진 상태.sourceRef가 있어도 지금 규칙을 그대로 따른다.evaluation.repayment)로 확인한다. 이렇게 해서 상환 계산 스위치를 우회할 수 없게 했다.funding:sync(sync.ts,scripts/sync-funding.ts)catalog.json의 상품과 합친 뒤, 기존 적재기(PENDING → ACTIVE)로 적재한다.sourceRef)를 가리키면 자동 상품을 뺀다.catalog.json에 자동 검수자 상품이 있으면 거부한다.동기화한 날.번호다. 같은 날 적재된 릴리스와catalog.json의 버전을 피해 번호를 올린다. 이렇게 해야 같은 날funding:load와 충돌하지 않는다.data/funding-sync/(Git 제외)에 남는다.--dry-run은 파일을 쓰고 검증만 한다.catalog.json만 새 릴리스로 적재한다.catalog.json: v1.1.02026-09-28.1로 올리고automation을 명시했다(두 스위치 모두 꺼짐). 상품 내용과 상품 버전(1.0.1)은 바뀌지 않는다.docs/domains/funding.md: 스키마, 동기화 규칙, 자동 상품 판정, 수집 출처와 허용 확인 기록(소진공 2026-09-28)을 적었다.DEVELOPMENT.md:funding:sync실행 방법을 적었다.sync.test.ts를 더했다.검증
npm --prefix app run verify:fast통과: 카탈로그 검증, Prettier, ESLint, TypeScript, 테스트, build.sync.test.ts의 DB 테스트다.verify:db는 돌리지 못했다. 대신 로컬 PostgreSQL 16에 migration을 적용하고 DB 모드를 직접 실행했다(run-tests.ts database). 287 passed, 6 skipped(data/raw/없음)였다.prisma migrate diff --from-config-datasource --to-schema는 빈 migration이었다. migration과 schema가 일치한다는 뜻이다.funding:sync --dry-run과 실제 적재를 실행했다. 사람이 기록한 상품 5건이 ACTIVE 릴리스로 적재됐다.npm --prefix app run verify를 한 번 돌려 보기를 권한다.위험·후속
funding:load가 아니라funding:sync를 써야 한다.funding:load로catalog.json만 적재하면 자동 상품이 빠진다(카탈로그 README).ols.semas.or.kr파서, 크롤링 규칙: 하루 한 번, 1초 간격, User-Agent 연락처, 403·429·CAPTCHA 시 중단)를 등록하는 PR이 이어진다. 이 환경에서 그 호스트에 접속할 수 있어야 한다.🤖 Generated with Claude Code
https://claude.ai/code/session_015LCE4DgT5qdHP8y8V5qtbL
Generated by Claude Code