# ACS 로그인 404 분석 및 조치 > 작성일: 2026-07-14 > 증상: 운영 배포 URL에서 로그인 시도 시 404 발생 > 대상 URL: `https://acs.apps.bokdev.in/login` ## 1. 증상 로그인 화면은 표시되지만, 아이디/비밀번호 입력 후 로그인 버튼을 누르면 404 오류가 발생한다. ## 2. 원인 프론트엔드 로그인 화면은 `POST /api/auth/login`을 호출한다. 현재 Node 배포 서버의 `/api` 라우터에는 `healthRouter`만 연결되어 있어 `/api/auth/login` 경로가 존재하지 않았다. 즉, 404는 `/login` 화면 경로가 아니라 로그인 API 경로인 `/api/auth/login`에서 발생한 것이다. ## 3. 조치 Node 서버에 Auth API를 추가했다. | API | 조치 내용 | |---|---| | `POST /api/auth/login` | 사용자 조회, bcrypt 비밀번호 검증, 세션 저장 | | `POST /api/auth/logout` | 세션 삭제 | | `GET /api/auth/me` | 현재 로그인 사용자 반환 | | `POST /api/auth/change-password` | 기존 비밀번호 검증 후 새 비밀번호 저장 | 세션은 PostgreSQL 기반 `connect-pg-simple` 스토어를 사용하도록 연결했다. ## 4. 확인 결과 | 항목 | 결과 | |---|---| | `npm run typecheck` | 성공 | | `npm run build:server` | 성공 | | `npm run build` | 성공 | 첫 번째 전체 빌드는 샌드박스 안에서 esbuild 프로세스 생성이 `spawn EPERM`으로 차단되었고, 승인 후 샌드박스 밖에서 재실행하여 성공을 확인했다. ## 5. 남은 확인 사항 운영 DB에 로그인 계정이 적재되어 있어야 한다. 기존 seed 파일 기준 기본 계정은 아래와 같다. | 계정 | 초기 비밀번호 | 역할 | |---|---|---| | `admin` | `ChangeMe123!` | ADMIN | | `security` | `ChangeMe123!` | SECURITY | | `host` | `ChangeMe123!` | HOST | | `a` | `1` | ADMIN | | `s` | `1` | SECURITY | | `h` | `1` | HOST | 운영 DB에 계정이 없으면 404는 해결되지만 로그인은 401로 실패한다. 이 경우 `scripts/seed-load.py`와 `scripts/seeds/users.csv` 기준으로 사용자 seed 적재가 필요하다. 원활한 테스트를 위해 `a/1`, `s/1`, `h/1` 단축 계정을 seed CSV에 추가했다. ## 6. 재테스트 기록 2026-07-14 사용자가 `a/1`로 운영 URL에서 다시 로그인 시도했으나 404가 재현되었다. 판단: 운영 서버가 아직 Auth API 추가 코드로 재배포되지 않은 상태다. 로컬 변경분을 원격 저장소에 push하고 Coolify 재배포가 완료된 뒤 다시 테스트해야 한다. 2026-07-14 Auth API 커밋 배포 후 `POST /api/auth/login` 응답이 404에서 500으로 변경되었다. 판단: 라우터는 배포에 반영되었고, 남은 문제는 운영 DB의 사용자 seed 또는 로그인 처리 중 DB 상태 문제로 좁혀졌다. 다음 배포부터 테스트 계정이 자동 보장되도록 `migrations/005_seed_test_users.sql`을 추가한다. 2026-07-14 after Coolify redeploy, `/api/health` returned `build: auth-seed-20260714`. However, `/api/auth/diagnostics` reported no `users` or `user_roles` table, and login still returned 500. Conclusion: runtime migration is not guaranteed when Coolify overrides Dockerfile CMD. Added startup migration in `server/index.ts` so `runMigrations()` executes before the Express server starts.