Skip to content

Repository files navigation

Bridgework Backend

사용자가 업로드한 사진의 개인정보 위험을 분석하고, 버전형 보호 결과와 프롬프트 기반 이미지 후처리 작업을 관리하는 모바일 앱의 백엔드 서버.

컴포넌트 역할
backend (FastAPI) 프론트엔드 REST API, S3 관리, Celery task 발행
worker (Celery) 비동기 이미지 처리 — AI 서버 HTTP API 호출
beat (Celery Beat) 타임아웃 스위퍼 스케줄러 (매 1분)
db (PostgreSQL 15) 분석 태스크, 비동기 operation, 버전별 이미지 결과
rabbitmq (RabbitMQ 3) 메시지 브로커

아키텍처

[React Native] --REST--> [FastAPI :8000] --Celery task--> [RabbitMQ :5672]
                              |                                  |
                              v                                  v
                        [PostgreSQL]                      [Celery Worker]
                              |                                  |
                              v                                  v
                         [AWS S3]  <-- presigned URL -->  [AI Server :8001]

플로우: v1 업로드·분석 → v2 보호 처리 operation 생성 → AI 서버 v2 /process 호출 → 버전 1 결과 저장 → 사용자 프롬프트와 기준 output 선택 → 새 edit operation 생성 → AI 서버 v2 /edit 호출 → 개인정보 보호가 재적용된 다음 결과 버전 저장. 프론트는 operation API를 폴링한다.

개발 환경

요구사항: uv, Docker + Docker Compose.

uv sync --dev                 # 의존성 설치 (Python 3.12 자동 관리)
uv run ruff check .           # 린트
uv run ruff format --check .  # 포맷 검사
uv run pytest                 # 단위 테스트 (외부 서비스 불필요)

로컬 전체 스택 실행 (E2E)

AWS/AI 서버 없이 MinIO(S3 호환) + 모의 AI 서버로 전체 플로우를 실행:

cp .env.example .env
docker compose -f docker-compose.yml -f docker-compose.local.yml up -d --build
서비스 주소
Backend API / Swagger http://localhost:8000 · http://localhost:8000/docs
RabbitMQ 관리 UI http://localhost:15672 (bw_user / strongpassword)
MinIO 콘솔 http://localhost:9001 (minioadmin / minioadmin)
Mock AI 서버 http://localhost:8001/health

운영 배포에서는 docker-compose.local.yml 없이 실제 AWS S3(IAM/환경변수 자격증명)와 실제 AI 서버(AI_SERVER_URL)를 사용한다.

Ping 테스트 / API 사용 명령어

BASE를 환경에 맞게 설정: 로컬 http://localhost:8000, 운영 http://3.34.99.130:8000.

BASE=http://localhost:8000

# 0) 서버 living 확인 (ping)
curl -s $BASE/api/v1/health
# → {"status":"ok","database":"connected"}

# 0-1) AI 서버 프록시 헬스체크
curl -s $BASE/api/v1/health/ai
# → {"ai_server":"ok","gpu_available":true,"model_loaded":true} 또는 {"ai_server":"down"}

# 1) 이미지 업로드 (JPEG/PNG, ≤10MB) → task_id 수신
curl -s -X POST $BASE/api/v1/images/upload \
  -F "file=@photo.jpg" \
  -F "remove_metadata=true"
# → {"task_id":"<uuid>","status":"PENDING"}

# 2) 상태 폴링 (3초 간격 권장) — ANALYZED가 되면 analysis 필드에 분석 결과 포함
TASK_ID=<uuid>
curl -s $BASE/api/v1/images/$TASK_ID/status

# 3) 처리 요청 (ANALYZED 상태에서만 가능; 빈 배열이면 딥페이크 방지만 적용)
curl -s -X POST $BASE/api/v1/images/$TASK_ID/process \
  -H "Content-Type: application/json" \
  -d '{
    "selected_regions": [
      {
        "detection_id": "det_plate_001",
        "risk_group": "VEHICLE",
        "polygon": [[820,750],[1100,750],[1100,840],[820,840]]
      }
    ]
  }'
# → {"task_id":"<uuid>","status":"PROCESSING"}

# 4) 상태 폴링 → SUCCESS가 되면 result_url 포함
curl -s $BASE/api/v1/images/$TASK_ID/status

# 5) 결과 이미지 다운로드 (result_url은 1시간 만료 presigned URL — 매 조회마다 새로 서명됨)
curl -s "$RESULT_URL" -o protected.png

v2 버전형 처리와 프롬프트 편집

업로드와 최초 분석은 위 v1 API를 그대로 사용한다.

# Step 2) 버전형 보호 처리 요청
curl -s -X POST $BASE/api/v2/images/$TASK_ID/process \
  -H "Content-Type: application/json" \
  -d '{"selected_regions": []}'
# → {"operation_id":"<uuid>","operation_type":"PRIVACY_PROCESS","status":"QUEUED",...}

OPERATION_ID=<uuid>
curl -s $BASE/api/v2/image-operations/$OPERATION_ID
# SUCCESS 응답의 output.output_id를 다음 편집 기준으로 사용

# Step 3) 사용자 프롬프트 기반 후처리
BASE_OUTPUT_ID=<uuid>
curl -s -X POST $BASE/api/v2/images/$TASK_ID/edits \
  -H "Content-Type: application/json" \
  -d "{\"base_output_id\":\"$BASE_OUTPUT_ID\",\"prompt\":\"배경을 따뜻하게 바꿔줘\"}"
# → 새 operation_id와 output_version 반환

v2는 image_outputs에 부모 결과와 버전을, image_operations에 비동기 상태를 저장한다. 결과 객체는 protected/v2/{task_id}/{output_id}.png에 저장하며 기존 결과를 덮어쓰지 않는다.

에러 응답 형식: {"error": {"code": "...", "message": "..."}} — 전체 에러코드 목록은 docs/INTERFACE-FOR-FRONTEND.md 참조.

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

uv run alembic upgrade head                          # 적용 (compose에서는 backend 시작 시 자동 실행)
uv run alembic revision --autogenerate -m "message"  # 새 마이그레이션 생성

CI/CD

.github/workflows/cicd.yml — main 브랜치 push / PR 시 실행:

  1. quality — ruff 린트/포맷 + pytest + Alembic 마이그레이션 왕복 검증
  2. containerghcr.io/tech4good-one-t/backend(API), ghcr.io/tech4good-one-t/backend-worker(worker/beat) 이미지 빌드·푸시 (latest + sha-<commit> 태그)
  3. deploy — GitHub OIDC → AWS SSM으로 backend EC2에 deploy/ec2-deploy.sh 실행 (compose pull & up + 헬스체크)

deploy 활성화에 필요한 설정 (미설정 시 deploy job은 자동 skip):

종류 이름
Repository variable AWS_ROLE_ARN GitHub OIDC로 assume할 IAM Role ARN (SSM SendCommand + Parameter Store 권한)
Repository variable EC2_INSTANCE_ID backend EC2 인스턴스 ID (SSM Agent 필요)
EC2 파일 /opt/bridgework-backend/.env .env.example 기반 운영 환경변수 (최초 1회 수동 배치)

EC2 사전 요구사항: Docker + Docker Compose + AWS CLI + SSM Agent, S3 접근용 IAM Role(infra/aws-infra-commands.sh 참조).

디렉토리 구조

├── app/               # FastAPI 앱 (api/, models/, schemas/, services/, worker/)
├── alembic/           # DB 마이그레이션
├── deploy/            # 운영 배포 스크립트 + prod compose
├── docs/              # 인터페이스 계약서, AI API 명세
├── infra/             # AWS 인프라 설정 명령어 모음
├── local/mock-ai/     # 로컬 E2E용 모의 AI 서버
├── scripts/           # RabbitMQ 초기화 등
└── tests/             # pytest 단위 테스트

보안 / 운영 주의사항

  • Presigned URL은 절대 로깅 금지 (임시 서명 포함) — OCR 원문/EXIF/GPS도 로깅 금지
  • 사용자 편집 프롬프트를 로그나 Celery 메시지 인자에 기록하지 않는다. worker는 DB에서 읽는다.
  • Celery result backend 미사용 (task_ignore_result=True) — worker가 DB에 직접 결과 기록
  • 상태 전이는 SELECT ... FOR UPDATE로 직렬화, 스위퍼가 15분 이상 정체된 task를 FAILURE(TASK_TIMEOUT) 처리
  • API 스키마 변경 시 docs/INTERFACE-FOR-*.md를 반드시 함께 갱신하고 담당자에게 공유

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages