feat: WTM 멀티프로젝트 플랫폼 구축 (BE + FE 전체 구현)

Phase 0: wbx-spring-core 라이브러리 전환
- java-library 플러그인, WbxAutoConfiguration, Admin 조건부 활성화
- 루트 settings.gradle + build.gradle (멀티모듈)

Phase 1: wtm-api 모듈 생성
- 23개 JPA Entity, 14개 Controller, 79개 API 엔드포인트
- Flyway V100~V107 MySQL 마이그레이션
- TimesheetRuleEngine, TimesheetApprovalHandler, P6WbsParser

Phase 2: wtm-frontend (Vue 3 + PrimeVue 4)
- 10개 도메인 모듈, 17개 View, 5개 서브컴포넌트
- 반응형 레이아웃 (AppLayout, AppSidebar, AppTopbar)
- BaseCrudTable, BaseFormDialog, BasePageHeader 표준 컴포넌트
- JWT 인터셉터, 역할 기반 메뉴 필터링

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
이 Commit은 다음에 포함되어 있습니다:
2026-03-25 21:01:43 +09:00
부모 783865266b
커밋 df723f1d59
533개의 변경된 파일15528개의 추가작업 그리고 154개의 파일을 삭제

파일 보기

@@ -0,0 +1,171 @@
# 01. WTM 모듈 구조
> **전제**: wbx-spring 프레임워크(인증/권한/결재/알림/WBX호환)가 구축되어 있음
## WTM 프로젝트 구조
```
wtm-api/
├── build.gradle
├── settings.gradle
├── Dockerfile # wbx-spring 표준 (07-infra-deploy.md)
├── src/main/java/kr/co/accura/wtm/
│ ├── WtmApplication.java
│ │
│ ├── domain/ # ★ 비즈니스 도메인만
│ │ ├── user/ # 사용자 (HR 필드 확장)
│ │ │ ├── entity/User.java
│ │ │ ├── repository/
│ │ │ ├── service/UserService.java
│ │ │ └── dto/
│ │ │
│ │ ├── project/ # 프로젝트 · 인력 배정
│ │ │ ├── entity/
│ │ │ ├── repository/
│ │ │ ├── service/
│ │ │ └── dto/
│ │ │
│ │ ├── wbs/ # WBS · TEAL · P6 파싱
│ │ │ ├── entity/
│ │ │ ├── repository/
│ │ │ ├── service/WbsService.java
│ │ │ ├── parser/P6WbsParser.java
│ │ │ └── dto/
│ │ │
│ │ ├── timesheet/ # 시수 입력 3종
│ │ │ ├── entity/
│ │ │ ├── repository/
│ │ │ ├── service/
│ │ │ ├── rule/TimesheetRuleEngine.java
│ │ │ └── dto/
│ │ │
│ │ ├── approval/ # ★ 핸들러만 (엔진은 wbx-spring)
│ │ │ └── handler/
│ │ │ └── TimesheetApprovalHandler.java
│ │ │
│ │ └── report/ # 리포트
│ │ ├── service/
│ │ └── dto/
│ │
│ ├── api/ # REST Controller
│ │ ├── UserController.java
│ │ ├── ProjectController.java
│ │ ├── WbsController.java
│ │ ├── TimesheetController.java
│ │ └── ReportController.java
│ │
│ ├── integration/ # 외부 연동
│ │ ├── sap/HrIntegrationController.java
│ │ ├── p6/P6WbsParser.java
│ │ └── cognite/CogniteExportService.java
│ │
│ └── config/ # WTM 전용 설정만
│ ├── WtmConfig.java
│ └── WorkRuleConfig.java
├── src/main/resources/
│ ├── application.yml
│ ├── application-local.yml
│ ├── application-prod.yml
│ └── db/migration/ # wtm_db Flyway
│ ├── V1__init_users.sql
│ ├── V2__init_projects_wbs.sql
│ ├── V3__init_timesheets.sql
│ ├── V4__init_approvals.sql
│ └── V5__init_reports.sql
└── src/test/
```
## 의존성 (build.gradle)
> 상세 Gradle 스크립트: `12-project-setup-plan.md` 참조 (Single Source of Truth)
```groovy
plugins {
id 'org.springframework.boot' version '3.5.0'
id 'io.spring.dependency-management' version '1.1.7'
}
dependencies {
// ★ wbx-spring 프레임워크 (멀티모듈 내 프로젝트 참조)
implementation project(':wbx-spring-core')
// WTM 전용 의존성만
implementation 'org.apache.poi:poi-ooxml:5.3.0' // P6 WBS 파싱
implementation 'org.flywaydb:flyway-sqlserver' // Azure SQL 마이그레이션
// QueryDSL (리포트 동적 쿼리)
implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.1.0:jakarta'
// MapStruct (DTO 매핑)
implementation 'org.mapstruct:mapstruct:1.6.3'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.6.3'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'com.h2database:h2'
}
```
## application.yml
```yaml
spring:
application:
name: wtm-api
wbx:
spring:
api-prefix: /api/wtm # ★ URL prefix
jwt:
secret: ${JWT_SECRET}
expiration: 28800
approval:
enabled: true
notification:
sse-enabled: true
spring:
datasource:
app:
url: ${WTM_DB_URL:jdbc:h2:mem:wtm}
username: ${WTM_DB_USER:sa}
password: ${WTM_DB_PASS:}
wbxgw:
url: ${WBX_GW_DB_URL:}
username: ${WBX_GW_DB_USER:}
password: ${WBX_GW_DB_PASS:}
jpa:
hibernate:
ddl-auto: validate
open-in-view: false
flyway:
enabled: true
locations: classpath:db/migration
wtm:
work-rules:
default-min-daily-hours: 8
default-max-weekly-hours: 52
```
## wbx-spring 활용 포인트
| WTM 코드 | wbx-spring 활용 |
|----------|----------------|
| `@PreAuthorize("@wbx.check('TIMESHEET','VIEW')")` | RBAC 권한 체크 |
| `DeptScope scope = evaluator.getScope(...)` | 데이터 필터링 범위 |
| `implements ApprovalHandler` | 결재 핸들러 등록 |
| `sseNotificationService.sendToUser(...)` | 실시간 알림 전송 |
| `Map.of("items", ..., "total", ...)` | WBX DataGrid 호환 응답 |
| `{"detail": "..."}` 에러 | WBX 에러 포맷 자동 적용 |
| `@RequestParam int skip, int limit` | WBX 페이징 파라미터 수용 |