← 전체 프로젝트

CareLink

요양시설의 수급자·직원·재고·청구·안전을 한 곳에서 관리하는 통합 웹 시스템

기간
2025.09 – 2025.10
구성
팀 프로젝트 — 도메인별로 나눠 담당
내 역할
DB 설계(31개 테이블) · 백엔드·API 대부분 · 목업을 실데이터에 연결하고 UX·예외처리 다듬기 · STT 음성인식 서버 (구현은 AI 페어)
Java 17JSP/ServletMySQL · JDBCFastAPI · Whisper

한눈에

CareLink 시스템 구성도
시스템 구성 — 자바(JSP/Servlet) 본체 + MySQL이 중심. 왼쪽이 내가 만든 음성인식(ngrok·FastAPI·Whisper), 오른쪽은 팀원의 낙상 감지(Flask·YOLO). 아래 라즈베리파이가 마이크·카메라로 둘에 연결된다.

내가 맡은 범위

요양시설은 수급자 기록·직원 근태·재고·청구·안전이 제각각 흩어져 관리되기 쉽다. 이걸 하나의 웹 시스템으로 묶는 팀 프로젝트다. 도메인별로 나눠 맡았고, 나는 시스템의 데이터와 백엔드를 책임졌다.

실시간 채팅(메신저), CCTV 스트리밍, 낙상 감지 AI(YOLO), 재활 자세추정은 다른 팀원이 맡았다.

내가 내린 설계 결정

데이터가 어긋나지 않는 31개 테이블

이 시스템의 토대는 데이터베이스다. 수급자·직원·재고·청구·간호기록이 서로 얽혀 있어, 한 곳이 틀어지면 전체가 어긋난다. 그래서 31개 테이블을 정규화해 설계하고, 어긋남을 막는 규칙을 스키마에 직접 넣었다. 몇 가지 예:

수급자 도메인 ERD
수급자 도메인 ERD — 입소·배정·처방·투약·간호기록·바이탈·청구·납부·보호자가 외래키로 연결돼 있다. 전체 31개 테이블 중 한 도메인.

인수인계를 보드 하나로 — 디지털 게시판

요양시설은 3교대라 인수인계·공지가 말로만 오가면 흩어지기 쉽다. 그래서 종이나 말 대신 모두가 같이 보는 디지털 게시판에 포스트잇으로 남기게 했다. 누가 올렸고(작성자) 누가 처리했는지(처리자)를 따로 기록하고, 완료된 메모는 일정 시간(72시간) 뒤 목록에서 자동으로 빠지게 해 보드가 끝없이 쌓이지 않게 했다. 급한 건 공지로 따로 강조한다.

디지털 게시판(포스트잇) 화면
디지털 게시판 — 색상·중요도로 구분한 포스트잇을 함께 보고, 완료한 작업은 따로 정리된다. 교대 근무의 인수인계·공지를 한 보드에서.

처방과 “실제 먹은 것”을 따로

처방(의사 지시)과 실제 투약(매번 먹인 것)을 한 표에 섞으면 기록이 엉킨다. 그래서 처방은 “계획” 표, 투약은 “실제 1회” 표로 분리했다. 처방 한 건(매일 1회, 3개월)에 매일의 투약 기록이 여러 건 달려도 깔끔하게 쌓이고, 처방의 유효기간(시작~종료일)으로 “오늘 유효한 처방”만 골라 보여준다.

처방/투약 관리 화면
처방/투약 — 위쪽 처방 목록(계획)과 아래쪽 투약 기록(실제 집행)이 분리돼 있고, 투약 추가 시 약물을 처방 목록에서 골라 연결한다.

건강을 한눈에 — 바이탈을 모아 그래프로

혈압·맥박·체온·혈당·체중 같은 바이탈을 표로만 보면 추세를 못 본다. 그래서 서버에서 날짜별 평균을 미리 계산해 그래프 데이터로 내려주고(하루만 보면 시간별로), 화면에서 추세 그래프로 보여줬다. 측정 안 한 항목은 0이 아니라 “빈 값”으로 구분해, 그래프가 0으로 곤두박질치지 않게 했다.

수급자 건강관리 바이탈 그래프
건강관리 — 혈압·맥박·체온·호흡·혈당·체중 6종의 추세를 그래프로(서버에서 일평균 집계, Chart.js). 미측정 구간은 빈 값으로 이어 그린다.

청구와 납부를 따로 — 부분 납부도 깔끔하게

한 번 청구한 본인부담금을 여러 번 나눠 낼 수 있다. 그래서 청구(낼 돈)와 납부(낸 돈)를 다른 표로 분리(1:N)하고, 납부가 쌓일 때마다 누적액과 본인부담금을 비교해 미납/부분 납부/완납을 서버에서 판정했다. 청구를 지울 때는 매달린 납부 기록을 먼저 정리해 데이터가 깨지지 않게 했다.

본인부담금 청구·수납 화면
본인부담금 — 청구마다 총비용·본인부담금·미납금을 계산하고, 납부가 쌓이면 부분 납부/완납으로 상태가 바뀐다.

생활실 정원을 바꾸면 침상이 알아서

생활실 정원을 바꿀 때 침상을 손으로 맞추면 실수가 난다. 그래서 정원만큼 침상이 자동 생성되고, 정원을 늘리면 침상이 추가, 줄이면 뒤 번호부터 삭제되며 번호가 1번부터 다시 정렬되게 했다. 단, 사용 중인 침상이 있으면 삭제를 거부해 배정된 어르신이 사라지지 않게 막았다. 침상의 “사용 중” 상태는 손으로 못 바꾸고 오직 배정/이동 흐름으로만 바뀐다(데이터가 실제와 어긋나지 않게).

생활실 및 침상 관리 화면
생활실·침상 — 층별 생활실마다 침상별 점유(사용중/사용가능)와 배정된 어르신이 보인다. 정원을 바꾸면 침상이 자동으로 따라 조정된다.

음성 호출을 글로 — 한국어 방언 음성인식

요양시설 어르신의 음성 호출(“허리가 너무 아파”)을 직원이 일일이 받아적기 어렵다. 그래서 음성을 자동으로 글로 바꾸는 음성인식(STT) 서버를 따로 만들었다. 한국어 방언까지 알아듣도록 방언으로 미세조정한 Whisper 모델을 쓰고(이전 프로젝트 ‘늘곁에’에서 만든 모델 재활용), 정확도를 위해 잡음 제거 → 저주파 필터 → 음량 정규화로 소리를 다듬은 뒤 인식하게 했다. 긴 음성은 30초씩 겹치게 잘라 처리하고, 외부에서 접속할 수 있게 ngrok으로 공개 주소를 열었다. 자바 본체는 이 서버로 음성을 보내, 받은 글을 호출 기록에 저장한다.

음성 호출 자동 전사 화면
음성 호출 상세 — 어르신의 음성("허리가 너무 아파")이 AI 인식 텍스트로 자동 전사되고, 원본 오디오도 함께 재생된다.

갖춘 기능

내가 맡은 도메인을 정리했다. 모든 화면은 로그인한 직원만 접근할 수 있고, 핵심 데이터는 실제 DB와 연결돼 동작한다.

대시보드 화면
대시보드 — 미처리 호출·재고 부족·외출 수급자·오늘의 근무자·침상 현황 등 흩어진 업무를 한 화면에 모아 실데이터로 보여준다.
직원 목록/정보 화면 직원 근무일정 화면

직원 관리(좌) — 직원 목록과 기본정보·계정·근태·입사퇴사 이력 탭. 근무일정(우) — 월별 근무 편성을 주간(D)/오후(E)/야간(N)으로 한눈에.

주간 식단표 화면 낙상 감지 기록 조회 화면

식단(좌) — 주간 식단표 엑셀을 올리면 요일×식사 달력으로 파싱해 표시. 낙상 기록(우) — 감지 결과를 영상·시각과 함께 조회·처리(감지 자체는 팀원).

전체 기능 펼쳐 보기

대시보드

  • 미처리 호출·재고 부족·신규 비품 요청·외출 수급자·오늘의 근무자(D/E/N)·최근 포스트잇·침상 현황을 실데이터로 집계

디지털 게시판

  • 포스트잇 작성/처리/복구, 작성자·처리자 기록, 본인 글만 수정, 공지·우선순위·색상 구분, 완료 후 일정 시간만 목록 유지
  • 개인 To-Do(미완료 우선 정렬)

수급자

  • 본인·보호자 등록(보호자 N:M), 나이는 생일로 서버에서 계산
  • 입소/퇴소(모든 입소기록 종료 시 침상 자동 반납), 재입소, 생활실·침상 배정 이력
  • 처방(계획)과 실제 투약(1회)을 분리 기록, 유효 기간으로 현재 처방 판별
  • 간호 일지(낙상·욕창·실금·섬망 등 위험지표 체크), 외출·외박 신청·관리
  • 바이탈 기록 + 추세 그래프(서버 집계, 미측정은 빈 값 처리)
  • 본인부담금 청구·수납(부분 납부·완납 판정, 아임포트 PG 결제, 청구 삭제 시 납부 먼저 정리)

직원·근태

  • 회원가입(이름·이메일·휴대폰 형식·중복 검사) → 가입 직후 “승인 대기” 상태, 관리자 승인 전까지 로그인 불가
  • 로그인 4단계 판정(미가입/미승인/비활성/정상)과 상태별 안내, 관리자 기능은 매 요청마다 권한 재확인
  • 출퇴근 — 직전 근무가 끝난 뒤에만 출근 허용, 야간 근무 종료를 다음 날로 보정, 퇴근 시 자동 로그아웃
  • 근무 일정 등록·수정(같은 날 중복 편성 차단), 근무 유형(주간/오후/야간)
  • 직원 정보·고용 이력(퇴사·재입사 누적), 프로필 사진, 임시 비밀번호 메일 재발급(Gmail SMTP)

식단

  • 주간 식단표 엑셀(.xlsx) 업로드 → Apache POI로 읽어 요일×식사 표로 파싱·표시

시설·재고

  • 시설 정보 관리(관리자 전용)
  • 생활실 등록 시 정원만큼 침상 자동 생성, 정원 변경 시 침상 추가·삭제·번호 재정렬, 사용 중 침상 보호
  • 침상은 배정/이동 흐름으로만 점유(직접 “사용중” 변경 차단), 침상 이동(전실)
  • 소모품 재고·변동 이력(트랜잭션으로 수량+이력 한 묶음), 부족 품목 청구(영수증·항목·당시 단가), 결제 승인 시 입고
  • 결제는 아임포트(PG) 카드 결제 연동

모니터링

  • 음성·긴급 호출 조회, 현장 확인 내용(메모) 기록으로 처리 완료 표시
  • 음성 호출은 STT 텍스트와 원본 오디오를 함께 표시, 실시간 호출 수신 시 자동 전사
  • 낙상 감지 결과(영상·카메라·시각) 조회·처리 (감지 AI는 팀원)

STT 음성인식 서버 (별도)

  • 방언 미세조정 Whisper, 잡음 제거→저주파 필터→음량 정규화 전처리, 30초 겹침 분할, API 키 인증, ngrok 공개 주소

정직하게 — 내가 한 일

이 시스템의 코드는 AI를 페어로 구현했다. 화면의 UI 목업은 팀의 퍼블리셔가 만들었고, 나는 그 화면들을 실제 데이터베이스·API와 연결해 동작하게 만들고, 사용 흐름과 예외 상황을 다듬고, 필요할 때 DB 스키마를 고쳤다(일부 화면은 직접 만들었다). 커넥션 풀 같은 공통 모듈 일부는 이미 있는 라이브러리를 가져다 썼다.

내가 책임진 핵심은 데이터를 어떻게 구조화하고(31개 테이블), 업무 규칙을 어떻게 서버에 녹일지(재고·청구·배정·근태·처방) 정하고 연결한 것, 그리고 음성인식 서버를 만들어 시스템에 붙인 것이다. 화려한 화면보다, 기록이 어긋나지 않고 업무가 흐르게 만드는 백엔드를 맡았다.