내부를 들여다 볼 수 있게.
디바이스에서 사용자 화면까지, CellOps의 데이터가 어떻게 흐르고 어떤 기술이 동작하는지 그대로 보여드립니다. 영업자료의 그림이 아니라 실제 배포된 구조입니다.
배터리 셀에서 운영자 알림까지 — 전체 경로
데이터의 한살이
- 01
수집 (Edge)
BMS 펌웨어가 5초마다 팩 상태, 60초마다 셀 단위 데이터를 batch로 POST 합니다.
- 02
인증
Authorization: Bearer <token> 헤더로 디바이스 식별. 토큰은 회전 가능, 회전 즉시 이전 토큰 무효화.
- 03
검증 + 저장
Zod 스키마로 모양 검증 후 TimescaleDB 하이퍼테이블에 INSERT. 미지의 팩 라벨은 조용히 스킵.
- 04
룰 평가
같은 요청 흐름 안에서 SOC·온도·셀 편차 임계 평가. OPEN 알람 중복 차단 + 정상 복귀 시 자동 RESOLVED.
- 05
알림
신규 알람은 텔레그램 봇으로 즉시 발송. 운영자 + 해당 고객사만 받습니다 (그룹 채팅 가능).
- 06
표시 / 자동 갱신
대시보드 15초, 디바이스 상세 10초 주기 server component re-fetch — 화면이 살아 움직입니다.
각 박스가 실제로 무슨 일을 하는가
구성요소
Edge · BMS 펌웨어
디바이스가 직접 클라우드로 push. 게이트웨이·MQTT 브로커 없이 단순화. 시연 단계에서는 cellops-sim PM2 워커가 8대를 흉내.
Ingest API
단일/배치 양쪽 지원. 알 수 없는 팩 라벨은 조용히 무시 → 펌웨어 마이그레이션 도중에도 안전.
Database
TelemetryPack/Cell은 하이퍼테이블. 1분·1시간 집계는 백그라운드로 자동 계산. 알람·사용자·사이트 등 메타는 일반 테이블.
Alarm Engine
low_soc · high_temp · cell_imbalance · offline 4종. 정상 복귀 시 자동 RESOLVED, 같은 종류는 1건만 OPEN.
Notification
DuckDNS NS 불안정 대응으로 폴링 백업 항상 가동. 운영자 + 해당 사이트 소유 고객만 수신.
Frontend
대부분 server component. AutoRefresh 컴포넌트가 router.refresh()를 주기 호출 → 데이터 살아 움직임.
Auth · Session
ADMIN / CUSTOMER 두 역할. 모든 admin API 호출에 역할 게이트. 토큰 회전·자동 정상화 가능.
Worker
텔레메트리가 안 오면 알람을 못 만드니까 별도 워커가 디바이스를 sweep. 텔레그램 폴링도 같은 프로세스에서 처리.
Infrastructure
DNS-01 챌린지로 SSL 발급 (DuckDNS NS 불안정 우회). 트래픽은 HTTPS 강제, internal 5435 PG는 127.0.0.1 바인딩.
배터리가 임계값을 넘긴 순간, 1초 안에 무슨 일이 일어나는가
요청 1건의 일생
전체 평균 지연 < 1초. 통신·네트워크 변동 포함 95-percentile 약 2–3초.
자산 계층 + 시계열 분리
데이터 모델
Site
고객사 소유의 운영 현장. ownerId가 CUSTOMER user를 가리킴.
Device
사이트에 설치된 게이트웨이. authToken으로 인증. 1개 디바이스 = 1개 BMS.
Pack
디바이스가 관리하는 배터리 팩. cellCount·nominalKwh 보유.
TelemetryPack
팩 단위 시계열. 5초 간격. 하이퍼테이블, 7일 보존.
TelemetryCell
셀별 vector(float[]). 1분 간격. 하이퍼테이블, 30일 보존.
AlarmEvent
OPEN/ACKNOWLEDGED/RESOLVED 라이프사이클. 무한 보존.
PolicyConfig
singleton row. 알람 임계값·텔레그램 on/off. 어드민에서 즉시 튜닝.
NotificationLog
텔레그램 전송 결과. 실패도 기록 → 사고 후 원인 추적.
TimescaleDB 연속 집계로 raw·집계가 자동 계단형 보존
데이터 보존
7일
5초 간격 원본
30일
1분 간격 셀 벡터
1년
자동 continuous agg
영구
자동 continuous agg
원본은 시간이 지나면 chunk 단위로 자동 삭제됩니다. 집계 테이블은 그대로 남아 장기 트렌드·연도별 비교에 사용됩니다.
버전까지 그대로
기술 스택
Runtime · 백엔드
- Node.js20 LTS
- Next.js16.2 (App Router)
- React19
- TypeScript5
- Prisma6
- Zod4
Database
- PostgreSQL17
- TimescaleDBlatest
- HypertablesTelemetryPack/Cell
- Continuous aggs1m · 1h
Frontend · UI
- Tailwind CSSv4
- Radix UIDialog/Tooltip 등
- recharts3
- lucide-reacticons
- PWAmanifest + sw.js
Auth · 보안
- bcryptjspassword hash
- joseJWT HS256
- HttpOnly cookieco_session
- 역할 게이트ADMIN/CUSTOMER
- HTTPSTLS 1.2/1.3
알림
- Telegram Bot APIsendMessage
- webhook기본
- polling fallbackDuckDNS NS 대비
- NotificationLog발송 로그
Infrastructure
- Ubuntu22.04
- DockerPG + TimescaleDB
- PM2web/worker/sim
- Nginxreverse proxy + HSTS
- Let's EncryptDNS-01 (DuckDNS)