LS이수종
← 프로젝트 목록

2026 보건의료빅데이터·AI 활용 창업경진대회

엄마약

자녀가 부모의 약·기저질환·알레르기를 등록하면 위험한 조합을 세 겹으로 걸러내고, 날씨 조건에 맞춰 주의 알림을 보내며, 응급실에서 로그인 없이 열 수 있는 QR 카드를 제공합니다.

기간2026.05
백엔드 2인 중 1인
내 역할공통 기반 · 안전 검증 · 알림 · 응급카드
스택Java 21 · Spring Boot 4 · PostgreSQL · Redis

담당 범위

시스템 아키텍처

자녀 앱 JWT 인증 응급카드 QR 인증 없음 · /em Bucket4j Spring Boot 4 · Java 21 SafetyJudge — 3겹 안전망 1 · DUR 연령 · 임부 금기 2 · NB 환자분류 금기 3 · 알레르기 성분 교차검사 SafetyBlockException → HTTP 409 응급카드 snapshot 자동 갱신 날씨 ETL · 32룰 조회 일일 배치 → 검수 큐 → 푸시 PostgreSQL · Flyway app / ref 스키마 분리 Redis · Redisson 캐시 · 분산 락 HIRA 공공 XML API ×3 병원 · 상세 · 질병코드 FCM 날씨 주의 푸시 DUR·KCD CSV(cp949) 적재
인증된 자녀 앱과 인증 없이 열리는 응급카드 QR이 같은 서버로 들어오되, 공개 경로에는 요청 제한을 따로 걸어 분리했습니다.

API 설계 구조

모든 개인 데이터가 “부모”에 종속되므로 /v1/parents/{parentId}를 공통 접두어로 두고 하위 자원을 중첩했습니다. 반대로 응급카드 공개 조회는 QR로 찍히는 주소라 /em이라는 짧은 별도 경로로 뺐습니다.

경로접근 주체역할
/v1/parents/{parentId}/medications자녀 (JWT)약장 등록 — 등록 시 3겹 안전 검증 자동 실행
/v1/parents/{parentId}/conditions자녀 (JWT)기저질환 — KCD 코드 FK 검증
/v1/parents/{parentId}/allergies자녀 (JWT)알레르기 성분
/v1/parents/{parentId}/weather-advisory자녀 (JWT)날씨 주의 조회 · simulate_alert로 발송 시뮬레이션
/v1/safety자녀 (JWT)등록 전 사전 안전 검사
/em/{…}비인증 (QR)응급카드 공개 조회 — Bucket4j 요청 제한
/v1/admin/weather-rules관리자날씨 규칙 관리 · ETL 실행 · 검수 큐

응답은 전부 RsData<T>로 감싸되, 안전 검증 차단만은 프론트와 합의한 BlockErrorResponse(HTTP 409)로 따로 내려보냅니다. 클라이언트가 “차단 / 경고 / 통과”를 응답 구조만으로 구분할 수 있게 하기 위해서입니다.

트러블슈팅

TS 1단일 규칙으로는 막을 수 없는 위험한 약 조합
문제

나이 때문에 금기인 약, 기저질환 때문에 금기인 약, 알레르기 성분이 겹치는 약은 각각 데이터 출처와 판정 기준이 다릅니다. 어느 하나만 검사하면 나머지 두 종류가 그대로 통과합니다.

해결
  • 판정을 SafetyJudge 한 곳으로 모으고 DUR 연령·임부 금기 → NB 환자분류 금기 → 알레르기 교차검사 3겹으로 확장
  • HIRA 질병코드 마스터를 Flyway로 적재하고(ref.disease_master), 환자 기저질환의 KCD 코드에 FK를 걸어 존재하지 않는 코드가 애초에 들어오지 못하게 차단 (cp949 CSV 적재 포함)
  • 차단은 일반 오류와 성격이 다르므로 SafetyBlockException(409)과 전용 응답 형식을 별도로 정의
결과

약을 추가하는 한 번의 요청으로 세 종류의 금기가 모두 검사되고, 클라이언트는 응답 구조만으로 차단 여부를 판별할 수 있게 됐습니다.

TS 2필드가 비어 오는 공공 XML API를 신뢰할 수 없는 입력으로 다루기
문제

병원·약국 정보를 HIRA 공공 API 3종에서 가져와야 했는데 응답이 XML이고 필드가 자주 비어 왔습니다. 요청마다 외부를 호출하면 정작 응급 상황에서 응답이 늦어질 위험도 있었습니다.

해결
  • 기관 검색(ykiho)·상세·응급실 운영 정보를 각각 전용 클라이언트로 분리하고, XML DOM 파싱 결과를 DB에 캐시해 조회 경로에서 외부 호출을 없앰
  • 요일별 진료시간처럼 형태가 유동적인 값은 weekly_hours JSON 컬럼으로 저장
  • 마이그레이션 중 CHAR(1) 컬럼이 Hibernate validate와 충돌해 부팅이 막힌 문제를, 후속 마이그레이션에서 VARCHAR(1)로 정정해 해결
TS 3로그인 없이 열려야 하는 응급카드를 어떻게 보호할 것인가
문제

응급카드 QR은 구급대원이 스캔해 인증 없이 열려야 의미가 있습니다. 그러나 공개 URL을 그대로 두면 무제한 조회·수집이 가능합니다. 동시에 약장이 바뀌었는데 카드가 옛 정보를 보여주면 더 위험합니다.

해결
  • 공개 경로를 /em으로 분리하고 Bucket4j 요청 제한을 적용해, 인증이 없어도 남용은 막도록 구성
  • 약장·알레르기·기저질환이 바뀔 때 응급카드 snapshot을 자동 갱신해, 조회 시점 계산 없이도 항상 최신 상태가 나오도록 처리
  • 경로 변수를 리터럴로 호출하면 500이 나던 문제를 MethodArgumentTypeMismatchException 핸들러로 400 응답으로 정정

저장소

Backend 저장소 ↗
이전← 이어두다다음마모키 출석체크 어플 →