ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 설계 회고
    Projects/약품고 (스마트 의약품냉장고) 2026. 2. 10. 16:31

    우리가 이렇게 나눈 이유와, 지금 다시 만든다면 바꿀 것들

    이 글은 “우리가 잘 설계했다”는 정리라기보다,
    왜 이런 선택을 했고, 그 선택이 구현 단계에서 어떻게 작동했는지를 남기기 위한 기록이다.

    그래서 이 글에서는 아래 세 가지를 한 번에 정리한다.

    1. 설계에서 실제로 잘 작동했던 선택들
    2. 구현하면서 설계가 흔들리거나 깨졌던 순간들
    3. 지금 다시 만든다면 아예 다르게 할 선택들

    1. 설계에서 가장 중요하게 잡았던 원칙 3가지

    설계 전반을 관통한 원칙은 복잡하지 않았다.

    ① 서버는 ‘사실’만 기억한다

    Draft, 임시 상태, 중간 결과는 서버의 책임이 아니라고 정의했다.
    서버에는 **이미 일어난 일(Commit)**만 남긴다.

    이 원칙 덕분에:

    • DB 데이터의 의미가 항상 명확했고
    • 이력, 재고, 로그 간 정합성을 유지하기 쉬웠다.

    ② 이력과 상태는 분리한다

    입고/출고/폐기는 **이력(Event)**으로 쌓고,
    재고는 빠른 조회를 위한 현재 상태 스냅샷으로 관리했다.

    이중 구조는 귀찮았지만,

    • 추적 가능성
    • 감사 대응\

    ③ 모든 데이터는 ‘업무 흐름’에 속해야 한다

    그래서 거의 모든 테이블에 세션 ID를 붙였다.

    “이게 어떤 작업 흐름에서 생겼는지”를 설명할 수 있는 로그를 만들수있었다.


    2. 구현하면서 설계 덕을 본 선택들

    설계가 실제 구현에서 힘을 발휘했던 순간들도 분명 있었다.

    Commit Only API 구조

    Draft API를 만들지 않고,
    Commit 시점에만 서버에 요청하도록 한 구조는 구현 단계에서 큰 안정감을 줬다.

    • 트랜잭션 경계가 명확했고
    • 재고와 이력 동기화 로직을 한 곳에 집중할 수 있었고
    • “이 데이터가 누가 언제 어떻게 생겼는지” 항상 설명 가능했다.

    인스턴스 단위 재고 모델

    입고 1건 = 인스턴스 1개라는 모델 덕분에

    • 유효기한 임박 우선 출고
    • 개봉 상태 관리
      같은 기능을 비교적 자연스럽게 얹을 수 있었다.
    이 인스턴스 단위라는걸 내부적으로 명확히 정하지않았고, 또 팀원들간의 이해나 합의를 제대로 거치지 않은채 진행을 해서 문제가 생겼었다.

    3. 설계가 부족했다고 느낀 지점들

    반대로, 구현하면서 “이건 설계 단계에서 더 생각했어야 했는데”라고 느낀 부분도 있다.

    세션을 ‘상태’로 다루지 못한 점

    세션 ID를 거의 모든 테이블에 붙였지만,
    정작 세션 자체는 업무 생명주기를 관리하는 객체로 충분히 정의하지 못했다.

    현재 구조에서 세션은:

    • 로그를 묶기 위한 ID에 가깝고
    • 시작과 종료 조건이 UX·API·DB 레벨에서 명확하지 않다.

    그 결과,

    • 브라우저 비정상 종료
    • 새로고침
    • 탭 이동
      같은 상황에서 세션 흐름이 꼬일 가능성이 남아 있다.

    트랜잭션 검증의 깊이 부족

    inbound_history와 inventory가 항상 함께 생성·갱신돼야 하는 구조였지만,
    이 규칙을 충분히 공격적으로 검증하지는 못했다는 아쉬움이 있다.


    4. 지금 다시 만든다면, 이렇게 바꿀 것들

    이 프로젝트를 다시 설계한다면, 가장 크게 바꿀 부분

    ① 세션을 명확한 상태 객체로 정의

    • 세션 시작 조건
    • 유효 범위
    • 종료 조건
    • 비정상 종료 시 회수 정책

    을 처음부터 UX·API·DB 레벨에서 명확히 합의했을 것이다.

    ② Draft 유실을 전제로 한 UX 가이드

    Draft를 브라우저에만 두는 구조는 유지하되,

     

    • 휘발되지 않는 브라우저 저장소(localStorage / IndexedDB 등)를 사용해
      Draft를 임시 복구 가능 상태로 유지
    • 혹은 Draft를 관리하는 외부 저장소 큐(임시 작업 목록)를 사용해 분리 관리.


    마무리하며

    기한에 맞는 scope의 설계를 해야한다고 느꼈고, 성능 개선을 위한 설계는 당장 적용하기보단. 우선 기본동작을 만든뒤 수치를 측정한뒤 병목지점에 적용하는게 좋다고 느꼈다. 처음부터 적용하니 그 효과를 알기 어렵고 또 복잡도가 올라서 힘들었다.

    'Projects > 약품고 (스마트 의약품냉장고)' 카테고리의 다른 글

    구현, 아키텍처  (0) 2026.02.10
    CI / CD  (0) 2026.02.10
    API 설계  (0) 2026.02.10
    데이터 모델링  (0) 2026.02.10
    시스템 설계  (0) 2026.02.10
Designed by Tistory.