Canteen POS
캔틴 주문 시스템
개요
- 캔틴 고객용 셀프 주문 키오스크로, 태블릿이 PIN으로 잠금 해제되면 풀스크린 PWA로 전환되어 상품 그리드와 사이드바 장바구니를 통해 주문을 진행
- 결제 완료 시 주방 영수증과 텀블러 라벨을 USB 프린터로 직접 출력하며, 운영 상태 및 원격 제어 이벤트는 실시간으로 반영
주요 기능
- PIN 잠금 및 세션 유지 6자리 PIN 검증 후 HMAC-SHA256 서명 쿠키(pos_session) 발급, 장기간 세션 유지로 재로그인 최소화
- 상품 그리드 및 장바구니 카테고리 탭 기반 상품 탐색, 인기·랜덤 추천·재고·품절 상태 라벨 표시, 옵션 선택 및 사이드바 장바구니 구성
- 실시간 동기화 Durable Object CanteenHub 기반 WebSocket으로 재고, 품절, 대기열, 운영 상태, 원격 제어를 즉시 반영, 자동 재연결 지원
- WebUSB 영수증 및 라벨 출력 ESC/POS 명령을 USB 프린터로 직접 전송, 컬럼 자동 감지 및 chunk 전송, 연결 상태 즉시 감지
- 자동 인쇄 설정 캔틴 설정의 autoPrint 값에 따라 결제 완료 시 자동 출력 처리
- 이벤트 모드 마퀴바 트리거로 이벤트 모드 전환, 전용 UI 및 스크린세이버 구성, 새로고침 후 상태 유지
- 스크린세이버 및 무인 복귀 일정 시간 비활동 시 자동 전환, 첫 터치 시 풀스크린 및 사운드 언락
- 마퀴 바 운영 정보 공지, 날씨, 트렌딩 메뉴, 관리자 메시지를 통합하여 순환 출력, 한국어 자연어 문장 처리 포함
- 비운영 및 원격 제어 오버레이 운영 종료 및 원격 제어 상태를 WebSocket 이벤트로 즉시 표시
- R2 이미지 프록시 /file/* 경로를 통해 R2 리소스를 동일 오리진으로 서빙하여 CORS 및 인증 단순화
- PWA 풀스크린 홈 화면 설치 시 네이티브 앱처럼 동작하는 풀스크린 모드 지원
기술 스택
- TypeScript 기반 Cloudflare Worker가 PIN 페이지, 주문 UI, API, 디스플레이, R2 프록시를 단일 호스트에서 라우팅
- 데이터는 D1, 실시간 채널은 Durable Object CanteenHub 기반 WebSocket 샤딩 구조로 처리
- 이미지는 R2에 저장되며, 프론트는 서버 렌더 HTML 위 Vanilla JS와 인라인 CSS로 구성
- 프린터 연동은 WebUSB API를 통해 ESC/POS 명령을 직접 전송하며, 풀스크린 및 입력 제어는 Web Platform API로 처리
설계 노트
- PIN 세션을 R2 다운로드 토큰 구조와 통합하여 인증 로직 단일화
- Durable Object 샤딩으로 단일 hub 부하 집중을 방지하고 키 기반 분산 처리
- R2 프록시 구조로 외부 이미지 호출을 내부 origin으로 통합하여 CORS 제거
- iOS 자동재생 정책 대응을 위해 첫 터치 시 풀스크린 및 오디오 언락 동시 처리
- 이벤트 모드는 sessionStorage 기반 상태 복원으로 새로고침 시 깜빡임 방지
- WebUSB 출력은 chunk 단위 전송으로 프린터 hang 및 timeout 이슈 방지
- WebSocket은 30초 keepalive로 연결 안정성 유지
- dvh 기반 레이아웃으로 모든 모바일 환경에서 풀스크린 UI 안정성 확보