StepZero νλ‘μ νΈμ Core Engine(λ°±μλ + κΈ°λ³Έ νλ‘ νΈμλ) λ ν¬μ§ν 리μ λλ€. μ΄ λ¬Έμλ νλ‘μ νΈμ μ²μ ν©λ₯ν μ£Όλμ΄ κ°λ°μ λΆλ€μ μν΄ μμ±λμμ΅λλ€.
μ΄ νλ‘μ νΈλ μ΄κΈ° μ€ννΈμ μ°½μ μλ₯Ό μν AI μ‘μ λ¬λ μ΄ν νλ«νΌμ ν΅μ¬ μμ§μ λ΄λΉν©λλ€. μ¬μ©μμ μ λ ₯μ λ°μ λ‘λλ§΅μ μμ±νκ³ , RAG(Retrieval-Augmented Generation)λ₯Ό ν΅ν΄ λ§μΆ€ν μ 보λ₯Ό μ 곡νλ κ²μ΄ λͺ©νμ λλ€.
| κ΅¬λΆ | κΈ°μ | μ€λͺ |
|---|---|---|
| Backend | FastAPI (Python 3.13) | κ³ μ±λ₯ λΉλκΈ° μΉ νλ μμν¬. API μλ² λ΄λΉ. |
| Frontend | Next.js 16 (App Router) | React κΈ°λ° μΉ νλ μμν¬. UI/UX λ΄λΉ. |
| Database | PostgreSQL 16 + pgvector | κ΄κ³ν λ°μ΄ν° λ° λ²‘ν° μλ² λ© μ μ₯μ. |
| Cache | Redis | μΈμ κ΄λ¦¬, μμ ν, μΊμ± μ©λ. |
| Deploy | Docker Compose | λ‘컬 κ°λ° νκ²½ ν΅μΌ λ° λ°°ν¬ κ΄λ¦¬. |
μ΄ νλ‘μ νΈλ Monorepo ꡬ쑰λ₯Ό λ°λ¦ λλ€. νλμ μ μ₯μ μμ λ°±μλμ νλ‘ νΈμλκ° ν¨κ» μμ΅λλ€.
step-zero/
βββ app-backend/ # π FastAPI λ°±μλ μ½λ
β βββ app/ # μ€μ μ ν리μΌμ΄μ
λ‘μ§
β β βββ api/ # API λΌμ°ν° (v1)
β β βββ features/ # feature λ¨μ λλ©μΈ/μ ν리μΌμ΄μ
λ‘μ§
β β βββ models/ # SQLModel/ORM λͺ¨λΈ
β β βββ repositories/ # λ°μ΄ν° μ κ·Ό κ³μΈ΅
β β βββ services/ # κ³΅ν΅ μλΉμ€ (RAG, Chat λ±)
β β βββ workers/ # ARQ λΉλκΈ° μ컀
β β βββ core/ # μ€μ (Config), DB μ°κ²° λ± ν΅μ¬ λ‘μ§
β βββ alembic/ # DB λ§μ΄κ·Έλ μ΄μ
(18κ° νμΌ)
β βββ scripts/ # κ°λ°/μ΄μ μ€ν¬λ¦½νΈ
β βββ tests/ # ν
μ€νΈ μ½λ (Pytest)
β βββ Dockerfile
β
βββ app-frontend/ # βοΈ Next.js νλ‘ νΈμλ μ½λ
β βββ src/
β β βββ app/ # νμ΄μ§ λ° λΌμ°ν
(App Router)
β β βββ components/ # μ¬μ¬μ© κ°λ₯ν UI μ»΄ν¬λνΈ
β β βββ features/ # feature λ¨μ λͺ¨λ
β β βββ lib/ # μ νΈλ¦¬ν° ν¨μ
β β βββ providers/ # React Context Providers
β βββ Dockerfile
β
βββ docs/ # π κΈ°ν λ° μ€κ³ λ¬Έμ (νλ
!)
βββ scripts/ # λ£¨νΈ μ νΈλ¦¬ν° μ€ν¬λ¦½νΈ (DB μ΄κΈ°ν λ±)
βββ docker-compose.dev.yml # π³ λ‘컬 κ°λ° νκ²½ κ΅¬μ± νμΌ
| μ€ν¬λ¦½νΈ | μ©λ |
|---|---|
setup_dev.sh |
λ‘컬 κ°λ°νκ²½ μ΄κΈ°ν (uv sync + .env) |
run_alembic.sh |
Alembic λνΌ (μ: ./scripts/run_alembic.sh upgrade head) |
reset_migrations.sh |
λ§μ΄κ·Έλ μ΄μ
ν΅ν© κ΄λ¦¬ (fresh / stamp / verify / status / history) |
bootstrap_actionkit.sh |
ActionKit λ§μ΄κ·Έλ μ΄μ + μλ ν΅ν© μ€ν |
bootstrap_rag.sh |
RAG λ§μ΄κ·Έλ μ΄μ + λ²‘ν° μλ ν΅ν© μ€ν |
seed_actionkit.py |
ActionKit μλ λ°μ΄ν° μ μ¬ |
seed_rag_vectors.py |
RAG λ²‘ν° μλ² λ© μ μ¬ |
export_openapi.py |
OpenAPI μ€ν μΆμΆ |
κ°μ₯ μ½κ³ λΉ λ₯΄κ² κ°λ° νκ²½μ μΈν νλ λ°©λ²μ λλ€. Dockerκ° μ€μΉλμ΄ μμ΄μΌ ν©λλ€.
- Docker Desktop (μ€ν μ€μ΄μ΄μΌ ν¨)
- Git
ν°λ―Έλμμ νλ‘μ νΈ λ£¨νΈ κ²½λ‘λ‘ μ΄λν λ€ μλ λͺ λ Ήμ΄λ₯Ό μ λ ₯νμΈμ.
# 컨ν
μ΄λ λΉλ λ° λ°±κ·ΈλΌμ΄λ μ€ν
docker compose -f docker-compose.dev.yml up -d --buildπ‘ Tip: λ‘κ·Έ νμΈμ΄ νμνλ©΄ μλΉμ€λ³λ‘ μ‘°ννμΈμ.
docker compose -f docker-compose.dev.yml logs -f app-backend app-worker app-frontend
μ€νμ΄ μλ£λλ©΄ λΈλΌμ°μ μμ μλ μ£Όμλ‘ μ μν΄λ³΄μΈμ.
- Frontend (λ©μΈ μ±): http://localhost:3000
- Backend (API λ¬Έμ): http://localhost:8000/docs
- DB κ΄λ¦¬ (νμ μ): λ³λ DB ν΄(DBeaver λ±) μ¬μ© (Port:
5432) - μν νμΈ:
docker compose -f docker-compose.dev.yml ps
μ°Έκ³ : λ‘λλ§΅ λΉλκΈ° μμ±μ
app-workerκ° μ€ν μ€μ΄μ΄μΌ μ§νλ©λλ€.
νλ‘λμ
μ docker-compose.prod.ymlμ μ¬μ©ν©λλ€.
# 1) μλΉμ€λ³ νκ²½ λ³μ νμΌ μ€λΉ
cp app-backend/.env.example app-backend/.env
cp app-frontend/.env.example app-frontend/.env
# Docker Compose μ μ© override (νμ μ)
cp app-backend/.env.docker.local.example app-backend/.env.docker.local
cp app-frontend/.env.docker.local.example app-frontend/.env.docker.local
# 2) νλ‘λμ
μ΄λ―Έμ§ λΉλ/κΈ°λ
docker compose -f docker-compose.prod.yml up -d --build
# 3) λ§μ΄κ·Έλ μ΄μ
(νμ μ)
docker compose -f docker-compose.prod.yml exec -T app-backend \
bash -lc "cd /app && ./scripts/run_alembic.sh upgrade head"μ°Έκ³ :
docker-compose.prod.ymlμ μμ€ λ³Όλ₯¨ λ§μ΄νΈμ--reloadλ₯Ό μ¬μ©νμ§ μμ΅λλ€.- λ°°ν¬ νκ²½μμλ
docker exec stepzero-backendλμdocker compose ... exec app-backendμ¬μ©μ κΆμ₯ν©λλ€.
DBμ Redisλ§ Dockerλ‘ λμ°κ³ , νλ‘ νΈ/λ°±μλλ λ‘컬μμ μ§μ μ€ννλ λ°©μμ λλ€.
docker compose -f docker-compose.dev.yml up -d app-db app-rediscd app-backend
# (μ΅μ΄ 1ν) νκ²½λ³μ νμΌ λ³΅μ¬
cp .env.example .env
# κ°λ°νκ²½ μλ μ΄κΈ°ν (Python 3.13 + dev μμ‘΄μ±)
./scripts/setup_dev.sh
# μλ² μ€ν / ν
μ€νΈ / λ§μ΄κ·Έλ μ΄μ
make run # uvicorn κ°λ° μλ² μ€ν
make test # pytest μ€ν
make migrate-up # alembic upgrade head
make migrate-verify # λͺ¨λΈ β DB μ€ν€λ§ diff κ²μ¦cd app-frontend
pnpm install
pnpm dev
# λ°±μλ OpenAPI κΈ°λ° νμ
λκΈ°ν
pnpm types:sync
types:syncλ μ€ν μ€μΈstepzero-backend컨ν μ΄λμμ OpenAPIλ₯Ό μΆμΆν©λλ€.
λ‘컬 μ§μ μ€νκ³Ό Docker Compose μ€νμ νμΌλ‘ λΆλ¦¬ν©λλ€. κ°μ ν€κ° μ¬λ¬ νμΌμ μμΌλ©΄ λμ€μ λ‘λλ νμΌ κ°μ΄ μ΅μ’ κ°μ λλ€.
| νμΌ | μ©λ |
|---|---|
app-backend/.env |
곡μ κ°λ₯ν κΈ°λ³Έκ° (λ―Όκ°ν€ κΈμ§) |
app-backend/.env.local |
λ‘컬 μ μ© λΉλ°κ° (Git μΆμ μ μΈ) |
app-backend/.env.docker.local |
Docker Compose μ μ© override (host=app-db λ±) |
app-frontend/.env |
NEXT_PUBLIC_* κΈ°λ³Έκ° |
app-frontend/.env.local |
νλ‘ νΈ λ‘컬 μ μ© λΉλ°κ° |
app-frontend/.env.docker.local |
νλ‘ νΈ Docker Compose μ μ© override |
# μ΅μ μ
μ
cp app-backend/.env.example app-backend/.env
cp app-frontend/.env.example app-frontend/.env
# Docker Compose μ μ© (μ ν)
cp app-backend/.env.docker.local.example app-backend/.env.docker.local
cp app-frontend/.env.docker.local.example app-frontend/.env.docker.localμ°Έκ³ :
- λ°±μλλ
uvλ₯Ό ν¨ν€μ§ λ§€λμ λ‘ μ¬μ©ν©λλ€.uvκ° μ€μΉλμ΄ μμ΄μΌ ν©λλ€.- μ€μΉ:
curl -LsSf https://astral.sh/uv/install.sh | sh
Docker 컨ν
μ΄λ λ΄λΆμμ μ€ννλ κ²μ κΆμ₯ν©λλ€.
μλ μμλ docker compose exec κΈ°μ€μ΄λ©°, docker exec -it stepzero-backend bash -lc "cd /app && ..." ννλ‘λ μ€νν μ μμ΅λλ€.
# μ DBμ λ§μ΄κ·Έλ μ΄μ
μ 체 μ μ©
docker compose -f docker-compose.dev.yml exec -T app-backend \
bash -lc "cd /app && ./scripts/reset_migrations.sh fresh"
# κΈ°μ‘΄ DBμ alembic_versionλ§ μ΅μ μΌλ‘ stamp (μ€ν€λ§ λ³κ²½ μμ)
docker compose -f docker-compose.dev.yml exec -T app-backend \
bash -lc "cd /app && ./scripts/reset_migrations.sh stamp"
# λͺ¨λΈ β DB μ€ν€λ§ diff κ²μ¦
docker compose -f docker-compose.dev.yml exec -T app-backend \
bash -lc "cd /app && ./scripts/reset_migrations.sh verify"# λ§μ΄κ·Έλ μ΄μ
+ μλ ν΅ν© μ€ν
cd app-backend
ACTIONKIT_BOOTSTRAP_MODE=docker ./scripts/bootstrap_actionkit.sh
# λλ κ°λ³ μ€ν
docker compose -f docker-compose.dev.yml exec -T app-backend \
bash -lc "cd /app && ./scripts/run_alembic.sh upgrade head"
docker compose -f docker-compose.dev.yml exec -T app-backend \
bash -lc "cd /app && python scripts/seed_actionkit.py"
seed_actionkit.pyλ λ°μ΄ν°κ° μ΄λ―Έ μ‘΄μ¬νλ©΄ skip νλ―λ‘ μ΄κΈ° μ μ¬/리μ νμ μ£Όλ‘ μ€νν©λλ€.
RAGλ DB λ§μ΄κ·Έλ μ΄μ (pgvector extension 보μ₯)κ³Ό λ²‘ν° μ μ¬λ₯Ό ν¨κ» μνν©λλ€.
# λ§μ΄κ·Έλ μ΄μ
+ λ²‘ν° μλ ν΅ν© μ€ν
cd app-backend
RAG_BOOTSTRAP_MODE=docker ./scripts/bootstrap_rag.sh
# ν
μ€νΈμ© μΌλΆλ§ μ μ¬ (μ: 20κ°)
RAG_BOOTSTRAP_LIMIT=20 RAG_BOOTSTRAP_MODE=docker ./scripts/bootstrap_rag.sh
bootstrap_rag.shλͺ¨λ:RAG_BOOTSTRAP_MODE=docker|local|auto(κΈ°λ³Έ: auto)- κΈ°λ³Έ μμ€ κ²½λ‘:
app-backend/.temp/rag(PDF/Markdown μ¬κ· νμ)
~/.docker/config.json νμΌμ μ΄μ΄ "credsStore": "desktop" λΆλΆμ μμ νμΈμ.
PostgreSQL λ²μ μ΄ μ λ§κ±°λ λ°μ΄ν°κ° κΌ¬μΈ κ²½μ°μ λλ€. λ³Όλ₯¨μ μ§μ°κ³ λ€μ μμνμΈμ.
docker compose -f docker-compose.dev.yml down -v
docker compose -f docker-compose.dev.yml up -d --build# Mac/Linux
chmod +x scripts/init_db.sh
# Windows (Git Bash)
git update-index --add --chmod=+x scripts/init_db.shλ‘컬 μ€ν μ Node.js 20.9.0 μ΄μμ΄ νμν©λλ€. Docker μ€ν μμλ Dockerfileμ node:20-alpine μ΄λ―Έμ§λ₯Ό μ μ§νμΈμ.
- μ»€λ° λ©μμ§:
feat:,fix:,docs:λ±μ Conventional Commits κ·μΉμ λ°λ¦ λλ€. - μ½λ μ€νμΌ:
- Backend:
black,isortν¬λ§·ν° μ¬μ© - Frontend: Prettier ν¬λ§·ν° μ¬μ© (μ€μ λ κ²½μ°)
- Backend:
- λ¬Έμ: μμ
μ
docs/ν΄λμ μ€κ³ λ¬Έμλ₯Ό λ¨Όμ μ½μ΄λ³΄μΈμ.
-
λΈλμΉ μ λ΅
main: λ°°ν¬ κ°λ₯ν μμ λΈλμΉ (μ§μ push κΈμ§, PRλ§ νμ©,developμμλ§ λ¨Έμ§)develop: κΈ°λ³Έ λΈλμΉμ΄μ κ°λ° ν΅ν© λΈλμΉfeature/*: κΈ°λ₯ λΈλμΉ (μμ νdevelopμΌλ‘ PR)- λΈλμΉλͺ
:
feature/<issue-number>-<short-slug>(μ:feature/1-login-page)
-
μ»€λ° λ©μμ§ κ·μΉ
- νμ:
type: subject - νμ© νμ
:
feat,fix,docs,refactor,test,chore,perf,ci,build,revert
- νμ:
-
λ‘컬 ν νμ±ν
# μ μ₯μ 루νΈμμ 1ν μ€ν pnpm installcommit-msg: Conventional Commits κ²μ¬pre-push: backend smoke subset(tests/services,tests/repositories,tests/integration) + frontend lint κ²μ¬
-
CI κ²μ¬
- PR μ λΈλμΉλͺ κ·μΉ κ²μ¬
- PR μ»€λ° λ©μμ§(commitlint) κ²μ¬
- backend μ 체 νκ·
pytest -q -m "not slow and not requires_openai" - frontend
lint,test,buildκ²μ¬
Made with β€οΈ by StepZero Team