18
deploy/vpd-backoffice/backoffice.env.example
Normal file
18
deploy/vpd-backoffice/backoffice.env.example
Normal file
@@ -0,0 +1,18 @@
|
||||
# HMM deployment profile for /etc/vpd-backoffice.env.
|
||||
# Append these non-secret values to the existing file. Keep DB passwords,
|
||||
# remember-me keys and user Bearer tokens outside Git.
|
||||
|
||||
BACKOFFICE_CATALOG_OWNER=ADMIN
|
||||
BACKOFFICE_CATALOG_OBJECTS='[{"key":"teams","tableName":"HMM_ORG_TEAMS","objectType":"TABLE","businessName":"조직 원장","description":"HMM HR 조직·팀 기본정보"},{"key":"employees","tableName":"HMM_HR_EMPLOYEES","objectType":"TABLE","businessName":"직원 원장","description":"직원·매니저·소속팀 정보"},{"key":"leave-balances","tableName":"HMM_LEAVE_BALANCES","objectType":"TABLE","businessName":"휴가 잔여 원장","description":"직원별 연도·휴가 유형별 부여·사용·잔여 일수"},{"key":"leave-requests","tableName":"HMM_LEAVE_REQUESTS","objectType":"TABLE","businessName":"휴가 신청 원장","description":"직원별 휴가 신청·승인 상태와 기간"},{"key":"attendance-daily","tableName":"HMM_ATTENDANCE_DAILY","objectType":"TABLE","businessName":"일별 근태 원장","description":"직원별 출퇴근·근무 상태와 근무 시간"},{"key":"hr-terms","tableName":"HMM_HR_TERMS","objectType":"TABLE","businessName":"HR 표준 용어 원장","description":"휴가·근태 표준 코드, 명칭과 유사 표현","previewColumns":["TERM_ID","TERM_CODE","TERM_KIND","CANONICAL_NAME","TERM_NAME","IS_CANONICAL","DESCRIPTION","EMBEDDED_AT"]}]'
|
||||
|
||||
BACKOFFICE_PRODUCT_NAME='HMM HR Access Console'
|
||||
BACKOFFICE_PRODUCT_TITLE='HMM HR Access Console'
|
||||
BACKOFFICE_PRODUCT_DATA_LABEL='HMM HR 데이터'
|
||||
|
||||
BACKOFFICE_MCP_PUBLIC_URL='https://hmm-backoffice.cloud-handson.com/mcp'
|
||||
BACKOFFICE_MCP_SERVER_NAME='hmm-hr-backoffice'
|
||||
BACKOFFICE_MCP_TOOLS='[{"name":"resolve_hr_term","label":"HMM HR 용어 표준화","description":"휴가·근태 표현을 HMM 표준 용어와 코드로 변환합니다. 모호한 표현은 데이터 조회 전에 이 도구를 사용합니다.","argumentName":"term","argumentDescription":"확인할 휴가·근태 용어, 동의어 또는 코드입니다.","executionType":"AGENT_TOOL","targetName":"HMM_HR_TERM_RESOLVER","targetParameterName":"P_TERM"},{"name":"search_hr_data","label":"HMM HR 데이터 조회","description":"조직, 직원, 휴가 잔여·신청, 근태 데이터를 읽기 전용 Select AI로 조회합니다.","argumentName":"query","argumentDescription":"조직, 직원, 휴가 또는 근태에 대한 완전한 자연어 질문입니다.","executionType":"AGENT_TOOL","targetName":"HMM_HR_NORMALIZED_DATA_SEARCH","targetParameterName":"P_QUERY"},{"name":"search_hr_policy","label":"HMM HR 규정 검색","description":"HR 규정 PDF의 문서 메타데이터, Abstract, 관련 청크를 계층형 벡터 검색으로 조회합니다.","argumentName":"query","argumentDescription":"HR 규정에 대한 완전한 자연어 질문입니다.","executionType":"AGENT_TOOL","targetName":"HMM_HR_POLICY_SEARCH","targetParameterName":"P_QUERY"}]'
|
||||
|
||||
BACKOFFICE_MASKING_POLICIES='[{"objectName":"HMM_HR_EMPLOYEES","policyName":"HMM_EMPLOYEE_PII_REDACT"},{"objectName":"HMM_LEAVE_BALANCES","policyName":"HMM_LEAVE_BALANCE_REDACT"},{"objectName":"HMM_LEAVE_REQUESTS","policyName":"HMM_LEAVE_REQUEST_REDACT"},{"objectName":"HMM_ATTENDANCE_DAILY","policyName":"HMM_ATTENDANCE_REDACT"}]'
|
||||
|
||||
BACKOFFICE_SECURITY_SQL_SCRIPTS='[{"scriptId":"hmm-leave-vpd","category":"HMM / VPD","fileName":"72_hmm_leave_team_vpd.sql","title":"HMM 휴가 팀 접근 정책","description":"직원 본인과 팀장의 직접 보고 팀원 휴가 행 접근 정책 및 토큰 컨텍스트를 구성합니다."}]'
|
||||
17
deploy/vpd-backoffice/caddy/Caddyfile.template
Normal file
17
deploy/vpd-backoffice/caddy/Caddyfile.template
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
email {{TLS_EMAIL}}
|
||||
}
|
||||
|
||||
{{PUBLIC_HOST}} {
|
||||
encode zstd gzip
|
||||
{{TLS_OPTIONS}}
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||
X-Content-Type-Options "nosniff"
|
||||
Referrer-Policy "same-origin"
|
||||
-Server
|
||||
}
|
||||
|
||||
reverse_proxy 127.0.0.1:{{APP_PORT}}
|
||||
}
|
||||
53
deploy/vpd-backoffice/caddy/install-caddy-config.sh
Executable file
53
deploy/vpd-backoffice/caddy/install-caddy-config.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# Runs on the target VM after a candidate Caddyfile has been uploaded.
|
||||
set -Eeuo pipefail
|
||||
|
||||
CANDIDATE="${1:?candidate Caddyfile is required}"
|
||||
APP_DIR="${2:?application directory is required}"
|
||||
TARGET="/etc/caddy/Caddyfile"
|
||||
|
||||
[[ -f "$CANDIDATE" ]] || { echo "candidate Caddyfile not found: $CANDIDATE" >&2; exit 1; }
|
||||
command -v caddy >/dev/null 2>&1 || { echo "caddy is not installed" >&2; exit 1; }
|
||||
command -v systemctl >/dev/null 2>&1 || { echo "systemctl is not installed" >&2; exit 1; }
|
||||
sudo -n true || { echo "passwordless sudo is required for Caddy configuration" >&2; exit 1; }
|
||||
sudo test -f "$TARGET" || { echo "existing $TARGET not found; install the official Caddy package first" >&2; exit 1; }
|
||||
|
||||
BACKUP_DIR="$APP_DIR/caddy-backups"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
BACKUP="$BACKUP_DIR/Caddyfile.$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
sudo cat "$TARGET" > "$BACKUP"
|
||||
chmod 600 "$BACKUP"
|
||||
|
||||
was_active="N"
|
||||
if sudo systemctl is-active --quiet caddy; then
|
||||
was_active="Y"
|
||||
fi
|
||||
|
||||
rollback() {
|
||||
status=$?
|
||||
trap - ERR
|
||||
echo "Caddy 적용 실패, 이전 설정 복원: $BACKUP" >&2
|
||||
sudo install -o root -g root -m 644 "$BACKUP" "$TARGET"
|
||||
if [[ "$was_active" == "Y" ]]; then
|
||||
sudo systemctl reload caddy || true
|
||||
else
|
||||
sudo systemctl stop caddy || true
|
||||
fi
|
||||
exit "$status"
|
||||
}
|
||||
trap rollback ERR
|
||||
|
||||
sudo caddy validate --config "$CANDIDATE" --adapter caddyfile
|
||||
sudo install -o root -g root -m 644 "$CANDIDATE" "$TARGET"
|
||||
|
||||
if [[ "$was_active" == "Y" ]]; then
|
||||
sudo systemctl reload caddy
|
||||
else
|
||||
sudo systemctl enable --now caddy
|
||||
fi
|
||||
|
||||
sudo systemctl is-active --quiet caddy
|
||||
sudo systemctl is-enabled --quiet caddy
|
||||
trap - ERR
|
||||
|
||||
printf 'caddy active; backup=%s\n' "$BACKUP"
|
||||
@@ -0,0 +1,2 @@
|
||||
[Service]
|
||||
EnvironmentFile=/etc/vpd-backoffice.env
|
||||
Reference in New Issue
Block a user