G-1: 메신저 Webhook Relay + _send_to_room 실제 httpx 호출 구현 G-2: POST /api/tasks/bulk SR 대량작업 엔드포인트 (최대 100건) G-3: 라이선스 만료 알림 스케줄러 (매일 09:00 KST) G-4: 체험판 upgrade_banner 필드 + license.py 배너 로직 G-5: core/auto_rca.py + incidents/problem auto-rca 엔드포인트 G-6: core/deploy_impact.py + vibe impact-analysis 엔드포인트 G-7: core/ticket_classifier.py + SR 생성 시 AI 분류 + ai-suggestion API G-8: VulnPatchRecord 모델 + vuln_scan 패치추적 4개 엔드포인트 G-9: core/jira_sync.py + gateway Jira/Confluence 연동 엔드포인트 G-10: core/push_notify.py + routers/push.py + PushSubscription 모델 G-11: approvals 다중승인 (위임/서명/기한초과/마감연장) G-12: alembic.ini + migrations/ + cicd/migrate_to_postgres.sh 하네스: guardia-orchestrator 확장기능 Phase 반영 봇명령어: /sr /status /license /bulk 슬래시 명령어 추가 설치스크립트: setup/ (Ubuntu, CentOS, RHEL, Windows) --test 옵션 포함 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
405 lines
9.8 KiB
JavaScript
405 lines
9.8 KiB
JavaScript
/*-------------------------------------------------------------------+
|
|
* 1. 파일명: valid.date.js
|
|
* 2. 설 명: 일자, 시간에 대한 유효성 점검 함수를 정의한다.
|
|
* 3. 의존성: string.js, date.js
|
|
* 4. 작성자:
|
|
* 5. 작성일: 2006.10.11.
|
|
-------------------------------------------------------------------*/
|
|
|
|
|
|
/**
|
|
* 주어진 문자열 값이 유효한 날짜 형식인지를 확인하여
|
|
* 유효하면 true를 돌려주고, 유효하지 않으면 적절한 오류 메시지를
|
|
* 보여준 다음 false를 돌려준다.
|
|
*/
|
|
function checkYearMonth(dateStr) {
|
|
// 아무값도 없으면 진행하지 않는다.
|
|
if ( trim(dateStr) == "" ) return true;
|
|
|
|
dateStr = removeChar(dateStr, DATE_DELIMETER);
|
|
|
|
// 슬래쉬를 제거한 나머지 자릿수가 8자인지 검사한다.
|
|
if (dateStr.length != 6) {
|
|
alert("YYYYMM의 형식으로 입력해 주십시오.");
|
|
return false;
|
|
}
|
|
|
|
// 숫자로만 구성되었는지 확인한다.
|
|
if ( isNaN(dateStr) ) {
|
|
alert("날짜에는 문자가 입력될 수 없습니다.");
|
|
return false;
|
|
}
|
|
|
|
// 연도 4자리, 월 2자리로 자른다.
|
|
var yearStr = dateStr.substring(0, 4);
|
|
var monthStr = dateStr.substring(4);
|
|
|
|
|
|
// 연도 값이 1900 ~ 2050 사이인지 점검한다.
|
|
if ( yearStr < 1900 || yearStr > 2050 ) {
|
|
alert("연도는 1900년 ~ 2050년 사이의 값을 입력해야 합니다.");
|
|
return false;
|
|
}
|
|
|
|
// 월이 1~12월 사이인지 점검한다.
|
|
if ( monthStr < 1 || monthStr > 12 ) {
|
|
alert("월은 01월에서 12월 사이의 값입니다.");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Text형 입력폼의 문자열 값이 유효한 날짜 형식인지를 확인하여
|
|
* 유효하면 연월 값 사이에 슬래쉬(/)를 넣은 문자열로 바꾼 후 true를 돌려주고,
|
|
* 유효하지 않으면 적절한 오류 메시지를 보여준 다음 false를 돌려준다.
|
|
*/
|
|
function checkYearMonthObj(obj) {
|
|
var dateStr = removeChar(obj.value, DATE_DELIMETER);
|
|
|
|
var valid = true;
|
|
|
|
// 빈 문자열이면 점검하지 않는다.
|
|
if ( trim(dateStr) != "" ) {
|
|
valid = checkYearMonth(dateStr);
|
|
if ( valid ) {
|
|
var yearStr = dateStr.substring(0, 4);
|
|
var monthStr = dateStr.substring(4);
|
|
|
|
obj.value = yearStr + DATE_DELIMETER + monthStr;
|
|
}
|
|
else {
|
|
obj.focus();
|
|
}
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
|
|
/**
|
|
* Text형 입력폼 에 입력된 날짜가 유효한지 체크하여
|
|
* 유효하면 YYYY/MM/DD의 형태로 변환하여 return
|
|
* 하고, 유효하지 않으면 에러메세지 보여줌
|
|
* (년월일 입력필드의 onblur event에 사용할것)
|
|
*
|
|
* @param obj Text형 입력폼 객체
|
|
*/
|
|
function checkDateObj(obj) {
|
|
return checkDate(obj.value);
|
|
}
|
|
|
|
|
|
/**
|
|
* 주어진 문자열값이 유효한 날짜값인지 점검하여
|
|
* 유효하면 true를 돌려주고, 유효하지 않으면
|
|
* 에러메세지를 보여주고 false를 돌려준다.
|
|
* (년월일 입력필드의 onblur event에 사용할것)
|
|
*
|
|
* @param dateStr 날짜형값을 가지는 문자열
|
|
*/
|
|
function checkDate(dateStr, fieldName) {
|
|
// 아무값도 없으면 진행하지 않는다.
|
|
if ( trim(dateStr) == "" ) return true;
|
|
|
|
/* 항목명이 없으면 "일자"을 사용. */
|
|
if ( isEmpty(fieldName) ) fieldName = "일자";
|
|
|
|
dateStr = removeChar(dateStr, DATE_DELIMETER);
|
|
|
|
// 숫자로만 구성되었는지 확인한다.
|
|
if ( isNaN(dateStr) ) {
|
|
alert(fieldName + "의 값에는 문자가 입력될 수 없습니다.");
|
|
return false;
|
|
}
|
|
|
|
// 구별자를 제거한 나머지 자릿수가 8자인지 검사한다.
|
|
if (dateStr.length != 8) {
|
|
alert(fieldName + "의 값을 YYYYMMDD의 형식으로 입력해 주십시오.");
|
|
return false;
|
|
}
|
|
|
|
// 연도 4자리, 월 2자리, 일 2자리로 자른다.
|
|
var yearStr = dateStr.substring(0, 4);
|
|
var monthStr = dateStr.substring(4, 6);
|
|
var dayStr = dateStr.substring(6);
|
|
|
|
|
|
// 연도 값이 1900 ~ 2050 사이인지 점검한다.
|
|
if ( yearStr < 1900 || yearStr > 2050 ) {
|
|
alert(fieldName + "의 연도는 1900년 ~ 2050년 사이의 값을 입력해야 주십시오.");
|
|
return false;
|
|
}
|
|
|
|
// 월이 1~12월 사이인지 점검한다.
|
|
if ( monthStr < 1 || monthStr > 12 ) {
|
|
alert(fieldName + "의 월을 01 ~ 12월 사이의 값으로 입력해 주십시오.");
|
|
return false;
|
|
}
|
|
|
|
// 일자가 해당월의 유효한 일자인지 검검한다.
|
|
// Date 객체 생성시 날짜가 유효범위를 넘어서면
|
|
// 달이 변하는 원리를 이용했다.
|
|
var date = new Date(yearStr, monthStr - 1, dayStr);
|
|
|
|
if (yearStr != date.getFullYear() || monthStr != (date.getMonth() + 1)) {
|
|
alert(monthStr + "월에는 " + dayStr + "일이 없습니다.");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* 주어진 일자값이 유효한지 검사하여 유효하면 true,
|
|
* 오류 메세지를 보여주고 false를 돌려 준다.
|
|
*
|
|
* @param dateStr 일자형의 문자열.
|
|
* @param filedName 유효성을 검증하려는 항목명.
|
|
* @return 유효여부.
|
|
*/
|
|
function validateDate(dateStr, fieldName) {
|
|
return checkDate(dateStr);
|
|
}
|
|
|
|
|
|
/**
|
|
* 주어진 객체의 값이 유효한 일자인지 검사하여,
|
|
* 유효하면 true, 그렇지 않으면 오류 메세지를 보여주고
|
|
* false를 돌려 준다.
|
|
*
|
|
* @param obj 일자형의 문자열을 값으로 가지는 객체.
|
|
* @param filedName 유효성을 검증하려는 항목명.
|
|
* @return 유효여부.
|
|
*/
|
|
function validateDateObj(obj, fieldName) {
|
|
var isValid = validateDate(obj.value, fieldName);
|
|
|
|
if ( ! isValid ) obj.focus();
|
|
|
|
return isValid;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* 주어진 객체의 값이 유효한 일자이면
|
|
* 객체의 값을 형식화한다.
|
|
*/
|
|
function formatDateStrObjIfValid(obj, fieldName) {
|
|
var dateStr = removeChar(obj.value, DATE_DELIMETER);
|
|
|
|
var valid = true;
|
|
|
|
valid = checkDate(dateStr, fieldName);
|
|
if ( valid ) {
|
|
formatDateStrObj(obj);
|
|
}
|
|
else {
|
|
obj.focus();
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
/**
|
|
* 두개의 연월(yyyy/MM형식) 문자열을 비교하여 앞 연월이 뒤 연월과
|
|
* 같으면 0, 앞 연월이 뒤 연월보다 빠르면 1, 앞 연월이 뒤 연월보다
|
|
* 느리면 -1을 돌려 준다.
|
|
*
|
|
* @param yearMonth1 앞 연월
|
|
* @param yearMonth2 뒤 연월
|
|
*/
|
|
function compareYearMonth(yearMonth1, yearMonth2) {
|
|
var result = 0;
|
|
|
|
yearMonth1 = removeChar(yearMonth1, DATE_DELIMETER);
|
|
yearMonth2 = removeChar(yearMonth2, DATE_DELIMETER);
|
|
|
|
if ( yearMonth1 < yearMonth2 ) {
|
|
result = 1;
|
|
}
|
|
else if ( yearMonth1 > yearMonth2 ) {
|
|
result = -1;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* 두개의 Text형 입력폼의 연월(yyyy/MM형식) 문자열 값을 비교하여
|
|
* 앞 연월이 뒤 연월과 같으면 0, 앞 연월이 뒤 연월보다 빠르면 1,
|
|
* 앞 연월이 뒤 연월보다 느리면 -1을 돌려 준다.
|
|
*
|
|
* @param obj1 앞 연월값을 가지는 Text형 입력폼
|
|
* @param obj2 뒤 연월값을 가지는 Text형 입력폼
|
|
*/
|
|
function compareYearMonthObj(obj1, obj2) {
|
|
return compareYearMonth(obj1.value, obj2.value);
|
|
}
|
|
|
|
|
|
/**
|
|
* 두개의 날짜 문자열을 비교하여 첫번째 파라미터(date1)의
|
|
* 날짜 값이 두번째 파라미터(date2)의 날짜 값과 비교하여
|
|
* 이르면 1을, 같으면 0을, 늦으면 -1을 돌려 준다.
|
|
* date1은 값이 있고, date2는 값이 없으면 -1,
|
|
* date1은 값이 없고, date2는 값이 있으면 1 이다.
|
|
*
|
|
* @param date1 yyyyMMdd형식의 날짜형 문자열.
|
|
* @param date2 yyyyMMdd형식의 날짜형 문자열.
|
|
*/
|
|
function compareDate(date1, date2) {
|
|
date1 = removeChar(date1, DATE_DELIMETER);
|
|
date2 = removeChar(date2, DATE_DELIMETER);
|
|
|
|
var result = 0;
|
|
|
|
if ( date1 < date2 ) {
|
|
result = 1;
|
|
}
|
|
else if ( date1 > date2 ) {
|
|
result = -1;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* 두개의 날짜 문자열을 비교하여 첫번째 파라미터(obj1)의
|
|
* 날짜 값이 두번째 파라미터(obj2)의 날짜 값과 비교하여
|
|
* 이르면 1을, 같으면 0을, 늦으면 -1을 돌려 준다.
|
|
* obj1은 값이 있고, obj2는 값이 없으면 -1,
|
|
* obj1은 값이 없고, obj2는 값이 있으면 1 이다.
|
|
*
|
|
* @param obj1 Text형 입력폼 객체
|
|
* @param obj2 Text형 입력폼 객체
|
|
*/
|
|
function compareDateObj(obj1, obj2) {
|
|
return compareDate(obj1.value, obj2.value);
|
|
}
|
|
|
|
|
|
/**
|
|
* 기간을 나타내는 두 개의 객체의 일자값의 유효성을 검증하여
|
|
* 유효하면 true를 돌려주고, 유효하지 않으면 오류메세지를
|
|
* 보여준 다음 false를 돌려 준다.
|
|
*
|
|
* @param rearDateStrObj 앞 일자 문자열 값을 갖는 객체.
|
|
* @param foreDateStrObj 뒤 일자 문자열 값을 갖는 객체.
|
|
* @param fieldName 항목명.
|
|
* @param allowSameDate 동일일 허용여부. 없으면 허용(true).
|
|
* @return 유효하면 true, 그렇지 않으면 false.
|
|
*/
|
|
function validateTermObj(rearDateStrObj, foreDateStrObj, fieldName, allowSameDate) {
|
|
if ( fieldName == undefined ) fieldName = "기간";
|
|
|
|
if ( allowSameDate == undefined ) allowSameDate = true;
|
|
|
|
/* 각각 유효한 일자인지 검사한다. */
|
|
if ( ! validateDateObj(rearDateStrObj, fieldName + " 앞일자") ) return false;
|
|
|
|
if ( ! validateDateObj(foreDateStrObj, fieldName + " 뒤일자") ) return false;
|
|
|
|
/* 둘 중 한 일자라도 없으면 true를 돌려 주고 끝낸다. */
|
|
if ( isEmptyObj(rearDateStrObj) || isEmptyObj(foreDateStrObj) ) return true;
|
|
|
|
/* 앞 일자와 뒤 일자를 비교한다. */
|
|
var result = compareDateObj(rearDateStrObj, foreDateStrObj);
|
|
|
|
/* 같은 일자를 허용하면 0이상 하지 않으면 1이상 이어야 한다. */
|
|
if ( allowSameDate && result < 0 ) {
|
|
showMessage(fieldName + " 뒤 일자는 앞 일자와 같거나 늦은 일자 이어야합니다.");
|
|
rearDateStrObj.focus();
|
|
return false;
|
|
}
|
|
else if ( ! allowSameDate && result < 1 ) {
|
|
showMessage(fieldName + " 뒤 일자는 앞 일자보다 늦은 일자 이어야합니다.");
|
|
rearDateStrObj.focus();
|
|
return false;
|
|
}
|
|
|
|
/* 여기까지 왔으면 유효하다. */
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Text형 입력폼에 입력된 시간(시+분)이 유효한지
|
|
* 체크하여 유효하면 hh24:mi의 형태로 변환하여
|
|
* return하고, 유효하지 않으면 에러메세지를
|
|
* 보여줌(시간 입력필드의 onblur event에 사용)
|
|
*/
|
|
function checkTimeObj(obj) {
|
|
var timeStr = obj.value;
|
|
|
|
var valid = true;
|
|
|
|
// 빈 문자열이면 점검하지 않는다.
|
|
if ( trim(timeStr) != "" ) {
|
|
valid = checkTime(timeStr);
|
|
|
|
if ( valid ) {
|
|
var hourStr = timeStr.substring(0, 2);
|
|
var minuteStr = timeStr.substring(2);
|
|
|
|
obj.value = hourStr + ":" + minuteStr;
|
|
}
|
|
else {
|
|
obj.focus();
|
|
}
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
|
|
/**
|
|
* Text형 입력폼에 입력된 시간(시+분)이 유효한지
|
|
* 체크하여 유효하면 hh24:mi의 형태로 변환하여
|
|
* return하고, 유효하지 않으면 에러메세지를
|
|
* 보여줌(시간 입력필드의 onblur event에 사용)
|
|
*
|
|
* @param timeStr HHmm 형식의 시간형 문자열
|
|
*/
|
|
function checkTime(timeStr) {
|
|
if ( trim(timeStr) == "" ) return true;
|
|
|
|
timeStr = removeChar(timeStr, ':');
|
|
|
|
// 길이가 4인지 점검한다.
|
|
if ( timeStr.length != 4 ) {
|
|
alert("형식이 맞지 않습니다. \"HHmm\" 형태의 숫자로 입력해 주십시오.");
|
|
return false;
|
|
}
|
|
|
|
// 숫자로만 구성되었는지 점검한다.
|
|
if ( isNaN(timeStr) ) {
|
|
alert("문자열은 입력할 수 없습니다. \"HHmm\" 형태의 숫자로 입력해 주십시오.");
|
|
return false;
|
|
}
|
|
|
|
// 시간 2자리, 분 2자리로 분리한다.
|
|
var hourStr = timeStr.substring(0, 2);
|
|
var minuteStr = timeStr.substring(2);
|
|
|
|
if ( hourStr < 0 || hourStr > 23 ) {
|
|
alert("시간 값은 00에서 23 사이의 값이어야 합니다.");
|
|
return false;
|
|
}
|
|
|
|
|
|
if ( minuteStr < 0 || minuteStr > 59 ) {
|
|
alert("분 값은 00에서 59 사이의 값이어야 합니다.");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|