Files
acs/docs/workflow.md
2026-07-10 15:18:29 +09:00

13 KiB

IT센터 출입자관리시스템(ACS) 워크플로우

문서 작성일: 2026-07-03 대상: C:\ai-dev\workspace\acs (Spring Boot 3.4.5 / Java 21 · React 19 · Vite 6) 목적: 방문자 사전신청 → 승인 → 출입증 발송 → 입·출입 체크 → 재실현황/리포트까지의 전체 업무 흐름 정리


1. 시스템 개요

IT센터를 방문하는 외부 방문자의 사전신청·승인·출입·통계를 관리하는 웹 시스템. 출입통제 하드웨어(게이트)는 AccessControlGateway 인터페이스로 추상화되어 있어 현재는 Mock으로 동작하고, 추후 실제 장비 연동이 가능하다.

구분 내용
백엔드 Spring Boot 3.4.5 / Java 21 · Spring Security(세션) · JPA · H2(dev)/PostgreSQL(prod) · POI · ZXing · Flyway
프론트엔드 React 19 · Vite 6 · TypeScript · react-router 7
포트 API 8080, 웹 5173(dev) / nginx 80(prod)
인증 세션 기반, 최초 로그인 시 비밀번호 강제 변경

2. 역할(Role)과 접근 범위

역할 주요 권한 접근 화면
ADMIN 전체 관리, 모든 승인/반려, 사용자·블랙리스트·리포트 대시보드, 방문신청, 승인함, 출입콘솔, 블랙리스트, 리포트
SECURITY 입·출입 콘솔(체크인/아웃), 재실현황, 배지 발급, 리포트 대시보드, 방문신청, 출입콘솔, 리포트
HOST 방문 사전신청 등록, 담당 방문 확인 대시보드, 방문신청, 출입콘솔
(비로그인) 방문자 공개 출입증(/pass/:token), 키오스크(/kiosk) 공개 페이지

라우팅 기준: frontend/src/App.tsx. 승인함(/approvals)·블랙리스트(/blacklist)는 ADMIN 전용, 리포트(/reports)는 SECURITY·ADMIN.


3. 방문 신청 생명주기 (상태 머신)

VisitStatus (backend/entity/VisitStatus.java) 기준 상태 전이:

                 신청 등록                    승인
   [DRAFT] ───────────────▶ [PENDING] ───────────────▶ [APPROVED] ──▶ 출입 가능
                                │                            │
                                │ 반려                       │ 방문일 경과(체크인 시도)
                                ▼                            ▼
                            [REJECTED]                    [EXPIRED]
                                
      [PENDING] 또는 [APPROVED] ──── 취소 ────▶ [CANCELLED]
상태 의미 진입 조건
DRAFT 임시 저장 신청 초안
PENDING 승인 대기 신청 제출
APPROVED 승인됨(출입 가능, qrToken 발급) 관리자 승인
REJECTED 반려됨 관리자 반려
CANCELLED 신청 취소됨 신청자/관리자 취소
EXPIRED 방문일 경과로 만료 방문 종료일 이후 체크인 시도 시 자동 전이

핵심 규칙: 승인 시점(ApprovalService.approve)qrToken = UUID가 발급되고, 이 토큰으로 출입증(QR)·공개 페이지·문자 발송이 이루어진다.


4. 전체 업무 워크플로우 (End-to-End)

[HOST/담당자]                [ADMIN]              [방문자]                 [SECURITY/게이트]
     │                          │                     │                          │
 ①방문 사전신청 ───────────▶ ②승인함 검토             │                          │
   (개별 or 엑셀 업로드)        │                     │                          │
     │                     ③승인 / 반려               │                          │
     │                          │ (승인 시 qrToken)   │                          │
     │                          ├── ④출입증 문자발송 ─▶ 휴대폰 링크 수신          │
     │                          │                  ⑤공개 출입증(/pass/:token)     │
     │                          │                     │  QR 확인                 │
     │                          │                     │                          │
     │                          │                     └── ⑥방문일 현장 도착 ────▶ ⑦체크인(QR/이름)
     │                          │                                                 │  ├ 블랙리스트 검증
     │                          │                                                 │  ├ 상태/일자 검증
     │                          │                                                 │  └ 게이트 오픈 + 입장기록
     │                          │                                            ⑧재실현황 표시
     │                          │                     └── ⑨퇴장 ───────────────▶ ⑩체크아웃(OUT 기록)
     │                          │                                                 │
     └───────────────── ⑪대시보드 통계 / ⑫방문 리포트(엑셀) ────────────────────┘

단계별 상세

① 방문 사전신청 (HOST/ADMIN/SECURITY)POST /api/visit-requests

  • 방문자 정보(이름·연락처·회사), 방문 구역(Zone), 방문 기간(visitFrom~visitTo), 담당 호스트 지정.
  • 개별 등록 또는 엑셀 일괄 업로드(POST /api/visit-requests/upload, ExcelImportService).
  • 상태 → PENDING.

② ③ 승인/반려 (ADMIN)GET /api/visit-requests/pendingPOST /api/approvals/{id}/approve|reject

  • PENDING 상태만 처리 가능(이미 처리된 건은 409 conflict).
  • 승인: 상태 → APPROVED, qrToken 발급, Approval 기록 저장.
  • 반려: 상태 → REJECTED, 사유(comment) 기록.

④ 출입증 발송 (자동)PassNotifier

  • 승인 직후 QR PNG(240px)를 생성하여 방문자에게 발송.
  • 발송 실패는 승인 트랜잭션을 롤백하지 않음 (catch & log — 승인은 정상 처리).
  • Provider: dev(로그만, LoggingPassNotifier) / hanbank(사내 메시지 API로 LMS 실발송, HanbankMessagePassNotifier).
  • 문자에는 ACS_PUBLIC_BASE_URL 기반 공개 출입증 링크 포함.

⑤ 공개 출입증 (방문자, 비로그인)GET /pass/:tokenPublicPassController

  • 방문자가 휴대폰에서 링크 접속 → QR/방문정보 확인.
  • secure context(HTTPS/localhost)에서만 카메라·안전 접속 보장.

⑥ ⑦ 입장 체크인 (SECURITY/게이트 or 키오스크)POST /api/access/check-in

  • 식별: QR 토큰 스캔 또는 방문자 이름 검색(GET /api/access/search?q=).
  • 검증 순서 (AccessService.checkIn):
    1. 상태 == APPROVED 아니면 거부.
    2. 방문 종료일 경과 → 상태 EXPIRED 전이 + 거부("재신청 필요").
    3. 방문 시작일 이전 → 거부("아직 방문일 아님").
    4. 블랙리스트 매칭(이름+연락처) → 403 차단.
    5. 이미 입장 중 → 409 중복입장.
    6. 금일 이미 퇴장 완료 → 재입장 불가.
  • 통과 시: AccessEvent(IN) 기록 + gateway.openGate() 호출(게이트 오픈).
  • 늦은 도착 허용: 같은 '일자'면 시간은 엄격히 보지 않음. 실제 입장 시각은 access_events.event_at에 별도 기록.

⑧ 재실현황 (SECURITY/ADMIN)GET /api/access/inside

  • 마지막 이벤트가 IN인 방문자 = 현재 재실 중. 이름·회사·구역·호스트·입장시각 표시.
  • 금일 전체 출입기록: AccessService.listTodayRecords (입장/퇴장/재실여부 포함).

⑨ ⑩ 퇴장 체크아웃POST /api/access/check-out

  • 입장 기록이 없으면 409(퇴장 불가).
  • AccessEvent(OUT) 기록. 재실현황에서 제외됨.

⑪ 대시보드 통계GET /api/stats/summaryStatsController

  • 오늘의 방문/승인대기/재실 인원 등 요약 집계.

⑫ 방문 리포트 (SECURITY/ADMIN)GET /api/reports/visits.xlsx?from=&to=

  • 기간별 방문 내역을 Apache POI로 엑셀 생성·다운로드(ReportService).

5. 키오스크 셀프 체크인 흐름 (비로그인)

GET /kioskKioskPage — 입구 무인 단말에서 방문자가 직접 QR을 스캔하여 셀프 체크인/아웃.

  • 백엔드는 동일한 check-in/check-out API 사용하되 operator = null(셀프서비스).
  • 웹캠 QR 스캔은 secure context 필요(useQrScanner.ts).

6. 블랙리스트 흐름 (ADMIN)

GET/POST /api/blacklist, DELETE /api/blacklist/{id}BlacklistController

  • 이름+연락처 기준 차단 명단 관리.
  • 체크인 시 자동 검증: BlacklistService.blockReason()이 매칭되면 입장 403 차단(사유 표시).

7. 컴포넌트 데이터 흐름 (백엔드 계층)

Controller  →  Service        →  Repository(JPA)  →  DB(H2/PostgreSQL)
   │              │                                      
   │              ├─ ApprovalService ─▶ QrService(ZXing) ─▶ PassNotifier(SMS)
   │              ├─ AccessService ───▶ AccessControlGateway(Mock/실장비)
   │              │                     └─ BlacklistService
   │              └─ ReportService(POI) / StatsService / ExcelImportService(POI)
   │
   └─ 공통: GlobalExceptionHandler(예외→ApiResponse), ApiResponse(응답 래퍼), SecurityConfig(세션 인가)

주요 엔티티: User, Visitor, VisitRequest, Approval, AccessEvent, Zone, Blacklist (공통 BaseEntity — JPA auditing으로 생성/수정 시각 자동 기록)


8. 배포/운영 워크플로우

로컬 개발 (H2)

run-backend.cmd     :: http://localhost:8080 (env.cmd로 포터블 JDK/Maven 로드)
run-frontend.cmd    :: http://localhost:5173

초기 계정(DataSeeder, dev 전용): admin / security / host — 비밀번호 ChangeMe123! (최초 로그인 시 변경 요구).

운영 (Docker, PostgreSQL)

cd infra
cp .env.example .env          # POSTGRES_PASSWORD, WEB_PORT, ACS_SMS_PROVIDER, ACS_PUBLIC_BASE_URL 설정
docker compose up -d --build  # db + app(:8080) + web(nginx :80)
docker compose run --rm seed  # 사용자 시드 적재
docker compose logs -f app    # Flyway 마이그레이션/기동 로그
  • prod 프로파일 + Flyway V1__init.sql로 스키마 관리, DB는 named volume(db_data)에 영속.
  • nginx가 정적 파일 서빙 + /api 리버스 프록시.

문자 실발송(hanbank) 전제

  1. 서버→메시지 API 도달 확인: nc -vz 210.104.132.59 8000
  2. ACS_SMS_PROVIDER=hanbank, ACS_PUBLIC_BASE_URL=외부 접속 가능한 실제 URL(localhost 금지) 설정 후 재기동.

9. 구현 현황 (7단계)

단계 내용 상태
1 스캐폴딩 (pom, 설정, 공통 클래스, 전역 예외/응답 래퍼, JPA auditing)
2 인증·인가 (세션 로그인, 역할 기반 권한, 시드)
3 방문 사전신청 + 승인 (신청/취소/엑셀 업로드, 승인/반려 시 qrToken 발급)
4 입·출입 체크인/체크아웃 + 재실현황 (AccessEvent, Gateway+Mock, 중복입장·만료 검증)
5 QR/배지 발급 (ZXing PNG, 배지 인쇄 화면)
6 블랙리스트(체크인 차단) + 대시보드 통계 + 방문 리포트 엑셀(POI)
7 Flyway V1__init.sql(prod) + Docker Compose(db·app·web nginx) + Python 사용자 시드

10. 주요 API 요약

분류 엔드포인트
인증 POST /api/auth/login · /logout · GET /api/auth/me · POST /api/auth/change-password
구역 GET /api/zones
방문신청 GET/POST /api/visit-requests · GET .../pending · POST .../{id}/cancel · POST .../upload(엑셀)
승인 POST /api/approvals/{id}/approve · /reject
출입 POST /api/access/check-in · /check-out · GET /api/access/inside · /search?q=
출입증 GET /api/passes/{id} · /qr.png · 공개 /pass/:token
통계/리포트 GET /api/stats/summary · GET /api/reports/visits.xlsx?from=&to=
블랙리스트 GET/POST /api/blacklist · DELETE /api/blacklist/{id} (ADMIN)

API 스모크 테스트: backend/test-api.http


11. 향후 연동 포인트

  • 실 출입장비 연동: AccessControlGateway 구현체를 Mock → 실장비 드라이버로 교체.
  • HTTPS/카메라 스캔: 사내 도메인·인증서 확보 후 nginx 443 TLS 블록 + ACS_PUBLIC_BASE_URL https 설정 (웹캠 QR 스캔은 secure context 필수).
  • 사내망 Docker 빌드: SSL 인스펙션 대응(사내 CA 주입 또는 내부 미러) 필요 시 Dockerfile 반영.