BE 하네스 심층
be-agent-harness 프리셋의 21개 규칙 + 19개 스킬을 카테고리별로 완전 분석합니다.
Flask/Python 백엔드 개발에 필요한 AI 운영 가이드라인 전체.

BE 기술 스택 규칙

tech-stack 1개 rule

be-stack-and-commands — GS Retail BE 표준 기술 스택과 명령어 기준선

레이어기술역할
FrameworkFlask웹 레이어. 항상 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 모델 생성
LanguagePython ≥3.11 (완전 type-hinted)모든 public 함수 annotate. 도메인 모델은 dataclass/Pydantic.
데이터AWS DynamoDB (local-first)모든 접근은 repository seam 뒤에. PoC/MVP는 local datastore. AWS는 준비됐을 때만
패키지 매니저uvuv sync, uv add, uv run. pip/poetry 사용 금지
⚠️ ASGI 서버 필수: Connexion 3.x는 ASGI입니다. bare WSGI server(plain gunicorn sync worker, serverless-wsgi) 사용 금지. Lambda는 Mangum 사용.

Flask 아키텍처 규칙

flask-architecture 3개 rules

레이어드 아키텍처

Routes (thin)
Connexion operationId → handler 함수. HTTP 파싱/직렬화만. 비즈니스 로직 없음.
Service Layer
비즈니스 로직. Flask import 없음. Repository를 주입받아 사용. 여기서 로직 결정.
Repository
boto3가 나타나는 유일한 곳. AbstractRepository interface + concrete impl. moto로 테스트.
Domain Models
dataclass 또는 Pydantic BaseModel. 순수 Python. 어떤 프레임워크도 import 안 함.

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 포함).

영속성 규칙

persistence 1개 rule

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)

타입 힌트 & 도메인 모델 규칙

type-modeling 1개 rule

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

워크플로우 규칙

workflow 4개 rules
  • plan-first: 코드 전에 구현 계획 (레이어 설계, 함수 시그니처, 변경 파일)
  • be-tdd: Red-Green-Refactor — 실패하는 pytest (서비스 유닛 테스트 또는 test_client 기능 테스트) 먼저
  • cleanup-after-green: 테스트 통과 후 ruff format, 죽은 import 제거, print 삭제
  • codegraph-first: 파일 직접 grep/read보다 CodeGraph 지식 그래프 (심볼, 콜 그래프, 영향) 우선 사용

보안 규칙

security 4개 rules
  • 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

기타 규칙들

naming, version-control, code-quality, critic-loop, guardrails 7개 rules
  • 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 scaffold-flask-resource sync-api-contracts-init
스킬역할
openapi-first-flask-initcontract-first Flask/Connexion 서비스 one-time 설정. Connexion + datamodel-code-generator, zero-Java 순수 Python 툴체인.
scaffold-flask-resourceREST resource 레이어 생성 — thin handler + service + request/response schema + domain model + AbstractRepository + FakeRepository + pytest 스켈레톤
sync-api-contracts-initOpenAPI spec → Pydantic 모델 생성 설정 스캐폴더

영속성 (2개)

setup-local-datastore provision-dynamodb-aws
스킬역할
setup-local-datastoreDynamoDB Local (Docker) + moto pytest fixture 설정. AWS 계정 없이 로컬 개발. PoC/MVP 단계.
provision-dynamodb-aws로컬 DynamoDB → 실제 AWS 전환. CDK/SAM/Terraform IaC, 최소 IAM, 런타임 역할 자격증명.

배포 (1개)

deploy-flask-aws

Flask/Connexion 서비스를 AWS에 배포 — gunicorn+UvicornWorker ECS/Fargate, 또는 Lambda+Mangum. DynamoDB 런타임 IAM 역할 설정 포함.

인증 (1개)

azure-ad-sso-flask

Azure AD SSO Flask 백엔드 — Bearer 토큰 JWKS 검증 (RS256), /acl 엔드포인트, @require_auth 데코레이터. deploy-edu Module 01 참조.

Git (3개)

conventional-commits pre-stage-secret-scan bitbucket-server

문서화 (1개)

api-docs

공개 프로그래밍 인터페이스 (함수, 메서드, 클래스, HTTP 엔드포인트) 문서 작성/업데이트. 시그니처, 요청/응답 형태, 상태 코드, 에러 동작, 계약이 변경될 때.

디버깅 (1개)

root-cause

버그/실패/크래시 수정 전 근본 원인 파악. 재현 가능한 테스트 케이스 작성, 가설 검증 후 수정.

QA & DevOps (5개)

generate-pytest-tests check-flask-deploy-readiness generate-pr-summary address-pr-feedback audit-security-baseline

상세 내용은 Module 08 — QA & 코드리뷰.

코드리뷰 (2개)

are-we-done pr-review-be
스킬사용 시점
are-we-donePR 열기 전 — SHIP/FIX-FIRST 판정
pr-review-beBE 전용 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 플래그로만
BE 하네스의 핵심 철학: 비즈니스 로직은 Flask를 모른다. Service 레이어가 Flask, Connexion, DynamoDB를 import하지 않으면 순수 Python 함수 단위 테스트가 가능해지고, 프레임워크 교체나 Lambda 이전도 훨씬 쉬워집니다.