- 프론트엔드: https://main.dypmcbje2h6zn.amplifyapp.com/
- 백엔드 API 문서 (Swagger): https://alon-iot.duckdns.org/docs
본 과제는 Claude Code (Opus 4.6 모델) 를 활용하여 개발했습니다. 각 디렉토리별로 작업을 시작하기 전에 plan.md를 먼저 작성하여 설계 방향과 구현 범위를 정리한 뒤, 계획에 따라 구현을 진행했습니다.
backend/plan.md— 백엔드 설계 계획frontend/plan.md— 프론트엔드 설계 계획sensor/plan.md— 가상 센서 시뮬레이터 설계 계획
백엔드 (FastAPI) — backend/README.md
백엔드는 제 주 전문 분야로, 코드 한 줄 한 줄 디테일하게 리뷰하며 작성했습니다. 아직 서비스의 규모나 트래픽 요구사항을 알 수 없는 상태이므로, 과도한 추상화나 오버엔지니어링을 지양하고 최대한 컴팩트한 구조를 유지하는 데 집중했습니다. 디자인 패턴은 FastAPI 공식 boilerplate의 레이어 구조(routes → crud → models/schemas)를 따랐으며, 서비스 규모가 커질 경우 자연스럽게 확장할 수 있는 기반을 갖추었습니다.
프론트엔드 (React) — frontend/README.md
프론트엔드는 전문 분야는 아니지만, UI/UX를 최대한 고려하여 개발했습니다. 다크/라이트 테마, 반응형 레이아웃, 타임존 선택 등 사용자 경험 측면에서 빠지지 않도록 신경 썼습니다. 프론트엔드 개발은 바이브 코딩(Vibe Coding) 방식으로 진행했습니다 — AI 코드 어시스턴트를 적극 활용하여 빠르게 프로토타이핑하고, 결과물을 직접 확인하며 방향을 잡아가는 방식입니다.
가상 센서 시뮬레이터 — sensor/README.md
과제 요구사항에는 포함되지 않지만, 실제로 시스템이 동작하는 모습을 보여주기 위해 가상 센서 서버를 별도로 구현했습니다. Docker Compose로 백엔드와 함께 띄우면 센서 등록 → 데이터 전송 → 상태 변경이 자동으로 이루어지므로, 별도의 테스트 스크립트 없이도 전체 흐름을 확인할 수 있습니다.
센서가 데이터를 전송할 때 단일 전송과 벌크(배열) 전송 두 가지 방식을 지원합니다.
- 단일 전송: 센서가 측정 주기마다 1건의 데이터를 즉시 전송
- 벌크 전송: 센서가 여러 건의 데이터를 모아서 배열로 한 번에 전송
벌크 전송은 "여러 센서를 묶어서 보내는 것"이 아니라, 한 센서가 여러 건의 측정 데이터를 모아서 보내는 것입니다. 예를 들어 NORMAL 모드(10분 주기)에서 매번 1건을 보내는 대신, 1분 간격으로 10건을 측정해서 10분마다 배열로 한 번에 보내는 방식입니다.
이렇게 설계한 이유:
- 실제 IoT 환경에서는 네트워크 비용을 줄이기 위해 데이터를 모아서 전송하는 것이 일반적
- 백엔드 입장에서는 단일이든 배열이든 동일한
POST /api/v1/sensor-data엔드포인트로 수신하므로, 전송 방식에 상관없이 처리 가능 - 센서를 "그룹으로 묶어서 벌크 전송"하는 방식은 실제 환경에서 불필요한 결합도를 만들기 때문에 채택하지 않음
센서 시뮬레이터에서는 BULK_COUNT 환경 변수로 벌크 전송 건수를 설정할 수 있습니다 (기본값: 10).
과제 명세에 명시되지 않았으나, 실제 운영 환경을 고려하여 추가한 기능들입니다.
배치(배열) 데이터를 수신하면 즉시 task_id를 반환(202 Accepted)하고, 실제 저장은 백그라운드에서 비동기 처리합니다. 대량 데이터 수신 시 클라이언트가 응답을 기다리지 않아도 되고, GET /api/v1/tasks/{task_id}로 처리 진행 상태를 추적할 수 있습니다.
과제에서 "데이터 누락 여부를 판단하라"는 요구사항이 있지만, 방법은 지정되어 있지 않습니다. API 호출 시점에만 상태를 계산하면, 아무도 조회하지 않는 동안 고장 센서를 놓칠 수 있습니다. 이를 방지하기 위해 APScheduler로 5초 간격 백그라운드 검사를 추가하고, API 조회 시에도 on-demand로 상태를 재계산하는 이중 안전장치를 적용했습니다.
센서의 broken 플래그를 토글하면 해당 센서의 데이터 전송이 중단됩니다. 프론트엔드 → 백엔드(DB 저장) → 센서 시뮬레이터 순서로 동기화되며, 백엔드의 MISSING 상태 판별 로직을 실제로 테스트할 수 있습니다.
과제에서는 "사용자의 브라우저 환경에 맞춰 일관된 시간대로 출력"을 요구합니다. 브라우저 로컬 타임존만 사용하면 리뷰어의 환경에 따라 결과가 달라지므로, KST(기본), JST, ET, GMT, UTC 중 선택할 수 있는 타임존 셀렉터를 추가했습니다.
모니터링 대시보드는 장시간 사용하는 경우가 많으므로, 사용자 환경에 맞는 테마 전환을 지원합니다. 시스템 설정 감지 + localStorage 저장으로 재방문 시에도 유지됩니다.
docker compose up --build 한 번으로 백엔드 + 프론트엔드 + 센서 시뮬레이터가 모두 구동됩니다. 백엔드 healthcheck를 통해 센서 시뮬레이터가 백엔드 준비 완료 후 시작되도록 구성했습니다.