Communitygithub.com

Island-Mode Server (온프레미스 Fallback 서버)

오프라인 상황에서도 현장 운영이 가능하도록, Firestore의 실시간 RxDB 복제본을 LAN에 구축하고 인터넷 복구 시 변경 사항을 클라우드로 안전하게 플러시하는 온프레미스 fallback 서버를 설계합니다.

Island-Mode Server (온프레미스 Fallback 서버)란 무엇인가요?

이 스킬은 인터넷 장애 시에도 키오스크/직원 PWA가 중단 없이 주문, 재고 이동, 하드웨어 제어를 계속할 수 있도록 하는 'Island-Mode Server'를 구축하는 방법을 제공합니다. 핵심 아이디어는 싱크를 두 시스템(문서 수준 RxDB 복제 + HTTP 플러시)으로 분리하는 것입니다. RxDB 복제는 상태를 실시간 동기화하고, HTTP 플러시는 재연결 시 비즈니스 이벤트(재고 증감, 감사 로그)를 멱등적으로 클라우드에 밀어 넣습니다. 이 설계는 Firestore를 단일 진실 공급원(SSoT)으로 유지하며, LAN failover, HMAC 하드웨어 인증, systemd/nginx 기반 온사이트 배포 전반을 다룹니다. 모든 컬렉션에 대해 pull-only, bidirectional, push-only 세 가지 복제 계층을 선택해야 하며, 오프라인 생성 문서 손실 방지와 멱등적 플러시 처리 등 중요한 트레이드오프와 하드 룰을 명확히 제시합니다. Claude Code, Cursor와 같은 AI 에이전트가 이 가이드를 따라 복잡한 온프레미스-클라우드 하이브리드 시스템을 단계적으로 구축할 수 있습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add timerise-ai/island-mode-server

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Island-Mode Server

현장에 작은 Node 서버를 배치하여 해당 사이트의 Firestore 데이터 조각에 대한 실시간 RxDB 복제본을 유지합니다. 인터넷이 연결되어 있는 동안에는 보이지 않다가, 인터넷이 끊기면 LAN에 있는 키오스크/직원 터미널이 이 서버로 failover되어 주문 접수, 재고 이동, 하드웨어 제어를 계속할 수 있습니다. 재연결 시 오프라인 작업이 클라우드로 플러시됩니다. 모든 설계를 관통하는 핵심 통찰은 동기화는 두 시스템으로 이루어진다는 것입니다. 즉, 상태를 위한 문서 수준 RxDB 복제와, 클라우드가 자체 로직(재고 증감, 감사 수집)으로 적용해야 하는 비즈니스 이벤트를 위한 HTTP 플러시가 따로 존재합니다. 둘 중 하나만으로는 충분하지 않습니다.

사용 시점

  • 사이트가 인터넷 장애 상황에서도 단순한 캐시 읽기가 아닌 실제 쓰기(예약, 재고, 하드웨어 제어)를 수행해야 할 때
  • 터미널이 브라우저 기반(PWA/키오스크)이고 투명하게 failover되어야 할 때
  • Firestore가 클라우드 진실 공급원이며 그 상태를 유지해야 할 때

사용하지 말아야 할 때

  • 순수 읽기 캐싱 또는 Firebase SDK의 내장 오프라인 지속성만으로 충분한 PWA — Firebase SDK가 이미 지원하므로 별도 서버 불필요
  • 다른 클라우드 데이터베이스(Supabase/Postgres) 사용 — 복제 계층 개념은 이식 가능하지만 여기 있는 모든 템플릿은 Firestore 전용
  • 피어 사이트 간의 다중 마스터 동기화 — 이 설계는 클라우드를 진실 공급원으로 하는 엄격한 허브-앤-스포크(hub-and-spoke) 방식이며, 마지막 쓰기 승리(last-write-wins) 충돌 해결을 사용

아키텍처

               인터넷
                  |
         +--------+---------+
         | 클라우드 (SSoT)  |  Firestore + 공개 API + cron 상태 마커
         +--------+---------+
              |           |
        RxDB 복제      HTTP 플러시 (재연결)
              |           |
         +----+-------------+
         | 로컬 서버        |  Node/NestJS + RxDB, LAN :443 via nginx TLS
         +--------+---------+
                  |
        LAN — 키오스크 PWA, 직원 PWA, 하드웨어 컨트롤러

중요 사실

  1. 복제된 컬렉션에 대한 모든 클라우드 쓰기에는 체크포인트 필드 (serverTimestamp: FieldValue.serverTimestamp())와 _deleted: false를 반드시 찍어야 합니다. RxDB Firestore 플러그인은 serverTimestamp > checkpoint 기준으로 데이터를 가져오므로, 스탬프가 찍히지 않은 문서는 복제되지 않습니다.
  2. 컬렉션별로 세 가지 복제 계층을 선택합니다: pull-only(해당 사이트가 소비하는 설정), bidirectional(사이트가 변경하는 운영 상태), push-only(사이트가 생성하는 로그). 컬렉션의 계층을 잘못 지정하는 것이 가장 큰 설계 오류입니다.
  3. 인메모리 RxDB 스토리지는 오프라인 재시작 시 모든 오프라인 작업을 잃습니다. 복제본은 Firestore에서 다시 채워지지만, 오프라인에서 생성된 문서는 사라집니다. 저장소 트레이드오프를 명시적으로 결정하세요. 자세한 내용은 replication.md를 참조하세요.
  4. 플러시는 최소 한 번(at-least-once) 전달이므로 클라우드 수집은 멱등적이어야 합니다. 모든 적용은 클라이언트 생성 ID를 키로 사용하고 이미 적용된 것은 건너뜁니다.
  5. Push 필터가 에코를 방지합니다. 양방향 푸시는 _offlineCreated / _locallyModified 플래그가 있는 문서만 전송하므로, 클라우드에서 가져온 문서가 다시 되돌아오지 않습니다.
  6. 터미널은 클라우드를 우선시합니다. N번 연속 헬스 체크 실패 후에만 failover가 활성화되며, 오프라인 상태에서도 한 번만 전환하는 것이 아니라 지속적으로 로컬 서버를 재스캔해야 합니다.

하드 룰

클라우드 동기화 수집 엔드포인트를 인증 없이 노출하지 마십시오. 재고 증감을 적용하고 주문을 주입합니다. 공유 시크릿 헤더는 최소 요구 사항입니다.

온라인 상태에서 오프라인 직원 토큰을 관대하게 검증하지 마십시오. 서명 없는 디코딩 폴백은 LAN 내에서만 허용되는 트레이드오프입니다. 서버가 실제로 오프라인일 때만 활성화되어야 하며, 그렇지 않으면 서명 검증을 우회하는 통로가 됩니다.

동기화가 확인되지 않은 트랜잭션에 대한 로컬 재고 델타를 절대 초기화하지 마십시오. ID별 승인 시에만 초기화하십시오. 그렇지 않으면 오프라인 판매가 이중 계산되거나 가용성에서 사라집니다.

로컬 서버가 클라우드가 관리하는 비즈니스 규칙(영업 시간, 가격)을 자체적으로 만드는 것을 절대 허용하지 마십시오. 설정을 복제하고 그로부터 계산을 수행하십시오. 그렇지 않으면 섬 모드 동작이 웹사이트와 달라집니다.

빠른 시작

  1. 컬렉션을 계층별로 모델링하고 경계 이름을 지정하십시오. — architecture.md
  2. 사용자 정의 토큰 인증 및 보안 규칙을 사용하여 RxDB + 복제를 구축하십시오. — replication.md
  3. 재연결 플러시 및 멱등적 클라우드 수집을 추가하십시오. — sync-flush.md
  4. 하트비트/상태 체인 및 클라이언트 failover를 연결하십시오. — network-failover.md
  5. 로컬 API(직원 / 키오스크 / 하드웨어 HMAC / 정적 토큰)를 보호하십시오. — auth.md
  6. 터미널이 필요로 하는 클라우드 엔드포인트를 미러링하십시오. — local-api.md
  7. 온사이트 배포: systemd, nginx TLS, mDNS, 모니터링 — operations.md

참조 디렉토리

시나리오트리거 키워드참조
토폴로지, 계층, 경계, 이름 변경 테이블pull-only, bidirectional, push-only, dual-path, locationId, conflictarchitecture.md
복제본 설정, 스키마, 체크포인트 트랩RxDB, replicateFirestore, serverTimestamp, custom token, storage-memory, firestore.rulesreplication.md
재연결 플러시, 재고 델타, 수집flushAll, idempotent, FieldValue.increment, localDelta, syncedIdssync-flush.md
장애 감지 및 API 전환heartbeat, lastHeartbeatAt, cron, NetworkManager, apiBaseUrl, failovernetwork-failover.md
로컬 API 인증AuthGuard, HMAC, replay window, offline JWT fallback, kiosk keyauth.md
오프라인 엔드포인트 및 쓰기availability, mutex, offline booking, check-in, pricing stock filterlocal-api.md
온사이트 배포 및 런북systemd, nginx, self-signed TLS, mDNS, avahi, journalctl, rollbackoperations.md
변경 사항 원장: 감사에서 무엇을 변경, 유지, 추가했는지provenance, audit, deviations, kept deliberatelyprovenance.md

신뢰에 중요한 로직(HMAC 검증, 오프라인 토큰 디코딩, 실제 RxDB에서의 덜타 폴드아웃, failover 재스캔)에 대한 vitest 스위트 통과 결과: assets/behavior.test.ts — 대상 프로젝트에 회귀 테스트로 포함시키십시오.

관련 스킬