파일
wbx-spring/plans/wtmgr/12-project-setup-plan.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

25 KiB

12. WTM 프로젝트 구성 계획

작성일: 2026-03-25 목적: wbx-spring-core를 라이브러리로 전환하고, wtm-api 모듈을 생성하기 위한 구체적 작업 계획


1. 현황 분석

wbx-spring-core 현재 구조

항목 현재 상태 문제점
Gradle 플러그인 org.springframework.boot (fat JAR) 라이브러리로 사용 불가
진입점 WbxSpringCoreApplication.java (@SpringBootApplication) 라이브러리에 main() 불필요
application.yml 하드코딩된 DB/Redis/서버 설정 소비 모듈이 자체 설정 불가
DB 드라이버 MySQL/PG/Oracle/MSSQL 4개 모두 포함 소비 모듈이 필요한 것만 선택해야 함
Admin UI Thymeleaf 세션 기반 (12개 템플릿) 모든 소비 모듈에 전이 의존성
Enable 어노테이션 main 클래스에 @EnableJpaAuditing 등 집중 라이브러리 전환 시 분리 필요

wbx-spring-core 제공 기능 (10개 모듈)

패키지 기능 주요 클래스 WTM 사용 여부
auth/ JWT, SSO, MFA, 비밀번호 정책, 리프레시 토큰 JwtProvider, JwtFilter, AuthController O
rbac/ 역할-모듈-액션 권한, dept_scope PermissionEvaluator (bean "wbx") O
approval/ 통합 결재 엔진 (Handler Registry) ApprovalHandler interface, UnifiedApprovalController O
notification/ SSE 실시간 알림 SseNotificationService O
compat/ WBX 호환 (detail 에러, skip/limit) WbxErrorHandler, WbxPaginationConfig O
file/ 파일 스토리지 (Local/Azure/AWS/GCP) FileStorageService interface O
datasource/ 멀티 데이터소스 라우팅 MultiDataSourceConfig, @DataSource O
config/ 시큐리티, CORS, OpenAPI, 중앙 설정 SecurityAutoConfig, WbxSpringProperties O
common/ 베이스 엔티티, 유틸, 예외 BaseEntity, SecurityUtils, BusinessException O
audit/ 감사 로그 AuditLogService O
admin/ 관리 콘솔 UI (Thymeleaf) AdminController, 12개 HTML 조건부

2. 목표 구조: 멀티프로젝트 플랫폼

설계 원칙

  • wbx-spring-core: 모든 프로젝트가 공유하는 프레임워크 (1개)
  • {project}-api: 고객/프로젝트별 백엔드 애플리케이션 (N개)
  • {project}-frontend: 고객/프로젝트별 프론트엔드 (N개, Gradle 외부)
  • 새 프로젝트 추가 = 모듈 2개 추가 (settings.gradle에 include만 추가)

전체 구조

WBX-Spring/
├── settings.gradle                 # rootProject.name = 'wbx-spring'
│                                    # include 'wbx-spring-core'
│                                    # include 'wtm-api'        ← 한화오션 WTM
│                                    # include 'xxx-api'        ← 향후 프로젝트 B
│                                    # include 'yyy-api'        ← 향후 프로젝트 C
├── build.gradle                    # 공통: Java 21, Lombok, Spring BOM
│
├── wbx-spring-core/                # 🔧 공유 프레임워크 라이브러리
│   ├── build.gradle                # java-library (Boot 플러그인 없음)
│   ├── src/main/java/kr/co/accura/wbx/spring/
│   │   ├── auth/                   # JWT, SSO, MFA, 비밀번호 정책
│   │   ├── rbac/                   # RBAC 권한 (PermissionEvaluator)
│   │   ├── approval/               # 통합 결재 엔진 (Handler Registry)
│   │   ├── notification/           # SSE 실시간 알림
│   │   ├── compat/                 # WBX 호환 (detail 에러, skip/limit)
│   │   ├── file/                   # 파일 스토리지 (Local/Azure/AWS/GCP)
│   │   ├── datasource/             # 멀티 데이터소스 라우팅
│   │   ├── config/                 # 시큐리티, CORS, OpenAPI, 중앙 설정
│   │   ├── common/                 # BaseEntity, SecurityUtils, 예외
│   │   ├── audit/                  # 감사 로그
│   │   └── admin/                  # 관리 콘솔 (조건부: wbx.spring.admin-ui.enabled)
│   └── src/main/resources/
│       ├── META-INF/spring/
│       │   └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│       └── templates/admin/        # Thymeleaf (admin-ui.enabled=true 시만)
│
├── wtm-api/                        # 🏗️ 한화오션 WTM 백엔드
│   ├── build.gradle                # spring-boot + project(':wbx-spring-core')
│   ├── src/main/java/kr/co/accura/wtm/
│   │   ├── WtmApplication.java     # @SpringBootApplication
│   │   ├── domain/
│   │   │   ├── user/               # HR 확장 필드 (discipline, location 등)
│   │   │   ├── project/            # 프로젝트, 인력 배정
│   │   │   ├── wbs/                # WBS, Canonical WBS, P6 파서
│   │   │   ├── teal/               # TEAL 버전, Activity
│   │   │   ├── timesheet/          # 시수 3종, 규칙 엔진
│   │   │   ├── approval/handler/   # TimesheetApprovalHandler
│   │   │   ├── report/             # QueryDSL 동적 리포트
│   │   │   ├── config/             # OverheadType, WorkRule
│   │   │   └── audit/              # SaAccessLog
│   │   ├── api/                    # REST Controller 13개 (79 API)
│   │   ├── integration/            # SAP BTP, P6, Cognite
│   │   └── config/                 # WTM 전용 설정
│   └── src/main/resources/
│       ├── application.yml         # WTM 전용 설정
│       ├── application-mysql.yml   # 개발 (MySQL)
│       ├── application-mssql.yml   # 운영 (Azure SQL)
│       └── db/migration/
│           ├── common/             # ANSI SQL (seed data)
│           ├── mysql/              # 개발용 DDL
│           └── mssql/              # 운영용 DDL
│
├── wtm-frontend/                   # 🎨 한화오션 WTM 프론트엔드
│   ├── package.json                # Vue 3 + PrimeVue 4 + Vite
│   └── src/
│       ├── app/                    # 셸 (router, plugins)
│       ├── core/                   # 공유 인프라
│       ├── modules/                # 도메인 모듈 10개
│       └── assets/                 # 스타일, 이미지
│
├── {향후}-api/                      # 🆕 프로젝트 B 백엔드 (동일 패턴)
│   ├── build.gradle                # project(':wbx-spring-core')
│   └── src/main/java/kr/co/accura/{project}/
│       ├── {Project}Application.java
│       ├── domain/                 # 프로젝트 B 전용 도메인
│       ├── api/                    # 프로젝트 B 전용 API
│       └── config/
│
└── {향후}-frontend/                 # 🆕 프로젝트 B 프론트엔드 (동일 패턴)
    └── src/
        ├── app/
        ├── core/                   # 복사 후 커스터마이징 또는 공유 npm 패키지
        └── modules/

프로젝트 간 관계도

                    ┌─────────────────────┐
                    │  wbx-spring-core    │  ← 공유 프레임워크
                    │  (java-library)     │
                    │  인증/권한/결재/알림  │
                    └──────┬──────┬───────┘
                           │      │
              ┌────────────┘      └────────────┐
              ▼                                ▼
    ┌─────────────────┐              ┌─────────────────┐
    │  wtm-api        │              │  {향후}-api      │
    │  (spring-boot)  │              │  (spring-boot)  │
    │  한화오션 WTM    │              │  고객 B 프로젝트  │
    └────────┬────────┘              └────────┬────────┘
             │                                │
    ┌────────┴────────┐              ┌────────┴────────┐
    │  wtm-frontend   │              │  {향후}-frontend │
    │  (Vue+PrimeVue) │              │  (Vue+PrimeVue) │
    └─────────────────┘              └─────────────────┘

새 프로젝트 추가 절차 (3단계)

Step 1. settings.gradle에 모듈 추가

include '{project}-api'

Step 2. {project}-api/build.gradle 생성

plugins {
    id 'org.springframework.boot' version '3.5.0'
}
dependencies {
    implementation project(':wbx-spring-core')
    // 프로젝트 전용 의존성 추가
}

Step 3. Application 클래스 + application.yml 생성

@SpringBootApplication(scanBasePackages = {
    "kr.co.accura.wbx.spring",
    "kr.co.accura.{project}"
})
@EntityScan(basePackages = {
    "kr.co.accura.wbx.spring",
    "kr.co.accura.{project}"
})
@EnableJpaRepositories(basePackages = {
    "kr.co.accura.wbx.spring",
    "kr.co.accura.{project}"
})
public class {Project}Application {
    public static void main(String[] args) {
        SpringApplication.run({Project}Application.class, args);
    }
}

각 프로젝트는 독립 실행 가능 — 자체 DB, 자체 포트, 자체 JWT 설정. wbx-spring-core의 기능(인증/권한/결재/알림)은 wbx.spring.* 속성으로 ON/OFF.

프로젝트별 커스터마이징 포인트

항목 설정 위치 예시
API prefix wbx.spring.api-prefix /api/wtm, /api/ems, /api/qms
JWT secret wbx.spring.jwt.secret 프로젝트별 독립 키
DB spring.datasource.* 프로젝트별 독립 DB
결재 핸들러 @Component implements ApprovalHandler Bean 등록만으로 자동 연동
SSO (Azure) spring.security.oauth2.client.* 고객별 Entra ID 테넌트
파일 스토리지 wbx.spring.file.storage-type local, azure, aws, gcp
Admin UI wbx.spring.admin-ui.enabled true / false
CORS wbx.spring.cors.allowed-origins 프로젝트별 프론트 URL

---

## 3. 전환 작업 상세

### Phase 0: wbx-spring-core 라이브러리 전환 (선행 작업)

#### 3.1 루트 프로젝트 생성

| 작업 | 파일 | 설명 |
|------|------|------|
| `settings.gradle` 이동 | `WBX-Spring/settings.gradle` | 프로젝트 모듈 등록 |
| 루트 `build.gradle` 생성 | `WBX-Spring/build.gradle` | 공통 설정 (Java 21, repositories, Lombok) |

```groovy
// WBX-Spring/settings.gradle
rootProject.name = 'wbx-spring'

// 공유 프레임워크
include 'wbx-spring-core'

// === 고객 프로젝트 (추가 시 여기에 include) ===
include 'wtm-api'           // 한화오션 WTM (시수관리)
// include 'xxx-api'        // 향후 프로젝트 B
// include 'yyy-api'        // 향후 프로젝트 C
// WBX-Spring/build.gradle (루트)
plugins {
    id 'java'
    id 'io.spring.dependency-management' version '1.1.7'
}

subprojects {
    group = 'kr.co.accura'
    version = '1.0.0-SNAPSHOT'

    apply plugin: 'java'
    apply plugin: 'io.spring.dependency-management'

    java {
        toolchain {
            languageVersion = JavaLanguageVersion.of(21)
        }
    }

    repositories {
        mavenCentral()
    }

    dependencyManagement {
        imports {
            mavenBom "org.springframework.boot:spring-boot-dependencies:3.5.0"
        }
    }

    dependencies {
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    }

    tasks.named('test') {
        useJUnitPlatform()
    }
}

3.2 wbx-spring-core build.gradle 변경

핵심 변경: org.springframework.boot 플러그인 제거 → java-library 적용

// wbx-spring-core/build.gradle
plugins {
    id 'java-library'
}

dependencies {
    // Spring Boot Starters (api로 노출 — 소비 모듈이 사용)
    api 'org.springframework.boot:spring-boot-starter-web'
    api 'org.springframework.boot:spring-boot-starter-data-jpa'
    api 'org.springframework.boot:spring-boot-starter-security'
    api 'org.springframework.boot:spring-boot-starter-validation'
    api 'org.springframework.boot:spring-boot-starter-data-redis'
    api 'org.springframework.boot:spring-boot-starter-cache'
    api 'org.springframework.boot:spring-boot-starter-actuator'
    api 'org.springframework.boot:spring-boot-starter-oauth2-client'
    api 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'

    // JWT
    api 'io.jsonwebtoken:jjwt-api:0.12.6'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
    runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'

    // OpenAPI
    api 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6'

    // Admin Console (조건부)
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

    // Flyway (소비 모듈이 DBMS별 추가)
    api 'org.flywaydb:flyway-core'

    // DB 드라이버 — compileOnly (소비 모듈이 runtimeOnly로 선택)
    compileOnly 'com.mysql:mysql-connector-j'
    compileOnly 'org.postgresql:postgresql'
    compileOnly 'com.oracle.database.jdbc:ojdbc11:23.6.0.24.10'
    compileOnly 'com.microsoft.sqlserver:mssql-jdbc:12.8.1.jre11'

    // Micrometer
    runtimeOnly 'io.micrometer:micrometer-registry-prometheus'

    // Test
    testRuntimeOnly 'com.h2database:h2'
}

3.3 Auto-Configuration 전환

작업 설명
WbxSpringCoreApplication.java 삭제 main() 제거, 라이브러리에 불필요
WbxAutoConfiguration.java 생성 @Configuration + @EnableJpaAuditing + @EnableAsync + @EnableScheduling + @EnableCaching
AutoConfiguration.imports 생성 Spring Boot 3.x 자동 설정 등록
application.yml 정리 하드코딩된 설정 제거, 기본값만 WbxSpringProperties에서 관리
HealthController 이동 범용으로 유지 (actuator가 대체 가능)
// META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
kr.co.accura.wbx.spring.config.WbxAutoConfiguration

3.4 Admin UI 조건부 활성화

// wbx-spring-core
@Configuration
@ConditionalOnProperty(name = "wbx.spring.admin-ui.enabled", havingValue = "true", matchIfMissing = true)
public class AdminAutoConfiguration {
    // AdminController, AdminLoginController, AdminUserDetailsService 등록
    // SecurityAutoConfig의 adminFilterChain도 여기로 이동
}

Phase 1: wtm-api 모듈 생성

3.5 wtm-api build.gradle

// wtm-api/build.gradle
plugins {
    id 'org.springframework.boot' version '3.5.0'
}

dependencies {
    // wbx-spring 프레임워크
    implementation project(':wbx-spring-core')

    // WTM 전용
    implementation 'org.apache.poi:poi-ooxml:5.3.0'       // P6 WBS, Excel 업로드/다운로드

    // 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'

    // Flyway — Azure SQL
    implementation 'org.flywaydb:flyway-sqlserver'

    // DB Driver — 개발: MySQL, 운영: MSSQL (Azure SQL)
    runtimeOnly 'com.mysql:mysql-connector-j'
    runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc:12.8.1.jre11'

    // Test
    testRuntimeOnly 'com.h2database:h2'
}

3.6 WtmApplication.java

@SpringBootApplication(scanBasePackages = {
    "kr.co.accura.wbx.spring",
    "kr.co.accura.wtm"
})
@EntityScan(basePackages = {
    "kr.co.accura.wbx.spring",
    "kr.co.accura.wtm"
})
@EnableJpaRepositories(basePackages = {
    "kr.co.accura.wbx.spring",
    "kr.co.accura.wtm"
})
public class WtmApplication {
    public static void main(String[] args) {
        SpringApplication.run(WtmApplication.class, args);
    }
}

Auto-Configuration 방식 적용 시 scanBasePackages 제거 가능

3.7 wtm-api application.yml

spring:
  application:
    name: wtm-api

  datasource:
    url: jdbc:mysql://${DB_HOST:ws.ubuilder.co.kr}:${DB_PORT:3306}/${DB_NAME:wtm_db}
    username: ${DB_USER:jsh}
    password: ${DB_PASS:jsh@}
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: validate    # Flyway로 스키마 관리
    open-in-view: false

  flyway:
    enabled: true
    locations: classpath:db/migration

  data:
    redis:
      host: ${REDIS_HOST:localhost}
      port: 6379

server:
  port: 8080

wbx:
  spring:
    api-prefix: /api/wtm
    jwt:
      secret: ${JWT_SECRET:dev-secret-key-minimum-256-bits}
      expiration: 28800
    admin-ui:
      enabled: false         # WTM은 자체 Admin 불필요
    cors:
      allowed-origins: ${CORS_ORIGINS:http://localhost:5173}
    notification:
      sse-enabled: true

wtm:
  work-rules:
    default-min-daily-hours: 8
    default-max-weekly-hours: 52

4. WTM 도메인 모듈별 구현 범위

신규 JPA Entity (23개)

DB 스키마 상세: 02-database-schema.md (Single Source of Truth) Flyway 마이그레이션: 02-database-schema.md의 V1~V7 참조 (본 문서에서 복제하지 않음)

도메인 Entity 테이블 Phase
user User users PH1-1
user Role roles PH1-1
user UserRole user_roles PH1-1
user OrgHierarchy org_hierarchy PH1-1
user HrUpload hr_uploads PH1-1
project Project projects PH1-1
project ProjectAssignment project_assignments PH1-1
project ProjectTypeConfig project_type_config PH1-1
wbs WbsVersion wbs_versions PH1-1
wbs WbsNode wbs_nodes PH1-1
wbs CanonicalWbs canonical_wbs PH1-1
wbs WbsDisciplineAssignment wbs_discipline_assignments PH1-1
teal TealVersion teal_versions PH1-1
teal TealEntry teal_entries PH1-1
timesheet Timesheet timesheets PH1-1
timesheet TimesheetEntry timesheet_entries PH1-1
timesheet TimesheetUpload timesheet_uploads PH1-1
approval TtApproval approvals PH1-1
approval TtApprovalLine approval_lines PH1-1
approval TtApprovalComment approval_comments PH1-1
config OverheadType overhead_types PH1-1
config WorkRule work_rules PH1-1
audit SaAccessLog sa_access_logs PH1-2

User Entity 전략 확정: WTM은 02-database-schema.md에 정의된 users 테이블을 직접 사용. wbx-spring-core의 WbxUser와 별도로, WTM 전용 User 엔티티가 HR 확장 필드(discipline, location, employment_type 등)를 포함한 users 테이블에 매핑됨. 인증은 wbx-spring-core의 WbxUser(wbx_users)가 담당하며, users.email = wbx_users.email로 연동.

신규 REST Controller (13개, 79 API)

Controller API 수 Phase
AuthController (WTM 전용 라우팅) 8 PH1-1
UserController 8 PH1-1 ~ PH1-2
ProjectController 7 PH1-1
WbsController 7 PH1-1 ~ PH1-2
TealController 4 PH1-1
TimesheetController 8 PH1-1
ApprovalController 8 PH1-1 ~ PH1-2
ReportController 9 PH1-1 ~ PH2
HomeController (대시보드/알림) 2 PH1-1
OverheadTypeController (SA) 3 PH1-1
WorkRuleController (SA) 2 PH1-1
ResourceAssignController 5 PH1-1
HrIntegrationController 2 PH1-2

wbx-spring-core 활용 포인트

// RBAC 권한 체크
@PreAuthorize("@wbx.check('TIMESHEET', 'VIEW')")

// 데이터 필터링 범위
DeptScope scope = evaluator.getScope("TIMESHEET", "VIEW");

// 결재 핸들러 등록 (Bean 등록만으로 자동 연동)
@Component
public class TimesheetApprovalHandler implements ApprovalHandler { ... }

// SSE 실시간 알림
sseNotificationService.sendToUser(approverId, notification);

// 에러 응답 (자동 적용)
throw new BusinessException("주간 합계 54시간 — 최대 52h 초과");
// → {"detail": "주간 합계 54시간 — 최대 52h 초과"}

5. User Entity 전략

선택지

방안 장점 단점
A: WbxUser 확장 (WTM 필드를 wbx_users에 추가) 테이블 하나, 간단 core 엔티티 오염
B: WtmUser 별도 (wtm.users + wbx.wbx_users 동기화) 도메인 분리 깔끔 두 테이블 동기화 필요
C: WtmUserProfile (wbx_users FK → wtm_user_profiles) core 불변, 확장 자유 JOIN 필요

권장: 방안 C — WtmUserProfile 확장 테이블

CREATE TABLE wtm_user_profiles (
    id              BIGINT IDENTITY PRIMARY KEY,
    wbx_user_id     BIGINT NOT NULL UNIQUE REFERENCES wbx_users(id),
    employee_id     VARCHAR(50) UNIQUE,
    discipline      VARCHAR(100),
    location        VARCHAR(50),
    employment_type VARCHAR(20) DEFAULT 'INTERNAL',
    business_unit   VARCHAR(100),
    division        VARCHAR(100),
    department      VARCHAR(100),
    part            VARCHAR(100),
    created_at      DATETIME2 DEFAULT GETDATE()
);

이유: wbx-spring-core의 WbxUser 엔티티를 수정하지 않고, WTM 전용 HR 필드를 별도 테이블로 관리. wbx_user_id FK로 연결.


6. 작업 순서 (Implementation Order)

Phase 0 — wbx-spring-core 라이브러리 전환 (1~2일)
├── 0-1. 루트 settings.gradle, build.gradle 생성
├── 0-2. wbx-spring-core build.gradle → java-library 전환
├── 0-3. WbxSpringCoreApplication 삭제, WbxAutoConfiguration 생성
├── 0-4. application.yml → 기본값만 남기고 정리
├── 0-5. Admin UI 조건부 활성화 (@ConditionalOnProperty)
├── 0-6. Enable 어노테이션 분리 → 개별 @Configuration
└── 0-7. 빌드 검증 (./gradlew :wbx-spring-core:build)

Phase 1 — wtm-api 스캐폴딩 (1일)
├── 1-1. wtm-api 디렉토리 + build.gradle 생성
├── 1-2. WtmApplication.java 생성
├── 1-3. application.yml (개발 환경)
├── 1-4. Flyway V1~V7 마이그레이션 SQL 생성
├── 1-5. 빌드 + 부팅 검증 (./gradlew :wtm-api:bootRun)
└── 1-6. wbx-spring-core 연동 검증 (JWT, RBAC, 결재 등)

Phase 2 — WTM 도메인 구현 (W3~W8, 계획서 10-schedule 참조)
├── 2-1. domain/user + domain/project (W3~W4)
├── 2-2. domain/wbs + domain/teal + P6 파서 (W4~W5)
├── 2-3. domain/timesheet + 규칙 엔진 (W5~W7)
├── 2-4. domain/approval/handler (W6~W7)
├── 2-5. domain/report + Excel Export (W7~W8)
└── 2-6. integration/sap (PH1-2)

7. 주의사항

어노테이션 프로세서 순서

Lombok + MapStruct + QueryDSL을 함께 사용 시:

annotationProcessor 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.6.3'
annotationProcessor 'com.querydsl:querydsl-apt:5.1.0:jakarta'

DB 이중 구조 — Flyway 듀얼 마이그레이션

  • 개발: MySQL (ws.ubuilder.co.kr) — wtm_db 스키마
  • 운영: Azure SQL (MSSQL) — Flyway 마이그레이션

DDL 구문 차이(IDENTITY vs AUTO_INCREMENT, DATETIME2 vs DATETIME, GETDATE() vs NOW())를 프로필별 마이그레이션 경로로 해결:

# application-mysql.yml (개발)
spring:
  flyway:
    locations: classpath:db/migration/common,classpath:db/migration/mysql

# application-mssql.yml (운영)
spring:
  flyway:
    locations: classpath:db/migration/common,classpath:db/migration/mssql
src/main/resources/db/migration/
├── common/                    # ANSI SQL 호환 (seed data, VIEW 등)
│   └── V10__seed_roles.sql
├── mysql/                     # MySQL 전용 DDL
│   ├── V1__init_users.sql     # AUTO_INCREMENT, DATETIME, NOW()
│   ├── V2__init_projects.sql
│   └── ...
└── mssql/                     # Azure SQL 전용 DDL
    ├── V1__init_users.sql     # IDENTITY, DATETIME2, GETDATE()
    ├── V2__init_projects.sql
    └── ...

02-database-schema.md의 DDL은 MSSQL 기준. MySQL 버전은 구현 시 변환 생성.

wbx-spring-core의 WbxUser와 WTM User

  • wbx-spring-core의 wbx_users 테이블: 인증/권한 용도 (JWT, SSO, MFA)
  • WTM의 users 테이블: HR 확장 필드 포함 (discipline, location, employment_type 등)
  • 연동: users.email = wbx_users.email 기준으로 매칭
  • WTM User 엔티티는 users 테이블에 직접 매핑 (별도 확장 테이블 불필요)