본 글에서는 handDoc 서비스에서의 API 구현 과정을 정리해보겠다.
예약 생성 → 예약 조회 → 의사 수락 → Telemed 연동까지 이어지는 전체 흐름을 기준으로 설명한다.
1. 로컬 개발 환경 구성
handDoc 백엔드는 모든 팀원이 동일한 환경에서 개발할 수 있도록 Docker 기반으로 구성된다.
1) 필요 도구 설치
- IntelliJ IDEA
- Docker Desktop (로컬 실행 시 항상 켜둬야 함)
2) 리포지토리 클론
git clone https://github.com/handdoc/backend.git
3) 통합 개발 환경 (docker-compose)
레포지토리에는 docker-compose.yml이 포함되어 있으며, MySQL, Redis 등 필요한 모든 로컬 환경을 자동으로 띄우도록 설정돼 있다.
docker-compose up -d

4) .env 설정
팀 공용 .env 템플릿을 기준으로 로컬에서 사용할 환경변수를 생성한다.
2. 데이터베이스 연결 방식
1) 로컬 DB 연결
로컬 개발 시 인텔리제이 Database 탭에서 docker-compose.yml에 정의된 설정대로 연결한다.
2) 배포 환경 DB
- MongoDB Atlas (채팅/요약 로그 저장)
- MySQL RDS (서비스 핵심 엔티티)
3. 브랜치 전략
- main : 배포 브랜치
- develop : 통합 개발 브랜치
- 이슈 단위로 feature/{issue-name} 브랜치 생성 후 개발
GitHub 이슈 → Development → Create a branch 기능을 사용해 브랜치를 자동 생성하도록 했다.
이제 본격적으로 ERD와 API를 설계한 구조에 대해 설명해보려 한다.
1. ERD 설계 및 Domain 구조
기능 구현 전, 진료 예약 과정에 필요한 엔티티 구조를 우선 정의했다.
본 ERD(Entity Relationship Diagram)은 비대면 진료 서비스(handDoc) 를 구성하는 핵심 데이터 모델을 나타낸다.
시스템은 크게 예약, 실시간 비대면 진료, 진료 요약, 사용자 / 의사 정보, 병원 정보 다섯 영역으로 구성되어 있으며, 각각이 자연스럽게 연결되어 하나의 진료 플로우를 형성한다.

1. 예약(Reservation): 전체 흐름의 기준점
Reservation 테이블은 시스템의 중심 역할을 한다. 환자가 입력한 증상, 통역 여부, 진료 날짜/시간, 담당 의사 프로필 등의 정보가 기록된다. 예약 ID는 이후 Telemed(비대면 진료) 와 Summary(진료 요약) 로 이어지는 모든 과정의 기준이 된다.
주요 필드
- 증상(symptom), 세부설명(description)
- 통역 필요 여부(interpolation_option)
- 진료 날짜(slot_date), 시작/종료 시간(start_time, end_time)
- doctor_profile_id / user_id FK
2. 비대면 진료(Telemed): 실시간 세션 관리
Telemed 테이블은 예약을 기반으로 생성되며, 실제로 의사와 환자가 접속해 진료를 진행하는 세션 상태를 기록한다.
주요 내용
- 세션 시작/종료 시간
- 의사/환자 입장 여부
- 예약 ID(FK)와 연결
진료 중 발생하는 대화 로그는 RDB가 아닌 MongoDB 의 Telemed_Chat_Log 컬렉션에 저장하여, 로그성 데이터의 특성과 확장성을 고려했다.
3. Summary: 진료 종료 후 생성되는 요약
진료가 종료되면 Summary 엔티티가 생성된다.
Telemed 또는 Reservation과 연결되어 있고, 의사가 작성한 요약 정보가 저장된다.
포함되는 정보
- 증상 요약(symptom)
- 의사 소견(impression)
- 처방(prescription)
- 진료실 ID(room_id)
4. 사용자 / 의사 프로필 정보
Users
환자와 의사 모두를 포함하는 공통 사용자 테이블이다. 이메일, 이름, 로그인 타입(소셜/일반), 주민등록번호 등 기본적인 사용자 정보가 저장된다.
Doctor_Profile
의사 전용 상세 프로필로 전문의 과목, 병원명, 소개글, 의사 상태 등이 포함된다. Users와 1:1 관계로 연결되어 있어, 사용자 계정을 기반으로 의사 프로필이 확장되는 형태다.
Doctor_Tag
의사의 전문분야를 태그 형식으로 추가할 수 있는 구조이다.
5. 병원 정보(Hospital 도메인)
Hospital
병원 개별 정보(주소, 위도/경도 등)를 저장한다.
Hospital_Hours
병원의 요일별 운영시간을 가지고 있으며, '병원-운영시간(1:N)' 구조로 설계되어 있다.
의사 프로필은 병원명과 연결되어 있어, 같은 병원 소속 의사 여러 명이 존재할 수 있다.
전체 구조 흐름 요약
- 환자(Users) 가 진료를 예약 → Reservation
- 예약 시간에 맞춰 비대면 진료(Telemed) 세션 시작
- 진료 내용은 MongoDB Chat Log 에 저장
- 종료 후 Summary 생성
- 모든 과정은 병원(Hospital) 및 의사(Doctor_Profile) 정보와 종합적으로 연결됨
2. API
그 다음으로, API 구성은 다음과 같다. handDoc 서버는 기능별로 API를 모듈화해 관리한다. 각 도메인은 명확한 prefix를 가지고 있으며, 역할 단위로 구분되어 확장성과 유지보수성을 높였다.

Map: GET으로 지도에서 주변 병원 조회, POST로 공공데이터 병원 정보 DB 적재
Diagnosis: POST로 진료 세션 생성, POST로 수어 텍스트 저장, POST로 의사 음성(CLOVA CSR) 저장, PATCH로 진료종료, GET으로 진료 요약을 제공한다.

Auth: POST로 소셜로그인, 일반 회원가입, 일반로그인을 진행한다.
Reservation: 환자-의사 간 진료 예약을 관리하는 API이다. POST로 환자 진료 예약을 진행하고, DELETE로 예약을 취소한다. 또 GET으로 단건 예약을 조회하고 GET으로 의사 전체 예약을 조회한다.

Doctor: 환자 화면에서 의사를 검색하는 API이다. GET으로 의사목록과 의사 상세 조회를 진행한다.

Telemed: 실시간 화상진료(WebRTC)와 관련된 모든 기능을 담당하는 API이다. POST로 진료실 입장을 하고 DELETE로 진료를 종료한다. POST로 환자 수어 텍스트를 전달하고 POST로 환자 음성을 STT하고 GPT에 입력해 3개후보로 나타낸다. 또 POST로 선택한 문장을 의사에게 전달한다. 그리고 GET으로 진료요약조회, 진료내역조회를 진행한다.

User: 기초 환자정보를 입력하는 API이다.
POST로 이름을 작성하고 resident-id 주민등록번호를 입력한다.
트러블슈팅 - Telemed 연동에서 발생한 문제 및 해결
Telemed 초기 구현은 다음과 같은 흐름을 사용했다.
findByUserId → 최근 예약 1건 조회
하지만 실제 진료 로직은 reservationId 기반이므로 findByUserId 자체가 필요하지 않은 구조였다. 다만 기존 코드 오류 방지를 위해 <최근 예약 한 건만 가져오는 nativeQuery> 를 최소 수정으로 추가해두었다.
이후 실제 Telemed 연동은 reservationId 기반으로 처리되므로 해당 메서드는 사용되지 않아도 무관하다.
7. 개발 완료 후 PR 작성
기능 구현 → 로컬 테스트 → GitHub PR 생성
레포지토리에서 PR 관리 정책을 따르고 있으며, 리뷰 후 merge 하는 구조다.
'프로젝트 > EWHA 캡스톤 졸업프로젝트' 카테고리의 다른 글
| [졸업프로젝트] handDoc 수어 인식 모델 구축 튜토리얼 : MediaPipe → BiLSTM 학습까지 전 과정 (0) | 2025.11.24 |
|---|---|
| [졸업프로젝트] handDoc 배포 환경 구축 정리 (AWS EC2 + Docker + Nginx + FastAPI + Spring Boot) + 트러블슈팅 (0) | 2025.11.23 |
| [졸업프로젝트] handDoc AI 모델(수어인식/음성교정) 구축 과정 (1) | 2025.11.18 |
| [졸업프로젝트] handDoc_ 서비스 핵심 기능과 전체 아키텍처 설계 (0) | 2025.11.18 |
| [졸업프로젝트] 청각장애인 대상 진료 플랫폼, handDoc 기획 (1) | 2025.11.12 |