eec18e7179bac384039422e46b94c9c236c9a6a9
IT센터 출입자관리시스템 (Access Control System)
IT센터 방문자/출입자 관리 웹 시스템. 방문 사전신청·승인, 입·출입 체크인, QR/배지 발급, 통계·리포트·블랙리스트를 목표로 하며, 출입통제 하드웨어는 추후 연동 가능하도록 추상화한다.
기술 스택
- 백엔드: Spring Boot 3.4.5 / Java 21 (JDK 26 빌드) · Spring Security(세션) · JPA · H2(dev)·PostgreSQL(prod) · POI · ZXing · Flyway
- 프론트엔드: React 19 · Vite 6 · TypeScript · react-router 7
- 포트: API
8080, 웹5173
역할
| 역할 | 권한 |
|---|---|
ADMIN |
전체 관리, 사용자/블랙리스트/리포트, 모든 승인 |
SECURITY |
입·출입 콘솔(체크인/아웃), 재실현황, 배지 발급 |
HOST |
방문 사전신청 등록, 담당 방문 승인 |
실행 (로컬 개발, H2)
:: 백엔드 (http://localhost:8080)
run-backend.cmd
:: 프론트엔드 (http://localhost:5173)
run-frontend.cmd
두 스크립트는
C:\ai-dev\scripts\env.cmd(포터블 JDK/Maven/Node)를 먼저 로드한다.
초기 계정 (DataSeeder, dev 전용)
| 아이디 | 비밀번호 | 역할 |
|---|---|---|
| admin | ChangeMe123! | ADMIN |
| security | ChangeMe123! | SECURITY |
| host | ChangeMe123! | HOST |
최초 로그인 시 비밀번호 변경이 요구된다.
주요 API
POST /api/auth/login·POST /api/auth/logout·GET /api/auth/me·POST /api/auth/change-passwordGET /api/zonesGET/POST /api/visit-requests·GET /api/visit-requests/pending·POST /api/visit-requests/{id}/cancel·POST /api/visit-requests/upload(엑셀)POST /api/approvals/{id}/approve·POST /api/approvals/{id}/rejectPOST /api/access/check-in·POST /api/access/check-out·GET /api/access/inside·GET /api/access/search?q=GET /api/passes/{id}·GET /api/passes/{id}/qr.png(배지 QR)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 참고.
구현 현황
- 1단계 스캐폴딩 (pom, 설정, 공통 클래스, 전역 예외/응답 래퍼, JPA auditing)
- 2단계 인증·인가 (세션 로그인, 역할 기반 권한, 시드)
- 3단계 방문 사전신청 + 승인 (신청/취소/엑셀 업로드, 승인/반려 시 qrToken 발급) + 프론트 화면
- 4단계 입·출입 체크인/체크아웃 + 재실현황 (
AccessEvent,AccessControlGateway+Mock, QR/이름 체크인, 재실 목록, 중복입장·만료 검증) + 출입콘솔 화면 - 5단계 QR/배지 발급 (ZXing PNG
/api/passes/{id}/qr.png, 배지 인쇄 화면) - 6단계 블랙리스트(체크인 시 차단) + 대시보드 통계 집계 + 방문 리포트 엑셀(POI) 다운로드
- 7단계 Flyway
V1__init.sql(prod) + Docker Compose(db·app·web nginx) + Python 사용자 시드
Docker 실행 (prod, PostgreSQL)
cd infra
cp .env.example .env # 값 수정 (아래 참고)
docker compose up -d --build # db + app(:8080) + web(nginx :80)
docker compose run --rm seed # 사용자 시드 적재 (admin/security/host)
docker compose logs -f app # 기동/마이그레이션 로그
- 백엔드는
prod프로파일로 기동, Flyway가 스키마를 생성/검증한다. - 웹(nginx)이 정적 파일 +
/api리버스 프록시를 담당한다. - DB는 named volume(
db_data)에 영속 — 재기동해도 데이터 유지(dev H2와 다름).
.env 주요 값
| 변수 | 설명 |
|---|---|
POSTGRES_PASSWORD |
DB 비밀번호 (실제값으로 변경) |
WEB_PORT |
웹 공개 포트 (기본 80) |
ACS_SMS_PROVIDER |
dev(로그만) / hanbank(사내 API로 LMS 실발송) |
ACS_PUBLIC_BASE_URL |
문자 링크가 가리키는 주소 — 방문자 휴대폰에서 접속 가능한 실제 URL (localhost 금지) |
ACS_SMS_API_URL |
사내 메시지 API 주소 (기본 http://210.104.132.59:8000) |
문자 실발송(hanbank) 전제
- 서버에서 메시지 API 도달 확인:
nc -vz 210.104.132.59 8000 ACS_SMS_PROVIDER=hanbank,ACS_PUBLIC_BASE_URL=외부 접속 URL 로 설정 후 재기동
HTTPS 적용 (TLS 종료는 nginx가 담당)
브라우저 → nginx(web, TLS 종료) → 내부 http → Spring(app) 구조. 앱은 server.forward-headers-strategy=framework
(prod에 반영됨)로 nginx의 X-Forwarded-Proto를 신뢰해 Secure 쿠키·https 리다이렉트를 처리한다.
TLS 오버레이가 준비돼 있다 — 인증서만 넣으면 된다:
- 인증서 준비 —
infra/certs/{fullchain.pem,privkey.pem}(사내 CA 발급 / 공인 CA / 테스트용 자체서명). 자체서명 예:openssl req -x509 -newkey rsa:2048 -nodes -days 825 -keyout infra/certs/privkey.pem -out infra/certs/fullchain.pem -subj "/CN=<host>"(infra/certs/*.pem은.gitignore로 커밋 제외.) .env:ACS_PUBLIC_BASE_URL=https://<도메인>,ACS_COOKIE_SECURE=true.- 기동 (base + TLS 오버레이):
→ nginx가
cd infra docker compose -f docker-compose.yml -f docker-compose.tls.yml up -d --build443TLS 종료 +80→443리다이렉트.frontend/nginx-tls.conf사용.
ACS_COOKIE_SECURE=true는 위처럼 실제 HTTPS로 서비스될 때만 켠다(평문 http에서 켜면 쿠키 미전송 → 로그인 불가).
- 출입콘솔의 웹캠 QR 스캔은 secure context(HTTPS 또는 localhost)에서만 동작 → HTTPS면
http://내부IP에서도 카메라 사용 가능. - 방문자 공개 링크(
/pass/{token})도 HTTPS 도메인이면 휴대폰에서 안전하게 열린다.
사내망 빌드 참고
docker compose build는 컨테이너 안에서 npm/maven 의존성을 받는다. dev 서버는 공개망 직접
접근이 되어 대개 그대로 성공하지만, 사내 SSL 인스펙션에 걸려 인증서 오류가 나면 Dockerfile에
사내 CA 주입 또는 내부 미러 설정이 필요하다(그때 별도 반영).
디렉터리
backend/ Spring Boot (com.itcenter.acs)
frontend/ React + Vite
docs/ 워크플로우·시퀀스 다이어그램·이슈/유의사항 문서
문서
- docs/workflow.md — 전체 업무 워크플로우(서술형)
- docs/workflow-sequence.md — 시퀀스/상태 다이어그램(Mermaid)
- docs/issues-and-guidelines.md — 이슈 정리 및 유의사항(규칙)
빌드 노트
- JDK 26 환경에서 Lombok은 1.18.46 + maven-compiler-plugin
annotationProcessorPaths설정이 필요하다 (Spring Boot가 핀한 1.18.38은 JDK 26에서 애너테이션 처리가 동작하지 않음).backend/pom.xml에 반영됨.
Description
Languages
TypeScript
58.5%
Java
34.7%
CSS
4.2%
JavaScript
1.4%
Python
0.7%
Other
0.4%