파일
wbx-spring/plans/wtmgr/01-architecture.md
accura0117 9707a6eeb1 feat: FE 화면 구현 완료 + 샘플 데이터 + 결재라인 연동
- WBS/TEAL 화면 실제 구현 (TreeTable, FileUpload, 버전관리)
- 시수이력/결재이력 화면 구현 (DataTable, Filter, Timeline)
- 비밀번호변경 화면 추가
- 로그인 snake_case 응답 매핑 수정
- Vite 프록시 8081 포트 수정
- auth guard에서 fetchMe 자동 호출
- V108 샘플 데이터 (10명 사용자, 4주 시수 215건, 결재 9건)
- 배너 추가 (WBX Spring)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:17:32 +09:00

172 줄
5.4 KiB
Markdown

# 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 페이징 파라미터 수용 |