전시장 화이트보드에 자석을 붙여 관리하던 차량 위치를, 여러 명이 동시에 쓰는 실시간 보드로 옮긴 웹앱.
데모 프로젝트입니다. 전시장을 대상으로 만들어 시연했고, 실제 운영에는 채택되지 않았습니다. 실고객 데이터는 들어 있지 않으며, 관리자 비밀번호도 데모용(
0123)으로 공개해 뒀습니다.
🔗 라이브 데모
BMW 전시장에서 영업을 할 때, 차량 위치는 사무실 화이트보드로 관리했다. 구역을 그려놓고 차량마다 자석을 붙이는 방식이다.
문제는 그 보드가 사무실에만 있다는 것이었다. 전시장 반대편에서 고객과 상담하다 "그 차 지금 어디 있죠?"를 들으면 데스크까지 걸어가야 했다.
그래서 화이트보드를 그대로 화면에 옮기되, 모든 직원 기기에서 실시간으로 같은 화면을 보게 만들었다.
현장 도구에서 로그인은 진입 장벽이다. 상담 중에 비밀번호를 치게 만들면 안 쓴다.
그래서 권한을 세 단계로 나눴다.
일반 접속 전체 현황 조회 (인증 없음)
🔓 이동 모드 마커 드래그 가능 (버튼 토글, 비번 없음)
👑 관리자 모드 차량 추가·삭제, 구역 편집 (비번)
"실수로 건드리는 것"과 "권한이 필요한 것"을 분리한 구조다. 위치 이동은 누구나 하되 토글을 한 번 거치게 했고, 데이터를 만들고 지우는 것만 잠갔다.
여러 명이 동시에 드래그하는 화면이라 폴링이 아니라 푸시가 필요했다.
onValue 구독으로 한 명이 마커를 옮기면 다른 기기 화면이 즉시 바뀐다.
무료 플랜으로 충분한 규모였고, 서버를 따로 둘 이유가 없었다.
빌드 단계 없이 파일 하나만 올리면 배포가 끝나게 했다. 전시장에 IT 담당자가 따로 없어서, 내가 없어도 유지되는 형태여야 했다.
main에 push하면 GitHub Actions가 HuggingFace Space로 밀어 올린다.
git push → .github/workflows/sync.yml → huggingface_hub API → Space 갱신
마커 — 차종·색상·차량번호·담당자를 4줄로 표시. 신차/시승차를 색으로 구분하고 구역 안에서 정렬 규칙을 따른다. 외장 24종·내장 33종 색상 코드는 어프로치북에서 추출해 정제했다.
구역 — 기본 9개. 관리자 모드에서 드래그로 순서를 바꾸면 order 값이 교체 저장된다. 꼬였을 때를 대비해 "기본 구역 복구"를 넣었다 — 마커 데이터는 유지하고 구역만 재생성한다.
겪은 버그 3개 (상세는 프로젝트 문서 §10)
| 증상 | 원인 | 해결 |
|---|---|---|
| 구역이 아예 안 뜸 | el.closest('.zone') 호출 시점에 DOM 미연결 → null 에러로 렌더 전체 중단 |
요소를 인자로 직접 전달 |
| 드롭이 구역 상단에서만 됨 | dragover가 zone-body에만 걸려 있었음 |
zone 전체에 등록 + relatedTarget 기반 dragleave 처리 |
| 프라자 슬롯 미표시 | 기존 Firebase 데이터에 신규 필드 없음 | 이름 기준 조건 분기로 하위 호환 |
관리자 비밀번호가 index.html에 하드코딩돼 있다.
정적 단일 파일 앱에서 클라이언트 비밀번호는 보안이 아니다. 개발자 도구만 열면 보인다.
데모라 의도적으로 그대로 뒀고, 실제 운영에 올린다면 이렇게 간다.
- Firebase Auth로 인증을 옮기고, 관리 동작은 인증된 사용자만
- Realtime Database 보안 규칙으로 읽기/쓰기를 서버 단에서 제한 (현재는 클라이언트가 곧 권한)
- 차량 이동 이력 로그 (누가 언제 어디서 어디로)
같은 문제를 실제로 푼 사례는 SCPAD에 있다. 거기서는 Supabase RLS로 사용자별 데이터를 DB 레벨에서 격리했다.
시연까지 했지만 채택되지 않았다. 기능이 부족해서가 아니라, 자석을 붙이던 습관을 바꿀 이유가 충분하지 않아서였다. 화이트보드는 이미 거기 있고, 새 도구는 폰을 꺼내야 한다.
이 경험이 이후 SCPAD를 만들 때 기준이 됐다. "좋은 기능"보다 "기존 방식보다 확실히 편한가" 를 먼저 물었고, 직접 시연하며 쓰게 만드는 과정이 개발만큼 중요하다는 걸 여기서 배웠다.
| 항목 | 선택 |
|---|---|
| 프론트엔드 | HTML/CSS/JS 단일 파일 |
| 실시간 DB | Firebase Realtime Database (asia-southeast1) |
| 배포 | GitHub Actions → HuggingFace Spaces |
| 폰트 | Bebas Neue + Noto Sans KR |
전체 설계·데이터 구조·작업 플로우는 BMW_GB_보드_프로젝트문서.md 참고.
전시장 차량 위치 보드을 포함한 전체 케이스 5건은 포트폴리오에 정리돼 있습니다 — chein206.github.io