TimeMachine 통합 API 명세
개요
이 문서는 AccessCode 도메인과 TimeMachine 도메인 간의 통합 API에 대한 세부 명세를 제공합니다. 이 API는 Access Code의 가상 시간 관리와 사용자 등록과의 연계 기능을 제공합니다.
API 정의
DTO 정의
TimeMachineOptionsDto
export class TimeMachineOptionsDto {
@IsBoolean()
@ApiProperty({
description: 'TimeMachine 사용 여부',
example: true,
})
useTimeMachine: boolean;
@IsOptional()
@IsDateString()
@ApiProperty({
description: '가상 시간 시작일(13자리 Unix 타임스탬프, 밀리초)',
example: 1710924000000,
required: false,
})
virtualTimeStartDate?: string;
@IsOptional()
@IsBoolean()
@ApiProperty({
description: '가상 시간 기준 만료 여부',
example: true,
required: false,
default: false,
})
expirationBasedOnVirtualTime?: boolean;
@IsOptional()
@IsBoolean()
@ApiProperty({
description: '사용자 등록과 동기화 여부',
example: true,
required: false,
default: false,
})
synchronizeWithUserRegistration?: boolean;
@IsOptional()
@IsString()
@ApiProperty({
description: 'TimeMachine 사용 이유',
example: '테스트 목적',
required: false,
})
timeMachineReason?: string;
}
TimeMachineStatusDto
export class TimeMachineStatusDto {
@ApiProperty({
description: 'TimeMachine과의 통합 여부',
example: true,
})
integratedWithTimeMachine: boolean;
@ApiProperty({
description: '가상 시간을 사용하는 총 Access Code 수',
example: 45,
})
totalVirtualTimeAccessCodes: number;
@ApiProperty({
description: '가상 시간을 사용하는 활성 Access Code 수',
example: 32,
})
activeVirtualTimeAccessCodes: number;
@ApiProperty({
description: '가상 시간을 사용하는 총 사용자 등록 수',
example: 28,
})
totalUserRegistrationsWithVirtualTime: number;
@ApiProperty({
description: '평균 가상 시간 오프셋',
type: TimeOffsetDto,
})
averageVirtualTimeOffset: TimeOffsetDto;
}
TimeOffsetDto
export class TimeOffsetDto {
@ApiProperty({
description: '일 수',
example: 15,
})
days: number;
@ApiProperty({
description: '시간',
example: 6,
})
hours: number;
@ApiProperty({
description: '분',
example: 30,
})
minutes: number;
}
AccessCodeTimeMachineInfoDto
export class AccessCodeTimeMachineInfoDto {
@ApiProperty({
description: '코드 ID',
example: 'code_789',
})
codeId: string;
@ApiProperty({
description: 'TimeMachine 사용 여부',
example: true,
})
timeMachineEnabled: boolean;
@ApiProperty({
description: '가상 시간 시작일(13자리 Unix 타임스탬프, 밀리초)',
example: 1710924000000,
})
virtualTimeStartDate?: number;
@ApiProperty({
description: '가상 시간 기준 만료 여부',
example: true,
})
expirationBasedOnVirtualTime: boolean;
@ApiProperty({
description: '생성일(13자리 Unix 타임스탬프, 밀리초)',
example: 1710924000000,
})
createdAt: number;
@ApiProperty({
description: '만료일(13자리 Unix 타임스탬프, 밀리초)',
example: 1713602400000,
})
expiresAt: number;
@ApiProperty({
description: '실제 생성일(13자리 Unix 타임스탬프, 밀리초)',
example: 1713171600000,
})
realCreatedAt: number;
@ApiProperty({
description: '실제 만료일(13자리 Unix 타임스탬프, 밀리초)',
example: 1715850000000,
})
realExpiresAt: number;
@ApiProperty({
description: '가상 시간 오프셋',
type: TimeOffsetDto,
required: false,
})
virtualTimeOffset?: TimeOffsetDto;
@ApiProperty({
description: '연결된 사용자 등록 정보',
type: AssociatedUserRegistrationDto,
required: false,
})
associatedUserRegistration?: AssociatedUserRegistrationDto;
}
AssociatedUserRegistrationDto
export class AssociatedUserRegistrationDto {
@ApiProperty({
description: '사용자 ID',
example: 'user_123',
})
userId: string;
@ApiProperty({
description: 'TimeMachine 사용 여부',
example: true,
})
timeMachineEnabled: boolean;
@ApiProperty({
description: '가상 시간 시작일(13자리 Unix 타임스탬프, 밀리초)',
example: 1710924000000,
required: false,
})
virtualTimeStartDate?: number;
}
TimeMachine 상태 조회 API
요청
- 메서드: GET
- 경로:
/v1/access-codes/time-machine/status - 헤더:
- Authorization: Bearer
{token}
- Authorization: Bearer
응답
- 성공 응답 (200 OK): TimeMachineStatusDto
- 오류 응답:
- 401 Unauthorized: 인증 실패
- 403 Forbidden: 권한 없음
예시
요청:
GET /v1/access-codes/time-machine/status
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
응답:
{
"integratedWithTimeMachine": true,
"totalVirtualTimeAccessCodes": 45,
"activeVirtualTimeAccessCodes": 32,
"totalUserRegistrationsWithVirtualTime": 28,
"averageVirtualTimeOffset": {
"days": 15,
"hours": 6,
"minutes": 30
}
}
특정 코드의 TimeMachine 정보 조회 API
요청
- 메서드: GET
- 경로:
/v1/access-codes/time-machine/{codeId} - 헤더:
- Authorization: Bearer
{token}
- Authorization: Bearer
- 파라미터:
- codeId: Access Code ID
응답
- 성공 응답 (200 OK): AccessCodeTimeMachineInfoDto
- 오류 응답:
- 401 Unauthorized: 인증 실패
- 403 Forbidden: 권한 없음
- 404 Not Found: 코드 없음
예시
요청:
GET /v1/access-codes/time-machine/code_789
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
응답:
{
"codeId": "code_789",
"timeMachineEnabled": true,
"virtualTimeStartDate": 1710924000000,
"expirationBasedOnVirtualTime": true,
"createdAt": 1710924000000,
"expiresAt": 1713602400000,
"realCreatedAt": 1713171600000,
"realExpiresAt": 1715850000000,
"virtualTimeOffset": {
"days": 26,
"hours": 0,
"minutes": 0
},
"associatedUserRegistration": {
"userId": "user_123",
"timeMachineEnabled": true,
"virtualTimeStartDate": 1710924000000
}
}
Access Code 생성 시 TimeMachine 옵션
Access Code 생성 API에서 TimeMachine 옵션을 사용하는 방법을 설명합니다.
코드 생성 시 TimeMachine 옵션 포함
요청
- 메서드: POST
- 경로:
/v1/access-codes - 헤더:
- Content-Type: application/json
- Authorization: Bearer
{token} - X-Admin-Token:
{admin_token}
- 본문:
{
"type": "TREATMENT",
"creatorId": "user_123",
"accountId": "account_456",
"treatmentPeriod": 90,
"usagePeriod": 30,
"email": "m***@example.com",
"registrationChannel": "WEB",
"randomizationCode": "RND123",
"deliveryMethod": "EMAIL",
"privacyConsent": {
"dataProcessing": true,
"emailMarketing": false,
"thirdPartySharing": false
},
"timeMachineOptions": {
"useTimeMachine": true,
"virtualTimeStartDate": 1710924000000,
"expirationBasedOnVirtualTime": true,
"synchronizeWithUserRegistration": true,
"timeMachineReason": "테스트 목적"
}
}
응답
{
"id": "code_789",
"code": "AB12CD34EF56GH78",
"expiresAt": 1713602400000,
"status": "UNUSED",
"createdAt": 1710924000000,
"timeMachineEnabled": true,
"virtualTimeStartDate": 1710924000000
}
일괄 코드 생성 시 TimeMachine 옵션 포함
요청
- 메서드: POST
- 경로:
/v1/access-codes/batch - 헤더:
- Content-Type: application/json
- Authorization: Bearer
{token} - X-Admin-Token:
{admin_token}
- 본문:
{
"count": 10,
"type": "TREATMENT",
"creatorId": "user_123",
"accountId": "account_456",
"treatmentPeriod": 90,
"usagePeriod": 30,
"registrationChannel": "WEB",
"timeMachineOptions": {
"useTimeMachineForAll": true,
"commonVirtualTimeStartDate": 1710924000000,
"expirationBasedOnVirtualTime": true,
"reason": "일괄 테스트 코드 생성"
}
}
응답
{
"items": [
{
"id": "code_789",
"code": "AB12CD34EF56GH78",
"expiresAt": 1713602400000,
"status": "UNUSED",
"createdAt": 1710924000000,
"timeMachineEnabled": true,
"virtualTimeStartDate": 1710924000000
}
],
"metadata": {
"totalCount": 10,
"currentPage": 1,
"pageSize": 10,
"totalPages": 1
},
"batchId": "batch_001",
"timeMachineEnabled": true
}
Access Code 사용 시 TimeMachine 옵션
Access Code 사용 API에서 TimeMachine 옵션을 사용하는 방법을 설명합니다.
코드 사용 시 TimeMachine 옵션 포함
요청
- 메서드: POST
- 경로:
/v1/access-codes/{codeId}/use - 헤더:
- Content-Type: application/json
- Authorization: Bearer
{service_token}
- 파라미터:
- codeId: Access Code ID
- 본문:
{
"userId": "user_123",
"deviceId": "DEVICE_001",
"timeMachineOptions": {
"useTimeMachine": true,
"virtualTimeStartDate": 1710924000000,
"overrideCodeSettings": false,
"reason": "사용자 등록 처리"
}
}
응답
{
"id": "code_789",
"status": "USED",
"usedAt": 1711374600000,
"userId": "user_123",
"timeMachineEnabled": true,
"virtualTimeStartDate": 1710924000000
}
TimeMachine 옵션 제약 조건
TimeMachine 옵션 사용 시 적용되는 제약 조건을 설명합니다.
시간 제약 조건
virtualTimeStartDate는 현재 시간보다 미래일 수 없음virtualTimeStartDate는 구성된 최대 과거 일수(기본값: 365일)보다 오래된 과거일 수 없음virtualTimeStartDate가 없으면useTimeMachine이true여도 TimeMachine 기능이 적용되지 않음
권한 제약 조건
- TimeMachine 상태 조회는 System Admin, IAM Admin, Service Account 권한 필요
- 특정 코드의 TimeMachine 정보 조회도 동일한 권한 필요
사용자 등록 동기화 제약 조건
- 코드 사용 시
synchronizeWithUserRegistration이true이고 코드가 TimeMachine을 사용하면, 사용자의 가상 시간이 자동으로 초기화됨 - 사용자 가상 시간은 코드의 가상 시간 설정을 따름
overrideCodeSettings이true이면 코드 사용 시 지정한 가상 시간으로 코드의 설정을 덮어쓰고, 이를 사용자에게도 적용
오류 코드
TimeMachine 관련 오류 코드
| HTTP 상태 코드 | 오류 코드 | 메시지 | 설명 | 대응 방법 |
|---|---|---|---|---|
| 400 | 4001 | INVALID_VIRTUAL_TIME | 가상 시간 설정이 유효하지 않음 | 유효한 시간을 설정하고 다시 시도 |
| 409 | 4002 | TIME_MACHINE_DISABLED | TimeMachine 기능이 비활성화됨 | TimeMachine 기능을 활성화하거나 관리자에게 문의 |
| 400 | 4003 | FUTURE_VIRTUAL_TIME | 현재보다 미래의 가상 시간으로 설정 불가 | 현재 시간보다 이전 시간으로 설정 |
| 400 | 4004 | VIRTUAL_TIME_TOO_OLD | 설정 가능한 범위보다 오래된 가상 시간 | 허용된 범위 내의 시간으로 설정 |
| 500 | 4005 | TIME_MACHINE_SYNC_ERROR | TimeMachine과의 동기화 중 오류 발생 | 잠시 후 다시 시도하거나 관리자에게 문의 |
이벤트 통합
TimeMachine 통합과 관련된 발행 이벤트를 설명합니다.
발행 이벤트
| 이벤트 이름 | 설명 | 페이로드 |
|---|---|---|
| access-code.created-with-time-machine | TimeMachine 옵션으로 Access Code 생성 | Access Code 정보 |
| access-code.used-with-time-machine | TimeMachine 옵션으로 Access Code 사용 | 사용된 Access Code 정보 |
| access-code.virtual-time-initialized | 사용자의 가상 시간 초기화 | 사용자 ID, 가상 시간 시작일 |
| access-code.expired-by-virtual-time | 가상 시간 기준으로 Access Code 만료 | Access Code 정보 |
이벤트는 Access Code의 라이프사이클 관리와 TimeMachine 통합을 위해 중요합니다. 이벤트 구독자는 적절한 처리를 통해 두 도메인 간의 일관성을 유지해야 합니다.
보안 고려사항
TimeMachine 통합 시 고려해야 할 보안 요소를 설명합니다.
권한 관리
- TimeMachine 상태 조회는 관리자 권한 필요
- 특정 코드의 TimeMachine 정보 조회도 관리자 권한 필요
- 가상 시간 설정은 예기치 않은 동작을 유발할 수 있으므로 권한 있는 사용자만 수행해야 함
감사 추적
- 모든 TimeMachine 관련 작업은 감사 로그에 기록
- 가상 시간 변경은 특히 중요하게 감사 기록 필요
일관성 보장
- 가상 시간 설정은 항상 검증 후 적용
- 코드와 사용자 간의 가상 시간 일관성 유지 필요
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-04-02 | bok@weltcorp.com | 최초 작성 |