홈으로 돌아가기

Next.js와 Flutter를 위한 통합 계산 엔진

저자가 Next.js 웹사이트와 Flutter 모바일 앱 간 계산 로직을 동기화한 방법에 대한 기사. JSON specs를 단일 진실 원천으로 사용한 접근법, 코드 생성, parity tests를 통해 동일한 결과 보장 설명.

하나의 JSON 파일이 두 런타임을 불일치로부터 구한 이야기
Advertisement 728x90

Next.js와 Flutter를 위한 통합 계산 엔진: 숫자 불일치 피하기

동일한 건설 계산기가 Flutter 모바일 앱과 Next.js 웹사이트로 모두 존재할 때, 공식의 사소한 차이조차 사용자 신뢰를 흔들 수 있습니다. 실제 사례에서 보듯: 앱과 사이트가 울타리 기둥에 대한 콘크리트 양을 다르게 출력하면, 이는 단순한 버그가 아니라—중복 로직의 체계적 문제입니다. 해결책은 선언적 JSON 사양과 패리티 테스트를 기반으로 한 단일 진실 원천입니다.

두 개의 독립 코드베이스 문제

처음에 계산 로직은 두 번 구현되었습니다: Flutter 앱용 Dart와 Next.js 사이트용 TypeScript로요. 두 프로젝트는 병렬로 진화했지만 독립적이었습니다. 계수, 기본값(예: 기둥 구멍 지름), 반올림 규칙, 자재 포장 방식이 각 런타임 코드에 별도로 존재했습니다. 결과: 동일 입력에 대한 출력 불일치.

이 아키텍처는 DRY(중복하지 말라) 원칙을 위반하며, 결국 사용자 불만으로 기술 부채가 드러납니다. 특히 계산 정확도가 제품 신뢰에 직결되는 틈새 도구에서 치명적입니다.

Google AdInline article slot

선언적 접근: JSON을 진실 원천으로

비즈니스 로직 중복 대신 모든 변수 매개변수를 구조화된 JSON 파일로 이동했습니다—계산기당 하나씩. 각 사양에는 다음이 포함됩니다:

  • 입력 필드 기본값(예: 말뚝 지름—150 mm)
  • 반올림 규칙(항상 올림)
  • 정확도 모드에 따른 손실 계수
  • 자재 포장 정보(25 kg 봉지, 봉지당 0.01 m³ 수율)
  • 최소 층 두께와 체결부 간격

이 JSON 파일들이 단일 진실 원천이 되었습니다. 이제 매개변수 변경은 JSON에서 한 번만 하고, 두 런타임에 자동 적용됩니다.

동기화를 위한 코드 생성

두 프로젝트가 동일 데이터를 사용하도록 코드 생성 프로세스를 도입했습니다:

Google AdInline article slot
  • JSON 사양 변경 시 npm run sync:specs 스크립트 실행
  • 스크립트가 모든 사양 읽고 상수 맵(const Map)으로 Dart 파일 생성
  • 생성된 파일을 Flutter 앱 저장소에 커밋
  • 두 시스템의 CI/CD가 변경 확인 후 업데이트 버전 배포

생성 파일은 @generated로 표시되며, 린터가 수동 편집 차단합니다. 이는 인간 오류를 없애고 데이터 일관성을 보장합니다.

패리티 테스트: 로직 불일치 방지

동일 데이터라도 언어 차이로 동작 차이가 발생할 수 있습니다: TypeScript의 Math.ceil()과 Dart의 num.ceil()이 경계 케이스에서 다를 수 있죠. 이를 막기 위해 패리티 테스트 시스템을 구현했습니다:

  • 고정 데이터 세트—61개 계산기 각각에 수십 개 입력 조합
  • TypeScript 엔진이 모든 고정 데이터 실행 후 참조 파일에 결과 저장
  • 동일 파일을 Flutter 저장소에서 Dart 엔진 결과와 비교
  • 불일치—마지막 소수점 자리라도—CI 실패

6개월간 이 테스트가 자동 검사 없이는 놓쳤을 세 가지 실제 불일치를 잡아냈습니다.

Google AdInline article slot

"+10% 더하기" 대신 세 가지 정확도 모드

전통 계산기는 보통 보편적 안전 계수(예: +10%)를 씁니다. 이 지름길은 부정확성을 초래하죠: 타일은 절단 여유, 석고는 바닥 불균일 보상, 접착제는 표면 흡수 고려가 필요합니다.

대신 세 가지 계산 모드를 구현했습니다:

  • Basic—여유 없는 표준 기반 계산, GOST/SP 준수
  • Realistic(기본)—일반 아파트 리모델링 조건 반영
  • Professional—복잡 프로젝트와 부족 보장에 최대 여유

각 모드 계수는 JSON 사양에 저장되어 앱 재빌드 없이 변경 가능합니다.

핵심 규칙: 동일 입력에서 결과가 Basic ≤ Realistic ≤ Professional을 만족해야 합니다. 전용 CI 테스트가 모든 계산기 확인합니다.

검증기를 두 번째 방어선으로

단위 테스트와 패리티 검사 외에 CI가 세 가지 전문 검증기를 실행합니다:

  • 논리 검증기: 구매 수량 ≥ 순수량 확인, 유효 입력에서 결과 0 방지, 라벨에 적절한 미터법 단위 사용(“m²”, “sq m” 아님)
  • 포장 검증기: 현실적 자재 포장 확인(접착제 5/10/15 L 버킷, 타일 팩 단위, 개별 아님)
  • 단위 검증기: 미터법 혼동 포착(예: 변환 없이 mm를 m에 더함)

이 스크립트들은 시스템 관문의 "보안 체크포인트" 역할을 합니다—단위 테스트 대체가 아니라, 단위 테스트가 놓칠 수 있는 어리석지만 치명적인 생태계 오류를 막습니다.

주요 교훈

  • JSON 사양을 통한 단일 진실 원천으로 런타임 간 매개변수 중복 제거.
  • 코드 생성으로 수동 개입 없이 데이터 동기화.
  • 패리티 테스트로 Dart와 TypeScript에서 동일 결과 보장.
  • 세 가지 정확도 모드로 단순 "+10%" 대체하고 사용자 여유 제어.
  • CI의 전문 검증기로 단위 테스트가 놓칠 체계 오류 방지.

— Editorial Team

Advertisement 728x90

다음 읽기