94 lines
3.4 KiB
Markdown
94 lines
3.4 KiB
Markdown
# baekjoon-bot
|
|
작성: AI / 수정: nkey
|
|
|
|
매일 백준(BOJ) 문제를 추천해주고, 디스코드 메시지(payload)로 쓸 수 있는 형태로 반환하는 FastAPI 서비스입니다.
|
|
`/today`에서 추천 문제 + 링크 + Discord embed payload를 생성하며, (선택) PostgreSQL에 문제집(workbook) 진행상황을 저장해 “문제집에서 아직 안 보낸 문제”를 고르는 모드도 제공합니다.
|
|
디스코드 메시지 자동화는 n8n을 활용하였습니다.
|
|
|
|
## Quickstart
|
|
### Recommended
|
|
```bash
|
|
# clone
|
|
git clone https://nkeystudy.site/gitea/nkey/baekjoon-bot.git
|
|
cd baekjoon-bot
|
|
|
|
# venv
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
|
|
# deps
|
|
pip install -r requirements.txt
|
|
|
|
# env (필수: DATABASE_URL)
|
|
cat > .env <<'EOF'
|
|
DATABASE_URL=postgresql+asyncpg://USER:PASSWORD@HOST:5432/DBNAME
|
|
# (admin API 사용 시 필수)
|
|
ADMIN_PASSWORD=change-me
|
|
EOF
|
|
|
|
# run
|
|
uvicorn app:app --host 0.0.0.0 --port 8000
|
|
|
|
# verify
|
|
curl -s http://localhost:8000/ | cat
|
|
curl -s "http://localhost:8000/today" | cat
|
|
```
|
|
|
|
### Alternative (optional) - Docker
|
|
```bash
|
|
docker build -f dockerfile -t baekjoon-bot:local .
|
|
docker run --rm -p 8000:8000 --env-file .env baekjoon-bot:local
|
|
|
|
# verify
|
|
curl -s http://localhost:8000/ | cat
|
|
```
|
|
|
|
## Requirements
|
|
- Runtime/Language: Python 3.12+ (Dockerfile 기준)
|
|
- Dependencies: `fastapi`, `uvicorn`, `sqlalchemy>=2.0`, `asyncpg`, `requests`, `httpx`, `python-dotenv` 등 (`requirements.txt`)
|
|
- Tools: (optional) Docker
|
|
|
|
## Configuration
|
|
### Environment Variables
|
|
| Key | Description | Default | Required |
|
|
|---|---|---:|:---:|
|
|
| `DATABASE_URL` | SQLAlchemy async DB URL (예: `postgresql+asyncpg://...`) | - | ✅ |
|
|
| `ADMIN_PASSWORD` | Admin API 인증 비밀번호 (`X-Admin-Password` 헤더와 비교) | `""` | ✅ (admin API) |
|
|
| `SOURCE_MODE_DEFAULT` | `/today` 기본 소스 모드 | `search` | |
|
|
| `WORKBOOK_ID_DEFAULT` | `source_mode=workbook`에서 `workbook_id` 미지정 시 기본값 | - | |
|
|
| `DIFFICULTY_MODE_DEFAULT` | `/today` 기본 난이도 모드 | `easy` | |
|
|
| `TAG_MODE_DEFAULT` | `/today` 기본 태그 모드 | `easy` | |
|
|
| `LANG_DEFAULT` | `/today` 기본 언어 | `all` | |
|
|
| `DIFFICULTY_EASY` | easy 난이도 범위 | `6..10` | |
|
|
| `DIFFICULTY_HARD` | hard 난이도 범위 | `11..15` | |
|
|
| `DIFFICULTY_ALL` | all 난이도 범위 | `1..30` | |
|
|
| `TAGS_EASY` | easy 태그 프리셋(CSV) | `""` | |
|
|
| `TAGS_HARD` | hard 태그 프리셋(CSV) | `""` | |
|
|
| `TAGS_ALL` | all 태그 프리셋(CSV) | `""` | |
|
|
| `TAG_PICK` | 태그 선택 정책 (random/none/전체) | `random` | |
|
|
| `TAG_PICK_EASY` | easy 태그 선택 정책 | `TAG_PICK` | |
|
|
| `TAG_PICK_HARD` | hard 태그 선택 정책 | `TAG_PICK` | |
|
|
| `TAG_PICK_ALL` | all 태그 선택 정책 | `TAG_PICK` 또는 `none` | |
|
|
| `TAGS_JOIN` | 태그 결합 방식 | `or` | |
|
|
|
|
### Ports
|
|
| Service | Port | Description |
|
|
|---|---:|---|
|
|
| API | 8000 | FastAPI(Uvicorn) |
|
|
|
|
## Usage (minimal)
|
|
- 오늘의 추천 문제(검색 모드, 기본값)
|
|
- `GET /today`
|
|
- 난이도/태그/언어 지정
|
|
- `GET /today?difficulty=6..10&tags=dp,graphs&lang=ko,en`
|
|
- 문제집(workbook) 모드로 추천
|
|
- `GET /today?source_mode=workbook&workbook_id=12345&workbook_pick=level_asc`
|
|
- Admin: 문제집 메타(제목/레벨/태그) 보강
|
|
- `POST /admin/workbooks/{workbook_id}/enrich` + `X-Admin-Password: ...`
|
|
|
|
## Docs
|
|
- Operations: `docs/OPERATIONS.md`
|
|
- Development: `docs/DEVELOPMENT.md`
|
|
- API: `docs/API.md`
|
|
|