VisitFlow 관리자 가이드
최초 실행
컨테이너에는 POSTGRES_DSN, BOOTSTRAP_ADMIN, BOOTSTRAP_ADMIN_PASSWORD, ENCRYPTION_KEY 네 환경변수만 전달한다. 최초 관리자와 설치 암호화 키만 환경변수로 주입하며 이후 비밀번호·SSO·정책·연동은 관리자 UI에서 바꾼다.
기동 시 서비스는 데이터베이스에 저장된 검증값을 복호화해 ENCRYPTION_KEY가 그 데이터베이스의 키와 같은지 확인한다. 검증값이 없는 기존 데이터베이스는 이미 저장된 암호문 한 건으로 대신 확인한다. 키가 다르면 기동을 중단하므로, 잘못된 키로 운영을 시작해 복구할 수 없는 데이터가 섞이는 일은 발생하지 않는다.
GET /readyz는 데이터베이스 연결과 함께 적용된 스키마 버전, 이 바이너리가 기대하는 스키마 버전, 알림 대기열 적체를 반환한다. 마이그레이션이 끝나지 않았으면 503을 반환하므로 롤링 배포의 준비 상태 점검에 그대로 사용할 수 있다.
필수 운영 설정
- 일반: 회사명과 외부 기준 URL
- 사업장: 주소, 시간대(IANA), 로비, 방문 안내. 시간대는 오늘 방문·통계·CSV의 날짜 기준이 되며 사업장·로비·조직 항목은 클릭해서 수정한다.
- Keycloak: Issuer, Client ID, Client Secret, 그룹 매핑
- 방문 정책: 승인 사용, 조기 체크인, 미방문 유예, 자동 퇴실. 자동 퇴실 시각은 사업장별 현지 시각으로 판정하므로, 시간대가 다른 사업장은 각자의 저녁에 미퇴실 방문자를 정리한다.
- QR: 1회 사용, Dynamic 주기
- 알림: 기존
log/Webhook 호환 설정과 SMS·MMS·카카오 다중 API 및 발송 규칙 - 개인정보: 마스킹·파기·감사 보존기간. 자주 방문자 주소록도 마지막 템플릿 사용 시점을 기준으로 동일한 파기 기간을 적용한다.
- 보안: Session, 개인 키 만료와 회전 유예, 로그인 실패 허용 횟수와 잠금 시간, 공개 API 분당 요청 한도, 신뢰할 Reverse Proxy, Prometheus 토큰
- 언어: 기본 언어와 지원 언어 목록. 모바일 방문증·셀프 사전등록 화면과 언어별 발송 규칙에 사용한다.
- 방문 유형: 관리자 → 방문 유형 · 키오스크에서 유형별 보안서약·안전교육·차량·반입장비 필수 여부와 승인 강제를 정의한다.
사용자 계정 관리
Keycloak을 쓰지 않는 환경에서는 조직 · 사업장 · 권한 → 로컬 사용자 추가로 계정을 만든다. 임시 비밀번호가 한 번만 표시되고, 사용자는 첫 로그인에서 새 비밀번호로 바꿔야 다른 기능을 쓸 수 있다(서버가 변경 전 모든 API를 403으로 차단). 비밀번호 초기화는 새 임시 비밀번호를 발급하며 그 계정의 모든 세션을 종료하고 로그인 잠금도 해제한다. 세션 종료는 퇴직·유출 의심 시 모든 세션과 개인 API 키를 즉시 폐기한다. 일반 사용자는 프로필 메뉴에서 스스로 비밀번호를 바꿀 수 있다.
사내 SMTP 메일
시스템 설정 → 메일(SMTP)에서 서버, 포트, 보안 방식(starttls/tls/none), 계정, 발신자를 입력하고 SMTP 메일 발송 사용을 켠다. 인증은 TLS 위에서 PLAIN, 그 외 LOGIN·CRAM-MD5를 서버가 광고하는 순서대로 자동 선택하므로 Exchange 계열도 그대로 연결된다. 사설 인증서를 쓰는 릴레이는 TLS 인증서 검증 생략을 켤 수 있다. 테스트 메일 발송은 저장된 설정으로 실제 메일을 보내고 결과·소요 시간을 표시하며 감사 로그에 남는다.
SMTP가 켜지면 두 기능이 동작한다.
- 승인 대기 알림: 방문은 담당자의 소속 부서를 물려받는다. 부서가 지정된 방문은 그 부서의 부서 관리자(및 대리자)에게, 담당자에게 부서가 없어 방문에도 부서가 없는 경우에는 어디서나 승인할 수 있는 보안 담당자·관리자에게 전달된다.
- 메일 알림: 담당자와 승인자가 프로필 메뉴에서 받을 이벤트(도착, 퇴실, 확정, 반려, 취소, 승인 대기, 승인 지연)를 직접 고른다. 계정에 이메일이 있어야 하며 대리 담당자도 같은 기준으로 받는다. 발송은 문자와 같은 알림 큐(
email채널)를 지나므로 재시도·이력·수동 재시도가 동일하게 적용된다. - 비밀번호 재설정 메일: 로컬(비 SSO) 계정은 로그인 화면의
비밀번호를 잊으셨나요?에서 아이디 또는 이메일로 재설정 링크를 요청한다. 응답은 계정 존재 여부와 무관하게 동일하고 IP·식별자별로 제한된다. 링크는 설정한 시간 동안 한 번만 유효하며 사용 시 모든 세션이 종료된다. 관리자의비밀번호 초기화에서도 임시 비밀번호 대신재설정 링크를 메일로 발송을 선택할 수 있다.로컬 계정 메일 비밀번호 재설정스위치로 끌 수 있다.
사용자 권한
사용자 · RBAC 표에서 Role과 함께 소속 부서(부서 관리자의 승인 범위)와 담당 사업장(로비 담당자의 조회·체크인 범위)을 바로 지정한다. 최고 관리자 계정을 만들거나 바꾸는 것은 최고 관리자만 할 수 있고, 마지막 최고 관리자는 보호된다.
접근 보호
로그인 실패는 요청 IP와 계정 각각에 대해 집계한다. 계정은 설정한 횟수, IP는 그 10배를 넘기면 잠금 시간 동안 로그인을 차단하고 429와 Retry-After를 반환하며 감사 로그에 남긴다. 잠금 정보는 데이터베이스에 저장되므로 재시작이나 다중 노드에서도 그대로 유지된다.
모바일 방문증, MMS용 QR 이미지, 셀프 사전등록, 로그인 엔드포인트에는 IP 단위 분당 요청 한도를 적용해 토큰 열거를 차단한다.
방문 유형과 체크리스트
방문 유형에는 코드, 이름, 설명과 함께 보안서약 확인, 안전교육 이수 확인, 차량번호 신고, 반입 장비 신고, 승인 강제를 지정한다. 신청 화면은 선택한 유형이 요구하는 항목을 채우지 않으면 제출을 막고, 승인 강제 유형은 전역 승인 정책이 꺼져 있어도 승인 대기 상태로 들어간다. 사용하지 않는 유형은 비활성화하며 과거 방문 기록의 유형 정보는 그대로 유지된다.
방문자 셀프 사전등록
방문 상세에서 방문자별 사전등록 링크를 발급하면 방문자가 직접 이름·회사·차량·반입 장비를 입력하고 본인이 개인정보 수집·이용에 동의한다. 동의 기록에는 동의 주체(담당자 대행/본인), 정책 버전, 언어, IP와 User Agent가 함께 저장된다. 동의 문구를 변경하면 동의 정책 버전을 올려 이후 동의와 구분한다.
링크는 설정한 시간 동안만 유효하고 1회 완료되면 재사용할 수 없다. 방문자가 입력한 회사명은 다시 Watch List로 검사한다.
부재 시 대리 담당자와 승인 에스컬레이션
프로필 메뉴에서 대리 담당자와 종료 시각을 지정하면 그 기간 동안 대리 담당자가 본인 방문의 취소·QR 재발급·알림 재발송·사전등록 링크를 처리하고 방문자 도착 알림도 받는다. 부서 관리자가 지정한 대리자는 그 부서의 승인 대기 방문을 보고 승인·반려할 수 있다. 승인 대기가 승인 지연 에스컬레이션 시간을 넘기면 approval_escalated 이벤트가 방문당 한 번 발생하므로, 이 이벤트에 규칙을 연결해 보안 담당자나 관리자에게 알릴 수 있다.
로비 키오스크
관리자 → 방문 유형 · 키오스크에서 기기 이름, 사업장, 로비, 유효기간을 지정해 기기 토큰을 발급한다. 태블릿에서 발급 링크를 한 번 열면 등록이 끝나고 이후에는 로그인 없이 로비 화면만 사용한다. 기기 토큰은 로비 API에만 접근할 수 있어 개인·관리자·감사 화면에는 도달하지 못하며, 목록에서 즉시 폐기할 수 있다.
비상 대피 명단
로비 서비스 → 비상 대피 명단에서 현재 체류 중인 방문자를 사업장·로비별로 확인하고 인쇄한다. 화면은 마지막으로 받은 명단을 브라우저에 보관하므로 네트워크나 서버가 끊긴 상황에서도 직전 명단을 열 수 있으며, 이때는 오프라인 상태임을 함께 표시한다.
방문자 이력과 삭제 요청
방문 · 방문자 관리 → 방문자 이력에서 방문자를 클릭하면 방문 목록과 동의 기록(주체·정책 버전)을 확인한다. 정보 주체의 삭제 요청은 즉시 파기로 처리한다. 요청 근거를 입력하면 이름·연락처·이메일·차량번호가 복구 불가능하게 대체되고, 담당자 주소록의 동일 방문자도 삭제되며, 감사 로그에 근거가 남는다. 진행 중이거나 예정된 방문이 있으면 먼저 종료해야 한다.
문자 API 테스트
메시지 API 목록의 테스트 발송으로 수신 번호를 지정해 실제 API를 한 번 호출한다. 템플릿 변수에는 테스트 값이 채워지고 소요 시간·게이트웨이 메시지 ID·오류가 표시되며 감사 로그에 기록된다.
설정 이관
시스템 설정 하단의 설정 내보내기는 비밀값(Client Secret, Authorization Header, metrics 토큰)을 제외한 모든 설정을 JSON으로 받는다. 다른 설치본에서 설정 가져오기로 읽으면 화면에 값이 채워지고 저장 시 일반 설정 변경과 같은 검증·감사가 적용된다. 비밀값은 설치별 키로 암호화되므로 항상 새로 입력한다.
지표와 내보내기
통계 · 알림은 7일·30일·90일·1년 기간을 선택할 수 있고 사업장별·방문 유형별·입실 시간대·신청 경로 분포와 방문자 수, 입실·미방문·취소, 본인 사전등록 건수, 평균 체류 시간, 평균 사전 신청 시간을 보여 준다.
리버스 프록시 뒤에 배치했다면 보안 · 키 탭의 신뢰할 Reverse Proxy에 프록시 주소를 IP 또는 CIDR로 등록한다. 사내 대역 전체를 한 번에 지정하려면 private 한 단어를 입력한다. 등록한 주소에서 도착한 요청만 X-Forwarded-For를 읽어 실제 접속 IP를 로그인 잠금, 공개 API 요청 한도, 동의 기록, 감사 로그에 사용하고, 나머지 요청은 헤더를 무시하고 TCP 접속 주소를 사용한다. 값을 비워 두면 어떤 요청에서도 헤더를 신뢰하지 않으므로, 프록시 없이 노출된 설치에서 헤더를 위조해 잠금과 요청 한도를 우회할 수 없다. 프록시를 등록하지 않은 상태로 운영하면 모든 요청이 프록시 한 주소로 집계되어 잠금과 한도가 전체 사용자에게 함께 적용되니 주의한다.
관리 Dashboard의 운영 지표 카드는 알림 대기열, 대기열 최장 지연, 잠긴 계정, 활성 세션·API 키, 스키마 버전을 보여 준다. 같은 값을 Prometheus 형식으로 수집하려면 보안 · 키 탭에서 Prometheus /metrics 토큰을 설정한 뒤 Authorization: Bearer <토큰>으로 /metrics를 호출한다. 토큰을 설정하기 전까지 이 엔드포인트는 404를 반환한다.
감사 로그는 이벤트 접두어·행위자·기간으로 필터링하고 더 보기로 이어서 조회한다. 방문자 이력은 이름·전화번호(정확히 일치) 또는 회사명으로 검색한다. 감사 로그, 방문 이력, 방문 통계는 각 화면의 CSV 버튼으로 내려받는다. 파일은 UTF-8 BOM을 포함해 Excel에서 바로 열리며, 감사 로그와 방문 이력 내보내기 자체도 감사 기록에 남는다. 방문자가 입력한 이름·회사명·목적처럼 =, +, -, @로 시작하는 값은 앞에 작은따옴표를 붙여 내보내므로 Excel이 수식으로 실행하지 않고 원문 그대로 보여준다. 감사 로그는 10,000행, 방문 이력은 50,000행이 한 번에 내려받는 상한이며, 상한에 걸려 잘린 파일은 마지막 행에 #로 시작하는 안내가 붙는다. 그 줄이 보이면 전량이 아니므로 기간이나 필터를 좁혀 나머지를 나눠 내려받는다.
메시지 API와 발송 규칙
관리자 → 메시지 API · 발송 규칙에서 Gateway를 여러 개 등록할 수 있다. 각 API는 채널(sms, mms, kakao), Base URL, Path, HTTP Method, 요청 형식(json, form, query), Header와 Parameter Template을 독립적으로 가진다. Header와 Parameter는 데이터베이스에 암호화 저장되며 secretKeys로 지정한 값은 조회 화면에서 마스킹된다.
Parameter 값에서는 ,, ,, ,, ,, ,, , 같은 발송 문맥 변수를 사용할 수 있다. MMS 이미지 Parameter에는 을 지정하면 외부 기준 URL을 포함한 주소가,에는 /img/visitor/{qrcode_file_seq}.jpg 상대 경로가 전달된다.
활성 API는 Header 또는 Parameter에 나 중 하나를 반드시 전달해야 한다. 같은 알림 ID로 재시도해도 중복 발송하지 않도록 Gateway도 이 값을 멱등성 키로 처리해야 한다. API를 중지하면 연결된 활성 규칙도 중지되고 아직 발송되지 않은 대기 건은 취소된다.
외부 Gateway가 QR 이미지를 가져가려면 일반 설정의 외부 기준 URL을 반드시 Gateway에서 접근 가능한 HTTPS 주소로 설정한다. Gateway가 호스트를 별도로 알고 있어 상대 경로를 요구하는 경우에는 /img/visitor/.jpg를 Parameter에 직접 조합할 수 있다.
발송 규칙은 방문 확정, 방문 시작, 체크인, 퇴실, 방문 취소, 방문 반려, 승인 지연 중 하나를 선택하고 방문자/담당자 수신 대상, 분 단위 오프셋, 메시지 Template과 호출 API를 연결한다. 방문 시작 규칙은 음수 오프셋으로 사전 알림을 예약할 수 있고, 나머지 이벤트는 0 이상의 지연 발송을 사용한다. 방문 시작 규칙을 바꾸면 기존 예약 건도 수신자·채널·API·본문·시각을 한 묶음으로 다시 계산한다. 다른 이벤트의 큐 정책을 바꾸거나 규칙을 중지하면 혼합 설정으로 발송되지 않도록 기존 대기 건을 취소하고 다음 이벤트부터 새 설정을 적용한다.
채널을 이메일 (SMTP)로 두면 문자 API 대신 시스템 설정의 SMTP로 발송한다. 수신자는 방문자 또는 담당자(대리 지정 중이면 대리자)의 이메일이고 주소가 없으면 그 방문자에게는 만들어지지 않는다. 메일 제목 템플릿은 본문과 같은 변수를 쓰며 비우면 [VisitFlow] 방문 안내 가 된다. 방문 확정 시 ``을 본문에 넣으면 모바일 방문증 링크가 메일로 전달된다.
규칙에 방문자 언어를 지정하면 그 언어를 선택한 방문자에게만 발송되므로, 같은 이벤트에 한국어와 영어 템플릿을 나란히 둘 수 있다. 언어를 지정하지 않은 규칙은 모든 방문자에게 적용된다.
수신 대상 외부 시스템과 채널 외부 시스템 연동을 조합하면 문자 대신 출입 게이트, 게스트 Wi-Fi 발급 같은 사내 API를 같은 화면에서 호출할 수 있다. 이때 ``에는 전화번호 대신 방문자 참가 ID가 전달되며 호출할 API를 반드시 선택해야 한다.
실패한 알림은 통계 · 알림 화면에서 건별 재시도, 실패 일괄 재시도, 대기 건 취소를 직접 수행할 수 있다. 재시도는 시도 횟수를 초기화하며, 연결된 API나 규칙이 중지된 알림은 이유를 표시하고 재시도를 거부한다.
기존 SMS Webhook 호환 계약
{
"recipient": "01012345678",
"message": "방문 안내 본문",
"channel": "sms",
"idempotencyKey": "notification-uuid"
}
2xx를 성공으로 처리한다. 실패는 5분 단위 Backoff로 최대 5회 재시도하며 관리자 통계·알림 화면에 사유를 표시한다.
사용자 가이드 게시판
관리자 → 사용자 가이드에서 제목, 분류와 본문을 등록한다. 초안은 관리자에게만 보이고 게시 상태로 바꾼 글만 로그인 사용자에게 노출된다. 자주 확인해야 하는 글은 상단 고정할 수 있으며 수정·게시·삭제는 감사 로그에 기록된다.
백업
PostgreSQL과 ENCRYPTION_KEY를 같은 복구 시점으로 백업한다. Encryption Key는 Client Secret과 개인정보 복호화에 필요하므로 별도 보안 백업을 유지한다.
오프라인 업그레이드
새 Release의 visitflow-vX.Y.Z.tar.gz를 반입해 docker load한다. 아카이브의 visitflow:latest 별칭을 Compose가 바로 사용한다. 업그레이드 전 PostgreSQL과 ENCRYPTION_KEY를 백업한다.
Migration은 버전별 파일로 관리하며 각 파일은 자신의 트랜잭션 안에서 한 번만 적용되고 schema_migrations에 기록된다. 실패한 Migration은 스키마와 버전 기록을 함께 되돌리므로 절반만 적용된 상태가 남지 않는다. 적용 결과는 GET /readyz의 schemaVersion과 expectedSchemaVersion으로 확인한다.