Flask/Python 백엔드 개발에 필요한 AI 운영 가이드라인 전체.
BE 기술 스택 규칙
be-stack-and-commands — GS Retail BE 표준 기술 스택과 명령어 기준선
| 레이어 | 기술 | 역할 |
|---|---|---|
| Framework | Flask | 웹 레이어. 항상 application factory(create_app) 사용 — 모듈 전역 app 객체 금지 |
| API 런타임 | Connexion 3.x (ASGI) | OpenAPI spec에서 라우팅/요청검증/인증 구동. Connexion 3은 ASGI — uvicorn/gunicorn+UvicornWorker로 서빙 |
| 계약 | OpenAPI YAML 3.0 (contract-first) | spec이 SSOT. 먼저 작성 후 Connexion이 런타임에서 사용. datamodel-code-generator로 Pydantic 모델 생성 |
| Language | Python ≥3.11 (완전 type-hinted) | 모든 public 함수 annotate. 도메인 모델은 dataclass/Pydantic. |
| 데이터 | AWS DynamoDB (local-first) | 모든 접근은 repository seam 뒤에. PoC/MVP는 local datastore. AWS는 준비됐을 때만 |
| 패키지 매니저 | uv | uv sync, uv add, uv run. pip/poetry 사용 금지 |
Flask 아키텍처 규칙
레이어드 아키텍처
flask-app-architecture 핵심 제약:
- 모듈 전역
app = Flask(__name__)절대 금지 → 항상create_app()factory - extension 객체는 unbound로 모듈 상단 선언, factory 안에서
ext.init_app(app) - Blueprint 등록은 factory 안에서만
- 비즈니스 로직은 Flask를 import하지 않음
# ❌ 금지 패턴 — 모듈 전역 app
app = Flask(__name__)
db = SQLAlchemy(app) # 이 패턴은 테스트와 팩토리 패턴을 막음
# ✅ application factory + unbound extensions
db = SQLAlchemy() # unbound
def create_app(config=None):
app = Flask(__name__)
db.init_app(app)
app.register_blueprint(api_bp)
return app
openapi-first-contract: OpenAPI YAML → SSOT. 손으로 생성 트리 편집 금지. Connexion이 spec에서 라우팅/검증 수행.
# Connexion은 operationId를 hand-written handler로 연결
# openapi.yaml
paths:
/api/users:
get:
operationId: app.handlers.users.list_users # ← 이 함수가 실제 구현
# handlers/users.py — Flask import 없음
def list_users(limit: int = 20) -> list[User]:
return user_service.list(limit=limit)
api-error-and-health: 글로벌 에러 핸들러, liveness/readiness 엔드포인트, 구조화 로그 (request ID 포함).
영속성 규칙
dynamodb-data-access 핵심 제약:
- 모든 boto3 코드는 repository seam 뒤에. service layer는 AbstractRepository에만 의존.
- access-pattern first: GSI 설계는 쿼리 패턴에서 시작. full-scan/N+1 금지.
- 개발은 local-first: DynamoDB Local (Docker). AWS는 준비됐을 때 connect.
- 테이블 프로비저닝은 IaC (CDK/SAM/Terraform). app 코드에서
create_table호출 금지. - FakeRepository (in-memory dict)로 서비스 레이어 단위 테스트. moto로 repository 테스트.
# AbstractRepository seam
class AbstractUserRepository(ABC):
@abstractmethod
def get(self, user_id: str) -> User | None: ...
@abstractmethod
def save(self, user: User) -> None: ...
# DynamoDB 구현
class DynamoUserRepository(AbstractUserRepository):
def __init__(self, table_name: str):
self._table = boto3.resource('dynamodb').Table(table_name) # boto3는 여기만
# 테스트용 FakeRepository
class FakeUserRepository(AbstractUserRepository):
def __init__(self): self._store: dict[str, User] = {}
def get(self, user_id: str) -> User | None: return self._store.get(user_id)
타입 힌트 & 도메인 모델 규칙
python-type-hints: 모든 public 함수에 type annotation. mypy로 검사 (gradual, ratcheting). 도메인 엔티티는 dataclass/Pydantic으로 명시적 정의.
# ✅ 완전한 type annotation
from dataclasses import dataclass
from typing import Optional
@dataclass
class User:
id: str
name: str
role: str
email: Optional[str] = None
def get_user(user_id: str) -> Optional[User]:
...
# mypy 설정 (pyproject.toml)
[tool.mypy]
python_version = "3.11"
strict = true
워크플로우 규칙
- plan-first: 코드 전에 구현 계획 (레이어 설계, 함수 시그니처, 변경 파일)
- be-tdd: Red-Green-Refactor — 실패하는 pytest (서비스 유닛 테스트 또는 test_client 기능 테스트) 먼저
- cleanup-after-green: 테스트 통과 후 ruff format, 죽은 import 제거, print 삭제
- codegraph-first: 파일 직접 grep/read보다 CodeGraph 지식 그래프 (심볼, 콜 그래프, 영향) 우선 사용
보안 규칙
- backend-api-access-control: BOLA 방지 (객체 레벨 권한), 모든 요청 인증, 비밀 정보는 env/Secrets Manager, IAM 최소 권한 (특정 table/index ARN 범위), CORS 허용 목록, rate limiting, 보안 헤더
- no-hardcoded-secrets: 소스 코드에 API 키/토큰/비밀 커밋 금지
- sanitize-untrusted-input: 모든 외부 입력을 신뢰 불가로 처리. SQL/command injection, path traversal 방지
- mask-pii: 로그/에러/애널리틱스에 원시 PII/토큰/자격증명 노출 금지
# ✅ BOLA 방지 예시 — 항상 current user의 소유권 확인
@require_auth
def get_document(document_id: str, current_user: User) -> Document:
doc = document_repo.get(document_id)
if doc.owner_id != current_user.id: # 소유권 검증 필수
raise Forbidden("Not your document")
return doc
기타 규칙들
- python-casing: snake_case (함수/변수/모듈/파일), PascalCase (클래스), UPPER_SNAKE_CASE (상수)
- commits: Conventional Commits, 명령형 제목
- language-policy: 코드/커밋=영어, PR/UI=한국어
- no-comments: WHY가 자명하지 않은 경우에만 주석. 코드가 WHAT을 설명해야 함. 멀티라인 docstring 금지.
- autonomous-retry: 빌드/lint/테스트 실패 시 최대 3회 자율 수정
- protected-config-be: pyproject.toml, uv.lock, OpenAPI spec, IaC, CI 설정 수동 승인 없이 수정 금지
BE 하네스 스킬 카탈로그 (19개)
API 연동 (3개)
| 스킬 | 역할 |
|---|---|
openapi-first-flask-init | contract-first Flask/Connexion 서비스 one-time 설정. Connexion + datamodel-code-generator, zero-Java 순수 Python 툴체인. |
scaffold-flask-resource | REST resource 레이어 생성 — thin handler + service + request/response schema + domain model + AbstractRepository + FakeRepository + pytest 스켈레톤 |
sync-api-contracts-init | OpenAPI spec → Pydantic 모델 생성 설정 스캐폴더 |
영속성 (2개)
| 스킬 | 역할 |
|---|---|
setup-local-datastore | DynamoDB Local (Docker) + moto pytest fixture 설정. AWS 계정 없이 로컬 개발. PoC/MVP 단계. |
provision-dynamodb-aws | 로컬 DynamoDB → 실제 AWS 전환. CDK/SAM/Terraform IaC, 최소 IAM, 런타임 역할 자격증명. |
배포 (1개)
Flask/Connexion 서비스를 AWS에 배포 — gunicorn+UvicornWorker ECS/Fargate, 또는 Lambda+Mangum. DynamoDB 런타임 IAM 역할 설정 포함.
인증 (1개)
Azure AD SSO Flask 백엔드 — Bearer 토큰 JWKS 검증 (RS256), /acl 엔드포인트, @require_auth 데코레이터. deploy-edu Module 01 참조.
Git (3개)
문서화 (1개)
공개 프로그래밍 인터페이스 (함수, 메서드, 클래스, HTTP 엔드포인트) 문서 작성/업데이트. 시그니처, 요청/응답 형태, 상태 코드, 에러 동작, 계약이 변경될 때.
디버깅 (1개)
버그/실패/크래시 수정 전 근본 원인 파악. 재현 가능한 테스트 케이스 작성, 가설 검증 후 수정.
QA & DevOps (5개)
상세 내용은 Module 08 — QA & 코드리뷰.
코드리뷰 (2개)
| 스킬 | 사용 시점 |
|---|---|
are-we-done | PR 열기 전 — SHIP/FIX-FIRST 판정 |
pr-review-be | BE 전용 PR 리뷰 — repository seam, no Scan/N+1, auth/BOLA, 비밀/IAM 최소권한, type hints, 생성 트리 미수정 여부 |
BE 하네스 표준 명령어
# 의존성 설치
uv sync
# 의존성 추가
uv add requests
# lint + 자동 수정
uv run ruff check --fix
# 포맷
uv run ruff format
# type check
uv run mypy .
# 테스트
uv run pytest
# OpenAPI spec 검증
uv run openapi-spec-validator openapi.yaml
# typed Pydantic 모델 재생성
uv run datamodel-codegen \
--input openapi.yaml --input-file-type openapi \
--output-model-type pydantic_v2.BaseModel \
--strict-nullable \
--output app/api/models.py
# 개발 서버
uv run uvicorn app:create_app --factory --reload
12-factor 설정 관리
| 원칙 | 구현 |
|---|---|
| 환경별 Config 클래스 | Config → Development/Testing/Production, env var로 선택 |
| 비밀은 환경 변수 | python-dotenv + git-ignored .env (로컬). 프로덕션은 SSM/Secrets Manager |
| 코드-환경 분리 | DynamoDB endpoint_url, AWS_REGION, table name은 env에서. 로컬/AWS를 config로만 분기 |
| DEBUG=True 금지 | 프로덕션에서 절대 금지 (Werkzeug RCE debugger 노출). 개발 시 --debug 플래그로만 |