9.2 KiB
9.2 KiB
시스템 아키텍처 정의서 (System Architecture)
1. 기술 스택
| 계층 | 기술 | 버전 |
|---|---|---|
| Backend | Spring Boot | 3.x |
| Java | 17 | |
| Spring Data JPA | - | |
| Spring Security | - | |
| Spring Batch | - | |
| Frontend | Next.js | 14+ (App Router) |
| TypeScript | - | |
| Tailwind CSS | - | |
| Pinia (State Management) | - | |
| Database | PostgreSQL | 15 |
| Infra | Nginx Proxy Manager | - |
| CI/CD | GitHub Actions | Release 트리거 |
| Notification | Slack Webhook / Email | - |
2. 전역 시스템 레이어 구조
┌─────────────────────────────────────────────────────────────┐
│ Frontend (Next.js 14+) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ Pinia │ │ Axios │ │ Tailwind │ │ Dynamic LNB │ │
│ │ Storage │ │ Intercep.│ │ CSS │ │ (RBAC) │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────────┘ │
└──────────────────────┬──────────────────────────────────────┘
│ HTTPS / REST API
▼
┌─────────────────────────────────────────────────────────────┐
│ Cloudflare Tunnel (SSL / Zero-Trust Proxy) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Backend (Spring Boot 3.x / Java 17) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Security Layer │ │
│ │ ┌─────────────────┐ ┌──────────────────────────┐ │ │
│ │ │ JWT Token │ │ Security Filter Chain │ │ │
│ │ │ Provider │ │ (RBAC Authorization) │ │ │
│ │ └─────────────────┘ └──────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ API Layer (REST Controllers) │ │
│ │ EmployeeController / TicketController / ... │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Service Layer (Business Logic + Transaction) │ │
│ │ ├─ @Transactional 선언 │ │
│ │ └─ ApplicationEventPublisher (EDA 발행) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Persistence Layer (Spring Data JPA) │ │
│ │ ├─ Entity / Repository / Specification │ │
│ │ ├─ @SQLDelete + @Where (Soft Delete 전역 필터) │ │
│ │ └─ @SequenceGenerator(allocationSize=50) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Infrastructure Layer │ │
│ │ ├─ @TransactionalEventListener(AFTER_COMMIT) │ │
│ │ ├─ @Async Notification Listener │ │
│ │ └─ Spring Batch SLA Scheduler (Chunk Size=100) │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PostgreSQL 15 Database │
│ ├─ Sequence (INCREMENT BY 50) │
│ ├─ Common Code Table (동적 드롭다운) │
│ └─ Batch Metadata Schema │
└─────────────────────────────────────────────────────────────┘
3. ApiResponse 공통 규격
모든 API 응답은 아래 포맷을 강제합니다.
성공:
{
"success": true,
"message": "요청이 성공적으로 처리되었습니다.",
"data": { ... }
}
실패 (비즈니스 예외):
{
"success": false,
"message": "이미 결재가 완료된 보고서는 수정할 수 없습니다.",
"errorCode": "RPT_ERR_001",
"data": null
}
4. 글로벌 예외 처리 (GlobalExceptionHandler)
- 모든 도메인 예외는
BusinessException(RuntimeException 상속) 통일 @RestControllerAdvice가 감지 →ErrorCodeEnum 매핑 →ApiResponse.error()변환
ErrorCode 매트릭스
| Enum | HTTP Status | ErrorCode | 메시지 |
|---|---|---|---|
RESIGNED_EMPLOYEE |
400 | EMP_ERR_001 | 퇴사 처리된 직원 정보는 수정할 수 없습니다 |
LOCKED_REPORT |
400 | RPT_ERR_001 | 결재 완료 보고서는 수정/삭제할 수 없습니다 |
FUTURE_REPORT_DATE |
400 | RPT_ERR_002 | 미래 날짜의 업무 보고는 작성할 수 없습니다 |
CLOSED_TICKET_MOD |
400 | TCK_ERR_001 | 종료된 티켓은 댓글/수정이 불가능합니다 |
ASSIGNEE_REQUIRED |
400 | TCK_ERR_002 | 담당자 미배정 티켓은 IN_PROGRESS 전환 불가 |
EQUIP_NOT_AVAILABLE |
400 | EQP_ERR_001 | 지급 가능한 재고 상태가 아닙니다 |
INVALID_ASSIGNEE |
400 | EQP_ERR_002 | 재직 중인 직원에게만 장비 지급 가능 |
SYSTEM_CONCURRENCY |
409 | SYS_ERR_001 | 동시성 충돌 - 다시 시도해 주세요 |
5. 이벤트 기반 비동기 알림 (EDA)
sequenceDiagram
Controller->>Service: 요청 처리
Service->>DB: 트랜잭션 커밋
Service->>EventPublisher: 이벤트 발행
EventPublisher->>Listener: @TransactionalEventListener(AFTER_COMMIT)
Listener->>Slack/Email: @Async 비동기 발송
Note over Listener: 메인 트랜잭션과 완전 격리
6. SLA 만료 배치 아키텍처 (Spring Batch)
- 트리거: Spring Scheduler (매시간)
- Chunk Size: 100건 단위 청크 분할
- 필터 조건:
SLA_WARN_FLAG = 'N'ANDstatus NOT IN (RESOLVED, CLOSED)ANDdue_date < NOW() - 처리: 대상 티켓 탐색 → 알림 이벤트 발행 →
SLA_WARN_FLAG = 'Y'갱신 - PostgreSQL 메타데이터: 배치 전용 메타 테이블 스키마 별도 구축
7. Soft Delete 전역 아키텍처
// BaseEntity 패턴
@SQLDelete(sql = "UPDATE tb_xxx SET is_deleted = 'Y' WHERE id = ?")
@Where(clause = "is_deleted = 'N'")
- 모든 엔티티가
BaseEntity상속 (created_at, updated_at, is_deleted) - 조회 시
@Where조건절 자동 적용 → 조건절 누수 방지 - 물리 삭제
DELETE→UPDATE is_deleted='Y'자변환