Skip to main content
이 페이지는 개발 규칙 및 코드 품질 표준을 다룹니다. 파이오니어 프로그램, 필드 테스팅, PR 프로세스 및 커뮤니티 링크를 포함한 전체 기여 가이드는 GitHub의 CONTRIBUTING.md를 참조하세요.

설정

전제 조건: Python 3.11+, uv, Node.js 18+, pnpm.
LLM_API_KEY는 백엔드를 로컬에서 실행하거나 커밋 시 자동 번역된 로케일 출력을 미리보기 위해서만 필요합니다. 키가 없는 기여자도 여전히 EN 변경 사항을 커밋할 수 있습니다. GitHub Actions 워크플로우가 PR 병합 후 master에서 번역합니다. 아래의 i18n을 참조하세요.
모든 것이 작동하는지 확인하세요:

타입 안전성

mypy strict 모드가 적용됩니다. 전체 코드베이스는 오류 없이 통과하며, pre-commit 훅은 모든 staged .py 파일에 대해 전체 import 체인 검사와 함께 mypy를 실행합니다. 규칙:
  • 모든 공개 함수에 타입 힌트가 필요합니다.
  • import-untyped (stub이 없는 타사 라이브러리)를 제외하고 # type: ignore를 사용하지 않습니다.
  • forward reference를 위해 from __future__ import annotations를 사용합니다.
  • CI를 통과시키기 위해 오류를 억제하지 말고 실제 타입을 수정합니다.

테스트

모든 새로운 모듈은 반드시 해당하는 테스트 파일을 가져야 합니다. 모든 기능 커밋은 테스트를 포함해야 합니다. 규칙:
  • 커밋하기 전에 모든 기존 테스트가 통과해야 합니다: uv run pytest tests/ -x -q.
  • 테스트는 외부 서비스에 의존하면 안 됩니다 — unittest.mock / AsyncMock을 사용하여 데이터베이스, MCP 서버, HTTP 엔드포인트, LLM 호출을 모킹하세요.
  • 커버리지와 함께 테스트를 실행하세요: uv run pytest --cov=fim_one.

코드 스타일

  • 비동기 우선. I/O 바운드 작업에는 async def를 사용하세요. 이벤트 루프를 블로킹하지 않도록 동기 호출을 asyncio.to_thread()로 래핑하세요.
  • 린팅을 위해 Ruff 사용. uv run ruff check src/ — 줄 길이는 100자입니다.
  • 최소한의 __init__.py 내보내기. 공개 API만 다시 내보내고 내부 기호는 비공개로 유지하세요.
  • 패키지 관리자. Python은 uv, 프론트엔드는 pnpm을 사용하세요. pipnpm은 절대 사용하지 마세요.

Git 규칙

원자적 커밋. 커밋 하나당 하나의 논리적 변경. 함께 개발되었더라도 관련 없는 변경사항은 분리하세요. 커밋 메시지 형식: type: description --no-verify로 훅을 건너뛰지 마세요. pre-commit 파이프라인은 오류가 저장소에 도달하기 전에 이를 감지하기 위해 존재합니다.

Pre-commit hook pipeline

훅은 모든 커밋에서 자동으로 실행됩니다. 각 단계와 관련된 스테이징된 파일만 처리합니다 — Python 파일만 변경한 경우 i18n 단계는 건너뛰고, 그 반대도 마찬가지입니다. 단계가 실패하면 커밋이 중단됩니다. 보고된 오류를 수정하고 다시 시도하세요.

i18n

FIM One는 6개 언어(EN, ZH, JA, KO, DE, FR)를 지원합니다. 번역은 완전히 자동화되어 있습니다. 영어 소스 파일만 편집하세요:
  • frontend/messages/en/{namespace}.json — UI 문자열
  • docs/*.mdx (로케일 하위 디렉토리 아님) — 문서
  • README.md — 프로젝트 readme
다른 로케일 파일(messages/zh/, docs/zh/, README.zh.md 등)은 자동 생성되며, pre-commit 훅은 이들을 수동으로 편집하는 커밋을 무조건 거부합니다. 번역 오류를 수정하려면 scripts/translation-glossary.md를 편집하세요. 이것은 모든 번역 규칙이 주입되는 단일 정보 소스입니다. 그 다음 uv run scripts/translate.py --files <en-sources> --force로 영향받는 파일을 재생성하세요. 모든 용어집 수정은 5개 로케일 전체에 영구적으로 적용됩니다. 로케일 파일 생성 경로 2가지:
  1. 로컬 pre-commit 훅.envLLM_API_KEY가 설정되어 있으면 실행됩니다. 번역은 푸시 전에 발생하므로 출력을 미리 볼 수 있습니다.
  2. CI 폴백 — 로컬 훅에 키가 없어 건너뛴 경우, .github/workflows/i18n-sync.yml이 병합 후 master에서 번역하고 결과를 자동 커밋합니다.
API 키가 없는 기여자는 EN 변경사항을 자유롭게 커밋할 수 있습니다. CI 경로가 로케일이 올바르게 적용되도록 보장합니다. 새로운 i18n 네임스페이스 추가: messages/en/{ns}.json 생성 — 다른 로케일 파일은 다음 커밋이나 병합 후 CI에서 생성됩니다. 전체 재번역 강제 실행: uv run scripts/translate.py --all (로컬 LLM_API_KEY 필요).

데이터베이스 마이그레이션

개발 환경에서는 SQLite를 사용하고, 프로덕션 환경에서는 PostgreSQL을 사용합니다. 하나의 Alembic 마이그레이션 파일 세트가 둘 다에서 작동해야 합니다. 주요 규칙:
  • 모든 새로운 ORM 모델 또는 열에는 반드시 마이그레이션이 필요합니다 — metadata.create_all()에 의존하지 마세요.
  • 모든 마이그레이션은 멱등성을 가져야 합니다 — fim_one.migrations.helpers의 헬퍼 함수(table_exists, table_has_column, index_exists)를 사용하세요.
  • Boolean 기본값: server_default=sa.text("FALSE") / sa.text("TRUE"). 절대 "0" / "1"을 사용하지 마세요 — PostgreSQL은 Boolean 열에 대한 정수 리터럴을 거부합니다.
  • SQLite는 ALTER COLUMN을 지원하지 않습니다 — 열 제약 조건 변경의 경우 op.batch_alter_table()을 사용하세요.
  • 마이그레이션을 작성한 후 즉시 uv run alembic upgrade head를 실행하여 적용하세요.

빠른 참조