DeepLine (딥라인)

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

Period & Role

  • 기간: 2025.11 ~ 진행 중
  • 역할: 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 Redis
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. JPA N+1 문제 해결과 성능 최적화 • 문제 : 결재 문서 상세 조회 시 결재선, 결재자, 부서, 직급 등 다중 연관관계로 인해 다수의 SELECT 쿼리가 폭주하는 현상 발견 • 결과 : @EntityGraph와 JPQL Join Fetch를 조합해 복잡한 데이터를 단일 쿼리(Left Join)로 로드하도록 튜닝. EntityManager로 영속성 컨텍스트를 제어하는 테스크 코드를 통해 쿼리 1회 발생을 검증 완료. 2. 웹소켓(STOMP) 전용 보안 인터셉트 구축 • 문제 : 실시간 채팅에서 기존 HTTP JwtFilter만으로는 웹소켓 파이프라인 내부의 메시지(Connect, Send) 인증을 제어할 수 없는 보안 한계 확인. • 결과 : Spring Messaging의 ChannelInterceptor를 구현하여, 메시지 채널(clientInboundChannel)로 들어오는 매 STOMP 메시지 헤더의 JWT 토큰을 낚아채어 검증하는 견고한 보안 아키텍처 설계. 3. AOP와 SpEL을 결합한 동적 감사 로그(AuditLog) 모듈 • 문제 : 결재 상신, 인사 발령 등 핵심 상태 변경을 추적하기 위해 커스텀 @AuditLog 어노테이션과 AOP를 도입했으나, 초기엔 단일 파라미터(Long)만 인식하는 한계가 존재. • 결과 : SpelExpressionParser를 도입하여 런타임에 파라미터 객체 내부 값(예 : #dto.memberId)를 동적으로 추출하도록 리팩토링, 결합도를 낮추고 모듈 재사용성을 극대화 4. 비동기 이벤트 기반 알림 분리 (RabbitMQ & SSE) • 문제 : 결재 처리 로직과 알림 발송 로직의 강결합으로 트랜잭션 병목 및 정합성 문제 발생 위험 존재. • 결과 : 알림 이벤트를 RabbitMQ로 비동기 발행(Publish)하고, 이를 구독(Consume)하여 SSE로 클라이언트에게 전송하는 아키텍처 도입. 핵심 도메인 로직과 부가 기능을 완벽히 분리. 5. Redis 글로벌 캐싱 및 인메모리 토큰 관리 • 결과 : RDB I/O 부하 감소를 위해 Redis를 도입. 부서/직급 등 변동이 적은 데이터에 Spring Cache(@Cacheable)를 연동하여 조회 성능 향상 및 Refresh Token의 만료(TTL) 자동 제어 구현.
Lessons Learned
DeepLine을 통해 기능 구현을 넘어 실제 서비스가 배포 환경에서 안정적으로 동작하기 위해 어떤 구조가 필요한지 직접 경험했습니다. Docker와 Nginx를 활용해 정적 리소스 처리, 프록시 설정, 네트워크 구조를 다뤘고, RabbitMQ와 SSE를 적용하며 핵심 로직과 부가 기능을 분리하는 이벤트기반 구조의 장점을 체감했습니다. 또한 전자결재와 근태 도메인을 구현하는 과정에서 @Transactional을 통한 데이터 무결성과 트랜잭션 관리의 중요성을 배웠습니다. 현재는 GitHub Actions를 활용해 main 브랜치에 push하면 홈 Linux 서버로 자동 배포되는 CI/CD 환경을 구축했으며, 앞으로는 테스트 코드 보강과 쿼리최적화를 통해 서비스 안정성을 운영 효율을 더욱 높이고자 합니다.