Files
acs/docs/ACS작업일지.md
2026-07-22 20:15:40 +09:00

50 KiB

ACS 작업일지

2026-07-10

작업 범위 합의

  • Codex는 C:\ai-dev\workspace\acs의 ACS 개선 및 배포 준비를 담당하기로 함.
  • RTGS 프로젝트는 별도 담당자가 작업하므로, 사용자가 명시적으로 요청하지 않는 한 C:\ai-dev\workspace\rtgs는 읽기/수정/빌드/배포하지 않기로 함.
  • ACS 관련 설치, 구성, 변경, 배포, 검증 내용은 이 파일에 계속 갱신하기로 함.
  • 서버/저장소 계정 정보와 비밀번호는 일지에 기록하지 않기로 함.

로컬 프로젝트 확인

  • ACS 구조 확인:
    • 백엔드: Spring Boot 3.4.5, Java 21, Maven, JPA, Flyway, PostgreSQL 운영 구성
    • 프론트엔드: React 19, Vite 6, TypeScript
    • 배포 구성: infra/docker-compose.yml, infra/docker-compose.tls.yml, nginx reverse proxy
  • Git 원격 저장소는 아직 등록되어 있지 않음을 확인함.
  • .git/index.lock 파일이 남아 있어, 추후 git add/commit/push 전 정리가 필요함.

배포 전 빌드/테스트 검증

  • 프론트엔드 npm run build 성공.
  • 백엔드 최초 테스트에서 운영 Flyway 스키마와 엔티티 불일치 발견:
    • visit_requests 테이블에 work_name, control_*, watcher*_ * 계열 컬럼 누락.
  • 신규 Flyway 마이그레이션 추가:
    • backend/src/main/resources/db/migration/V4__visit_request_contact_fields.sql
    • 기존 DB에도 적용 가능하도록 ALTER TABLE ... ADD COLUMN 방식 사용.
  • 테스트용 H2 호환성을 위해 컬럼 추가 구문을 개별 ALTER TABLE 문으로 분리함.
  • DataSeeder의 로컬 계정과 테스트 코드 기대 계정 불일치 수정:
    • 기존 단축 계정 a/s/h 유지
    • 테스트 및 CSV seed와 맞는 admin/security/host도 함께 생성하도록 보정
  • 백엔드 mvn -B -ntp test 성공:
    • 9 tests, 0 failures, 0 errors
  • 백엔드 mvn -B -ntp -DskipTests package 성공:
    • backend/target/acs-0.0.1-SNAPSHOT.jar 생성 확인

Docker/Compose 확인

  • 로컬 Docker 설치 확인:
    • docker --version 성공
    • docker compose 플러그인은 없음
    • docker-compose --version은 사용 가능
  • Compose 설정 문법 확인:
    • docker-compose --env-file infra/.env.example -f infra/docker-compose.yml config 성공
    • docker-compose --env-file infra/.env.example -f infra/docker-compose.yml -f infra/docker-compose.tls.yml config 성공
  • 운영 배포 URL을 환경변수로 넣은 HTTPS 구성 확인:
    • ACS_PUBLIC_BASE_URL=https://acs.apps.bokdev.in
    • ACS_COOKIE_SECURE=true
    • Compose config 정상
  • Docker 이미지 빌드는 로컬 Docker 빌더 문제로 실패:
    • buildx 플러그인 없음
    • Docker legacy builder가 Docker API v1.54 build 요청에서 500 Internal Server Error 반환
    • 코드/Compose 문법 문제보다는 로컬 Docker Desktop/빌더 환경 문제로 판단

서버/URL 접근성 확인

  • https://portal.bokdev.in/:
    • HTTPS 접근 가능
    • HTTP 200 OK 확인
  • https://acs.apps.bokdev.in:
    • DNS 해석 가능
    • 현재 HTTP 503 Service Unavailable 확인
    • 아직 앱이 정상 배포/기동되지 않은 상태로 판단
  • https://acs.bokdev.in/0420301/repo:
    • 현재 PC 네트워크에서 acs.bokdev.in DNS 해석 실패
    • 저장소 원격 등록/푸시 전 네트워크 또는 도메인 확인 필요

저장소 URL/DNS 추가 확인

  • 저장소 후보 URL https://acs.bokdev.in/0420301/repo 확인.
  • 로컬 ACS Git remote 확인 결과, 등록된 원격 저장소 없음.
  • git ls-remote https://acs.bokdev.in/0420301/repo 실행 결과:
    • Could not resolve host: acs.bokdev.in
  • 현재 PC DNS 서버:
    • 210.104.132.1, 210.104.132.2
    • 10.168.198.34, 10.168.198.35
  • 기본 DNS 및 공개 DNS 확인 결과:
    • portal.bokdev.in27.96.158.129로 해석됨.
    • acs.apps.bokdev.in27.96.158.129로 해석됨.
    • acs.bokdev.in은 해석 실패.
  • bokdev.in 권한 DNS 서버 확인:
    • salvador.ns.porkbun.com
    • fortaleza.ns.porkbun.com
    • curitiba.ns.porkbun.com
    • maceio.ns.porkbun.com
  • 권한 DNS 서버 curitiba.ns.porkbun.com에 직접 질의한 결과:
    • portal.bokdev.in A 레코드 존재: 27.96.158.129
    • acs.apps.bokdev.in A 레코드 존재: 27.96.158.129
    • acs.bokdev.in A/CNAME 레코드 없음
    • nslookup acs.bokdev.in curitiba.ns.porkbun.com 결과: Non-existent domain
  • 결론:
    • 현재 저장소 URL의 호스트명 acs.bokdev.in은 DNS에 등록되어 있지 않은 것으로 판단.
    • 저장소 URL이 잘못 전달되었거나, DNS 레코드 생성이 아직 완료되지 않았을 가능성이 큼.
    • 원격 저장소 등록/푸시 전에 정확한 저장소 URL 재확인이 필요.

AI DEV 매뉴얼 확인

  • 참조 파일: docs/AIdev.md
  • 매뉴얼 기준 주요 서비스:
    • 포털: https://portal.bokdev.in
    • Coder: https://coder.bokdev.in
    • Gitea: https://gitea.bokdev.in
    • Kubero: https://kubero.bokdev.in
    • Coolify: https://coolify.bokdev.in
  • Gitea 저장소 생성/Push 기준:
    • Gitea의 playground 조직에 저장소를 생성.
    • 저장소 URL 형식은 https://gitea.bokdev.in/playground/<repo>.git.
    • 예: ACS 저장소명이 acs라면 https://gitea.bokdev.in/playground/acs.git.
  • 배포 기준:
    • Gitea 저장소 1개가 배포 앱 1개에 대응.
    • Kubero 또는 Coolify 중 하나를 사용.
    • Coolify는 Public Repository 방식으로 Gitea 저장소 URL 전체를 입력하고 Dockerfile 빌드를 사용.
    • Coolify에서 도메인 생성 시 https://<repo>.apps.bokdev.in 형식으로 지정되는 것으로 매뉴얼에 기재되어 있음.
  • ACS에 대한 적용 판단:
    • 기존 후보 https://acs.bokdev.in/0420301/repo는 매뉴얼 기준 저장소 URL 형식이 아님.
    • ACS 저장소 URL은 우선 https://gitea.bokdev.in/playground/acs.git로 보는 것이 타당.
    • 저장소가 아직 없다면 Gitea playground 조직에 acs repository를 생성해야 함.
    • 배포 URL https://acs.apps.bokdev.in은 Coolify 도메인 형식과 일치.

프로젝트 설정 URL 오류 확인

  • 사용자가 포털 프로젝트 수정 화면에서 저장소 URL을 https://acs.bokdev.in/0420301/repo로 임의 입력한 사실 확인.
  • 해당 값은 Gitea 저장소 URL이 아니므로 수정 필요.
  • 후보 저장소 페이지 확인:
    • https://gitea.bokdev.in/playground/acs: Not found
    • https://gitea.bokdev.in/playground/ACS: Not found
    • https://gitea.bokdev.in/0420301/acs: Not found
    • https://gitea.bokdev.in/0420301/ACS: Not found
  • 결론:
    • 현재 ACS Gitea 저장소는 아직 생성되지 않았거나, 비공개/다른 이름으로 생성된 상태일 수 있음.
    • 매뉴얼 기준으로는 playground 조직에 acs 저장소를 새로 만들고, 프로젝트 저장소 URL을 https://gitea.bokdev.in/playground/acs.git로 설정하는 것이 우선 추천.
    • 배포 URL https://acs.apps.bokdev.in은 유지 가능.

Gitea Credential Helper 및 저장소 재확인

  • Git 접근 중 Windows CredentialHelperSelector 팝업 발생.
  • 권장값인 manager 선택 완료.
  • 이후 git ls-remote https://gitea.bokdev.in/playground/acs.git 재시도 시 인증 대기 상태로 타임아웃됨.
  • 비대화식 확인:
    • GIT_TERMINAL_PROMPT=0
    • git -c credential.helper= ls-remote https://gitea.bokdev.in/playground/acs.git
    • 결과: could not read Username for 'https://gitea.bokdev.in': terminal prompts disabled
  • Gitea API 비교 확인:
    • https://gitea.bokdev.in/api/v1/repos/playground/MANUAL: 200 OK
    • https://gitea.bokdev.in/api/v1/repos/playground/acs: The target couldn't be found
  • 판단:
    • Gitea 서버와 API는 정상 접근 가능.
    • playground/acs 저장소는 비로그인/API 기준으로 존재하지 않거나 private/권한 미승인 상태.
    • 포털 프로젝트의 저장소 URL 수정만으로 Gitea 저장소가 자동 생성되는 것은 아니므로, Gitea에서 playground/acs repository 생성 여부를 별도로 확인해야 함.

Gitea ACS 저장소 생성 및 원격 등록

  • 사용자가 Gitea에서 ACS 저장소 생성 완료.
  • 생성된 저장소 확인:
    • 웹 URL: https://gitea.bokdev.in/0420301/acs
    • Git URL: https://gitea.bokdev.in/0420301/acs.git
    • playground/acs가 아니라 개인 네임스페이스 0420301/acs로 생성됨.
  • 빈 저장소 상태 확인:
    • git ls-remote https://gitea.bokdev.in/0420301/acs.git 결과가 비어 있으나 exit code 0으로 정상.
  • 이전 타임아웃된 Gitea 확인용 Git 프로세스와 stale lock 파일 정리:
    • .git/config.lock
    • .git/index.lock
  • 로컬 ACS Git remote 등록 완료:
    • origin https://gitea.bokdev.in/0420301/acs.git
  • 남은 사항:
    • push 전 커밋 대상 정리 필요.
    • 로그 파일(backend/backend-run.log, frontend/frontend-dev.log)과 백업 파일(docs/ACS작업일지.md.bak)은 커밋 제외 권장.
    • 작업트리 변경분 검토 후 최초 commit/push 진행 필요.

최초 커밋 및 Gitea Push

  • 커밋 대상 정리:
    • .gitignore*.log, *.bak 제외 규칙 추가.
    • backend/backend-run.log, frontend/frontend-dev.log, docs/ACS작업일지.md.bak는 커밋 제외.
  • 최초 Gitea push용 커밋 생성:
    • 커밋: 01d48fe
    • 메시지: feat: prepare ACS deployment
    • 포함: ACS 코드 변경, Flyway V4, 문서, 작업일지, AI DEV 매뉴얼 참조 파일.
  • 원격 push 완료:
    • remote: origin
    • URL: https://gitea.bokdev.in/0420301/acs.git
    • branch: main
    • origin/main 추적 설정 완료.
  • 원격 검증:
    • git ls-remote origin main 결과 01d48fe... refs/heads/main 확인.
    • https://gitea.bokdev.in/0420301/acs 웹 페이지 접근 200 OK 확인.

Gitea 저장소 위치 수정

  • 서버담당자/매뉴얼 기준 배포용 저장소는 개인 네임스페이스가 아니라 playground 조직 아래여야 함을 확인.
  • 기존 개인 저장소:
    • https://gitea.bokdev.in/0420301/acs.git
  • 새 배포용 저장소:
    • https://gitea.bokdev.in/playground/acs.git
  • 사용자가 Gitea playground 조직 아래 acs 저장소 생성 완료.
  • 로컬 ACS Git remote 변경:
    • originhttps://gitea.bokdev.in/playground/acs.git로 변경.
  • main 브랜치 push 완료:
    • git push -u origin main
    • 원격 origin/main 확인: 4fe4c37... refs/heads/main
  • 포털 프로젝트의 저장소 URL도 https://gitea.bokdev.in/playground/acs.git로 맞춰야 함.

테스트용 화면 URL 확인

  • 프론트 라우트 정의 파일: frontend/src/App.tsx
  • 관리자/담당자 로그인 화면:
    • 운영 배포 기준: https://acs.apps.bokdev.in/login
    • 로컬 개발 기준: http://localhost:5173/login
  • 로그인 후 주요 내부 화면:
    • 대시보드: /dashboard
    • 방문 신청 목록: /visit-requests
    • 방문 신청 등록: /visit-requests/new
    • 승인 대기: /approvals
    • 출입 콘솔: /access
    • 관리자 감사 로그: /audit
    • 발송 내역: /deliveries
  • 방문자/출입 QR 관련 공개 화면:
    • 방문자 휴대폰 출입증 화면: /pass/{qrToken}
    • 출입구 키오스크 QR 태깅/스캔 화면: /kiosk
    • 운영 배포 기준 키오스크 URL: https://acs.apps.bokdev.in/kiosk
  • QR/출입증 API:
    • 공개 출입증 조회: /api/public/passes/{qrToken}
    • 공개 QR 이미지: /api/public/passes/{qrToken}/qr.png
    • 키오스크 체크인: /api/public/passes/{qrToken}/check-in
    • 키오스크 체크아웃: /api/public/passes/{qrToken}/check-out
  • QR 토큰은 방문 신청 승인 후 qrToken으로 발급됨.
  • 문자/이메일 발송 링크는 ACS_PUBLIC_BASE_URL + "/pass/" + qrToken 형식으로 생성됨.

배포 URL 접속 상태 확인

  • 운영 배포 후보 URL 확인:
    • https://acs.apps.bokdev.in
    • https://acs.apps.bokdev.in/login
  • 확인 결과:
    • 두 URL 모두 no available server 응답.
  • 판단:
    • Gitea push는 완료되었으나, Coolify 등 배포 플랫폼에서 해당 도메인에 연결된 앱 서버가 아직 생성/기동되지 않았거나 배포가 실패한 상태로 판단.
    • 포털의 프로젝트 등록/저장소 URL 설정과 실제 앱 배포는 별도 단계임.
  • 다음 확인 필요:
    • Coolify에 ACS resource/app 생성 여부.
    • Repository URL이 https://gitea.bokdev.in/0420301/acs.git로 설정되었는지.
    • Branch가 main인지.
    • 빌드 방식이 Docker Compose 또는 Dockerfile 중 무엇인지.
    • 배포 도메인이 https://acs.apps.bokdev.in로 연결되었는지.
    • Deployments 로그에서 빌드/기동 실패 원인 확인.

Coolify Docker Compose 리소스 설정 진행

  • 사용자가 Coolify aidev 프로젝트에서 + Add Resource를 통해 Docker Compose Empty 리소스 생성 화면 진입.
  • Docker Compose file 입력 화면에 최초로 https://acs.apps.bokdev.in만 입력했으나, 해당 칸은 도메인 입력칸이 아니라 compose YAML 전체를 입력하는 영역임을 안내.
  • Coolify용 compose는 repository root 기준으로 ./backend, ./frontend build context를 사용하는 형태가 필요하다고 안내.
  • 도메인 https://acs.apps.bokdev.in은 compose file 영역이 아니라 resource의 Domains 설정에서 별도 입력해야 함.
  • 환경변수는 리소스 저장 후 resource 상세 화면의 Environment Variables, Variables, 또는 Developer view에서 입력해야 함.
  • Coolify 배포에 필요한 최소 환경변수:
    • POSTGRES_PASSWORD
    • POSTGRES_USER=acs
    • POSTGRES_DB=acs
    • ACS_PUBLIC_BASE_URL=https://acs.apps.bokdev.in
    • ACS_COOKIE_SECURE=true
    • ACS_SMS_PROVIDER=dev
  • Docker Compose 입력 화면에서 저장 시 권한 없음 메시지 발생.
  • Teams > aidev > General 화면 확인:
    • 팀 설정 입력칸이 비활성화된 상태로 보임.
    • 현재 계정은 aidev 팀/프로젝트 조회는 가능하지만 resource 생성/수정 권한이 부족할 가능성이 큼.
  • 다음 확인 필요:
    • Teams > aidev > Members에서 사용자 0420301의 역할 확인.
    • aidev 팀 또는 프로젝트에서 resource create/update/deploy 권한 부여 요청.
    • 권한이 없는 경우 권한 있는 관리자가 ACS resource를 생성하거나, 사용자에게 프로젝트 관리자 권한을 부여해야 함.

인프라 담당자 피드백 반영 필요

  • 인프라 담당자 피드백 요지:
    • AI DEV 표준 환경에는 .project-env가 미리 정의되어 있음.
    • DB를 로컬/compose 내부에 직접 만들고 전체 기술구조를 통째로 배포하는 방식은 표준 흐름과 맞지 않을 수 있음.
    • 개발은 PC 로컬보다 포털의 Coder 환경에서 진행하는 것을 권장.
    • 배포 앱은 Node.js 기반으로 맞추는 것이 좋다는 의견.
    • CLAUDE.md 등 프로젝트 작업 규칙 파일이 표준 템플릿에 이미 준비되어 있음.
  • 현재 ACS와의 차이:
    • 현재 ACS는 Spring Boot 백엔드 + React 프론트 + PostgreSQL + nginx의 다중 컨테이너 구조.
    • 기존 compose는 자체 PostgreSQL 컨테이너를 포함함.
    • AI DEV 표준은 Coder에서 제공하는 .project-envDATABASE_URL 등 환경값을 사용하고, 앱 소스 중심으로 배포하는 방식으로 보임.
  • 대응 방향:
    • Coolify Docker Compose 직접 배포 시도를 잠시 중단.
    • Coder 환경에서 playground/acs를 clone한 뒤, 실제 제공되는 .project-env와 sample/템플릿 구조를 먼저 확인.
    • 인프라 담당자에게 Java/Spring Boot Dockerfile 배포 허용 여부를 확인.
    • Node.js가 필수라면 ACS 백엔드 구조를 Node 기반으로 전환하거나, 최소 배포 가능 범위를 재설계해야 함.
    • 자체 DB 컨테이너 대신 플랫폼 제공 PostgreSQL 접속정보(DATABASE_URL)를 쓰는 구조로 변경 검토.
    • ACS용 CLAUDE.md 또는 동등한 작업 규칙 문서를 추가해 Claude/Codex 협업 기준을 명시하는 방안 검토.

AI DEV 배포 제약 확정

  • 인프라 담당자 확인 결과:
    • 배포 앱은 Node.js 앱만 허용.
    • DB는 반드시 Coder/AI DEV 환경의 .project-env에 제공되는 DATABASE_URL을 사용해야 함.
  • 영향:
    • 현재 Spring Boot 백엔드(backend/)는 AI DEV 표준 배포 대상이 아님.
    • 현재 infra/docker-compose.yml의 자체 PostgreSQL 컨테이너 방식은 표준 배포 방식과 맞지 않음.
    • ACS를 배포하려면 Node.js 기반 서버/API로 전환하거나, Node.js 배포 앱이 기존 기능을 대체하도록 재구성해야 함.
  • 권장 전환 방향:
    • React 프론트엔드는 유지 가능.
    • 백엔드는 Node.js(Express/Fastify 등)로 재작성 검토.
    • DB 접속은 process.env.DATABASE_URL 사용.
    • 기존 Flyway SQL은 Node 앱 시작/배포 시 적용 가능한 SQL migration 방식으로 재활용 검토.
    • 배포 산출물은 단일 Node.js 앱 또는 Node.js + 정적 프론트 서빙 구조로 단순화하는 방향을 우선 검토.

인증서 확인

  • infra/certs/fullchain.pem, infra/certs/privkey.pem 존재 확인.
  • 현재 인증서는 CN=localhost, SAN도 localhost, 127.0.0.1용임.
  • 운영 도메인 acs.apps.bokdev.in용 인증서가 아니므로 실제 HTTPS 운영 배포에는 부적합.
  • 운영 배포 전 포털/플랫폼 인증서 자동 제공 여부 또는 도메인 인증서 교체 필요.

배포 정책 추천

  • 권장 흐름:
    • 로컬 개발
    • Git commit/push
    • 서버 개발환경 배포
    • 서버 개발환경 검증
    • 운영 배포 승인
    • 서버 운영환경 배포
  • 서버에서 직접 코드를 수정하며 개발하는 방식은 비추천.
  • 서버 개발환경도 Git으로 받은 검증 대상 환경으로 운영하고, 운영환경에는 검증된 커밋/태그만 배포하는 정책을 권장.
  • 권장 브랜치/환경:
    • dev 또는 develop: 서버 개발환경 배포
    • main: 운영 배포 가능 브랜치
    • 운영 배포 시 태그 사용 예: acs-v0.1.0
  • DB 변경은 Flyway migration으로만 반영하는 정책 유지.

남은 작업

  • .git/index.lock 정리 후 Git 작업 가능 상태 확인.
  • ACS 원격 저장소 URL/DNS 문제 확인.
  • 원격 저장소 등록 및 최초 push 여부 결정.
  • 서버 개발환경과 운영환경을 포털에서 분리 구성할 수 있는지 확인.
  • 운영 도메인 인증서 처리 방식 확인.
  • 로컬 Docker buildx 또는 Docker Desktop 빌더 문제 해결.
  • 실제 배포 전 운영 .env 값 확정:
    • POSTGRES_PASSWORD
    • ACS_PUBLIC_BASE_URL
    • ACS_COOKIE_SECURE
    • ACS_SMS_PROVIDER
    • SMTP 또는 사내 메시지 API 설정

2026-07-13

Node.js 전환 착수

  • 사용자가 C:\ai-dev\workspace\acs - 복사본에 기존 소스 백업이 있으므로, 원본 C:\ai-dev\workspace\acs를 AI DEV 표준 배포 구조로 전환하기로 결정.
  • 목표:
    • Spring Boot 백엔드 배포 방식에서 Node.js 앱 배포 방식으로 전환.
    • DB는 자체 PostgreSQL 컨테이너가 아니라 AI DEV .project-envDATABASE_URL 사용.
    • 기존 React 프론트와 /api 계약은 최대한 유지.
  • 추가 문서:
    • docs/node-migration-plan.md
  • 추가된 Node 골격:
    • 루트 package.json, tsconfig.json
    • server/index.ts
    • server/config/env.ts
    • server/db/pool.ts
    • server/db/migrate.ts
    • server/http/apiResponse.ts
    • server/http/errors.ts
    • server/routes/health.ts
    • server/routes/index.ts
  • Flyway SQL을 Node migration 구조로 1차 이관:
    • migrations/001_init.sql
    • migrations/002_audit_log.sql
    • migrations/003_pass_delivery.sql
    • migrations/004_visit_request_contact_fields.sql
  • 검증:
    • npm install 완료.
    • npm run typecheck 성공.
    • npm audit --omit=dev 결과 운영 의존성 취약점 0건.
    • npm run build 성공. 단, 로컬 PC 권한 정책상 프론트 esbuild는 승인 권한으로 실행 필요.
    • node dist/server/index.js 기동 후 GET /api/health 응답 확인.
    • 정적 React build(/) 응답 200 확인.
  • 다음 작업:
    • Auth/session/role middleware 구현.
    • PostgreSQL session store 연결.
    • 사용자 seed 전략 확정.
    • /api/auth/login, /api/auth/logout, /api/auth/me, /api/auth/change-password부터 Spring 기능 parity 구현.

AIdev.md 배포 가이드 준수 보완

  • docs/AIdev.md 기준 ACS 배포 필수 항목을 재점검.
  • 보완 사항:
    • 루트 Dockerfile 추가. AI DEV Coolify/Kubero Dockerfile build pack 기준으로 빌드.
    • 루트 .dockerignore 추가.
    • Node engine 기준을 >=22로 조정.
    • /healthz 추가: {"ok": true} 응답.
    • /db 추가: DATABASE_URL로 PostgreSQL SELECT now() 점검.
    • /s3 추가: ACS는 S3/MinIO 미사용이므로 skip 응답.
    • npm run db:check 추가: .project-env/.env 로드 후 DB 점검.
    • npm run minio:check 추가: ACS S3 미사용 skip 출력.
    • npm run start:deploy 추가: migration 적용 후 Node 서버 기동.
    • CLAUDE.md 추가: AI DEV 배포 제약과 ACS 전환 규칙 명시.
  • 검증:
    • npm run typecheck 성공.
    • npm audit --omit=dev 운영 의존성 취약점 0건.
    • npm run build 성공. 이 PC에서는 esbuild 실행 정책 때문에 승인 권한 필요.
    • GET /healthz 정상.
    • GET /api/health 정상.
    • GET /s3 skip 응답 정상.
    • GET /db는 현재 Windows 로컬에 DATABASE_URL이 없어 500과 명확한 오류 메시지를 반환. AI DEV/Coder에서 .project-env 로드 후 재검증 필요.
    • docker build -t acs-node-guide-check .는 Docker daemon 미기동(dockerDesktopLinuxEngine pipe 없음)으로 실행 전 실패. Docker Desktop 또는 AI DEV/Coder 배포 환경에서 재검증 필요.

Coder / Gitea / Coolify 배포 검증

  • Coder 접속:
    • https://coder.bokdev.in/workspaces에서 ws-aidev-0420301 워크스페이스 확인.
    • 최초 VS Code Web 접속 시 Agent state is "disconnected" 404가 발생했으나, 잠시 대기 후 VS Code Web 아이콘이 활성화되어 접속 성공.
    • VS Code Web 작업 위치: /home/coder/projects.
  • Gitea 장애:
    • 초기에는 Gitea 루트는 200이었으나 저장소 URL은 500 오류:
      • https://gitea.bokdev.in/playground/MANUAL
      • https://gitea.bokdev.in/playground/acs
      • https://gitea.bokdev.in/0420301/acs
      • git ls-remote https://gitea.bokdev.in/playground/acs.git
    • 인프라 확인 후 Gitea가 정상화되어 clone 가능해짐.
  • AI DEV 표준 프로젝트 생성:
    • 단순 git clone https://gitea.bokdev.in/playground/acs.git만 수행하면 .project-env가 생성되지 않아 DATABASE_URL이 없음.
    • docs/AIdev.md의 6번 절차에 따라 아래 순서로 표준 프로젝트 재생성:
      • mv acs acs-from-git
      • new-project acs
      • cd ~/projects/acs
      • .project-env 생성 확인.
    • 이후 원격 소스 반영:
      • git init -b main
      • git remote add origin https://gitea.bokdev.in/playground/acs.git
      • git fetch origin
      • git reset --hard origin/main
    • .project-env가 유지되었고 DATABASE_URL 환경변수 로드 확인.
  • Coder 로컬 검증:
    • npm install 성공.
    • npm --prefix frontend install 성공.
    • npm run typecheck 성공.
    • npm run db:check 성공:
      • DB OK: Mon Jul 13 2026 10:53:51 GMT+0900 (한국 표준시)
    • npm run minio:check는 ACS S3 미사용으로 정상 skip:
      • S3 SKIPPED: ACS does not currently use S3/MinIO storage.
    • npm run build 성공.
    • npm run migrate 성공:
      • Applied migration 001_init.sql
      • Applied migration 002_audit_log.sql
      • Applied migration 003_pass_delivery.sql
      • Applied migration 004_visit_request_contact_fields.sql
    • npm start 성공:
      • ACS Node app listening on port 3000
    • Coder 로컬 endpoint 확인:
      • curl 127.0.0.1:3000/healthz -> {"ok":true}
      • curl 127.0.0.1:3000/db -> {"ok":true,"now":"..."}
      • curl 127.0.0.1:3000/s3 -> ACS S3 미사용 skip 응답.
    • Coder 내 Docker/Podman build 성공:
      • docker build -t acs-node-local .
      • Successfully tagged localhost/acs-node-local:latest
  • Coolify 리소스 생성:
    • Coolify 팀/프로젝트: aidev / production.
    • Resource type: Public Repository.
    • Repository URL: https://gitea.bokdev.in/playground/acs.git.
    • Branch: main.
    • Build Pack: Dockerfile.
    • Base Directory: /.
    • Port: 3000.
    • Static site: 비활성.
    • 최초 자동 생성 resource 이름:
      • obedient-ocelot-w6wzpkzzv8qua4uzejznirp
    • 최초 자동 생성 domain:
      • https://hridawfl9pktjtzq1vj92zbb.apps.bokdev.in
  • Coolify 환경변수 등록:
    • .project-env에서 제공된 값 중 아래 DB 관련 변수를 등록:
      • DATABASE_URL
      • PGHOST
      • PGPORT
      • PGDATABASE
      • PGUSER
      • PGPASSWORD
      • PGOPTIONS
      • PORT
    • 추가 ACS 변수:
      • SESSION_SECRET
      • ACS_PUBLIC_BASE_URL=https://hridawfl9pktjtzq1vj92zbb.apps.bokdev.in
      • ACS_SMS_PROVIDER=dev
    • S3 관련 변수는 ACS 현재 범위에서는 사용하지 않으므로 필수 등록 대상에서 제외.
  • Coolify healthcheck 설정:
    • Type: HTTP
    • Method: GET
    • Scheme: http
    • Host: localhost
    • Port: 3000
    • Path: /healthz
    • Return Code: 200
    • Healthcheck enabled.
  • 1차 Coolify 배포 결과:
    • Docker image build와 container start는 성공.
    • 컨테이너 로그에 ACS Node app listening on port 3000 확인.
    • 그러나 Coolify healthcheck 실패:
      • /bin/sh: 1: curl: not found
      • /bin/sh: 1: wget: not found
    • 원인:
      • node:22-bookworm-slim runtime image에 Coolify가 healthcheck에 사용하는 curl/wget이 없음.
  • healthcheck 실패 조치:
    • Dockerfile runtime stage에 curlca-certificates 설치 추가:
      • apt-get update
      • apt-get install -y --no-install-recommends curl ca-certificates
      • rm -rf /var/lib/apt/lists/*
    • Coder에서 커밋:
      • Install curl for Coolify healthcheck
    • Coder에서 최초 git push는 upstream 미설정으로 실패.
    • git push --set-upstream origin main은 인증 실패.
    • Gitea Settings > Applications에서 repository read/write 권한 토큰 생성 후 토큰 URL 방식으로 push 성공.
  • 2차 Coolify 배포 결과:
    • commit 44a4bc1086ab9d57dd9815e519c2d2c3c2d0d9c4 기준 배포.
    • Docker image build 성공.
    • New container started.
    • Healthcheck URL:
      • GET http://localhost:3000/healthz
    • Healthcheck passed:
      • Healthcheck status: "healthy"
      • Return code: 0
    • Rolling update completed.
    • Coolify 상태:
      • Running (healthy)
  • 외부 배포 URL 검증:
    • https://hridawfl9pktjtzq1vj92zbb.apps.bokdev.in/healthz
      • {"ok":true}
    • https://hridawfl9pktjtzq1vj92zbb.apps.bokdev.in/db
      • {"ok":true,"now":"2026-07-13T05:12:54.842Z"} 등 정상 응답.
    • https://hridawfl9pktjtzq1vj92zbb.apps.bokdev.in/login
      • React 로그인 화면 표시 정상.
  • 현재 배포 상태:
    • AI DEV 표준 Node.js + Dockerfile + .project-env/DATABASE_URL 기반 배포 파이프라인 성공.
    • 현재 Node 서버는 health/db/static frontend 기반까지만 구현됨.
    • 기존 ACS 업무 기능은 아직 Spring Boot 백엔드에서 Node API로 이관 전.
    • 로그인 화면은 표시되지만 /api/auth/login 등 Node Auth API 구현 전이므로 실제 로그인은 다음 단계에서 구현 필요.
  • 도메인 정리 및 고정 도메인 전환:
    • 최초 Coolify 자동 생성 임시 도메인:
      • https://hridawfl9pktjtzq1vj92zbb.apps.bokdev.in
    • 인프라팀에 고정 도메인 사용 가능 여부 확인 요청:
      • 희망: https://acs.apps.bokdev.in
      • 또는 AI DEV 표준: https://acs.playground.bokdev.in
    • 팀장 확인 결과, Coolify에서 사용자가 직접 고정 도메인으로 변경하면 되는 것으로 판단.
    • Coolify Configuration > General에서 Domains 값을 아래로 변경:
      • https://acs.apps.bokdev.in
    • Set Direction은 기존 direction 확인/적용용이며, domain 자체 저장은 General 제목 옆 Save 버튼으로 처리.
    • 도메인 저장 직후 /healthz에서 일시적으로 no available server가 표시되었으나, 재배포/라우팅 반영 후 정상화.
    • Coolify Configuration > Environment Variables에서 ACS_PUBLIC_BASE_URL 값 변경:
      • 변경 전: https://hridawfl9pktjtzq1vj92zbb.apps.bokdev.in
      • 변경 후: https://acs.apps.bokdev.in
    • 변경 후 재배포 및 최종 확인 완료:
      • https://acs.apps.bokdev.in/healthz -> {"ok":true}
      • https://acs.apps.bokdev.in/db -> {"ok":true,"now":"..."}
      • https://acs.apps.bokdev.in/login -> React 로그인 화면 표시 정상.
    • AI DEV 포털 프로젝트의 배포 URL도 https://acs.apps.bokdev.in로 맞추는 방향으로 정리.
  • 다음 작업:
    • Node Auth/session/role middleware 구현.
    • PostgreSQL session store 구성.
    • 사용자 seed 또는 기존 사용자 적재 방식 확정.
    • /api/auth/login, /api/auth/logout, /api/auth/me, /api/auth/change-password 구현.
    • 이후 방문신청/승인/출입/리포트 API를 순차 이관.

2026-07-14

ACS 테스트 준비 및 문서 산출물

  • ACS 수동 테스트 시나리오 문서 작성:
    • docs/ACS-test-scenarios.md
    • 운영 기준 URL을 https://acs.apps.bokdev.in로 정리.
    • Smoke, 권한, 방문신청, 승인/반려, 출입증/QR, 출입콘솔, 키오스크, 블랙리스트, 리포트, 발송함, 엑셀 업로드, 보안/세션, UI 테스트 항목 작성.
  • 로그인 404 분석 문서 작성:
    • docs/ACS-login-404-analysis.md
    • 증상, 원인, 조치, 재테스트 기록, 운영 반영 확인 기준 정리.
  • 출입신청 화면 UI 수정 문서 작성:
    • docs/ACS-visit-form-ui-update.md
    • 1차/2차 UI 변경 내용, 빌드 검증, 최신 asset 기준 기록.

로그인 404/500 조치

  • 운영 https://acs.apps.bokdev.in/login에서 로그인 시도 시 POST /api/auth/login 404 발생.
  • 원인:
    • Node 서버의 /api 라우터에 health 라우터만 연결되어 있었고 Auth API가 미구현 상태.
  • Node Auth API 추가:
    • server/routes/auth.ts
    • POST /api/auth/login
    • POST /api/auth/logout
    • GET /api/auth/me
    • POST /api/auth/change-password
  • 세션 처리 추가:
    • express-session
    • connect-pg-simple
    • PostgreSQL 기반 user_sessions 세션 스토어 사용.
  • 사용자 seed 보장:
    • scripts/seeds/users.csv에 테스트 단축 계정 추가.
    • migrations/005_seed_test_users.sql 추가.
    • 테스트 계정:
      • a / 1 = ADMIN
      • s / 1 = SECURITY
      • h / 1 = HOST
  • 운영 재배포 후 404는 해소되었으나 500 발생.
  • /api/auth/diagnostics 추가 후 확인 결과, 운영 DB에 users, user_roles 테이블이 없는 상태 확인.
  • Coolify 실행 명령이 Dockerfile CMD ["npm", "run", "start:deploy"]를 타지 않을 수 있다고 판단.
  • 서버 시작 시 migration을 직접 보장하도록 server/index.tsrunMigrations() 추가.
  • Coolify Redeploy 후 로그인 성공 확인:
    • a / 1 로그인 성공.

운영 배포 및 커밋

  • 원격 origin/main에 반영한 주요 커밋:
    • 7c8bd37 Add Node auth routes for ACS login
    • 9562766 Seed ACS test login accounts
    • e02afcd Add auth deployment diagnostics
    • 0ae4b73 Run migrations on server startup
    • 7a404cd Update visit request form layout
    • 2653ed6 Compact visit request form
  • Coolify Redeploy 후 /api/health에서 최신 build marker 확인:
    • build: auth-seed-20260714
    • authApi: true

출입신청 화면 UI 1차 개선

  • 요청사항 반영:
    • 화면 콘텐츠 폭을 브라우저 창 기준으로 넓게 사용하도록 조정.
    • 입력 항목과 레이블을 한 줄 배치로 변경.
    • 필수 입력 * 표시를 red로 변경.
    • 방문자 연락처, 현장감시자2 연락처 11자리 숫자 입력 시 000-0000-0000 자동 변환.
    • 방문자, 출입통제담당자, 현장감시자1과2 테두리 그룹 박스 적용.
    • 범례/레이블/개인정보 수집·이용 동의 문구 수정.
  • 검증:
    • npm run typecheck 성공.
    • npm --prefix frontend run build 성공.

출입신청 화면 UI 2차 압축 개선

  • 목표:
    • 출입신청 화면의 모든 내용을 수직 스크롤 없이 한 화면에 최대한 보이도록 조정.
  • 반영 내용:
    • 전체 콘텐츠 padding 축소.
    • 폼 그룹/필드/동의 영역 여백 축소.
    • 그룹 내부를 3열 기반으로 조정.
    • 출입 전산실추가 구역을 같은 라인에 배치.
    • 출입 목적작업명을 같은 라인에 배치.
    • 불필요한 레이블 설명을 제거하고 필요한 안내는 placeholder로 이동.
    • 퇴실예정일시퇴실 예정일시로 수정.
    • 직원명이름으로 수정.
    • 현장감시자1과2현장감시자로 수정.
    • 현장감시자1 : IT센터 사무보조원 (자동 지정) 문구 반영.
    • 출입통제담당자 연락처 표시를 내선번호/휴대폰번호 placeholder 기준으로 정리.
  • 최신 프론트 빌드 asset:
    • JS: /assets/index-Cc3Y9nv_.js
    • CSS: /assets/index-V1wV5EGT.css
  • 검증:
    • npm run typecheck 성공.
    • npm --prefix frontend run build 성공.

현재 상태

  • 로그인:
    • a / 1 로그인 성공.
  • 운영 URL:
    • https://acs.apps.bokdev.in
  • 출입신청 UI:
    • 최신 UI 커밋은 원격 main 반영 완료.
    • 운영 반영은 Coolify Redeploy 후 HTML asset 해시 확인 필요.
  • 로컬 작업트리:
    • 이전 작업 중 생성/수정된 미정리 파일이 일부 남아 있음.
    • 배포용 커밋은 임시 worktree를 사용해 원격 최신 main 기준으로 선별 push 완료.

다음 작업

  • Coolify Redeploy 후 운영 HTML이 최신 asset을 참조하는지 확인:
    • 기대 JS: /assets/index-Cc3Y9nv_.js
    • 기대 CSS: /assets/index-V1wV5EGT.css
  • /visit-requests/new 화면 실브라우저 확인:
    • 한 화면 표시 여부.
    • 레이블/placeholder/그룹 박스/연락처 자동 포맷 확인.
  • 방문 신청 저장 API가 아직 Node로 이관되지 않은 경우, 다음 테스트 단계에서 /api/visit-requests 구현 필요.

2026-07-16

출입신청 날짜 검증 및 QR 유효기간 정책

  • 출입신청 화면에서 퇴장일이 출입일 다음날 이후인 경우 2건 분리 신청 안내 후 제출 차단.
  • 출입일시가 현재 시스템 일시 이전이어도 입력 가능하도록 과거일자 차단 제거.
  • 출입일시가 퇴장일시보다 늦은 경우 안내 메시지 후 제출 차단.
  • 백엔드 신청 생성 API에도 동일한 역전/익일 퇴장 검증 추가.
  • 방문자 QR은 visitFrom의 일자 동안만 유효하도록 입장 판정 기준을 visitTo가 아닌 visitFrom.toLocalDate()로 변경.
  • 지난 출입일 QR을 스캔하면 입장을 차단하고 해당 신청을 EXPIRED로 전이하도록 조정.
  • 매일 00:10 만료 배치도 visitFrom 기준으로 지난 승인 건을 만료 처리하도록 변경.
  • 검증:
    • npm.cmd run build 성공.
    • mvn.cmd test 성공.

개인정보 동의 문구 조정

  • [개인정보 수집·이용 동의 확인][방문자에 대한 개인정보 수집·이용 동의 확인]으로 변경.
  • 보유·이용 기간 문구를 전산실 퇴장 등록시 입력된 방문자 이름, 연락처, 이메일, 차량번호는 바로 삭제로 변경.
  • 해당 보유·이용 기간 한 줄만 red 색상으로 표시.
  • 검증:
    • npm.cmd run build 성공.

시스템 관리 및 출입목적 코드화

  • 관리자 전용 시스템관리 메뉴 추가.
  • 관리 탭:
    • 현장감시자1 정보 수정.
    • 출입목적 코드/표시명/사용 여부/기타 입력 허용 관리.
    • 사용자별 ADMIN/SECURITY/HOST 권한 관리.
  • 출입신청 화면의 출입목적 목록을 고정 상수에서 서버 코드 목록 기반으로 변경.
  • 방문신청 저장 시 purposeCode, purposeDetail을 함께 저장하도록 확장.
  • 기타 목적 입력값이 기존 출입목적 코드/표시명과 일치하면 해당 코드로 자동 정규화.
  • Flyway V5__admin_config.sql 추가:
    • purpose_codes
    • system_settings
    • visit_requests.purpose_code
    • visit_requests.purpose_detail
  • 검증:
    • mvn.cmd test 성공.
    • npm.cmd run build 성공.
    • 로컬 새 API 확인: /api/purpose-codes, /api/admin/purpose-codes, /api/settings/watcher1, /api/admin/users 모두 200.

팀 기반 권한관리 개선

  • 개발1팀 등 조직 변경이 잦은 운영을 고려해 사용자별 권한 직접 수정만 두지 않고, 팀 기준 권한 템플릿을 추가.
  • 시스템관리 > 팀 관리 탭 추가:
    • 팀 코드, 팀명, 사용 여부, 기본권한 관리.
    • 기본권한은 ADMIN/SECURITY/HOST 다중 선택 가능.
    • 팀별 기본권한을 해당 팀 소속 전체 사용자에게 일괄 적용 가능.
  • 시스템관리 > 권한관리 탭 개선:
    • 사용자 검색, 팀 필터 추가.
    • 사용자별 소속 팀 변경 가능.
    • 팀 변경 시 팀 기본권한을 즉시 적용할지 선택 가능.
    • 특정 사용자에게 팀 기본권한만 별도 재적용 가능.
  • 기존 users.department는 호환성을 위해 유지하되, 신규 teams 마스터와 users.team_id를 기준으로 운영하도록 확장.
  • Flyway V6__teams.sql 추가:
    • teams
    • team_default_roles
    • users.team_id
    • 기존 IT운영팀/개발1팀/보안팀 및 기본권한 seed.
  • 검증:
    • mvn.cmd test 성공.
    • npm.cmd run build 성공.
    • 로컬 서버 재기동 후 /api/admin/teams, /api/admin/users 모두 200.

팀/권한 엑셀 업로드

  • 시스템관리 > 팀 관리에 엑셀 업로드 기능 추가.
    • 컬럼: 팀 코드, 팀명, 기본권한.
    • 팀 코드를 기준으로 신규/수정 구분.
    • 기본권한은 업로드 값으로 교체.
    • 양식 다운로드 제공.
  • 시스템관리 > 권한관리에 엑셀 업로드 기능 추가.
    • 컬럼: 아이디, 이름, 팀명, 권한.
    • 기존 사용자만 수정하며 신규 사용자 생성은 제외.
    • 아이디 기준으로 사용자 확인, 이름 불일치/없는 팀/잘못된 권한/중복 행은 오류 처리.
    • 양식 다운로드 제공.
  • 업로드는 즉시 반영하지 않고 검증으로 미리보기 결과를 확인한 뒤, 오류가 0건일 때만 적용 가능하도록 구성.
  • 백엔드에서 Apache POI로 .xlsx를 파싱하고 적용 시 ADMIN_CONFIG_UPDATE 감사로그 기록.
  • 검증:
    • mvn.cmd test 성공.
    • npm.cmd run build 성공.
    • 로컬 서버 재기동 후 팀 양식 다운로드 및 /api/admin/teams/upload?dryRun=true 200 확인.
    • 권한 양식 다운로드 및 /api/admin/users/roles/upload?dryRun=true 200 확인.

권한관리 운영 방식 일원화

  • 시스템관리 > 권한관리 하단 목록의 사용자별 기본권한 적용 버튼 제거.

  • 사용자별 권한 변경은 팀 선택/권한 체크박스 수정 후 저장 버튼으로 반영하도록 변경.

  • 팀 변경 시에도 팀 기본권한을 자동 적용하지 않고, 관리자가 화면에서 확인한 권한 체크 상태 그대로 저장.

  • 팀 기본권한 적용 기능은 팀 관리의 팀원 일괄 적용 또는 권한 엑셀 업로드 방식으로만 유지.

  • /api/admin/**는 기존 보안 설정상 ADMIN 권한자만 접근 가능함을 확인.

  • 검증:

    • npm.cmd run build 성공.
    • mvn.cmd test 성공.
  • 2026-07-16 배포 준비:

    • 서버 배포 구조가 루트 Node Dockerfile 기준임을 확인하고, Spring Boot 변경사항 중 서버에서 필요한 기능을 Node API로 이관.
    • 원격 최신 playground/acs 기준의 클린 클론(acs-deploy)에 Node/프론트/마이그레이션 변경만 적용.
    • 클린 클론 검증:
      • npm.cmd run typecheck 성공.
      • npm.cmd run build 성공.
      • npm.cmd test 성공.
    • 로컬 DB 접속 정보(DATABASE_URL)가 없어 신규 마이그레이션은 서버 기동 시 적용되는 방식으로 확인 예정.
    • 원격 playground/acs main에 배포 커밋 c6f342a push 완료.
    • 운영 URL 확인:
      • /healthz 200, /db 200, /login 200.
      • /api/health의 build marker가 여전히 auth-seed-20260714이고 /api/purpose-codes가 JSON이 아니라 SPA HTML을 반환.
    • 판단:
      • Gitea push는 성공했지만 Coolify가 아직 새 커밋을 재배포하지 않음.
      • Public Repository 방식은 webhook 미설정 시 push만으로 자동 배포되지 않으므로 Coolify에서 수동 Redeploy 또는 Gitea webhook 설정 필요.
  • 2026-07-16 서버 배포 기능 보완:

    • Node 배포본의 /api/visit-requests/upload 방문자 명단 엑셀 업로드 stub 제거.
    • 기존 Spring ExcelImportService 기준으로 방문자명단 시트 3행부터 출입목적, 작업명, 장소, 출입일자, 출입시간, 방문자 정보, 통제담당자, 현장감시자 정보를 읽어 출입신청을 생성하도록 이관.
    • 엑셀 출입목적 값이 시스템 출입목적 코드명/표시명과 일치하면 purpose_code로 정규화 저장하도록 보완.
    • 엑셀에 출입통제담당자/현장감시자1 값이 있으면 해당 값을 우선 저장하고, 비어 있으면 기존처럼 로그인 사용자/시스템 설정값을 사용.
    • 검증:
      • npm.cmd run typecheck 성공.
      • npm.cmd run build 성공.
      • npm.cmd test 성공.
    • 운영 서버 배포 후 검증:
      • Coolify Redeploy 완료.
      • /db 200 OK.
      • /api/purpose-codes 200 OK.
      • a / 1 로그인 성공.
      • /api/admin/teams 200 OK.
      • /api/visit-requests/upload 테스트 엑셀 업로드 성공: totalRows=1, successCount=1, errors=[].
      • 업로드로 생성된 테스트 신청은 즉시 취소 처리.
  • 2026-07-16 출입신청 일시 선택 UI 수정:

    • 운영 서버 출입신청 화면에서 출입일시 캘린더의 [입력] 버튼 클릭 시 선택값이 확정되지 않는 문제 확인.
    • DateTimePicker를 확정형 동작으로 변경:
      • 달력 내부 선택값은 draft로 보관.
      • [입력] 버튼 클릭 시 visitFrom/visitTo 값으로 반영 후 팝업 닫기.
      • 팝업 open 상태를 컴포넌트 state로 제어해 브라우저별 동작 차이를 줄임.
    • 검증:
      • npm.cmd run typecheck 성공.
      • npm.cmd run build 성공.
      • npm.cmd test 성공.
  • 2026-07-16 승인 시 방문자 QR 문자 발송 구조 추가:

    • 관리자 승인(POST /api/approvals/{id}/approve) 시 방문자 연락처로 공개 출입증 링크(/pass/{qrToken})를 SMS 전송하도록 Node 서버에 sendSms 어댑터 추가.
    • 문자 본문은 방문 승인 안내, 방문자명, 출입일시, 출입증(QR) URL을 포함.
    • QR 이미지를 MMS로 직접 첨부하지 않고, 방문자 휴대폰에서 공개 출입증 URL을 열면 QR Code가 표시되는 방식으로 구성.
    • 문자 발송 실패가 승인 자체를 롤백하지 않도록 하고, 성공/실패 및 오류는 pass_deliveries에 기록.
    • 발송내역 화면의 재발송 버튼이 실제 SMS 재전송을 수행하도록 변경.
    • SMS 환경변수:
      • ACS_SMS_PROVIDER=dev: 실제 발송 없이 서버 로그 및 발송내역 성공 처리.
      • ACS_SMS_PROVIDER=http: ACS_SMS_API_URL로 HTTP POST 전송.
      • 선택값: ACS_SMS_API_KEY, ACS_SMS_SENDER, ACS_SMS_TIMEOUT_MS.
    • 검증:
      • npm.cmd run typecheck 성공.
      • npm.cmd test 성공.
      • npm.cmd run build 성공.
  • 2026-07-16 출입신청 일시 선택 UI 재수정:

    • 운영 서버에서 출입일시 캘린더 [입력] 버튼 흐름이 다시 막히는 현상 확인.
    • 달력 팝업 내부 확정 버튼이 브라우저/라이브러리 이벤트와 충돌할 가능성이 있어 [입력] 버튼 의존 구조 제거.
    • 날짜/시간 선택 즉시 visitFrom/visitTo 입력값에 반영되도록 단순화.
    • 검증:
      • npm.cmd run typecheck 성공.
      • npm.cmd run build 성공.
      • npm.cmd test 성공.
  • 2026-07-16 출입신청 일시 적용 버튼 및 관리자 즉시승인:

    • 출입일시/퇴실예정일시 입력칸 옆에 적용 버튼 추가.
    • 캘린더에서 고른 날짜/시간은 임시값으로 유지하고, 적용 클릭 시 실제 입력값으로 확정되도록 변경.
    • ADMIN/SECURITY 권한 사용자가 직접 출입신청을 등록하는 경우 승인대기 없이 즉시 APPROVED 처리.
    • 즉시승인 시 일반 승인과 동일하게 승인 이력 저장 및 QR 출입증 링크 SMS 발송 로직 실행.
    • 검증:
      • npm.cmd run typecheck 성공.
      • npm.cmd test 성공.
      • npm.cmd run build 성공.
  • 2026-07-16 사내 SMS API 가이드 반영 및 일시 선택 UI 개선:

    • C:\ai-bok\SMS API가이드.pdf를 로컬에서만 확인했고, PDF 원문 및 민감 자료는 저장소/서버 배포물에 포함하지 않음.
    • 사내 메시지 발송은 네이버 API 직접 호출이 아니라 DMZ 보안 API 호출 방식임을 확인.
    • Node SMS 어댑터에 ACS_SMS_PROVIDER=hanbank/bok provider를 추가:
      • POST /sens/sms
      • 요청 필드: receive_number, content, msg_type=LMS, reserve_time
      • 응답 statusCode=202 또는 statusName=success를 성공으로 처리.
    • 기존 ACS_SMS_PROVIDER=dev는 로컬/서버 모의 발송 검증용으로 유지.
    • 출입신청 일시 선택 UI는 입력칸 옆 외부 적용 버튼을 제거하고, 캘린더 팝업 우측 상단 닫기 버튼으로 닫도록 변경.
    • 검증:
      • npm.cmd run typecheck 성공.
      • npm.cmd run build:frontend 성공.
      • npm.cmd run build:server 성공.
      • npm.cmd test 성공.
  • 2026-07-16 시스템관리 SMS 연결 점검 기능 추가:

    • Coolify 서버 화면에서 컨테이너 터미널 접근 메뉴가 보이지 않아, 운영자가 화면에서 직접 점검할 수 있도록 시스템관리 > SMS 점검 탭 추가.
    • ADMIN 전용 POST /api/admin/sms/diagnostics 추가.
    • 실제 문자 발송 없이 현재 SMS provider/API URL 기준으로 서버 컨테이너에서 /sens/sms 연결을 짧게 점검.
    • 점검 결과로 provider, URL, 연결 성공/실패, HTTP 상태, 소요시간, 오류 메시지를 표시.
    • timeout이면 방화벽/라우팅/허용 IP 문제, HTTP 응답이면 API 서버 도달 성공으로 판단 가능.
  • 2026-07-16 시스템관리 Email SMTP 연결 점검 기능 추가:

    • Dooray API 가이드는 API 인증/서비스 API 안내 성격이고, 방문자 QR 이메일 발송은 별도 메일 발송 API보다 SMTP 경로를 우선 검증하는 방식이 적합하다고 판단.
    • ADMIN 전용 POST /api/admin/email/diagnostics 추가.
    • ACS_MAIL_HOST, ACS_MAIL_PORT, ACS_MAIL_FROM, ACS_MAIL_USERNAME, ACS_MAIL_PASSWORD, ACS_MAIL_SMTP_AUTH, ACS_MAIL_STARTTLS, ACS_MAIL_TIMEOUT_MS 환경변수를 서버에서 읽도록 추가.
    • 실제 메일 발송 없이 서버 컨테이너에서 SMTP host/port TCP 연결만 점검.
    • 시스템관리 화면에 Email 점검 탭을 추가하고 host, port, 발신자, 인증/STARTTLS 설정 여부, 계정/비밀번호 설정 여부, 연결 성공/실패, 소요시간, 오류 메시지를 표시.
  • 2026-07-22 발표자료 화면 캡처 테스트 및 ACS 운영 흐름 보정:

    • 개발/배포 원칙 재확인:
      • 소스 변경은 반드시 로컬에서 수정 및 테스트 완료 후 서버 배포.
      • 서버에서만 소스 수정하는 방식은 금지.
      • 운영 DB 데이터 정리는 필요 시 서버 DB 또는 운영 UI에서 별도 수행.
    • 로컬/서버 버전 정렬:
      • 서버에 반영된 변경이 로컬과 어긋난 상태를 확인하고, 로컬 저장소를 원격 최신 기준으로 맞춤.
      • 이후 모든 변경은 로컬 수정, 로컬 검증, 커밋, push, Coolify Redeploy 순서로 진행.
    • 운영 테스트 데이터 정리:
      • 시스템관리 > 데이터 정리 > 출입신청 테스트 데이터 초기화 기능으로 비정상 테스트 데이터를 정리.
      • 출입신청, 방문자, 승인 기록, 입/퇴장 기록, 출입증 발송 기록을 삭제하고 사용자/팀/권한/목적 코드/시스템 설정/블랙리스트는 유지.
    • 승인대기 화면 UX 보정:
      • 승인 버튼 클릭 시 반려 버튼까지 함께 처리 중처럼 보이는 문제 수정.
      • 행 단위 busy 상태를 approve/reject 액션별로 분리.
      • 커밋: ed972a3 fix: align access console status actions.
    • 출입콘솔 상태 및 수기 입장 기능 보정:
      • 입장대기 별도 표시를 제거하고 승인완료로 통일.
      • 출입콘솔 금일 출입 현황 목록에서도 관리자/담당자가 승인완료 건을 직접 입장 처리할 수 있도록 보정.
      • 입장/퇴장 처리 성공 메시지에 출입구역을 함께 표시하도록 보정.
      • 커밋: 3efe493 fix: show access action zone.
    • 키오스크 QR 처리 보정:
      • QR에 토큰만이 아니라 /pass/{token} 전체 URL이 들어오는 경우를 처리.
      • 키오스크에서 스캔한 전체 URL에서 토큰만 추출하도록 수정.
      • public pass API 호출 시 토큰을 URL 인코딩하도록 수정.
      • 키오스크에서 입장 후 같은 QR을 다시 입력하면 퇴장 처리 버튼이 표시되는 흐름 확인.
      • 커밋: 7c57960 fix: parse kiosk qr pass urls.
    • 대시보드 출입 상태 반영 보정:
      • 키오스크/출입콘솔 입퇴장 후 대시보드가 최초 조회 상태에 머무르는 문제 수정.
      • 대시보드를 3초 주기로 자동 갱신하도록 변경.
      • 커밋: 7cbc660 fix: refresh dashboard access state.
    • 출입신청 목록 상태 반영 보정:
      • 신청 자체의 상태만 표시하여 실제 입퇴장 후에도 승인완료로 남던 문제 수정.
      • 오늘 출입 현황을 함께 조회하고 재실중/퇴장을 신청 상태보다 우선 표시.
      • 3초 주기 자동 갱신 추가.
      • 커밋: dee612f fix: show access state in request list.
    • 보고서 상태 반영 보정:
      • 보고서 화면에서도 실제 입퇴장 상태가 아닌 신청 상태만 보이던 문제 수정.
      • 오늘 출입 현황을 함께 조회하고 재실중/퇴장을 우선 표시.
      • 커밋: eec18e7 fix: show access state in reports.
    • 검증:
      • 각 수정마다 npm --prefix frontend exec tsc -- --noEmit 통과.
      • 각 수정마다 npm run typecheck 통과.
      • Vite/esbuild는 샌드박스에서 spawn EPERM이 발생하여 권한 밖에서 npm run build 재실행 후 통과.
      • Coolify Redeploy 후 서버 화면에서 주요 흐름 재확인.
    • 발표자료 캡처:
      • C:\ai-bok\20260729\AIdev2.pptm 12~45페이지 화면 캡처 완료.
    • 비고:
      • 서버 URL: https://acs.apps.bokdev.in.
      • 테스트 중 발견된 화면 상태 불일치는 대시보드, 출입신청 목록, 보고서 순으로 동일 원칙에 맞춰 보정.