매장을 운영하면서 직원 출퇴근 관리를 직접 만들어 1년 가까이 굴리고 있습니다. 처음에는 시중 근태관리 서비스를 쓰려고 가격을 알아봤는데, 직원 수가 늘수록 비용이 같이 올라가는 구조가 부담스러웠습니다. 결국 "필요한 기능이 그렇게 많지 않으니 직접 짜보자"는 결론으로 시작했고, 지금까지 운영 비용 0원으로 굴러가는 중입니다.
이 글에서는 어떤 구조로 만들었는지, 1년 동안 어디서 막혔고 어떻게 풀었는지 정리합니다.
저는 방탈출 카페 5년차로, 매장 3개에 직원 12명을 두고 운영하고 있습니다. 시중 근태관리 서비스는 직원당 월 과금 구조가 많아 인원이 늘수록 비용이 따라 커지는 게 부담스러웠습니다. 필요한 기능이 출퇴근 찍기·기록 조회·급여 계산 정도라 차라리 직접 짜는 게 낫겠다는 결론이었습니다.
1. 무엇을 만들었나
직원이 매장 PC에서 출근/퇴근을 찍고, 관리자가 그 기록으로 월말에 급여명세서까지 뽑는 사내용 웹앱입니다.
직원 화면
- 로그인 → 🟢 출근 / 🔴 퇴근 버튼
- 본인 출퇴근 기록(표·캘린더) 조회
- 누락된 기록은 "수정 신청"으로 관리자에게 요청
- 본인 급여명세서 확인
관리자 화면
- 직원 관리, 전체 기록 CRUD
- 수정 신청 승인/반려
- 통계 (오늘 출근/퇴근, 이번 달 근무시간)
- 급여명세서 자동 발행 + Gmail 이메일 발송
- 모든 변경의 감사 로그
- 자정마다 "미퇴근" 직원 푸시 알림
2. 어떤 스택으로 만들었나
| 영역 | 선택 |
|---|---|
| 프론트 | Vanilla JavaScript (한 페이지짜리 SPA) |
| 백엔드 | Vercel Functions (서버리스, Node.js 24) |
| DB | Neon Postgres (서버리스) |
| 인증 | bcrypt + JWT + DB 세션 테이블 |
| 푸시 | Web Push API (관리자 알림) |
| 메일 | Gmail SMTP (급여명세서 발송) |
| 배포 | Vercel (수동 배포) |
프레임워크(React·Vue·Next 등)는 일부러 안 썼습니다. 화면이 한 장이라 라우터가 필요 없고, 빌드 단계 없이 정적 파일을 그대로 올리면 끝나는 구조가 디버깅이 빠르기 때문입니다.
3. 비용 — 1년간 진짜 0원이 가능한가
| 서비스 | 무료 한도 | 실제 사용량 | 비용 |
|---|---|---|---|
| Vercel Hobby | 함수 12개, 대역폭 100GB/월 | 함수 12/12, 대역폭 약 5GB/월 | 0원 |
| Neon Postgres | DB 0.5GB, 컴퓨트 191시간/월 | DB 약 50MB, 컴퓨트 약 30시간/월 | 0원 |
| Gmail SMTP | 일 500건 | 월 평균 30건 (급여명세서) | 0원 |
| 도메인 | (선택) | xxx.vercel.app 그대로 사용 |
0원 |
| 합계 | — | — | 1년 0원 |
단, Vercel 함수 12개 한도에 부딪힌 뒤로는 새 기능을 만들 때 기존 파일에 합치는 식으로 관리하고 있습니다. 예를 들어 로그인·로그아웃·회원가입·내 정보 조회는 전부 [action].js 파일 하나가 처리합니다.
처음에는 새 기능마다 함수 파일을 따로 만들었습니다. 한도가 있다는 걸 알고는 있었는데 "아직 여유 있겠지" 하다가 어느 순간 12 / 12로 막혀서, 그때부터 비슷한 동작끼리 통합하는 작업을 했습니다. 예를 들어 감사 로그 API는 따로 두지 않고 통계 API 안에 옵션으로 흡수했습니다.
4. 1년 운영하며 마주친 진짜 문제 3가지
(1) 출퇴근 시간이 9시간 늦게 저장되던 버그
Vercel Functions는 UTC 시간대로 동작하는데, 시간을 그대로 DB에 저장하면서 한국 시간(+9) 변환을 안 거치니, 오전 9시에 출근 찍은 기록이 DB에는 자정 0시로 들어가는 사고가 있었습니다.
해결: 서버에서 시간을 다룰 때 항상 KST 변환 헬퍼를 거치도록 통일했습니다.
발견한 계기는 한 직원이 "왜 어제 자정에 출근으로 떠요?" 라고 물어와서였습니다. 본인이 평소처럼 오전에 찍었는데 기록상으로는 자정에 출근한 걸로 떠 있었던 거죠. 같은 패턴의 기록이 다른 직원들 것에도 똑같이 있던 걸 확인하고 그제야 원인을 추적했습니다.
(2) 직원이 화면 켜둔 채로 자리 비우면 다음 직원이 그 계정으로 출근 찍힘
매장 PC 1대를 직원 여러 명이 돌려쓰는 구조라, 로그인한 채로 자리 비우면 그 다음 직원이 그대로 출근 버튼을 눌러버리는 사고가 종종 있었습니다.
해결: 5분 동안 마우스·키보드 입력이 없으면 자동 로그아웃. 이제는 자리 비웠다 와도 무조건 다시 로그인부터 해야 합니다.
(3) 직원이 집에서 출근 찍는 경우
매장 PC에서만 찍어야 의미가 있는데, 직원이 본인 휴대폰으로 출근을 찍는 사례가 생겼습니다.
해결: 모바일 User-Agent에서 직원 로그인을 서버가 거부(403). 관리자만 모바일 접속 가능하게 막아뒀습니다. 직원은 매장 PC에서만 찍힙니다.
5. 1년 만들어 굴리고 알게 된 것
- 시중 근태 서비스를 안 쓰고 1년 운영한 결과 이론상 절약 금액은 적게는 수십만 원입니다 (직원 수에 따라 차이 큼).
- 다만 직접 만든 시간 비용은 따로 — 초기 2~3주 + 운영 중 버그 픽스 시간이 적지 않게 들었습니다. 솔직히 이게 더 큽니다.
- 직원 10명 미만이라면 시중 서비스가 더 싸게 먹힙니다. 직접 만들기는 운영 규모가 일정 이상 + 매장 운영자가 코드 다룰 줄 알 때 의미가 있습니다.
- 무료 플랜의 한도(Vercel 함수 12개, Neon DB 0.5GB)는 자영업 규모에선 충분합니다. 대형 매장이라면 다른 얘기.
종합해서, 직접 만들길 잘했다는 쪽입니다. 시간 비용은 분명 있었지만 그건 한 번 들이고 나면 줄어드는 비용이고, 시중 서비스의 월 구독료는 줄지 않습니다. 매달 나가는 돈이 빠지지 않는다는 게 가장 큽니다.
다음 글 예고
이 시리즈는 계속 이어집니다.
- (2편) 인증과 세션 — bcrypt + JWT만으로는 "관리자가 직원을 즉시 강제 로그아웃" 못 시킵니다. 어떻게 해결했나
- (3편) 급여명세서 모듈 — 시급제·월급제·주휴수당 자동 계산식과 직원 통합(한 사람이 호점 여러 개 가질 때)
- (4편) Vercel 함수 12개 한도 — 어떻게 통합해서 살아남는가
- (5편) Cron과 푸시 알림 — 자정에 미퇴근 직원 잡아내는 자동화
각 편의 상세 기술 노트는 자매 사이트 「주간 소식」의 개발일지 시리즈에도 올라갑니다 → https://weekly-postman.vercel.app/posts/dev-attendance-web-1-overview
다 읽어주셔서 감사합니다. 비슷한 고민하시는 자영업자 분 계시면 댓글로 어떤 부분이 궁금하신지 남겨주세요. 다음 글에 우선해서 다루겠습니다.
— 사장J · 자매 사이트 「주간 소식」 https://weekly-postman.vercel.app (일상·동네 관찰)
1. 무엇을 만들었나
직원이 매장 PC에서 출근/퇴근을 찍고, 관리자가 그 기록으로 월말에 급여명세서까지 뽑는 사내용 웹앱입니다.
직원 화면
- 로그인 → 🟢 출근 / 🔴 퇴근 버튼
- 본인 출퇴근 기록(표·캘린더) 조회
- 누락된 기록은 "수정 신청"으로 관리자에게 요청
- 본인 급여명세서 확인
관리자 화면
- 직원 관리, 전체 기록 CRUD
- 수정 신청 승인/반려
- 통계 (오늘 출근/퇴근, 이번 달 근무시간)
- 급여명세서 자동 발행 + Gmail 이메일 발송
- 모든 변경의 감사 로그
- 자정마다 "미퇴근" 직원 푸시 알림
2. 어떤 스택으로 만들었나
| 영역 | 선택 |
|---|---|
| 프론트 | Vanilla JavaScript (한 페이지짜리 SPA) |
| 백엔드 | Vercel Functions (서버리스, Node.js 24) |
| DB | Neon Postgres (서버리스) |
| 인증 | bcrypt + JWT + DB 세션 테이블 |
| 푸시 | Web Push API (관리자 알림) |
| 메일 | Gmail SMTP (급여명세서 발송) |
| 배포 | Vercel (수동 배포) |
프레임워크(React·Vue·Next 등)는 일부러 안 썼습니다. 화면이 한 장이라 라우터가 필요 없고, 빌드 단계 없이 정적 파일을 그대로 올리면 끝나는 구조가 디버깅이 빠르기 때문입니다.
3. 비용 — 1년간 진짜 0원이 가능한가
| 서비스 | 무료 한도 | 실제 사용량 | 비용 |
|---|---|---|---|
| Vercel Hobby | 함수 12개, 대역폭 100GB/월 | 함수 12/12, 대역폭 약 5GB/월 | 0원 |
| Neon Postgres | DB 0.5GB, 컴퓨트 191시간/월 | DB 약 50MB, 컴퓨트 약 30시간/월 | 0원 |
| Gmail SMTP | 일 500건 | 월 평균 30건 (급여명세서) | 0원 |
| 도메인 | (선택) | xxx.vercel.app 그대로 사용 |
0원 |
| 합계 | — | — | 1년 0원 |
단, Vercel 함수 12개 한도에 부딪힌 뒤로는 새 기능을 만들 때 기존 파일에 합치는 식으로 관리하고 있습니다. 예를 들어 로그인·로그아웃·회원가입·내 정보 조회는 전부 [action].js 파일 하나가 처리합니다.
처음에는 새 기능마다 함수 파일을 따로 만들었습니다. 한도가 있다는 걸 알고는 있었는데 "아직 여유 있겠지" 하다가 어느 순간 12 / 12로 막혀서, 그때부터 비슷한 동작끼리 통합하는 작업을 했습니다. 예를 들어 감사 로그 API는 따로 두지 않고 통계 API 안에 옵션으로 흡수했습니다.
4. 1년 운영하며 마주친 진짜 문제 3가지
(1) 출퇴근 시간이 9시간 늦게 저장되던 버그
Vercel Functions는 UTC 시간대로 동작하는데, 시간을 그대로 DB에 저장하면서 한국 시간(+9) 변환을 안 거치니, 오전 9시에 출근 찍은 기록이 DB에는 자정 0시로 들어가는 사고가 있었습니다.
해결: 서버에서 시간을 다룰 때 항상 KST 변환 헬퍼를 거치도록 통일했습니다.
발견한 계기는 한 직원이 "왜 어제 자정에 출근으로 떠요?" 라고 물어와서였습니다. 본인이 평소처럼 오전에 찍었는데 기록상으로는 자정에 출근한 걸로 떠 있었던 거죠. 같은 패턴의 기록이 다른 직원들 것에도 똑같이 있던 걸 확인하고 그제야 원인을 추적했습니다.
(2) 직원이 화면 켜둔 채로 자리 비우면 다음 직원이 그 계정으로 출근 찍힘
매장 PC 1대를 직원 여러 명이 돌려쓰는 구조라, 로그인한 채로 자리 비우면 그 다음 직원이 그대로 출근 버튼을 눌러버리는 사고가 종종 있었습니다.
해결: 5분 동안 마우스·키보드 입력이 없으면 자동 로그아웃. 이제는 자리 비웠다 와도 무조건 다시 로그인부터 해야 합니다.
(3) 직원이 집에서 출근 찍는 경우
매장 PC에서만 찍어야 의미가 있는데, 직원이 본인 휴대폰으로 출근을 찍는 사례가 생겼습니다.
해결: 모바일 User-Agent에서 직원 로그인을 서버가 거부(403). 관리자만 모바일 접속 가능하게 막아뒀습니다. 직원은 매장 PC에서만 찍힙니다.
5. 1년 만들어 굴리고 알게 된 것
- 시중 근태 서비스를 안 쓰고 1년 운영한 결과 이론상 절약 금액은 적게는 수십만 원입니다 (직원 수에 따라 차이 큼).
- 다만 직접 만든 시간 비용은 따로 — 초기 2~3주 + 운영 중 버그 픽스 시간이 적지 않게 들었습니다. 솔직히 이게 더 큽니다.
- 직원 10명 미만이라면 시중 서비스가 더 싸게 먹힙니다. 직접 만들기는 운영 규모가 일정 이상 + 매장 운영자가 코드 다룰 줄 알 때 의미가 있습니다.
- 무료 플랜의 한도(Vercel 함수 12개, Neon DB 0.5GB)는 자영업 규모에선 충분합니다. 대형 매장이라면 다른 얘기.
종합해서, 직접 만들길 잘했다는 쪽입니다. 시간 비용은 분명 있었지만 그건 한 번 들이고 나면 줄어드는 비용이고, 시중 서비스의 월 구독료는 줄지 않습니다. 매달 나가는 돈이 빠지지 않는다는 게 가장 큽니다.
다음 글 예고
이 시리즈는 계속 이어집니다.
- (2편) 인증과 세션 — bcrypt + JWT만으로는 "관리자가 직원을 즉시 강제 로그아웃" 못 시킵니다. 어떻게 해결했나
- (3편) 급여명세서 모듈 — 시급제·월급제·주휴수당 자동 계산식과 직원 통합(한 사람이 호점 여러 개 가질 때)
- (4편) Vercel 함수 12개 한도 — 어떻게 통합해서 살아남는가
- (5편) Cron과 푸시 알림 — 자정에 미퇴근 직원 잡아내는 자동화
각 편의 상세 기술 노트는 자매 사이트 「주간 소식」의 개발일지 시리즈에도 올라갑니다 → https://weekly-postman.vercel.app/posts/dev-attendance-web-1-overview
다 읽어주셔서 감사합니다. 비슷한 고민하시는 자영업자 분 계시면 댓글로 어떤 부분이 궁금하신지 남겨주세요. 다음 글에 우선해서 다루겠습니다.
— 사장J · 자매 사이트 「주간 소식」 https://weekly-postman.vercel.app (일상·동네 관찰)
'1인 개발 노트' 카테고리의 다른 글
| 카카오 API 처음 연동하다가 막힌 것들 (0) | 2026.06.08 |
|---|---|
| 직원이 퇴근을 안 찍고 갔어요 — 자정에 자동으로 잡아주게 만들기 (0) | 2026.06.04 |
| 서버 비용 0원으로 버티기 — 무료 한도 12칸 안에 기능 다 욱여넣기 (0) | 2026.06.02 |
| 시급·월급·주휴수당 섞인 직원 급여명세서, 직접 만들면서 알게 된 것 (3) | 2026.05.31 |
| 직원이 매장 PC를 돌려쓸 때 로그인은 어떻게 짜야 하나 — 1년 굴려보고 정한 인증 구조 (0) | 2026.05.29 |