34P by GN⁺ | ★ favorite | 댓글 2개
  • 회계는 지난 수백 년 동안 크게 변하지 않았음
  • 그럼에도 불구하고, 금융 시스템을 위한 소프트웨어를 구축하는 올바른 방법에 대해 많은 혼란이 있음
  • 이 글에서는 대기업에서 금융 시스템을 구축한 경험을 바탕으로 한 교훈을 공유
  • 회계 시스템 구축에 초점을 맞추겠지만, 이 원칙들은 더 일반적인 금융 시스템에도 적용됨

기본 금융 용어 정의

  • 일반 원장 (General Ledger, GL): 특정 기간 동안의 모든 금융 거래를 요약한 회사의 주요 회계 기록. 이는 해당 하위 원장의 집계로 생각할 수 있음
  • 보조 원장 (Sub-ledger): 특정 GL과 관련된 모든 개별 거래에 대한 세부 정보를 포함. 보조 원장의 레코드에는 일반 원장보다 훨씬 더 세분화된 데이터가 포함되어 있음 (예: 특정 고객, 주문의 특정 항목 등). 보조 원장과 GL 간의 데이터 차이는 비즈니스 유형과 작업 중인 데이터 양에 따라 달라짐. 일부 소규모 기업은 보조 원장 없이 운영할 수 있지만, 규모가 작은 경우 맞춤형 소프트웨어가 필요할 가능성은 별로
  • 재무 기록 (Financial Record): 일반 원장과 보조 원장을 통칭
  • 중요성 (Material): 재무제표의 정보 왜곡이 합리적인 이해관계자의 의사 결정에 영향을 미치는지 여부를 나타냄. 이 정의는 의도적으로 다소 애매모호한데, 서로 다른 기업은 서로 다른 중요성 기준을 가지고 있기 때문. 예를 들어 연 매출 25만 달러를 버는 기업에게 중요한 것이 연 매출 10억 달러를 버는 기업에게는 중요하지 않을 수 있음. 설계 관점에서 이 개념의 주요 가치는 다양한 범주의 재무 데이터를 분류하는 것임

High Level Data Flow

Business System --(Financial Events)--> Sub Ledger(s) --(Summarized Accounting Entries)--> General Ledger

회계 시스템의 세 가지 주요 목표

  1. 정확성 (Accurate): 재무 기록은 비즈니스의 알려진 상태를 반영해야 함
  • 예: $9.99의 제품 10개를 판매한 경우, 해당 재무 기록의 합계는 $99.90이어야 함
  • 이는 명백해 보이지만 수천, 수백만 건의 거래를 집계할 때 시스템 간 단순 합산이나 반올림 오류로 인해 중대한 부정확성이 발생할 수 있음
  • Wasteman의 노트

    • 사람들은 명명(naming)이 컴퓨터 과학에서 가장 어려운 문제라고 하지만, 덧셈이 그 다음으로 어렵다고 생각함
    • 지난 몇 년 동안 대규모 금융 시스템에서 일하면서, 아주 작은 버그가 데이터에 큰 차이를 유발한 경우를 셀 수 없이 많이 봄
    • float에 대한 합계는 얘기도 꺼내지 말 것. 항상 정수를 사용해야 하는 이유를 힘들게 배움
  • 재무 기록은 완전 (complete) 해야 함
    • 더 구체적으로, 보조 원장과 일반 원장은 특정 시점에 발생한 모든 비즈니스 활동을 완전히 표현해야 함
    • 발생했지만 재무 기록에 없는 이벤트가 있다면 시스템이 완전하지 않은 것
    • 이는 최종 일관성 (eventual consistency)이 허용되지 않음을 의미하지는 않음
    • 데이터가 언제 완전해질지 알아야 이해관계자에게 데이터가 확정되었음을 알릴 수 있음
  • Wasteman의 노트

    • 완전성을 보장하는 것도 놀라울 정도로 어려운 문제임
    • 시스템이 확장됨에 따라 데이터가 여러 시스템을 거치면서 실수로 변형되거나 누락될 수 있음
  1. 감사 가능성 (Auditable): 이해관계자가 오류를 감지하고 비즈니스 성과를 정확하게 측정할 수 있도록 재무 기록을 쉽게 감사할 수 있어야 함
  2. 적시성 (Timely): 회계 시스템은 비즈니스의 특정 요구 사항을 충족해야 함
  • 소규모 기업은 월말에 모든 숫자를 덤프하는 것으로 충분할 수 있지만, 대기업은 일반적으로 실시간에 가까운 시스템을 원함
    • 이를 통해 한 달 내내 재무 상태를 모니터링하고, 재무 데이터에 기반한 의사 결정을 더 빠르게 내리며, 월/분기 초에 마감하기 위한 촉박함을 줄일 수 있음
  • 그 필요가 무엇이든, 우리의 회계 시스템은 비즈니스의 요구 사항을 충족해야 하며, 그들에게 적시가 의미하는 바 그대로여야 함
  • Wasteman의 노트

    • 사람들은 적시성과 관련하여 배치 대 스트리밍 시스템에 대한 대화에서 길을 잃는 경향이 있음
    • 내 견해로는 대부분의 시스템에서 이것이 중요한 구분이 아님
    • 초 단위에서 분 단위에 이르는 매우 짧은 지연 시간에 대해 신경 쓴다면 이것이 중요함
    • 그러나 소비자가 하루에 몇 번 이상 업데이트를 볼 필요가 없을 때 사람들이 어떤 것을 해야 할지에 대해 논쟁하는 것을 듣는 경우가 놀라울 정도로 많음
    • 요청했다고 해서 반드시 필요한 것은 아님

회계 시스템이 지켜야 할 세 가지 주요 엔지니어링 원칙

  1. 데이터의 불변성 (Immutability)과 내구성 (Durability)
  • 감사 가능성을 허용하여 디버깅과 정확성에 도움이 됨
  • 데이터가 불변하면 언제든지 시스템의 상태를 기록할 수 있음
  • 이는 이전 상태에서 세계를 재계산하는 것을 정말 쉽게 만듦. 어떤 상태도 잃어버리지 않기 때문
  • 한 번 재무 기록에 명시된 데이터는 삭제할 수 없음
  • 시스템에 대한 모든 수정 사항은 새로운 금융 거래로 표시되어야 함
    • 예: 시스템에 버그가 있어 $900이어야 할 서비스가 실수로 $1000에 판매된 것으로 보고된 경우
    • 이 실수를 바로잡으려면 먼저 실수에 해당하는 회계 항목을 취소하고 정확한 금액으로 회계 항목을 다시 기술해야 함
  1. 데이터는 가장 작은 단위로 표현되어야 함(Data recorded at the smallest grain)
  • 위의 원칙과 유사하게, 이것은 또한 명확한 감사 추적을 가능하게 하는 데 매우 중요함
  • 재무 보고서와 일반 원장이 집계되더라도, 그것들은 더 세분화된 이벤트에서 계산됨
  • 데이터가 이해되지 않을 때, 문제가 무엇이었는지 디버깅하기 위해 가장 세분화된 데이터가 필요함
  • 가장 낮은 수준의 세분성으로 데이터를 저장하면 해당 데이터셋에서 파생된 데이터를 수정하는 것도 매우 쉬워짐
    • 단일 불변 데이터셋이 해당 데이터의 모든 뷰에 대한 진실의 핵심 소스인 경우,
    • 뷰를 수정하려면 데이터를 수정한 후 해당 뷰를 생성하는 파이프라인을 다시 실행하기만 하면 됨
  • 이와 유사하게 회계사가 장부를 마감할 준비를 할 때,
    • 그들은 장부가 정확한지 검증하기 위해 발생한 모든 거래와 계정 잔액을 조정함
    • 불일치가 발견되면 문제를 일으키고 있는 정확한 거래를 파고들 수 있음
  1. 멱등성 (Idempotency)이어야 함
  • 모든 재무 이벤트는 한 번만 처리될 수 있으며, 재무 기록의 중복은 명백한 부정확성을 야기할 것임
  • 이러한 이유로 재무 기록을 생성하는 모든 코드는 멱등원 (idempotent)이어야 함
    • 멱등원이란 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미
    • 즉, 재무 이벤트를 여러 번 처리하더라도 결과는 처음 처리한 것과 동일해야 함

모범 사례

  • 금융 금액을 나타내기 위해 정수를 선호할 것: 산술 연산이 훨씬 쉬워짐. float는 피할 것
  • 통화 변환 시 정밀도 손실을 최소화할 수 있도록 금융 금액의 세분성을 지원할 것
    • 달러만 다루는 경우 센트 단위로 표현하는 것으로 충분할 수 있음
    • 글로벌 비즈니스의 경우 마이크로 단위나 DECIMAL(19, 4)와 같은 소수를 선호
    • 금융 시스템에서 소수 선택이 인기가 있지만, 광고 금융 시스템에서는 마이크로가 표준
  • 일관된 반올림 방법을 사용할 것: 반올림 방식에 따라 예상 금액과 중요한 차이가 발생할 수 있음
    • 모든 값을 5 이상은 다음 유효 숫자로, 4 이하는 내림하는 방법
    • 항상 반올림하는 방법 등
    • 중요한 것은 전체적으로 일관성을 유지하는 것 (거래당 1센트씩 차이나는 경우 1천만 건이면 $100k 차이)
  • 가능한 한 통화 변환을 지연시킬 것: 통화를 미리 변환하면 정밀도 손실이 발생할 수 있음
    • 현지 통화로 집계가 발생한 후까지 통화 변환을 지연
  • 시간의 정수 표현 사용: 약간 논란의 여지가 있지만 강력 추천
    • 타임스탬프를 객체로 파싱하는 다양한 라이브러리들이 각각 다르게 처리함
    • 이러한 골치 거리를 피하고 정수를 사용하는 것이 좋음
    • Unix 타임스탬프나 UTC 기반 정수 datetime도 완벽하게 작동
    • 시스템 간 데이터 변환이 적을수록 좋음
    • Wasteman의 노트

      • 일광 절약 시간제 관련 버그는 언급조차 하지 않았음. 증가하는 정수를 사용하면 이를 완전히 피할 수 있음
      • datetime을 고집한다면 적어도 UTC를 사용할 것. 매우 큰 기업들이 UTC가 아닌 타임스탬프를 사용하는 경우가 놀라울 정도로 많음
GeekNews Weekly에 포함된 글입니다. 에디터 코멘트 보기

댓글과 토론

이거 진짜 유용하네요. 아무 생각 없이 형변환(decimal float double),반올림을 현업 논의 없이 그냥 해버리면 큰일 납니다.

Hacker News 의견
  • 일관된 반올림 방법론 사용의 중요성 강조

    • 비즈니스 도메인 코드에서 반올림 전략을 국가 코드별로 관리할 필요성 언급
  • 시간을 정수로 표현하는 방법 추천

    • Unix 타임스탬프나 정수 기반 UTC 날짜시간 사용 권장
    • 과거 또는 미래의 특정 시간에 대해 유효함
    • 예: 48시간 취소 정책을 가진 회사의 경우 미래 타임스탬프 계산 가능
    • 국가별 세금 연도 종료 시간 등은 시간대 저장 필요
  • 회계 시스템에서 관계형 데이터베이스 사용 권장

    • ACID 특성 제공
    • 임의 정밀도 숫자 데이터 타입과 검증된 연산 및 반올림 모드 제공
    • SQL을 통한 계산 및 보고 가능
    • SQL 전문가 고용 시 우아한 보고서 작성 가능
    • 고속 성능 및 재해 예방 및 복구 도구 제공
    • 다국적 기업의 금융 시스템 구축 경험 공유
  • 회계 시스템의 주요 목표는 정확성, 감사 가능성, 적시성임

    • 일관성도 중요한 요소로 언급
    • 여러 시간 차원이 존재하며, 각 차원에 따라 일관된 뷰 제공 필요
    • 예: 거래가 완료되었지만 정산되지 않은 경우 프론트 오피스 회계에만 포함
  • 회계 시스템의 완전성에 대한 의견

    • 모든 거래가 제때 처리되지 않음을 가정
    • 여러 계층의 원장을 통해 거래를 처리하고 조정 프로세스 필요
  • 글로벌 비즈니스의 경우 최소 8자리 소수점 사용 권장

    • 환율 변환을 가능한 한 지연시킬 필요성 강조
    • 환율 변환은 법적 및 회계적 의무의 일부임
  • 사용자 인터페이스(UI)의 중요성 언급

    • 회계 소프트웨어의 UI에 대한 실망감 표현
    • 더 나은 UI 솔루션 필요성 강조
  • 배치 처리와 스트리밍 처리의 차이점 설명

    • 두 시스템의 설계가 완전히 다름
    • 대량의 기존 데이터를 처리하는 데 어려움 존재
  • TypeScript를 사용한 송장 시스템 구축 경험 공유

    • 반올림 오류 방지 방법 설명
    • 관련 링크 제공
  • 표준 라이브러리의 클래스 사용 권장

    • Java의 BigDecimal 및 Python의 Decimal 사용 추천
    • 동일한 스케일을 유지하거나 스케일을 저장하는 표준 적용 필요성 강조
  • 반올림 및 데이터 공유의 어려움 설명

    • 두 자리 소수점만 처리할 수 있는 시스템과의 데이터 공유 문제
  • 미국 상위 10대 은행의 API 작업 경험 공유

    • 이자율 저장 방식의 일관성 문제 언급
    • 일관성의 중요성 강조
  • Martin Fowler의 "Accounting Patterns" 추천

    • 금융 이벤트 관리 시스템 구축 경험 공유
    • 관련 링크 제공