3.2 KiB
3.2 KiB
Development Guide
프로젝트 구조
| 파일 | 역할 |
|---|---|
app.py |
FastAPI 엔트리포인트. /, /today, /admin/* 라우팅 |
utils.py |
환경변수 헬퍼, solved.ac 검색 쿼리 빌드, HTTP 호출(retry), admin 인증 |
db.py |
SQLAlchemy async 엔진/세션 설정, get_db() DI |
workbook_picker.py |
문제집에서 미발송 문제 1개 선택 + workbook_sends 기록 |
workbook_enricher.py |
solved.ac problem/show로 문제 메타데이터 채우기 |
workbook_importer.py |
BOJ 문제집 페이지 크롤링 (현재 미사용, BOJ 스크래핑 차단) |
로컬 셋업
git clone https://nkeystudy.site/gitea/nkey/baekjoon-bot.git
cd baekjoon-bot
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cat > .env <<'EOF'
DATABASE_URL=postgresql+asyncpg://USER:PASSWORD@HOST:5432/DBNAME
ADMIN_PASSWORD=change-me
EOF
uvicorn app:app --reload --host 0.0.0.0 --port 8000
의존성
requirements.txt 기준:
fastapi/uvicorn- 웹 프레임워크 / ASGI 서버sqlalchemy/asyncpg- 비동기 PostgreSQL ORMrequests/httpx- 동기/비동기 HTTP 클라이언트python-dotenv-.env파일 로딩beautifulsoup4/lxml- HTML 파싱 (workbook_importer용, 현재 미사용)
데이터베이스
PostgreSQL 필수. DDL은 레포에 포함되어 있지 않으므로 수동으로 생성해야 한다.
CREATE TABLE IF NOT EXISTS workbooks (
id BIGINT PRIMARY KEY,
title TEXT,
source TEXT NOT NULL DEFAULT 'boj',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS workbook_problems (
workbook_id BIGINT NOT NULL REFERENCES workbooks(id) ON DELETE CASCADE,
problem_id INTEGER NOT NULL,
title_ko TEXT,
title_en TEXT,
level INTEGER,
tags TEXT[] DEFAULT NULL,
added_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (workbook_id, problem_id)
);
CREATE INDEX IF NOT EXISTS idx_workbook_problems_workbook
ON workbook_problems(workbook_id);
CREATE TABLE IF NOT EXISTS workbook_sends (
workbook_id BIGINT NOT NULL REFERENCES workbooks(id) ON DELETE CASCADE,
problem_id INTEGER NOT NULL,
sent_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (workbook_id, problem_id)
);
CREATE INDEX IF NOT EXISTS idx_workbook_sends_workbook
ON workbook_sends(workbook_id);
테이블 설명
| 테이블 | 역할 |
|---|---|
workbooks |
문제집 메타 (BOJ workbook id를 PK로 사용) |
workbook_problems |
문제집-문제 매핑 + 메타데이터 (제목, 난이도, 태그) |
workbook_sends |
발송 기록. 중복 추천 방지의 핵심 |
환경변수
필수:
DATABASE_URL- PostgreSQL 연결 URL (미설정 시 앱 시작 불가)
Admin API 사용 시:
ADMIN_PASSWORD-X-Admin-Password헤더와 비교
검색 기본값 커스터마이징:
SOURCE_MODE_DEFAULT,WORKBOOK_ID_DEFAULTDIFFICULTY_MODE_DEFAULT,TAG_MODE_DEFAULT,LANG_DEFAULTDIFFICULTY_EASY/HARD/ALL,TAGS_EASY/HARD/ALLTAG_PICK,TAG_PICK_EASY/HARD/ALL,TAGS_JOIN