본문 바로가기
백엔드

카테캠4기 2단계/아이담 개발 1주차 — 백엔드 실행 기반을 다지고 협업 구조 정리하기

by 발빠진 쥐 2026. 9. 15.

아이담은 어린이집에서 수집한 사진, 영상, 음성 속 맥락을 바탕으로 관찰일지와 알림장 작성을 돕는 서비스다.

브라우저와 서버가 미디어를 처리하고, AI가 근거를 바탕으로 초안을 생성하면 교사가 이를 검토·승인한다. 최종적으로는 승인된 문서만 학부모에게 전달되는 구조를 목표로 한다.

개발 1주차에는 본격적인 기능 개발에 앞서 팀원들이 같은 환경에서 안정적으로 작업할 수 있도록 백엔드 공통 실행 기반을 정리하는 일에 집중했다.


1. 프로젝트 구조와 담당 범위 파악

프로젝트 백엔드는 기능에 따라 다음 7개 도메인으로 나뉜다.

도메인역할
auth 교사·학부모 인증
organization 기관·반·원아·동의 정보 관리
face 얼굴 임베딩 저장·관리
media S3 업로드 및 미디어 메타데이터 관리
agents AI 초안 생성 및 검증 파이프라인
documents 교사 검토·승인 및 학부모 공개
audit 접근·삭제 이력 기록

처음에는 AI 작업 큐와 worker 구성을 담당하는 것으로 이해했지만, 팀 분업이 변경되면서 현재 역할은 다음과 같이 정리됐다.

  • 백엔드 A: 인증과 공통 실행 기반
  • AI C: 근거 통합과 관찰일지·알림장 생성

역할이 바뀌면서 특히 중요했던 것은 “AI 기능”과 “AI 기능을 실행하는 백엔드”의 경계를 구분하는 일이었다.

AI C는 근거를 구성하고 프롬프트와 출력 형식을 만든다. 반면 실제 외부 API 호출, Celery 작업 실행, 결과 저장과 재시도는 domains/agents를 담당하는 백엔드 팀원이 구현한다.


2. FastAPI와 PostgreSQL 실행 환경 구성

가장 먼저 FastAPI 서버와 PostgreSQL을 Docker Compose로 함께 실행할 수 있는 환경을 정리했다.

현재 Compose 구성에는 다음 요소가 들어 있다.

  • FastAPI API 컨테이너
  • PostgreSQL 16 컨테이너
  • PostgreSQL 데이터 보존용 볼륨
  • API와 데이터베이스 상태 확인
  • 컨테이너 재시작 정책
  • 환경변수를 통한 접속 정보 관리

API에는 두 가지 상태 확인 주소를 두었다.

GET /health
GET /health/db

/health는 API 프로세스가 정상적으로 실행 중인지 확인하고, /health/db는 실제로 PostgreSQL에 SELECT 1을 실행해 연결 상태를 검사한다.

단순히 컨테이너가 실행됐는지만 확인하는 것이 아니라, 애플리케이션에서 데이터베이스까지 접근할 수 있는지 확인하도록 구성했다.


3. SQLAlchemy Base를 독립 모듈로 분리

초기 구조에서는 SQLAlchemy의 Base가 데이터베이스 연결 코드와 함께 놓여 있었다. 규모가 커지고 여러 도메인에서 모델을 정의하게 되면 순환 참조가 발생하거나 모델 로딩 순서가 복잡해질 수 있었다.

이를 방지하기 위해 Base를 별도 모듈로 분리했다.

backend/core/
├── base.py
├── config.py
└── database.py

각 파일의 책임은 다음과 같다.

  • base.py: 모든 ORM 모델이 상속할 SQLAlchemy Base
  • config.py: 환경변수와 애플리케이션 설정
  • database.py: 엔진, 세션과 DB 의존성

도메인 모델은 데이터베이스 연결 구현을 직접 참조하지 않고 core.base의 Base만 상속한다.

작은 변경처럼 보이지만, 이후 7개 도메인의 모델과 Alembic 마이그레이션을 추가할 때 구조가 꼬이지 않도록 만드는 작업이었다.


4. .env 생성 스크립트 안전성 개선

프로젝트에는 .env.example을 기반으로 실제 .env를 만드는 초기화 스크립트가 있다.

기존 스크립트는 다음 문자열을 찾아 생성한 PostgreSQL 비밀번호로 치환했다.

replace-with-a-generated-password

문제는 Python의 replace()가 대상 문자열을 찾지 못하더라도 오류를 발생시키지 않는다는 점이었다.

누군가 .env.example의 문구를 수정하거나 삭제하면 치환이 실패하지만, 스크립트는 정상 실행된 것처럼 보일 수 있다. 그 결과 기본 문구가 비밀번호로 남은 잘못된 .env가 만들어질 가능성이 있었다.

이를 막기 위해 치환 전에 대상 문자열이 정확히 존재하는지 검증하도록 변경했다.

검증 대상은 다음과 같다.

  • 치환 문구가 없는 경우
  • 치환 문구가 변경된 경우
  • 치환 문구가 중복된 경우
  • 기존 .env가 있는 경우
  • 정상적으로 비밀번호를 생성할 수 있는 경우

검증에 실패하면 .env를 만들거나 기존 파일을 덮어쓰지 않는다. 잘못된 설정 파일이 조용히 생성되는 상황을 차단한 것이다.

이 변경과 함께 초기화 스크립트 테스트도 추가했다.


5. 서버와 데이터베이스 시간대를 서울로 통일

로그, 생성 시간, 승인 시간처럼 시간이 중요한 서비스에서는 애플리케이션과 데이터베이스의 시간대가 다르면 오류를 찾기 어렵다.

특히 아이담은 다음과 같은 시간 정보를 다룬다.

  • 사진·영상 촬영 시간
  • 음성 구간 타임스탬프
  • 관찰일지 대상 날짜
  • 교사 승인 시간
  • 학부모 열람 및 회수 가능 시간

따라서 API와 PostgreSQL의 시간대를 모두 Asia/Seoul로 통일했다.

environment:
  TZ: Asia/Seoul

PostgreSQL에는 서버 시간대와 로그 시간대도 명시했다.

command:
  - postgres
  - -c
  - timezone=Asia/Seoul
  - -c
  - log_timezone=Asia/Seoul

컨테이너 환경변수만 설정하는 데서 끝내지 않고 PostgreSQL 설정값까지 적용해 DB가 반환하는 현재 시간과 로그 시간 모두 서울 시간으로 표시되는지 확인했다.


6. 테스트를 통한 공통 기반 검증

공통 기반의 변경은 이후 모든 도메인에 영향을 준다. 따라서 기능 수보다 “환경이 안정적으로 재현되는가”를 확인하는 것이 중요했다.

이번 주에는 다음 항목을 중심으로 테스트했다.

  • 환경변수 설정 검증
  • PostgreSQL 접속 정보 생성
  • ORM 모델의 공통 Base 사용 여부
  • .env 정상 생성
  • 치환 문구 누락·변경·중복 처리
  • 기존 .env 보호
  • API와 PostgreSQL 시간대

당시 작성된 전체 테스트 16개가 통과하는 것을 확인했다.

이 테스트들은 서비스 기능을 검사하기보다, 앞으로 팀원들이 기능을 추가할 때 공통 환경이 쉽게 깨지지 않도록 보호하는 역할을 한다.


7. Git 브랜치와 협업 문서 정리

프로젝트를 진행하면서 로컬 코드와 GitHub의 코드가 서로 달라지는 상황도 경험했다.

다른 팀원이 변경 사항을 공유하지 않은 채 원격 저장소에 반영하면서, 로컬에서 보고 있던 코드와 GitHub의 코드가 달라졌다. 이 과정에서 단순히 git pull부터 실행하면 기존 작업과 충돌하거나 작업 출처를 구분하기 어려울 수 있다는 점을 확인했다.

먼저 현재 브랜치와 변경 파일을 확인한 뒤 작업을 분리했다.

리팩터링 작업은 refactor 브랜치에 정리했고, 다음과 같은 단위로 커밋했다.

  • 불필요한 빈 Python 파일과 기존 문서 정리
  • SQLAlchemy Base 독립 모듈 분리
  • .env 초기화 검증 추가
  • API·PostgreSQL 시간대 설정

이후 refactor 브랜치를 원격 저장소에 push했다.

git push -u origin refactor

문서 작업은 별도의 feat/docs-claude-hierarchy 브랜치에서 필요한 파일만 가져왔다.

  • 루트 CLAUDE.md
  • backend/CLAUDE.md
  • backend/domains/agents/CLAUDE.md
  • backend/domains/face/CLAUDE.md
  • backend/domains/media/CLAUDE.md
  • docs/ 아래 프로젝트 문서

브랜치 전체를 병합하지 않고 필요한 문서만 가져오면서 코드 변경과 문서 변경을 구분할 수 있었다.


8. AWS EC2 개발 환경 시작

배포를 위한 AWS EC2 인스턴스를 생성하고 Systems Manager의 Session Manager를 통해 서버에 접속했다.

서버에서는 패키지 목록을 갱신하고 Python 패키지 도구를 설치했다.

sudo apt update
sudo apt install -y python3-pip

여기까지는 EC2 인스턴스 접속과 기본 준비 단계다. 아직 GitHub 코드 자동 배포나 실제 서비스 배포가 완료된 것은 아니다.

앞으로 EC2에서는 다음 작업이 필요하다.

  1. GitHub 저장소 연결
  2. Docker와 Docker Compose 준비
  3. 운영 환경변수 설정
  4. API·PostgreSQL·Redis·worker 실행
  5. Nginx 및 HTTPS 연결
  6. GitHub Actions를 이용한 배포 자동화
  7. 서비스 상태와 로그 확인

9. 설계 문서와 실제 코드의 차이 발견

문서를 검토하면서 설계와 현재 구현 사이에 몇 가지 차이가 있다는 점도 확인했다.

가장 큰 차이는 비동기 AI 작업 실행 기반이다.

domains/agents/tasks.py에는 Celery 작업의 골격이 있지만, 현재 다음 요소는 아직 없다.

  • backend/celery_app.py
  • Redis 서비스
  • Celery worker 서비스
  • Celery·Redis Python 의존성
  • 실제 AI 파이프라인 서비스 함수
  • 작업 상태와 결과 조회 흐름

즉, 코드에 작업 함수의 형태는 있지만 실제로 실행할 수 있는 상태는 아니다.

다만 변경된 분업에서는 이를 한 사람이 전부 구현하지 않는다.

  • 백엔드 A는 Redis·worker의 공통 실행 기반을 담당
  • 백엔드 agents 담당은 작업 등록, 파이프라인 실행과 결과 저장을 담당

또한 초기 문서에는 브라우저에서 Whisper를 실행하는 내용이 있었지만, 최신 AI 계획에서는 외부 STT API를 사용하는 방향으로 변경됐다.

이처럼 문서가 여러 버전으로 나뉘면 팀원마다 서로 다른 구조를 구현할 수 있기 때문에, 기능 개발 전에 최신 결정을 하나의 문서로 맞추는 작업이 필요하다.


10. 이번 주에 배운 점

이번 주는 사용자에게 직접 보이는 기능보다 기반 작업이 많았다. 하지만 공통 기반이 흔들리면 팀원들이 각자 만든 기능을 나중에 합치는 데 더 많은 시간이 든다.

특히 다음 세 가지를 배웠다.

첫째, 설정 스크립트는 정상 상황보다 실패 상황을 먼저 고려해야 한다. 문자열 치환처럼 단순한 작업도 실패 여부를 명시적으로 검사하지 않으면 잘못된 설정이 조용히 만들어질 수 있다.

둘째, 브랜치를 병합하기 전에 로컬 변경과 원격 변경을 먼저 확인해야 한다. 누가 만든 변경인지 모르는 상태에서 코드를 섞으면 충돌을 해결하더라도 변경 의도를 잃기 쉽다.

셋째, 담당 영역은 폴더 이름만으로 나눌 수 없다. AI 프롬프트 작성, 외부 API 호출, 작업 큐 실행, DB 저장은 하나의 흐름에 들어 있지만 각각 다른 책임이다. 먼저 입출력 형식과 책임 경계를 합의해야 병렬로 개발할 수 있다.


다음 주 계획

다음 주부터는 두 역할의 실제 기능 구현을 시작한다.

AI C 영역에서는 다음 작업을 진행할 예정이다.

  • 원아·날짜별 근거 묶음 구성
  • 다른 원아와 다른 날짜 자료 제외
  • 사진 관찰·아동 발화·교사 진술·활동계획 구분
  • 이름을 토큰으로 바꾸는 비식별 입력 구성
  • 관찰일지와 알림장 생성 프롬프트 작성
  • 생성 문장과 근거 ID 연결
  • 검증 실패 결과를 반영하는 재생성 프롬프트 작성

백엔드 A 영역에서는 다음 작업을 진행한다.

  • Account, Teacher, Parent 인증 모델 설계
  • 인증 요청·응답 스키마와 서비스 구현
  • 다른 도메인이 현재 사용자를 확인할 공통 인증 기능 구성
  • Redis·Celery worker 실행 기반의 담당 경계 확정
  • Alembic 초기 설정과 마이그레이션 사용법 정리
  • EC2 배포 환경 연결

아이담 개발 1주차는 기능을 빠르게 늘리는 시간이라기보다, 팀이 같은 구조와 환경에서 개발할 수 있도록 바닥을 다지는 시간이었다. 다음 주에는 이 기반 위에서 실제 인증과 AI 문서 생성 흐름을 하나씩 연결해 볼 예정이다.