chore: 저장소 구조 정리 및 문서화, 첫 커밋

- src/dist 산출물 분리 원칙 정리(.gitignore, .gitattributes)
- 루트 및 주요 폴더(config/scripts/prompts/tests/src, 런타임 폴더 5종)에
  안내용 README.md 추가
- CHANGELOG.md, LICENSE, docs/ops/05-release-and-versioning.md 추가
- docs/README.md 문서 지도 갱신
This commit is contained in:
Yun Chan 2026-09-04 09:25:44 +09:00
commit 56a6e2da93
159 changed files with 145825 additions and 0 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,401 @@
# 공식 데이터 제공 요청 채널과 승인 절차
> **이 문서의 역할**: DMF_Crawler 가 식약처 원료의약품 등록(DMF) 오픈API 에서 받지 못하는 6개 필드(`최종변경일자`, `최종연차보고년도`, `취소/취하구분`, `취소/취하일자`, `문서번호`, `대상의약품`)를 **웹 크롤링 없이 공식 절차로 확보**하기 위한 채널을 조사하고, 실제로 발송 가능한 요청 문구 초안까지 준비한다. 이 프로젝트는 `nedrug.mfds.go.kr``robots.txt`(`User-agent: * / Disallow: /`, 2026-09-02 실측, `docs/research/04-anti-bot-and-legal.md` §4 참조)를 존중하기로 이미 확정했으며([`design/00-DATA-SOURCE-DECISION.md`](../design/00-DATA-SOURCE-DECISION.md)), 이 문서는 그 결정을 되돌리지 않는다. 대신 "화면에만 있고 API 에 없는 6개 필드"를 합법적·공식적 채널로 요청하는 구체적 실행 계획을 제공한다.
---
## 0. 한눈에 보기
- **이 프로젝트가 실제로 취할 행동(1순위)**: 공공데이터포털 DMF 데이터셋 상세 페이지(`https://www.data.go.kr/data/15057075/openapi.do`)의 **"데이터 개선요청"** 기능으로 API 응답 항목에 6개 필드 추가를 요청한다. 관리부서가 **데이터혁신기획팀**으로 명시돼 있어 요청이 담당 부서로 직접 라우팅될 가능성이 가장 높고, 비용이 0원이며, 접수 즉시 처리가 시작된다. §11 에 발송 가능한 요청 문구 초안을 완성해 두었다.
- **2순위**: 1순위 요청 후 2주 내 응답이 없거나 거부되면, 식약처 **종합상담센터(1577-1255)** 를 통해 **데이터혁신기획팀** 앞 민원으로 재요청하거나, **국민신문고(epeople.go.kr)** 를 통해 동일 내용을 정식 민원으로 접수한다. 국민신문고는 처리기한이 법정으로 정해져 있어(⚠️ 정확한 일수는 미검증, §6 참조) 응답 강제력이 공공데이터포털 1:1문의보다 크다.
- **3순위(백업, 일회성)**: **정보공개청구**(`open.go.kr`, 근거: 「공공기관의 정보공개에 관한 법률」)로 현재 시점의 6개 필드 값을 전자파일(엑셀/CSV)로 청구한다. 정부24 안내 기준 처리기한은 "기본 20일"이며 수수료는 전자파일 복제 시 무료(매체비용 별도)다. **단, 이 채널은 정기 자동 수집에 부적합하다 — 이유는 §1.3, §6.3 참조.**
- **웹 크롤링/robots.txt 예외 요청은 이 프로젝트의 행동 계획에 포함하지 않는다.** 조사는 했으나(§10) 실효성이 낮고, 이미 API 우선 원칙이 확정돼 있어 우선순위가 낮다.
- **식의약 데이터 포털(`data.mfds.go.kr`)은 DMF 관련 데이터셋을 메인 화면에서 확인하지 못했다.** 로그인 후 재확인이 필요하며, 현재는 대안 채널로 채택하지 않는다(§8).
- **확인된 담당 연락처는 제한적이다.** 공공데이터포털 데이터셋 페이지에 "관리부서 전화번호" 항목은 있으나 실제 번호가 비어 있었고, 식약처 조직도에서 데이터혁신기획팀은 부서명만 확인되고 전화번호는 미기재였다. 직통 번호가 없으므로 **공공데이터포털 고객센터(1566-0025, opendata_help@nia.or.kr)** 또는 **식약처 종합상담센터(1577-1255)** 를 경유해야 한다.
- **법령 조문의 정확한 조 번호·일수는 이번 조사에서 원문 확인에 실패했다.** `law.go.kr` 이 자바스크립트 기반 SPA 로 렌더링되어 자동 조회 도구로는 조문 텍스트를 가져오지 못했다. 이 문서의 법령 관련 서술은 **정부24·공공데이터포털 등 2차 안내 페이지에서 실제로 확인한 내용**으로 한정했고, 조문 번호가 필요한 부분은 ⚠️ 미검증으로 표시했다.
---
## 1. 문제 정의
### 1.1 데이터 격차
DMF_Crawler 는 식약처 공식 오픈API 로 원료의약품 등록(DMF) 데이터를 수집한다.
| 구분 | 내용 |
|---|---|
| API 엔드포인트 | `https://apis.data.go.kr/1471000/MdcDmfInfoService01/getMdcDmfList01` |
| 공공데이터포털 데이터셋 | `https://www.data.go.kr/data/15057075/openapi.do` (ID `15057075`) |
| API 응답 필드(7개) | `DMF_PERMIT_NO`, `INGR_KOR_NAME`, `ENTP_NAME`, `MNFCTR_NAME`, `MNFCTR_PLACE`, `MANUF_COUNTRY_CODE_NM`, `DMF_PERMIT_DATE` |
| 웹 화면(의약품안전나라) 컬럼 | 14개 — API 7개 필드 + 아래 6개 필드 |
같은 데이터를 사람이 웹 화면에서 조회하면 컬럼이 14개인데, API 응답은 7개뿐이다. 화면에만 있고 API 에 없는 6개 컬럼이 이 프로젝트의 핵심 기능(변경·취하 탐지)에 직결된다.
| 화면 전용 컬럼 | 이 프로젝트에서의 의미 |
|---|---|
| `최종변경일자` | 변경 탐지의 **직접 신호**. 현재는 API 스냅샷을 매일 전량 받아 자체 diff 로 변경을 추론하는 간접 방식을 쓴다(`design/00-DATA-SOURCE-DECISION.md` §7). |
| `최종연차보고년도` | 연차보고 이벤트 추적에 필요. API 에는 대응 필드가 없다. |
| `취소/취하구분`(실측값 예: `정상`) | **취하 탐지의 직접 신호.** 현재는 "어제는 있었는데 오늘 없는 등록번호"를 취하로 추론하는 간접 방식이며, 전량 수집이 불완전하면 오판 위험이 있다(§7.2 안전장치, 같은 문서). |
| `취소/취하일자` | 취하 이벤트의 정확한 발생일. |
| `문서번호` | 등록 건의 행정 문서 추적키. |
| `대상의약품`(`별표1`/`신물질`) | 규제 분류. 현재 API 에는 없음. |
### 1.2 왜 웹 크롤링을 하지 않는가
`nedrug.mfds.go.kr/robots.txt``User-agent: * / Disallow: /` 로 전면 금지다(2026-09-02 실측, `docs/research/04-anti-bot-and-legal.md` §4). 이 프로젝트는 이미 **robots.txt 를 우회하지 않고, 공식 API 를 1차 소스로 채택**하기로 확정했다(`design/00-DATA-SOURCE-DECISION.md`). 이 결정을 뒤집지 않는 것이 이 조사의 전제다.
### 1.3 왜 "공식 절차로 요청"이 필요한가
크롤링을 배제한 이상, 6개 필드를 확보하는 유일하게 남은 길은 **공식 창구를 통해 데이터 제공 주체(식약처)에게 직접 요청**하는 것이다. 이 문서는 그 창구들을 비교하고, 이 프로젝트의 요구사항(① API 항목 추가가 최선, ② 안 되면 정기적 파일 제공, ③ 최후 수단으로 일회성 정보공개청구)에 맞는 우선순위를 정한다.
**정보공개청구가 정기 자동 수집에 부적합한 이유**는 명확하다. 「공공기관의 정보공개에 관한 법률」에 따른 청구는 **건별로 접수·심사·결정하는 절차**이며, 정부24 안내 기준으로도 처리에 기본 20일이 걸린다(§6.3). 매일 자동으로 갱신되는 DMF 현황 데이터를 일일 단위로 정보공개청구로 받으려면 **매일 새 청구를 접수하고 매일 최대 20일을 기다려야 하는 구조적 모순**이 생긴다. 청구권자가 기관인지 개인인지를 떠나, 이 법은애초에 "특정 시점의 특정 정보"를 1회성으로 공개받기 위한 제도이지 상시·자동·반복 제공을 전제한 제도가 아니다. 따라서 정보공개청구는 **API 항목 추가 요청이 지연되거나 거부됐을 때, 현재 시점의 6개 필드 스냅샷 1회를 확보해 급한 불을 끄는 백업 수단**으로만 유효하다.
---
## 2. 채널 비교표
| 채널 | 근거(확인된 범위) | 신청 방법 | 처리기한 | 정기 제공 가능 여부 | 이 프로젝트 적합도 | 권고 순위 |
|---|---|---|---|---|---|---|
| 공공데이터포털 "데이터 개선요청" | 데이터셋 상세 페이지 내 기능(URL 미확인, §4) | 로그인 후 데이터셋 페이지에서 의견 등록 | ⚠️ 미검증 | 요청이 반영되면 **API 자체가 바뀌므로 자동으로 정기 제공됨** | 매우 높음 — 담당부서(데이터혁신기획팀) 직행 가능성 | **1순위** |
| 공공데이터포털 "공공데이터 제공신청" | 「공공데이터의 제공 및 이용 활성화에 관한 법률」(추정, 조문 미검증) | 메인 메뉴 존재 확인, 정확한 신청 URL 은 자바스크립트 처리로 미확인(§3) | ⚠️ 미검증 | 신규 데이터셋 개방 요청 제도 — 기존 API 의 "항목 추가"에도 쓰이는지는 미검증 | 중간 — 절차는 있으나 실제 URL·양식 미확인 | 2순위(1순위 병행 시도) |
| 식약처 데이터혁신기획팀 직접 문의(전화/민원) | 조직도상 부서 실존 확인(§7) | 종합상담센터(1577-1255) 경유 또는 부서명 지정 민원 | ⚠️ 미검증 | 담당자 확답 시 가능 | 높음 — 관리부서 자체 | 2순위 |
| 국민신문고(epeople.go.kr) | 「민원 처리에 관한 법률」(추정, 조문 미검증) | 사이트 자바스크립트 SPA 로 상세 메뉴 확인 실패(§6) | ⚠️ 미검증 | 요청 취지에 따라 다름 | 중간 — 법정 절차라 응답 강제력은 있으나 상세 미확인 | 3순위 |
| 정보공개청구(open.go.kr / 정부24) | 「공공기관의 정보공개에 관한 법률」 | 정부24 안내 페이지에서 청구방법 확인(§6.3) | 기본 20일(정부24 안내, 조문 번호 미검증) | **부적합**(§1.3) | 낮음(정기 수집 기준) / 높음(일회성 백업 기준) | 4순위(백업 전용) |
| 식약처 정보공개제도 사전 청구 | 식약처 자체 정보공개 메뉴(`/wpge/m_11/de010101l0001.do`, URL 확인됨) | 미확인(§7) | ⚠️ 미검증 | ⚠️ 미검증 | ⚠️ 미검증 | 참고용 |
| 식의약 데이터 포털(data.mfds.go.kr) | 식약처 운영 별도 포털(존재 확인) | 회원가입 후 "데이터셋 분양" 메뉴(§8) | ⚠️ 미검증 | ⚠️ 미검증 — DMF 데이터셋 존재 자체가 메인 화면에서 미확인 | 낮음(현재 근거 부족) | 참고용 |
| robots.txt 예외 요청 | 관행(법적 근거 없음, RFC 9309 는 자발적 준수 규범) | 사이트 운영자 연락 — 구체적 창구 미확인 | 해당 없음 | 승인돼도 크롤링 허용일 뿐, API 필드 추가와 무관 | 낮음 | 채택 안 함 |
---
## 3. 채널 A — 공공데이터포털 "공공데이터 제공신청" / "분쟁조정 신청"
### 3.1 확인된 사실
`https://www.data.go.kr` 메인 메뉴 구조를 실제로 열어 확인한 결과, **"공공데이터"** 대분류 아래 다음 항목이 존재한다.
```
공공데이터
├── AI 검색
├── 데이터목록
├── 데이터 큐레이션
├── 국가중점데이터
├── 공공데이터 제공신청 ← 이 절의 대상
└── 분쟁조정 신청
```
"분쟁조정 신청"의 실제 링크는 `/tcs/dor/insertTrublMdatReqstProcssView.do` 로 확인됐다. 페이지 내 안내 문구에는 **"공공데이터 제공을 거부당했을 때 분쟁조정신청을 할 수 있다"**는 취지가 명시돼 있어, 이 메뉴는 **공공데이터제공분쟁조정위원회**로 이어지는 창구로 보인다.
반면 **"공공데이터 제공신청"** 항목은 여러 차례 HTML 을 직접 열어 `href`/`onclick` 속성을 확인했으나, 두 경우 모두 `href="#"` 로만 나타났고 실제 이동 대상 URL 은 자바스크립트로 동적 처리돼 자동 조회 도구로는 확인하지 못했다. ⚠️ **미검증: 정확한 신청 URL, 신청 양식 항목, 처리기한.**
### 3.2 추정되는 절차 (⚠️ 미검증 — 근거 없이 확정하지 말 것)
"공공데이터 제공신청" 제도는 명칭상 **공공데이터포털에 아직 개방되지 않은 데이터를 새로 개방해달라고 요청하는 제도**로 보인다. 이것이 "이미 개방된 API 의 항목을 추가해달라"는 이 프로젝트의 요구사항과 정확히 일치하는지는 이번 조사에서 확인하지 못했다. **DMF API 는 이미 개방된 데이터셋이므로, 이 창구보다는 §4 의 "데이터 개선요청"(기존 데이터셋에 대한 의견 제출 기능)이 이 프로젝트의 목적에 더 정확히 맞을 가능성이 높다.**
### 3.3 이 채널을 이용해야 할 경우
만약 §4 의 데이터 개선요청이 응답 없이 종료되거나 "항목 추가는 개선요청 대상이 아니다"라는 답변을 받는다면, 그때 실제로 `data.go.kr` 사이트에 로그인해 "공공데이터 제공신청" 메뉴를 직접 열어 정확한 절차를 재확인해야 한다. 이 문서에서 추정으로 절차를 서술하지 않는 이유는, 팀 지침("연락처나 절차를 기억으로 채우지 마라")을 따르기 위함이다.
### 3.4 분쟁조정 신청(공공데이터제공분쟁조정위원회)
이 채널은 **"제공을 신청했지만 거부당했을 때"** 쓰는 이의절차이지, 최초 요청 채널이 아니다. 따라서 이 프로젝트는 우선 §4·§7 로 요청을 시도하고, **명시적으로 거부 통보를 받은 경우에만** 분쟁조정 신청(`/tcs/dor/insertTrublMdatReqstProcssView.do`)을 검토한다. 조정위원회의 정확한 심의 절차, 기간, 결정의 구속력은 이번 조사에서 원문을 확인하지 못했다. ⚠️ 미검증.
---
## 4. 채널 B — 공공데이터포털 데이터셋 페이지 "데이터 개선요청" (1순위 채택)
### 4.1 확인된 사실
DMF 데이터셋 상세 페이지(`https://www.data.go.kr/data/15057075/openapi.do`)를 직접 열어 다음을 확인했다.
- **제공기관**: 식품의약품안전처
- **관리부서명**: **데이터혁신기획팀**
- **관리부서 전화번호**: 항목 자체는 페이지에 있으나 **실제 번호가 비어 있음**(미기재)
- 페이지 내 버튼/링크: **"활용신청"**, "관심목록에 추가"
- 페이지 하단 섹션 "데이터 오류·개선 의견이 있으신가요?" 아래 **"데이터 개선요청"**, **"오류신고 및 문의"** 두 개의 항목이 확인됨
- 위 두 항목의 정확한 `href`/`onclick` URL 은 자동 조회로 확인하지 못했다(로그인 후 노출되는 모달/폼일 가능성). ⚠️ 미검증
- 공공데이터포털 전체 고객센터: **전화 1566-0025**, **이메일 opendata_help@nia.or.kr** (페이지 하단 확인)
### 4.2 왜 이 채널을 1순위로 두는가
1. **관리부서가 명시적으로 데이터혁신기획팀**이다. 다른 채널(국민신문고, 정보공개청구)은 접수창구가 별도 부서를 거쳐 담당 부서로 재배정되는 구조지만, 이 채널은 데이터셋 페이지에 직접 달린 의견 기능이라 **담당 부서로 직행할 가능성이 가장 높다.**
2. 비용이 없고, 계정만 있으면 즉시 접수된다.
3. 반영되면 **API 응답 자체가 바뀌므로**, 이후 이 프로젝트가 매일 API 를 호출하는 것만으로 6개 필드가 자동으로 들어온다. 정보공개청구처럼 매번 재청구할 필요가 없다.
### 4.3 실행 절차 (확인된 범위)
1. `https://auth.data.go.kr/sso/login` 에서 공공데이터포털 계정으로 로그인한다(회원가입 필요 시 포털 내 가입 절차를 따른다 — 이번 조사에서 가입 절차 자체는 확인하지 않음, ⚠️ 미검증).
2. `https://www.data.go.kr/data/15057075/openapi.do` 로 이동한다.
3. "데이터 오류·개선 의견이 있으신가요?" 섹션에서 **"데이터 개선요청"**을 클릭한다(정확한 폼 화면은 로그인 후에만 노출되어 이번 조사에서 화면 구성까지는 확인하지 못했다).
4. §11.1 의 요청 문구 초안을 작성해 제출한다.
5. 응답이 없거나 "이 창구 대상이 아니다"라는 답변을 받으면 "오류신고 및 문의" 또는 공공데이터포털 고객센터(1566-0025 / opendata_help@nia.or.kr)로 재문의한다.
---
## 5. 채널 C — 공공데이터포털 "활용신청" (참고 — 이미 사용 중일 가능성)
데이터셋 페이지의 "활용신청" 버튼은 **API 이용 자체를 신청하는 절차**(인증키 발급 등)로 보이며, DMF_Crawler 는 이미 이 API 를 호출하고 있으므로 이 절차는 이미 완료됐을 것으로 추정된다. 항목 추가와는 무관한 기능이다. 별도 조치 불필요.
---
## 6. 채널 D — 국민신문고(epeople.go.kr) 및 정보공개청구(open.go.kr)
### 6.1 국민신문고 — 확인 시도와 한계
`https://www.epeople.go.kr` 를 여러 방식으로 열어봤으나, 이 사이트는 **자바스크립트 기반 SPA(단일 페이지 애플리케이션)로 구축돼 있어 자동 조회 도구(WebFetch)로는 페이지 제목 외의 실질적 콘텐츠를 가져오지 못했다.** 메뉴 구조, 민원 신청 폼의 정확한 URL, 처리기한 안내 문구를 이번 조사에서 확인하지 못했다. ⚠️ **미검증 — 메뉴 경로, 처리기한, 민원 유형별 차이 전부.**
**확인된 것은 도메인 자체(`epeople.go.kr`)뿐이다.** 실제 활용 시에는 담당자가 직접 브라우저로 접속해 "민원신청" 메뉴를 찾아 진행해야 한다.
### 6.2 국민신문고를 통한 요청의 실익
법적 근거를 원문으로 확인하지는 못했으나, 국민신문고는 정부 부처 횡단 민원 접수 시스템이므로 접수 후 **식약처로 이송되고, 부처는 법정 처리기한 내에 답변할 의무**를 진다고 알려져 있다(⚠️ 정확한 일수·근거 조문은 이번 조사로 원문 확인 못함, 팀 지침에 따라 확정 서술 보류). 공공데이터포털 1:1문의보다 **응답 강제력이 강할 가능성**이 있어 2순위 채택 이유가 된다.
### 6.3 정보공개청구 — 확인된 내용
`open.go.kr` 자체 페이지는 SPA 구조로 직접 조회에 실패했으나, **정부24의 정보공개청구 안내 페이지**(`https://www.gov.kr/mw/AA020InfoCappView.do?CappBizCD=13110000037`)를 열어 다음을 확인했다.
| 항목 | 확인된 내용 |
|---|---|
| 청구 방법 | 인터넷, 방문, FAX, 우편, 민원우편 |
| 처리기한 | **"기본 20일"**(정부24 페이지 원문 표현). 연장 사유로 "정보량이 많을 때 5일 이하 연장", "추가 검토 필요 시 6일 이상 연장", "대량 정보 공개 시 주·월·년 단위로 기한 재설정"이 안내됨 |
| 수수료 | 문서 사본(종이출력물): A3 이상 300원+초과분 100원/장, B4 이하 250원+초과분 50원/장. **전자파일(문서·도면·사진) 복제는 무료**(매체비용 별도). 오디오·비디오 복제는 1GB당 800원. 열람료는 1일 1시간 이내 무료, 초과 시 30분마다 1,000원 |
| 문의처 | 1588-2188 또는 02-721-0600 (09:00~18:00) |
⚠️ **미검증**: 위 내용의 근거가 되는 정확한 법률 조문 번호(예: 「공공기관의 정보공개에 관한 법률」 제11조, 제15조 등)는 `law.go.kr` 원문 조회 실패로 조문 번호까지는 확인하지 못했다. "기본 20일"이라는 정부24 표현이 "10일 + 10일 연장"을 합산한 것인지, 별도 규정인지도 원문으로 재확인이 필요하다.
**전자파일 제공이 무료로 확인된 점은 이 프로젝트에 유용하다** — 6개 필드의 현재 스냅샷을 엑셀/CSV 로 청구할 때 비용 부담이 없다는 뜻이다. 다만 §1.3 에서 설명한 대로 **정기·자동 제공에는 구조적으로 맞지 않으므로 백업 수단으로만 쓴다.**
### 6.4 식약처 자체 정보공개 메뉴
식약처 메인 페이지에서 다음 메뉴 URL을 확인했다(둘 다 접속 가능한 링크로 확인, 내용 상세는 미확인).
- 정보공개제도: `https://www.mfds.go.kr/wpge/m_11/de010101l0001.do`
- 사전정보공개: `https://www.mfds.go.kr/wpge/m_633/de010102l0002.do`
정부 공통 창구인 `open.go.kr`/정부24와 별도로 식약처 자체 메뉴가 있다는 뜻이며, 두 경로 중 어느 쪽이 이 사안에 더 빠른지는 확인하지 못했다. ⚠️ 미검증.
---
## 7. 채널 E — 식약처 직접 문의처
### 7.1 확인된 연락처
| 연락처 | 확인 경로 | 상태 |
|---|---|---|
| 식약처 종합상담센터 **1577-1255** (유료, 평일 09:00~18:00, 공휴일 제외) | `mfds.go.kr` 메인 페이지 및 조직도 페이지 반복 확인 | ✅ 확인 |
| 데이터혁신기획팀 (부서명) | `mfds.go.kr/wpge/m_271/de010705l0001.do`(조직도) — **기획조정관 산하**로 존재 확인 | ✅ 부서 존재 확인, 전화번호는 페이지에 **미기재** |
| 정보화담당관 (부서명) | 같은 조직도 페이지, 데이터혁신기획팀과 같은 기획조정관 산하 | ✅ 부서 존재 확인, 전화번호 미기재 |
| "허가총괄담당관" 043-719-2312, 2325 / 팩스 043-719-2300 | 팀에서 제공한 배경 정보 — 「원료의약품 등록 제도(DMF) 해설서」 명시 | ⚠️ **이번 조사에서 직접 재검증하지 못함.** 식약처 현재 조직도 페이지에서는 "허가총괄담당관"이라는 명칭의 부서를 찾지 못했고, 대신 **"의약품허가총괄과"**, **"의료기기허가과"**가 확인됐다 — 조직 개편으로 명칭이 바뀌었을 가능성이 있다. 실제 연락 전에 043-719-2312 로 먼저 걸어 현재도 유효한 번호인지 확인 필요. |
| 통합상담예약 | `mfds.go.kr/usr/tCounsel_1024/list.do` | ✅ URL 확인, 상세 절차 미확인 |
| 민원편람 | `mfds.go.kr/brd/m_1208/list.do` | ✅ URL 확인, 내용 미확인 |
| 자주하는 질문 | `mfds.go.kr/brd/m_1060/list.do` | ✅ URL 확인, 내용 미확인 |
| 의약품/화장품전자민원(의약품안전나라) | `nedrug.mfds.go.kr/index` | ✅ 확인 — 법령/자료실, 고시/공고알림, 통합검색 메뉴 존재. DMF 오픈API 전용 메뉴는 확인 안 됨 |
### 7.2 왜 "데이터혁신기획팀 직통 연락처"를 확보하지 못했는가
공공데이터포털 데이터셋 페이지와 식약처 조직도 페이지 **두 곳 모두에서 부서명(데이터혁신기획팀)은 명확히 확인**됐지만, 두 페이지 모두 전화번호 필드가 비어 있거나 표시되지 않았다. 이는 실제로 번호가 없어서가 아니라, **공개 페이지에는 대표 상담센터로 안내를 유도**하는 정책일 가능성이 높다. 따라서 이 프로젝트는 부서명(데이터혁신기획팀)을 명시한 채로 **종합상담센터(1577-1255)** 나 **통합상담예약**을 거쳐 연결을 요청하는 방식을 취해야 한다.
### 7.3 허가총괄담당관 경로에 대한 판단
허가총괄담당관 연락처(043-719-2312, 2325)는 DMF **제도 자체**(등록·심사 실무)를 담당하는 부서로 보이며, 데이터혁신기획팀은 **오픈API·데이터 공개**를 담당하는 부서로 보인다. 이 프로젝트가 요청하는 것은 "API 필드 추가"이므로 **1차 대상은 데이터혁신기획팀**이고, 허가총괄담당관(또는 개편된 의약품허가총괄과)은 "이 6개 필드가 왜 화면에는 있고 API 에는 없는지"에 대한 **제도적 배경을 확인하는 보조 채널**로 병행 문의하는 것이 합리적이다.
---
## 8. 채널 F — 식의약 데이터 포털(data.mfds.go.kr)
### 8.1 확인된 사실
`https://data.mfds.go.kr` 은 식약처가 운영하는 별도의 데이터 포털로 확인됐다. 메인 메뉴 구조는 다음과 같다.
```
data.mfds.go.kr
├── 공공데이터 (목록, 상세, 일상)
├── 파일데이터
├── 데이터활용 (데이터셋 분양, 신청/결과 내역)
├── 경진대회 (참가, 개발사례)
└── 이용안내 (공지사항, 관련 사이트)
```
회원가입 페이지(`/OPAAB01F01`)가 확인됐고, 로그인 화면(`data.mfds.go.kr/OPAAB01F01` 접속 시)에서는 콘텐츠가 제한적으로만 노출됐다.
### 8.2 DMF 데이터셋 존재 여부
메인 화면에 노출된 의약품 관련 데이터로는 DUR품목정보, 의약품 제품 허가정보, 의약품개요정보(e약은요), 임상시험 관련 정보가 확인됐으나, **"DMF" 또는 "원료의약품"을 키워드로 한 데이터셋은 로그인 없이 접근 가능한 범위에서는 발견하지 못했다.** ⚠️ **미검증 — 로그인 후 재확인 필요.**
### 8.3 "데이터셋 분양"의 의미
메뉴명으로 미루어 "데이터셋 분양"은 **공공데이터포털에 개방되지 않은 원본 데이터를 신청자에게 개별 제공(분양)하는 기능**으로 추정되나, 로그인 후에만 상세를 확인할 수 있어 이번 조사로는 신청 대상·절차·처리기한을 확인하지 못했다. ⚠️ 미검증.
### 8.4 이 채널을 참고용으로만 두는 이유
DMF 관련 데이터셋의 존재 자체가 확인되지 않았고, 확인하려면 회원가입과 로그인이 필요해 이번 조사 범위(공개 페이지 확인)를 벗어난다. §4 의 채널이 응답 없이 종료되면, 담당자가 직접 가입해 이 포털의 "데이터셋 분양" 메뉴를 열어 DMF 관련 항목이 있는지 재확인하는 것을 권고한다.
---
## 9. API 항목 추가 요청 선례
이번 조사에서 **다른 공공 API 에서 항목 추가가 실제로 반영된 구체적 사례(기관명, 데이터셋명, 소요 기간)를 찾지 못했다.** 검색 결과 페이지에서는 관련 기관·포털 이름만 스치듯 나왔을 뿐, "항목 추가 요청 → 처리 결과"를 상세히 서술한 문서에 접근하지 못했다. ⚠️ **미검증 — 이 항목은 부록 B 의 우선 재조사 대상으로 남긴다.**
**현실적 기대치에 대한 판단(추정, 근거 자료 없음으로 표시)**: 공공데이터포털의 "데이터 개선요청"은 시민 의견 수렴 성격의 창구이며, API 스키마 변경은 원본 시스템(식약처 내부 DB)과 API 게이트웨이 양쪽의 개발·검증·배포를 수반하는 작업이다. 따라서 접수만으로 즉시 반영되기보다는 **수 주에서 수 개월 단위의 검토 기간**이 걸릴 가능성이 높다고 보되, 이는 확인된 사례가 아니라 일반적인 공공기관 IT 변경관리 관행에 대한 추정이므로 계획에 반영하되(§11 의 "1주 내"·"응답 없을 때" 단계 구성 이유) 확정된 사실로 서술하지 않는다.
---
## 10. robots.txt 예외 요청
### 10.1 조사 결과
"웹사이트 운영자에게 특정 크롤러의 접근을 허용해달라고 요청하는 관행"에 대해 검색을 시도했으나, 유의미한 결과를 얻지 못했다(검색 결과가 무관한 주제로 반환됨). **한국 공공기관을 대상으로 한 robots.txt 예외 요청 사례나 연락처 관행은 이번 조사로 확인하지 못했다.** ⚠️ 미검증.
### 10.2 실효성 평가
이 프로젝트에는 이 채널이 애초에 우선순위가 낮다. 이유는 세 가지다.
1. `design/00-DATA-SOURCE-DECISION.md` 에서 이미 **API 를 1차 소스로 채택**하기로 확정했고, HTML 크롤링은 "API 로 대체 불가능한 공고 게시판"에만 한정하기로 했다(같은 문서 §2 참조 배경).
2. robots.txt 예외를 받아도 **화면 크롤링이 가능해질 뿐, API 응답 필드 자체가 늘어나는 것은 아니다.** 이 프로젝트의 진짜 목표(6개 필드 확보)에는 §4·§7 의 채널이 더 직접적이다.
3. 정부기관 사이트의 robots.txt 예외 요청은 창구 자체가 불분명하고(위 10.1), 승인 여부·기간이 불확실해 계획에 넣기 어렵다.
**결론: robots.txt 예외 요청은 이 프로젝트의 행동 계획에서 제외한다.**
---
## 11. 권고 행동 계획
### 11.1 지금 당장 할 것 — 공공데이터포털 "데이터 개선요청" 제출
**대상**: `https://www.data.go.kr/data/15057075/openapi.do` 의 "데이터 개선요청" (로그인 필요)
**요청 문구 초안** (복사해 그대로 제출 가능하도록 완성):
> **[요청 제목]** 원료의약품등록(DMF) 오픈API(`getMdcDmfList01`) 응답 항목 추가 요청 — 최종변경일자·취소취하구분 등 6개 필드
>
> **[요청 내용]**
>
> 안녕하십니까. 식품의약품안전처_원료의약품등록(DMF)현황 오픈API(`https://apis.data.go.kr/1471000/MdcDmfInfoService01/getMdcDmfList01`, 데이터셋 ID 15057075)를 활용해 제약업계 규제 정보 모니터링 시스템을 운영 중인 이용자입니다.
>
> 귀 포털이 제공하는 오픈API 응답은 `DMF_PERMIT_NO`(등록번호), `INGR_KOR_NAME`(성분명), `ENTP_NAME`(업체명), `MNFCTR_NAME`(제조소명), `MNFCTR_PLACE`(제조소 소재지), `MANUF_COUNTRY_CODE_NM`(제조국가명), `DMF_PERMIT_DATE`(발급일자) 7개 항목을 제공합니다. 그런데 동일한 데이터를 사람이 의약품안전나라 웹 화면에서 조회하면 다음 6개 항목이 추가로 표시됩니다.
>
> 1. 최종변경일자
> 2. 최종연차보고년도
> 3. 취소/취하구분 (예시값: 정상)
> 4. 취소/취하일자
> 5. 문서번호
> 6. 대상의약품 (별표1 / 신물질)
>
> 저희는 이 API 를 매일 자동 호출해 등록 현황을 수집하고, 전날 대비 오늘의 차이를 비교(diff)하는 방식으로 신규·변경·취하를 추론하고 있습니다. 그러나 API 에 상태 필드가 없어 다음과 같은 근본적 한계가 있습니다.
>
> - **취소/취하구분** 필드가 없어, "어제는 있었는데 오늘 목록에 없는 등록번호"를 취하로 추론하는 간접적 방식에 의존하고 있습니다. 이 방식은 수집이 단 1건이라도 누락되면 정상 등록 건을 취하로 오판할 위험이 있습니다. API 가 취소/취하구분을 직접 제공하면 이 위험이 완전히 사라집니다.
> - **최종변경일자**가 없어 "무엇이 바뀌었는지"는 알 수 있어도 "언제 바뀌었는지"를 API 만으로는 알 수 없습니다.
> - **최종연차보고년도, 취소/취하일자, 문서번호, 대상의약품** 역시 웹 화면에는 존재하나 API 응답에는 없어, 규제 준수 모니터링에 필요한 정보를 자동으로 얻지 못하고 있습니다.
>
> **요청 사항**: 위 6개 항목을 오픈API(`getMdcDmfList01`) 응답 스키마에 추가해 주시기를 요청드립니다. 신규 API 버전 신설(예: `getMdcDmfList02`)이나 기존 API 에 파라미터로 선택 노출하는 방식 모두 무방합니다.
>
> 만약 API 스키마 변경이 즉시 어렵다면, 대안으로 위 6개 필드를 포함한 전체 현황을 **정기적으로(예: 매일 또는 매주) 파일(CSV/Excel) 형태로 제공**받는 방법이 있는지도 함께 안내 부탁드립니다.
>
> 검토와 답변 부탁드립니다. 감사합니다.
**제출 방법**: 공공데이터포털 계정으로 로그인 후 위 URL 접속, "데이터 개선요청" 클릭, 위 문구를 제목/내용란에 붙여넣기. 접수 후 접수번호를 반드시 캡처해 보관한다.
### 11.2 1주 내 — 데이터혁신기획팀 병행 접촉
11.1 제출 후 **1주 이내 접수 확인 연락(자동 접수 메일 등)이 없으면**, 다음을 병행한다.
1. **식약처 종합상담센터 1577-1255** 로 전화해 "데이터혁신기획팀 앞으로 오픈API 항목 추가 문의를 전달해달라"고 요청한다. 상담원에게 데이터셋명("원료의약품등록(DMF)현황"), 데이터셋 ID(15057075), 요청 요지(6개 필드 추가)를 정확히 전달한다.
2. 동시에 **국민신문고(epeople.go.kr)** 에 아래 문구로 민원을 접수한다.
**국민신문고 제출용 문구 초안**:
> **[민원 제목]** 식품의약품안전처 원료의약품등록(DMF) 오픈API 데이터 항목 추가 요청
>
> **[민원 내용]**
>
> 귀 부(식품의약품안전처)가 공공데이터포털을 통해 제공하는 "원료의약품등록(DMF)현황" 오픈API(데이터셋 ID 15057075, 엔드포인트 `getMdcDmfList01`)를 제약 규제 정보 모니터링 목적으로 활용하고 있는 국민입니다.
>
> 해당 API 는 등록번호·성분명·업체명·제조소명·제조소 소재지·제조국가명·발급일자 7개 항목만 제공하나, 동일 데이터를 조회하는 의약품안전나라 웹 화면에는 최종변경일자·최종연차보고년도·취소/취하구분·취소/취하일자·문서번호·대상의약품 6개 항목이 추가로 존재합니다. 특히 취소/취하구분은 원료의약품 등록의 취하 여부를 직접 나타내는 핵심 정보인데, API 로는 확인할 방법이 없어 취하 시점의 데이터 유실 등을 우회적으로 추론해야 하는 상황입니다.
>
> 이에 아래 사항을 문의 및 요청드립니다.
>
> 1. 위 6개 항목을 오픈API 응답에 포함해 주실 수 있는지, 가능하다면 예상 반영 시기를 안내해 주시기 바랍니다.
> 2. API 반영이 어렵다면, 해당 항목을 포함한 데이터를 정기적으로 파일 형태로 제공받을 수 있는 방법이 있는지 안내해 주시기 바랍니다.
> 3. 본 오픈API 의 관리부서로 알고 있는 데이터혁신기획팀의 문의 가능한 연락처(전화 또는 이메일)를 안내해 주시면 감사하겠습니다.
>
> 성실한 답변 부탁드립니다.
### 11.3 응답이 없거나 거부됐을 때의 대안
1. **명시적 거부 통보를 받은 경우**: 공공데이터포털 "분쟁조정 신청"(`/tcs/dor/insertTrublMdatReqstProcssView.do`)으로 공공데이터제공분쟁조정위원회에 조정을 신청하는 것을 검토한다. 다만 이 절차의 소요 기간·실효성은 이번 조사에서 확인하지 못했으므로(⚠️ 미검증), 신청 전 위원회 관련 안내를 재조회해 절차를 확정한다.
2. **응답이 아예 없는 경우(4주 이상)**: 정보공개청구로 **현재 시점의 6개 필드 값 전량을 전자파일(CSV/Excel)로 1회 확보**해 급한 데이터 공백을 메운다. 정기 수집 목적은 아니며, 어디까지나 "API 반영까지의 임시 우회"임을 청구서에도 명시한다.
**정보공개청구 제출용 문구 초안**:
> **[청구 대상 정보]** 원료의약품등록(DMF) 현황 중 오픈API 미제공 항목(최종변경일자, 최종연차보고년도, 취소/취하구분, 취소/취하일자, 문서번호, 대상의약품) 전량
>
> **[청구 취지]**
>
> 귀 처가 공공데이터포털을 통해 공개 중인 "원료의약품등록(DMF)현황" 오픈API(데이터셋 ID 15057075)는 등록번호·성분명·업체명·제조소명·제조소 소재지·제조국가명·발급일자 7개 항목만 제공하고 있으나, 동일 데이터의 웹 화면(의약품안전나라)에는 최종변경일자·최종연차보고년도·취소/취하구분·취소/취하일자·문서번호·대상의약품 항목이 추가로 존재함을 확인했습니다.
>
> 이에 현재 등록된 전체 원료의약품 등록 건에 대한 위 6개 항목의 값을 전자파일(Excel 또는 CSV) 형태로 청구합니다. 등록번호(DMF_PERMIT_NO)를 매칭 키로 하여 오픈API 응답과 대조할 수 있도록 등록번호를 함께 포함해 주시기 바랍니다.
>
> 본 청구는 오픈API 항목 추가가 반영되기 전까지 임시로 데이터 공백을 메우기 위한 목적이며, 별도로 데이터혁신기획팀에 오픈API 항목 추가를 요청한 상태임을 참고 부탁드립니다.
### 11.4 진행 상황 추적
각 채널에 접수한 날짜, 접수번호, 응답 기한, 실제 응답 여부를 아래 표 형식으로 관리할 것을 권고한다. 이 문서에는 접수 이력을 담지 않으며, 실제 접수가 이뤄지는 대로 담당자가 행을 채워 넣는다.
| 채널 | 접수일 | 접수번호/참조번호 | 예상 응답기한 | 실제 응답일 | 결과 요약 | 다음 조치 |
|---|---|---|---|---|---|---|
| 공공데이터포털 데이터 개선요청(§11.1) | | | | | | |
| 식약처 종합상담센터 전화(§11.2) | | | | | | |
| 국민신문고 민원(§11.2) | | | | | | |
| 분쟁조정 신청(§11.3, 거부 시) | | | | | | |
| 정보공개청구(§11.3, 무응답 시) | | | | | | |
### 11.5 채널 선택 시 판단 기준 요약
담당자가 매 상황마다 §2 표를 다시 읽지 않아도 되도록, 판단 기준을 한 문단으로 요약한다. **아직 아무 요청도 하지 않았다면 §11.1(데이터 개선요청)부터 시작한다.** 접수 후 1주가 지나도 자동 접수 확인조차 없다면 §11.2(전화 + 국민신문고)를 병행한다. 국민신문고나 전화 문의에서 담당 부서로부터 "항목 추가는 어렵다"는 **명시적 거부**를 받으면 분쟁조정 신청을 검토하고, 반대로 **4주 이상 아무 응답도 없다면** 분쟁조정보다 먼저 정보공개청구로 현재 스냅샷을 확보해 데이터 공백을 메운다. 즉 "거부"와 "무응답"은 서로 다른 다음 단계로 이어진다 — 거부는 이의절차(분쟁조정)로, 무응답은 백업 확보(정보공개청구)로 대응한다.
---
## 부록 A. 출처
| 제목 | URL | 확인 여부 |
|---|---|---|
| DMF 오픈API 데이터셋 상세 | https://www.data.go.kr/data/15057075/openapi.do | ✅ 직접 확인(제공기관, 관리부서, 활용신청/데이터 개선요청 버튼, 고객센터 연락처) |
| 공공데이터포털 메인 | https://www.data.go.kr | ✅ 직접 확인(메뉴 구조: 공공데이터 제공신청, 분쟁조정 신청) |
| 공공데이터포털 분쟁조정 신청 | https://www.data.go.kr/tcs/dor/insertTrublMdatReqstProcssView.do | ✅ URL 확인(안내 문구까지) |
| 공공데이터 제공신청 정확한 URL | — | ❌ 미확인(자바스크립트 처리, `href="#"`만 확인) |
| 국민신문고 메인 | https://www.epeople.go.kr | ⚠️ 도메인만 확인, SPA 로 콘텐츠 미확인 |
| 국민신문고 원패스뷰(추정 URL) | https://www.epeople.go.kr/kordep/cop/onePassView.npaid | ❌ 404 |
| 정보공개포털 메인 | https://www.open.go.kr | ⚠️ 제목만 확인, 콘텐츠 미확인 |
| 정보공개포털 안내 페이지(추정) | https://www.open.go.kr/gov/govView.do | ❌ 404 |
| 정부24 정보공개청구 안내 | https://www.gov.kr/mw/AA020InfoCappView.do?CappBizCD=13110000037 | ✅ 직접 확인(청구방법, 처리기한, 수수료, 문의처) |
| 식약처 메인 | https://www.mfds.go.kr | ✅ 직접 확인(주요 메뉴 URL 목록) |
| 식약처 조직도/부서 안내 | https://www.mfds.go.kr/wpge/m_271/de010705l0001.do | ✅ 직접 확인(데이터혁신기획팀, 정보화담당관 부서 존재, 전화번호는 미기재) |
| 식약처 정보공개제도 | https://www.mfds.go.kr/wpge/m_11/de010101l0001.do | ✅ URL 확인, 내용 미확인 |
| 식약처 사전정보공개 | https://www.mfds.go.kr/wpge/m_633/de010102l0002.do | ✅ URL 확인, 내용 미확인 |
| 식약처 통합상담예약 | https://www.mfds.go.kr/usr/tCounsel_1024/list.do | ✅ URL 확인, 내용 미확인 |
| 식약처 민원편람 | https://www.mfds.go.kr/brd/m_1208/list.do | ✅ URL 확인, 내용 미확인 |
| 식약처 자주하는 질문 | https://www.mfds.go.kr/brd/m_1060/list.do | ✅ URL 확인, 내용 미확인 |
| 식약처 부서 페이지(1차 시도, 서비스 오류) | https://www.mfds.go.kr/wpge/m_39/de0304010101.do | ❌ 서비스 오류 페이지 |
| 의약품안전나라(nedrug) | https://nedrug.mfds.go.kr/index | ✅ 직접 확인(법령/자료실, 고시/공고알림, 통합검색 메뉴) |
| 식의약 데이터 포털 | https://data.mfds.go.kr | ✅ 직접 확인(메뉴 구조, 회원가입 링크) — DMF 데이터셋 존재는 미확인 |
| 식의약 데이터 포털 로그인 | https://data.mfds.go.kr/OPAAA01F01 | ✅ 로그인 화면임을 확인 |
| 공공데이터법(law.go.kr, 제27조 시도) | https://www.law.go.kr/법령/공공데이터의제공및이용활성화에관한법률/제27조 | ❌ SPA 렌더링으로 조문 텍스트 미확인 |
| 정보공개법(law.go.kr, 제11조 시도) | https://www.law.go.kr/법령/공공기관의정보공개에관한법률/제11조 | ❌ SPA 렌더링으로 조문 텍스트 미확인 |
| 민원처리법(law.go.kr 시도) | https://www.law.go.kr/법령/민원 처리에 관한 법률 | ❌ SPA 렌더링으로 조문 텍스트 미확인 |
| law.go.kr DRF Open API(비인증 시도) | https://www.law.go.kr/DRF/lawService.do?OC=test&target=law&type=HTML&LM=... | ❌ 미인증 OC 파라미터로 조문 미출력, 메인 화면으로 리다이렉트 |
---
## 부록 B. 미해결
- [ ] 공공데이터포털 "공공데이터 제공신청"의 정확한 URL, 신청 양식 항목, 처리기한. (§3.1)
- [ ] "공공데이터 제공신청"이 신규 데이터 개방용인지, 기존 API 항목 추가에도 쓰이는지 여부. (§3.2)
- [ ] 데이터셋 페이지 "데이터 개선요청"/"오류신고 및 문의"의 정확한 제출 폼 URL 과 처리기한. 로그인 후 직접 확인 필요. (§4.1)
- [ ] 공공데이터제공분쟁조정위원회의 심의 절차, 처리기간, 결정의 구속력. (§3.4)
- [ ] 국민신문고의 민원 신청 메뉴 정확한 경로, 민원 유형(일반민원/정책제안 등)별 법정 처리기한. SPA 라서 담당자가 직접 브라우저로 열어 확인 필요. (§6.1)
- [ ] 「공공데이터의 제공 및 이용 활성화에 관한 법률」, 「공공기관의 정보공개에 관한 법률」, 「민원 처리에 관한 법률」의 정확한 조 번호와 일수. `law.go.kr` 이 자동 조회 도구로 렌더링되지 않아 원문 확인 실패 — 담당자가 직접 브라우저로 열거나, 등록된 이메일로 `law.go.kr` Open API 를 정식 신청해 재조회 필요. (§6.3, §3.1)
- [ ] 데이터혁신기획팀의 직통 전화번호 또는 이메일. 조직도 페이지에는 부서명만 있고 번호가 없어, 종합상담센터(1577-1255)를 통한 연결 시도 결과를 기록해야 한다. (§7.2)
- [ ] "허가총괄담당관"(043-719-2312, 2325)이 현재도 유효한 부서/번호인지. 현재 조직도에서는 "의약품허가총괄과"로 보이는 명칭만 확인됨 — 개편 여부 재확인 필요. (§7.1, §7.3)
- [ ] 식의약 데이터 포털(`data.mfds.go.kr`)에 DMF 관련 데이터셋이 실제로 있는지. 회원가입 후 "데이터셋 분양" 메뉴를 열어야 확인 가능. (§8.2, §8.3)
- [ ] 다른 공공 API 에서 항목 추가가 실제로 반영된 구체적 사례와 소요 기간. (§9)
- [ ] robots.txt 예외 요청의 구체적 창구(연락처)와 실제 성사 사례. (§10.1)
- [ ] 식약처 자체 정보공개 메뉴(`/wpge/m_11/de010101l0001.do`)가 `open.go.kr`/정부24 경로와 별도로 더 빠른 처리 경로인지. (§6.4)

View file

@ -0,0 +1,98 @@
# 05. 릴리스와 버전 관리
> 이 문서는 **버전 번호·git 태그·릴리스 절차의 정본**이다. "몇 버전을 언제 어떻게 배포하는가"는
> 여기서 결정한다. 배포판을 실제로 만드는 절차(원드라이브 zip 등 수동 전달)의 실측 로그는
> `docs/HANDOFF.md`에 있다.
## 1. 버전 번호 — Semantic Versioning
`pyproject.toml``[project].version`이 유일한 버전 정본이다. 형식은 `MAJOR.MINOR.PATCH`.
| 자리 | 올리는 경우 |
|---|---|
| `MAJOR` | 설정 파일 스키마·CLI 인자·DB 스키마 등 하위 호환을 깨는 변경 |
| `MINOR` | 하위 호환을 유지하며 기능을 추가(새 시트, 새 알림 채널, 새 CLI 서브커맨드 등) |
| `PATCH` | 버그 수정, 문서 정리, 리팩터링 등 사용자에게 보이는 동작 변화가 없는 변경 |
`0.y.z` 동안은(1.0.0 이전) 아직 안정 API 이전이므로 `MINOR`도 하위 호환을 깰 수 있다.
## 2. 릴리스 절차
```text
1. CHANGELOG.md의 [Unreleased] 섹션을 확정 버전으로 승격
- 헤더를 `## [X.Y.Z] - YYYY-MM-DD`로 바꾼다
- 문서 하단 비교 링크(compare/... , releases/tag/...)를 갱신한다
2. pyproject.toml의 version = "X.Y.Z" 를 갱신
3. 필수 smoke 실행 (AGENTS.md §3)
.\.venv\Scripts\python.exe -m compileall -q src tests
.\.venv\Scripts\python.exe -m dmf_crawler --help
.\.venv\Scripts\python.exe -m dmf_crawler doctor --json
.\.venv\Scripts\python.exe -m pytest tests -q
4. (선택) 배포용 빌드 산출물 생성 — §3 참고
5. 커밋: "release: vX.Y.Z"
6. 태그: git tag -a vX.Y.Z -m "vX.Y.Z"
7. 푸시: git push origin main --follow-tags
8. git.chanpaca.net 웹에서 Releases → 해당 태그로 릴리스 노트 작성
(본문은 CHANGELOG.md의 해당 버전 섹션을 그대로 옮긴다)
```
태그 이름은 항상 `v` 접두어를 붙인다(`v0.1.0`, `v1.2.0`). `pyproject.toml`의 버전 문자열에는
`v`를 붙이지 않는다.
## 3. 빌드 산출물 (`dist/`) — `src/`와의 구분
이 저장소는 **소스와 빌드 산출물을 엄격히 분리**한다.
| 디렉터리 | 내용 | git 추적 여부 |
|---|---|---|
| `src/dmf_crawler/` | 사람이 직접 편집하는 유일한 소스. 여기가 정본이다 | 추적함 |
| `dist/` | `python -m build` 등이 만들어내는 sdist(`.tar.gz`)·wheel(`.whl`) | **추적 안 함**(`.gitignore`) |
| `build/` | setuptools가 빌드 중 쓰는 임시 작업 디렉터리 | **추적 안 함** |
| `*.egg-info/` | 패키지 메타데이터 캐시 | **추적 안 함** |
`dist/`는 **항상 `src/`에서 재생성 가능**해야 한다. `dist/` 안의 파일을 손으로 고쳐서는 안 된다
(고칠 게 있으면 `src/`를 고치고 다시 빌드한다). 그래서 저장소에 커밋하지 않는다 — 커밋하면
"소스와 다른 빌드 산출물이 정본 행세를 하는" 사고가 난다.
빌드 확인 절차:
```powershell
.\.venv\Scripts\python.exe -m pip install --upgrade build
.\.venv\Scripts\python.exe -m build # dist/dmf_crawler-X.Y.Z-py3-none-any.whl + .tar.gz 생성
.\.venv\Scripts\python.exe -m pip install --force-reinstall dist\dmf_crawler-*.whl
.\.venv\Scripts\python.exe -m dmf_crawler --help
```
이 프로그램은 PyPI에 올리지 않는다(`pyproject.toml``Private :: Do Not Upload` 분류자).
`dist/`의 wheel은 다른 PC에 수동 배포할 때만 쓴다. 일반 사용자 배포는 `bootstrap.cmd` +
저장소 zip 방식을 쓴다(§4).
## 4. 최종 사용자 배포판 (zip)
이 프로그램은 개발자가 아닌 사용자가 쓴다(`AGENTS.md`, `README.md` 참고). PyPI/wheel 설치가
아니라 **저장소를 그대로 zip으로 압축해 전달**하는 방식을 쓴다. 실제 배포 사례와 포함/제외
감사 체크리스트는 `docs/HANDOFF.md`의 "릴리즈 배포본 생성 완료" 절을 참고한다.
핵심 원칙만 요약한다:
- 포함: `bootstrap.cmd`, `README.md`, `LICENSE`, `pyproject.toml`, `src/`, `config/`,
`scripts/`, `prompts/`, `docs/`(필요한 만큼).
- 제외: `.venv/`, `data/`, `logs/`, `reports/`, `backup/`, `state/`, `tests/`, `__pycache__/`,
`*.pyc`, `*.lnk`, `config.local.toml`, `service_key*`, `*oauth-token*`.
- 압축 해제 후 `bootstrap.cmd`가 정상 동작하는지 새 폴더에서 재현 검증한다.
## 5. 원격 저장소
정본 원격은 `git.chanpaca.net`(공개 저장소, Forgejo)이다.
```powershell
git remote -v
# origin ssh://git@git.chanpaca.net:2222/yunchan/DMF_Crawler.git
```
이 저장소는 **공개(public)**다. 그래서 커밋 전 다음을 반드시 확인한다(AGENTS.md §6와 동일):
- API 키·OAuth 토큰·웹훅 URL·비밀번호가 코드·설정·로그·문서 어디에도 평문으로 없는가
- `config/config.local.toml`, `*.sqlite3`, `data/`, `logs/`, `reports/`, `backup/`, `state/`
`.gitignore`로 실제로 제외되는가 (`git status` 로 커밋 전 매번 확인)
- 실제 수집 데이터(엑셀·DB)가 우연히 스테이징되지 않았는가