Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copy to .env and fill in. NEVER commit .env.
# cp .env.example .env

# 공공데이터포털 (https://www.data.go.kr) — 일반 인증키 (Decoding)
DATA_GO_KR_API_KEY=

# KOSIS 국가통계포털 OpenAPI (https://kosis.kr/openapi)
KOSIS_API_KEY=

# LLM providers (use whichever you have; open models via OpenAI-compatible endpoint)
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
# e.g. vLLM / Ollama / LM Studio: http://localhost:11434/v1
OPENAI_BASE_URL=
LLM_MODEL=
27 changes: 27 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# CODEOWNERS — PR이 해당 경로를 수정하면 소유자에게 자동으로 리뷰 요청이 갑니다.
# 채우는 법:
# 1) GitHub Org > Teams 에서 팀 생성 (예: core-maintainers, group1 ... group6)
# 2) 아래 @CausalInferenceLab/<team> 핸들을 실제 팀 이름으로 교체
# 3) 조 폴더가 생기면 한 줄씩 추가: /cases/group3-*/ @CausalInferenceLab/group3
# 4) 팀에 저장소 Write 권한을 부여해야 리뷰 요청이 동작합니다.
# 규칙: 아래쪽 줄이 위쪽 줄보다 우선합니다.

# 기본: 운영진
* @CausalInferenceLab/mentors

# 공통 엔진
/core/ @CausalInferenceLab/core-maintainers
/tests/core/ @CausalInferenceLab/core-maintainers

# 운영/인프라
/.github/ @CausalInferenceLab/mentors
/app/ @CausalInferenceLab/mentors
/cases/_template/ @CausalInferenceLab/mentors

# 조별 케이스 (조 편성 후 주석 해제·수정)
# /cases/group1-*/ @CausalInferenceLab/group1
# /cases/group2-*/ @CausalInferenceLab/group2
# /cases/group3-*/ @CausalInferenceLab/group3
# /cases/group4-*/ @CausalInferenceLab/group4
# /cases/group5-*/ @CausalInferenceLab/group5
# /cases/group6-*/ @CausalInferenceLab/group6
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: 버그 리포트
description: 코드·CI·앱이 예상대로 동작하지 않을 때
title: "[버그] "
labels: ["bug"]
body:
- type: input
id: where
attributes:
label: 위치
placeholder: core/estimators, app/streamlit_app.py, cases/group3-.../estimate.py
validations:
required: true
- type: textarea
id: repro
attributes:
label: 재현 방법
description: 실행한 명령어를 그대로 붙여 주세요
render: bash
validations:
required: true
- type: textarea
id: error
attributes:
label: 에러 메시지 / 기대 동작
render: text
- type: input
id: env
attributes:
label: 환경
placeholder: macOS 14 / Python 3.11 / uv
80 changes: 80 additions & 0 deletions .github/ISSUE_TEMPLATE/case-proposal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: 케이스 제안
description: 분석할 정책/사회 문제를 제안합니다 (조 주제 후보)
title: "[케이스] "
labels: ["case-proposal"]
body:
- type: markdown
attributes:
value: |
결과를 보기 전에 질문을 먼저 적는 것이 목표입니다. 모르는 칸은 "미정"으로 두세요.
- type: input
id: group
attributes:
label: 조
placeholder: group3
validations:
required: true
- type: textarea
id: question
attributes:
label: 질문
description: 어떤 정책이 어떤 결과를 바꿨는지, 한 문장으로
placeholder: 2022년 청년월세 특별지원이 수혜 지역 청년 1인가구의 전출률을 낮췄는가?
validations:
required: true
- type: textarea
id: treatment
attributes:
label: 처치 (정책·시점·대상)
placeholder: 시행일, 적용 지역/집단, 처치 강도
validations:
required: true
- type: textarea
id: control
attributes:
label: 대조군
description: 정책이 없었다면 어땠을지 보여줄 비교 대상
placeholder: 미시행 지역, 연령 경계 바로 위 집단 등
validations:
required: true
- type: textarea
id: outcomes
attributes:
label: 결과 지표
placeholder: 월별 시군구 전출률 (KOSIS 인구이동통계)
- type: textarea
id: data
attributes:
label: 데이터 출처
description: 기관/데이터셋 이름과 URL, 기간·단위
validations:
required: true
- type: dropdown
id: license
attributes:
label: 데이터 라이선스
options:
- 공공누리 제1유형 (출처표시)
- 공공누리 제2유형 (출처표시+상업적 이용금지)
- 공공누리 제3유형 (출처표시+변경금지)
- 공공누리 제4유형 (출처표시+상업적 이용금지+변경금지)
- KOSIS 이용약관
- 기타 / 확인 필요
validations:
required: true
- type: dropdown
id: estimator
attributes:
label: 예상 추정 방법
options:
- 이중차분(DiD)
- 이벤트 스터디
- 합성통제(Synthetic Control)
- 단절적 시계열(ITS)
- 회귀불연속(RD)
- 모름 / 멘토링 필요
- type: textarea
id: risks
attributes:
label: 우려되는 가정 위반·중단 조건
placeholder: 동시 시행 정책, 사전 추세 불일치, 데이터 단절 등
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: GitHub 사용법이 막혔어요
url: https://github.com/CausalInferenceLab/policy-effect-analytics-agent/blob/main/docs/ops/github-onboarding.md
about: 초대 수락 → clone → 브랜치 → PR 단계별 가이드
- name: 기여 규칙
url: https://github.com/CausalInferenceLab/policy-effect-analytics-agent/blob/main/CONTRIBUTING.md
about: 브랜치·커밋·리뷰 규칙
16 changes: 16 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## 무엇을 했나요?
<!-- 한두 줄 요약. 관련 이슈: Closes #번호 -->

## 조 / 케이스
<!-- 예: group3 / cases/group3-youth-rent -->

## 체크리스트
- [ ] `plan.yaml`을 **결과를 보기 전에** 작성·커밋했습니다 (이후 변경 시 이유를 커밋 메시지에 기록)
- [ ] 데이터 출처와 **라이선스**(공공누리 유형 등)를 `plan.yaml > data_sources`에 명시했습니다
- [ ] API 키·`.env`·개인정보가 담긴 원자료·재배포 불가 데이터를 포함하지 않았습니다
- [ ] 그림/수치는 `fetch.py` → `estimate.py` 실행으로 **재현** 가능합니다
- [ ] `make check` (ruff + pytest)가 통과합니다
- [ ] 다른 조의 폴더나 `core/`를 (합의 없이) 수정하지 않았습니다

## 리뷰어에게
<!-- 특히 봐줬으면 하는 부분, 막힌 부분 -->
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: CI

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
# Tests must never hit external data APIs; keys are intentionally empty.
DATA_GO_KR_API_KEY: ""
KOSIS_API_KEY: ""
MPLBACKEND: Agg
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Ruff
run: |
ruff check .
ruff format --check . || echo "::warning::ruff format differences (run 'ruff format .')"
- name: Pytest
run: pytest -q
41 changes: 41 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Python
__pycache__/
*.py[cod]
*.egg-info/
.eggs/
build/
dist/
.venv/
venv/
.python-version
.pytest_cache/
.ruff_cache/
.mypy_cache/
.ipynb_checkpoints/
.coverage
htmlcov/

# Secrets — never commit keys
.env
.env.*
!.env.example
*.pem
*.key
secrets.toml
.streamlit/secrets.toml

# Data: raw/intermediate files stay local (license + size + privacy)
data/raw/
data/cache/
**/data/raw/
**/data/cache/
*.parquet.tmp
*.xlsx~
~$*

# OS / editors
.DS_Store
Thumbs.db
.idea/
.vscode/
*.swp
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-yaml
- id: check-added-large-files
args: [--maxkb=5000]
- id: detect-private-key
14 changes: 14 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# 행동 강령 (Code of Conduct)

이 프로젝트는 [Contributor Covenant 2.1](https://www.contributor-covenant.org/ko/version/2/1/code_of_conduct/)을 따릅니다.

## 요약

- 경험·배경·직무와 관계없이 모두를 존중합니다. 처음 GitHub를 쓰는 분의 질문을 환영합니다.
- 비판은 **코드와 분석**에 대해, 구체적이고 건설적으로 합니다.
- 괴롭힘, 차별적 언행, 타인의 개인정보 공개는 허용되지 않습니다.
- 공공데이터를 다룰 때 개인·기관을 특정하거나 낙인찍는 해석을 피합니다.

## 신고

위반 사례는 멘토(신진수) 또는 운영진에게 GitHub 비공개 메시지나 프로그램 공식 채널로 알려 주세요. 신고자의 신원은 보호됩니다. 위반 시 경고, 일시적 또는 영구적 참여 제한이 있을 수 있습니다.
66 changes: 66 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# 기여 가이드 (CONTRIBUTING)

GitHub 협업이 처음이라면 먼저 [`docs/ops/github-onboarding.md`](docs/ops/github-onboarding.md)를 따라 하세요.

## 1. 작업 방식: 조별 브랜치 (권장)

| 방식 | 언제 | 비고 |
|---|---|---|
| **조직 저장소에서 브랜치** (권장) | 조직 초대를 수락한 멘티 | CI·리뷰·모니터링이 한 곳에서 보임 |
| Fork → PR | 초대 전이거나 외부 기여자 | PR 대상은 `main` |

- `main`은 보호 브랜치입니다. **직접 push 금지, PR로만 병합.**
- 브랜치 이름: `<조>/<작업>` — 예) `group3/plan`, `group3/fetch-kosis`, `group1/fix-report`
- 공통 코드(`core/`)는 `core/<작업>` 브랜치로, 먼저 이슈에서 논의한 뒤 수정합니다.

## 2. 폴더 소유권

| 경로 | 소유 | 규칙 |
|---|---|---|
| `cases/<조>-<주제>/` | 해당 조 | 조 안에서 자유롭게. 다른 조 폴더는 수정하지 않음 |
| `core/` | 멘토·코어 메인테이너 | 이슈 → 합의 → PR. 테스트 필수 |
| `cases/_template/`, `app/`, `.github/`, `docs/` | 운영진 | 개선 제안은 이슈로 |

소유자는 [`.github/CODEOWNERS`](.github/CODEOWNERS)로 자동 리뷰 요청됩니다.

## 3. 커밋 규칙 (Conventional Commits)

```
<type>(<scope>): <요약, 50자 이내>
```

- type: `feat` 기능 · `fix` 버그 · `data` 수집/전처리 · `analysis` 추정/그림 · `docs` 문서 · `plan` plan.yaml · `test` · `chore`
- scope: 조 폴더명 또는 `core`, `app`
- 예) `plan(group3-youth-rent): 처치·대조 지역 정의`, `analysis(group3-youth-rent): DiD 1차 추정`
- 작은 단위로 자주 커밋하세요. 주 1회 이상 커밋이 활동 확인 기준입니다.

## 4. PR 흐름

1. 최신 `main`에서 브랜치 생성 → 작업 → `make check` 통과 확인
2. PR 생성 (템플릿 체크리스트 작성). 작업 중이면 **Draft PR**로 일찍 올리세요.
3. 리뷰: **승인 1명 + CI 통과** 시 병합 (조원 상호 리뷰 가능, `core/`는 코어 메인테이너 승인)
4. 병합 방식: **Squash merge** (PR 제목이 커밋 메시지가 되므로 규칙에 맞게)
5. 병합 후 브랜치 삭제, 로컬 `git switch main && git pull`

## 5. 분석 원칙 (리뷰에서 확인)

- **plan.yaml을 결과보다 먼저 커밋** (사전 등록). 이후 변경은 커밋 메시지에 이유를 적습니다.
- 데이터 출처·라이선스 명시 (공공누리 유형 등). 재배포 불가 원자료, 개인정보, API 키는 커밋 금지.
- 그림·수치는 `estimate.py` 실행으로 재현 가능해야 합니다.
- 가정이 깨지면 `abstention` 규칙에 따라 **결론을 보류**하는 것도 좋은 결과입니다.

## 6. 개발 환경

```bash
make install # 의존성 설치 (dev 포함)
make check # ruff + pytest — CI와 동일
make app # Streamlit 로컬 실행
```

선택: `pre-commit install` 로 커밋 시 ruff 자동 실행.

## 7. 질문·제안

- 버그: 이슈 → `버그 리포트`
- 새 케이스 주제: 이슈 → `케이스 제안`
- 행동 강령: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.PHONY: install check lint test format app activity

PY ?= python

install:
@command -v uv >/dev/null 2>&1 && uv pip install -e ".[dev]" || $(PY) -m pip install -e ".[dev]"

check: lint test

lint:
ruff check .

test:
pytest -q

format:
ruff format . && ruff check --fix .

app:
streamlit run app/streamlit_app.py

activity:
$(PY) scripts/weekly_activity.py --days 7
Loading
Loading