데이터 매핑 사양
버전 0.1 (2026-08-12) · 상태 개발 착수용 초안 대상 5240 조회 응답 한 건이 구글 캘린더 이벤트 하나가 되기까지.
이 문서는 F-08(캘린더 동기화) 를 만드는 사람이 본다. 규칙의 근거는 기능정의서 R-01~R-07에 있다.
0. 전제 — 신청건 하나 = 이벤트 하나
5240에는 삭제도 변경도 없고 취소만 있으며, 부분 취소가 없다. 고치려면 취소하고 새로 신청하므로 그것은 다른 신청번호의 새 건이다. 따라서 신청건과 캘린더 이벤트는 1:1이고, 이미 만든 이벤트의 날짜·종류가 뒤에서 바뀌는 일이 없다.
바뀌는 것은 결재중(20) → 결재완료(30) 전이 하나뿐이고, 그때 제목의 [진행중]만 뗀다.
이 전제가 매핑을 단순하게 만든다. 병합·분할·기간 조정이 필요 없다.
1. 이벤트 식별 표식 — 가장 먼저 정할 것
대조 삭제(S-01)가 안전하려면 "이 이벤트를 우리가 만들었는가" 를 이벤트만 보고 판별할 수 있어야 한다. 사람이 손으로 넣은 일정을 지우면 되돌릴 방법이 없다.
구글 캘린더 이벤트의 extendedProperties.private에 다음을 넣는다.
| 키 | 값 | 쓰임 |
|---|---|---|
x5240 | "1" | 우리가 만든 것인가 — 이 키가 없으면 어떤 경우에도 건드리지 않는다 |
servareaId | 예: 300 | 연동함 식별. 한 캘린더를 여러 연동함이 쓰는 사고를 잡는다 |
kind | LEAV / BSTRIP / EDU | 갈래 |
reqNo | 예: 101254 | 신청번호 — 대조의 열쇠 |
staffId | 예: 100:2007:00204:kkHT | 누구 것인가 |
srcStatus | 20 / 30 | 만들 때의 결재상태. 20→30 전이 감지에 쓴다 |
- 대조 키는
(servareaId, kind, reqNo)다. 이 조합이 같으면 같은 일정이다. private에 넣는 까닭 — 이벤트를 구독하는 직원에게 보이지 않는다.shared에 넣으면
직원 캘린더에 내부 식별자가 노출된다.
- 표식 없는 이벤트는 읽지도 지우지도 않는다. 사람이 넣은 것으로 본다.
2. 공통 필드 매핑
| 캘린더 필드 | 값 | 비고 |
|---|---|---|
summary | 아래 3. 제목 규칙 | |
start / end | 아래 4. 날짜와 시간 | 종일이 기본 |
description | 비운다 | 사유(REASON)는 넣지 않는다 — 개인정보이고 옵션 1426의 통제 밖이다 |
location | 비운다 | 출장지도 넣지 않는다(가림 규칙이 없으므로 제목에만 최소로) |
transparency | transparent | 회사 휴가가 직원 개인 일정의 "바쁨"을 덮지 않게 한다 |
visibility | default | 캘린더 자체의 공개 설정을 따른다 |
reminders | 끔(useDefault: false, 목록 비움) | 남의 휴가에 알림이 울리면 안 된다 |
extendedProperties.private | 1. 표식 |
description을 비우는 것은 의도된 결정이다. 담을 것이 없어서가 아니라, 한 번 담기 시작하면 무엇을 담을지의 기준이 옵션 1426 바깥에 하나 더 생기기 때문이다.
3. 제목 규칙
[진행중] 홍길동 · 연차
└─ 20일 때만 └─ 직원명 └─ 표시명
| 요소 | 규칙 |
|---|---|
[진행중] | REQ_STATUS_CD = '20' 일 때만 앞에 붙인다. 30이면 없다 |
| 직원명 | STAFF_NM |
| 구분자 | · (가운뎃점, 앞뒤 공백) |
| 표시명 | 마스킹 대상이면 MASK_NM, 아니면 TYPE_NM |
마스킹 치환
MASK_YN | 제목에 쓰는 이름 |
|---|---|
N | TYPE_NM (예: 연차) |
Y | MASK_NM (예: 기타휴가) |
Y 인데 MASK_NM이 비었다 | O-01 미결 — 정해야 한다. 잠정 휴가를 권한다 |
- 미표시 대상(
CNFG_VAL01)은 응답에 아예 오지 않는다. 연동이 거를 일이 없다. - 갈래별 표시명 출처는 아래 5장.
4. 날짜와 시간
기본은 종일 이벤트다. 근태 일정은 시각보다 "그날 자리에 없다"가 중요하다.
| 조건 | 이벤트 형태 |
|---|---|
반차 아님(STA_HALF_YN='N', END_HALF_YN='N') | 종일 — start.date = STA_YMD, end.date = END_YMD + 1일 |
반차이고 STA_HM/END_HM이 있다 | 시간 — start.dateTime, end.dateTime (타임존 Asia/Seoul) |
| 반차인데 시각이 없다 | 종일로 두고 제목 끝에 (반차) 를 붙인다 |
⚠ 구글 종일 이벤트의
end.date는 배타적이다. 8/10 하루 휴가는start.date=2026-08-10,end.date=2026-08-11이다. 여기서 하루를 빼먹으면 모든 휴가가 하루씩 짧게 보인다 — 가장 흔한 실수다.
5. 갈래별 매핑
5.1 휴가 (kind = LEAV)
| 응답 필드 | 이벤트 |
|---|---|
STAFF_NM | 제목의 직원명 |
TYPE_NM / MASK_NM | 제목의 표시명 |
STA_YMD / END_YMD | 기간 |
STA_HM / END_HM | 반차일 때 시각 |
REQ_NO | 표식 reqNo |
휴가 테이블에는 휴가신청(1022)·조퇴/외출(1122)·경조휴가(1123) 가 함께 쌓이며 셋 다 내보낸다. 신청서 종류를 구분하지 않으므로 매핑도 하나다.
5.2 출장 (kind = BSTRIP)
휴가와 같다. 표시명은 TAA_BSTRIP_TYPE_CD 공통코드에서 온다. 가림 규칙이 없다 — 출장 구분이 그대로 나간다.
5.3 교육 (kind = EDU)
| 출처 | 표시명 | 기간 |
|---|---|---|
EDUT_REQ | EDUT_COURS.EDU_NM(과정명) | EDUT_COURSN.END_YMD |
EDUT_HST2 | EDU_NM(직접입력) | 자체 STA_YMD/END_YMD |
API 응답에서는 둘 다 TYPE_NM(= TYPE_NM_RAW)으로 평탄화되어 온다. 연동은 구분할 필요가 없다.
교육에는
CHG_DATE가 없다(NULL). 증분 비교가 듣지 않으므로 대조로만 맞춘다.
6. 대조 동작
| 상태 | 판정 | 동작 |
|---|---|---|
| 응답에 있고 캘린더에 없다 | 새 신청 | 생성 |
양쪽에 있고 srcStatus가 20인데 응답은 30 | 결재 완료됨 | 수정 — 제목의 [진행중] 제거, 표식 srcStatus를 30으로 |
| 양쪽에 있고 나머지가 같다 | 변화 없음 | 건드리지 않는다 |
| 캘린더에 있고 응답에 없다 | 취소승인 / 1426 미표시 전환 / 범위 밖 | 삭제(단 S-02~S-04 확인 후) |
| 표식이 없다 | 사람이 만든 일정 | 건드리지 않는다 |
수정은 patch로 한다. 지웠다 다시 만들면 직원이 걸어 둔 알림·색상 설정이 사라진다.
7. 열린 항목
| # | 항목 | 비고 |
|---|---|---|
| O-01 | MASK_NM이 비었을 때 쓸 이름 | 잠정 휴가 제안 |
| M-01 | 반차인데 시각이 없을 때 (반차) 표기를 쓸지 | 화면 문구와 맞춰야 함 |
| M-02 | 한 캘린더를 여러 연동함이 가리키는 것을 막을지 | 표식 servareaId로 감지는 되나 차단 정책 미정 |