DeepLine (딥라인)

데이터의 흐름을 잇는 직관적인 자원 관리(ERP) 시스템

Period & Role

  • 기간: 2025.11 ~ 2026.01 (약 3개월)
  • 역할: Full Stack (1인 개발)

Description

  • DeepLine은 중소규모 조직은 위한 웹 기반 ERP 시스템입니다. 사용자 관리, 근태, 전자결재 기능을 하나의 서비스로 통합해 데이터 분산을 줄이고 업무 효율을 높이는 것을 목표로 설계했습니다. 1인 개발 프로젝트로 진행하며 Spring Boot 기반 백엔드, React 프론트엔드, JWT 인증/인가, RabbitMQ·SSE 기반 실시간 알림, Docker·Nginx 배포 환경까지 직접 설계하고 구현했습니다.

Tech Stack

Backend
Java Spring Boot Spring Security JPA
Frontend
React TypeScript Zustand Shadcn UI
Database
PostgreSQL
Realtime / Messaging
RabbitMQ SSE STOMP WebSocket
Infra / DevOps
Docker Docker Compose Nginx Rocky Linux

Key Features

  • JWT 기반 인증/인가
    • Spring Security + JWT 기반 Stateless 인증
    • Role(Admin/User) 기반 접근 제어 적용
  • 전자결재 프로세스 자동화
    • 기안-승인-반려-최종승인의 다단계 결재 프로세스 구현
    • 결재 상태에 따른 후처리 로직 자동화
  • RabbitMQ + SSE 실시간 알림
    • 결재 요청/완료 이벤트 발행
    • 클라이언트에 실시간 알림 전송 및 상태 동기화
  • 근태 및 인사 관리
    • 출/퇴근 기록 및 근무 시간 계산
    • 부서/직급 체계, 사원별 계정 및 프로필 관리
  • 1:1 실시간 채팅 구조
    • STOMP over WebSocket 기반 실시간 메시지 송수신
    • RabbitMQ relay 구조 적용

System Architecture & ERD

ERD Diagram

프로젝트의 데이터베이스 설계도(ERD)입니다.

Architecture

프로젝트의 시스템 아키텍처입니다.

Troubleshooting
1. 배포 환경에서 이미지 404 및 데이터 유실 • 문제 : 배포 환경에서 업로드한 프로필 이미지가 404/401 오류로 표시되지 않았고, 컨테이너 재시작 시 이미지가 사라졌습니다. • 원인 : 이미지 요청 경로가 정적 리소스로 분리되지 않았고, 업로드 파일이 컨테이너 내부에만 저장되어 있었습니다. • 해결 : Nginx에서 /images 경로를 정적 리소스로 직접 서빙하고, Docker Volume으로 업로드 경로를 호스트와 연결했습니다. • 결과 : 배포 환경에서도 이미지가 정상 노출되었고, 재배포 이후에도 업로드 데이터가 유지되도록 개선했습니다. 2. Docker 환경에서 API 통신 및 CORS 문제 • 문제 : 로컬에서는 정상 동작하던 프론트엔드와 백엔드가 Docker 기반 배포 환경에서는 API 통신 오류와 CORS 문제를 일으켰습니다. • 원인 : 컨테이너 간 네트워크 구조와 브라우저 요청 출처 설정이 로컬 환경과 달랐고, 배포 환경을 고려한 CORS 설정이 부족했습니다. • 해결 : Docker Compose 네트워크 구성을 정리하고, Spring Boot와 Nginx 환경에 맞게 허용 출처와 요청 경로를 재설정했습니다. • 결과 : 배포 환경에서도 프론트엔드와 백엔드 간 통신이 안정적으로 동작하도록 개선했습니다. 3. SSE 연결 유지 및 실시간 알림 지연 문제 • 문제 : 실시간 알림 기능 구현 과정에서 SSE 연결이 일정 시간 이후 끊기거나, 알림이 즉시 반영되지 않는 문제가 있었습니다. • 원인 : 기본 프록시 설정에서는 SSE의 장시간 연결 유지와 버퍼링 제어가 충분하지 않았습니다. • 해결 : Nginx에서 SSE 구독 경로를 별도로 분리하고, buffering 비활성화 및 timeout 설정을 적용했습니다. • 결과 : 배포 환경에서도 SSE 연결이 안정적으로 유지되었고, 알림이 실시간으로 반영되도록 개선했습니다. 4. 실시간 채팅 구조 확장 • 문제 : 초기 채팅 기능은 단순 STOMP over WebSocket 구조로 구현되어 구조 확장에 한계가 있었습니다. • 원인 : Spring 내장 브로커만 사용하는 구조로는 메시지 중계와 확장성을 충분히 확보하기 어려웠습니다. • 해결 : STOMP over WebSocket 구조는 유지하되, Spring 내장 브로커 대신 RabbitMQ(StompBrokerRelay)를 연동했습니다. • 결과 : 채팅 구조를 더 확장 가능한 형태로 개선했고, 메시지 처리 구조를 분리해 설계할 수 있었습니다.
Lessons Learned
DeepLine을 통해 기능 구현을 넘어 실제 서비스가 배포 환경에서 안정적으로 동작하기 위해 어떤 구조가 필요한지 직접 경험했습니다. Docker와 Nginx를 활용해 정적 리소스 처리, 프록시 설정, 네트워크 구조를 다뤘고, RabbitMQ와 SSE를 적용하며 핵심 로직과 부가 기능을 분리하는 이벤트기반 구조의 장점을 체감했습니다. 또한 전자결재와 근태 도메인을 구현하는 과정에서 @Transactional을 통한 데이터 무결성과 트랜잭션 관리의 중요성을 배웠습니다. 현재는 GitHub Actions를 활용해 main 브랜치에 push하면 홈 Linux 서버로 자동 배포되는 CI/CD 환경을 구축했으며, 앞으로는 테스트 코드 보강과 쿼리최적화를 통해 서비스 안정성을 운영 효율을 더욱 높이고자 합니다.