Skip to content

kangwooc/measurement-api

Repository files navigation

Measurement API

NestJS 기반의 IoT 디바이스 및 온도 측정 로그 관리 API

프로젝트 개요

이 프로젝트는 IoT 온도 측정 디바이스를 관리하고 온도 로그 데이터를 수집, 저장, 분석하는 백엔드 API입니다. Clean Architecture와 Domain-Driven Design 원칙을 따르며, 엔터프라이즈급 애플리케이션 구조를 갖추고 있습니다.

주요 기능

1. 디바이스 그룹 관리

  • 디바이스 그룹 등록 (시리얼 번호 기반)
  • 디바이스 그룹 목록 조회
  • 디바이스 그룹별 통계 (평균, 최소, 최대 온도, MKT)

2. 디바이스 관리

  • 디바이스 등록 (그룹별 연결)
  • 디바이스 조회
  • 디바이스별 온도 통계

3. 온도 로그 관리

  • 온도 데이터 기록 (16진수 형식 지원)
  • 디바이스별 온도 로그 조회
  • Mean Kinetic Temperature (MKT) 계산

4. 동시성 제어

  • SELECT FOR UPDATE를 이용한 row-level locking
  • 동시 등록 방지 메커니즘
  • 트랜잭션 기반 데이터 무결성 보장

기술 스택

Backend Framework

  • NestJS v11 - Progressive Node.js framework
  • TypeScript - Type-safe development

Database

  • PostgreSQL - Production database
  • Sequelize ORM - Database abstraction layer
  • sequelize-typescript - TypeScript decorators for Sequelize

Validation & Configuration

  • class-validator - DTO validation
  • class-transformer - Object transformation
  • Joi - Configuration validation

Testing

  • Jest - Unit & E2E testing framework
  • Supertest - HTTP assertion library
  • SQLite - In-memory database for tests

Additional Tools

  • Winston - Logging
  • Swagger - API documentation
  • Terminus - Health checks

아키텍처

레이어드 아키텍처

프로젝트는 엄격한 레이어 분리와 의존성 역전 원칙을 따릅니다:

src/
├── {feature}/
│   ├── presentation/       # Controllers, DTOs (API Layer)
│   ├── application/        # Services, Use Cases (Business Logic)
│   ├── domain/             # Domain Models, Interfaces
│   └── infra/              # Repository Implementations, Entities
├── common/                 # Shared utilities, exceptions, config
└── database/               # Database configuration

의존성 흐름

presentation → application → domain ← infra
  • Domain Layer: 비즈니스 로직의 핵심, 다른 레이어에 의존하지 않음
  • Infrastructure Layer: Domain 인터페이스를 구현
  • Application Layer: Use case 조율 및 비즈니스 로직 실행
  • Presentation Layer: HTTP 요청/응답 처리

설치 및 실행

환경 설정

.env 파일을 프로젝트 루트에 생성:

# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=your_username
DB_PASS=your_password
DB_NAME=measurement_db

# Application
NODE_ENV=development
PORT=3000

설치

npm install

실행

# 개발 모드
npm run start:dev

# 프로덕션 빌드
npm run build
npm run start:prod

# 디버그 모드
npm run start:debug

API 엔드포인트

Device Group

POST /device-groups

디바이스 그룹 등록

{
  "deviceGroupSerial": "GROUP-001"
}

GET /device-groups

전체 디바이스 그룹 목록 조회

GET /device-groups/statistics?groupSerial={serialNumber}&start={startDate}&end={endDate}

디바이스 그룹 통계 조회

  • Query Parameters:
    • groupSerial: 그룹 시리얼 번호
    • start: 시작 날짜 (YYYY-MM-DD)
    • end: 종료 날짜 (YYYY-MM-DD)

Device

POST /devices

디바이스 등록

{
  "serialNumber": "DEVICE-001",
  "deviceGroupSerial": "GROUP-001"
}

GET /devices?groupSerial={serialNumber}

디바이스 목록 조회 (그룹별 필터링 가능)

GET /devices/statistics?serialNumber={deviceSerial}&start={startDate}&end={endDate}

디바이스별 온도 통계 조회

Temperature Log

POST /temperature-logs

온도 데이터 기록

{
  "serialNumber": "DEVICE-001",
  "interval": 60,
  "temperatures": "00FA00FB00FC",
  "registered_at": "2024-01-01T12:00:00Z"
}

GET /temperature-logs?serialNumber={deviceSerial}

디바이스별 온도 로그 조회

테스트

Unit Tests

# 전체 테스트 실행
npm run test

# Watch 모드
npm run test:watch

# 커버리지 확인
npm run test:cov

E2E Tests

npm run test:e2e

테스트 구조

test/
├── {feature}/
│   ├── presentation/       # Controller tests
│   ├── application/        # Service tests
│   └── infra/              # Repository tests
├── config/                 # Test configuration
└── concurrency/            # Concurrency tests

중요:

  • Unit/E2E 테스트는 SQLite in-memory 데이터베이스 사용
  • Concurrency 테스트는 PostgreSQL 필요 (SQLite의 트랜잭션 제한으로 인해)

데이터베이스

Schema

device_groups

  • id (PK, AUTO_INCREMENT)
  • serial_number (UNIQUE)
  • created_at

devices

  • id (PK, AUTO_INCREMENT)
  • serial_number (UNIQUE)
  • device_group_id (FK → device_groups.id)
  • created_at

temperature_logs

  • id (PK, AUTO_INCREMENT)
  • device_id (FK → devices.id)
  • temperature (DECIMAL)
  • recorded_at
  • created_at

동시성 제어

Production 환경(PostgreSQL)에서는 SELECT ... FOR UPDATE를 사용하여 동시 등록을 방지합니다:

// DeviceGroup 등록 시
await this.repository.findBySerial(serial, {
  lock: true,
  transaction
});

이를 통해:

  • Race condition 방지
  • 중복 등록 차단
  • 데이터 무결성 보장

코드 품질

Linting

npm run lint

Formatting

npm run format

주요 구현 사항

Mean Kinetic Temperature (MKT) 계산

온도 데이터의 평균 동역학 온도를 계산하여 제공합니다.

공식:

MKT = (ΔH/R) / ln(Σ(e^(ΔH/RTi))/n) - 273.15
  • ΔH (Activation Energy): 83,144 J/mol
  • R (Gas Constant): 8.314 J/(mol·K)

16진수 온도 데이터 파싱

16진수 형식의 온도 데이터를 signed 16-bit integer로 변환하여 처리합니다.

예시:

"00FA00FB00FC" → [25.0, 25.1, 25.2]°C

트랜잭션 관리

모든 쓰기 작업은 트랜잭션 내에서 실행되어 ACID 속성을 보장합니다.

License

UNLICENSED

About

NestJs 기반 온도 데이터 처리 API

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors