
SOFTMOA TECHNOLOGY
사내 우편물 입고와 수령 확인 시스템 구축 방법
소프트모아가 정리한 기술 기록입니다.
Contents
우편물 도착 알림을 보냈는데도 보관함에 물건이 남아 있다면, 발송 성공을 수령 완료로 처리하고 있지 않은지 먼저 확인해야 합니다. 사내 우편물 관리 시스템은 입고·보관·실물 인계를 연결하되, 알림 상태는 따로 기록하도록 구축합니다. 아래는 사무실 총무팀을 위한 가상 설계이며 실제 고객의 도입 사례가 아닙니다.
알림 성공과 보관 종료를 다른 칸에 둡니다
예시에서는 물품 상태를 수취인 확인 대기(REVIEW), 보관 중(STORED), 수령 완료(COLLECTED), 반송 완료(RETURNED)로 나눕니다. 알림에는 대기(WAIT), 발송 서비스 접수 성공(SENT), 실패(FAILED)를 별도로 둡니다. SENT는 직원이 메시지를 읽었다거나 물건을 가져갔다는 뜻이 아닙니다. 알림 실패를 고쳐도 우편물이 자동으로 수령 완료가 되지 않아야 합니다.
입고 화면에는 물품 번호, 도착 시각, 수취인 사번, 부서, 운송장 번호, 보관함 위치와 수량을 받습니다. 같은 사람이 박스 2개를 받더라도 각각 인계할 수 있다면 물품 번호도 2개로 나눕니다. 운송장 재스캔은 기존 건을 먼저 보여주고, 한 운송장에 여러 상자가 딸린 경우는 별도 포장 번호를 붙여 구분합니다.
동명이인이나 퇴사자에게 온 물품은 임의의 직원에게 배정하지 않습니다. REVIEW 목록에서 총무 담당자가 소속과 수취인을 확인한 다음 STORED로 전환하고 통지를 요청합니다. 보관함이 정해지지 않은 물품을 먼저 통지하지 않도록 입고 확정 조건에 위치 입력도 넣습니다.
수령 화면은 실제로 건넨 물품만 닫습니다
- 직원은 본인 계정에서 물품 번호와 수령 장소를 조회합니다. 공용 화면에는 다른 직원의 이름·운송장·라벨 사진을 한꺼번에 노출하지 않습니다.
- 대리수령은 원래 수취인이 대리인 사번, 대상 물품 번호, 만료 시각을 지정해 승인하도록 설계합니다. 승인은 물품 1건에만 적용하고, 인계 시점에 만료·취소 여부를 다시 확인합니다. 이 예시에서 기밀 표시 물품은 대리수령을 허용하지 않습니다.
- 총무 직원은 수령인의 신원과 승인 범위를 확인하고 물품 번호를 대조합니다. 실물을 건넨 뒤 인계 직원, 실제 수령인, 인계 시각과 확인 기록을 함께 저장합니다. 대리 승인 자체는 인계 기록이 아닙니다.
수령 완료 저장은 아직 STORED인 건에만 허용하고, 두 창에서 같은 물품을 처리하면 나중 요청에는 이미 인계됐다는 결과를 돌려줍니다. 물건을 건넨 직후 저장 오류가 났다면 새 물품으로 다시 등록하지 말고 확인 필요 건으로 남겨 실물과 이력을 대조합니다. 잘못된 완료 기록도 삭제 버튼으로 없애기보다 책임자가 정정 사유와 전후 값을 남기도록 합니다.
미수령 3건과 재알림 1건을 구분하는 조회
이 설계의 장기 보관 기준은 도착 후 정확히 72시간 이상이며 주말도 포함합니다. 달력 날짜가 세 번 바뀌었는지를 세는 기준이 아닙니다. 아래 SQL은 한국시간 2026년 10월 28일 09:00을 고정 기준으로 사용합니다. 예제 데이터 4건만 읽으며 운영 DB에 연결하거나 알림을 보내지 않습니다.
다음을 mail_check.sql로 저장하고 sqlite3 -header -column :memory: < mail_check.sql로 실행합니다. 로컬 SQLite 3.54.0에서 확인했습니다. WITH는 한 문장 안에서 쓸 예제 행을 정의하고, unixepoch는 시간대가 표시된 시각을 초 단위 값으로 비교하는 데 사용합니다.[1][2]
WITH mail(id, arrived, status, notice) AS (
VALUES
('M01','2026-10-25T09:00:00+09:00','STORED','SENT'),
('M02','2026-10-27T09:00:00+09:00','STORED','FAILED'),
('M03','2026-10-24T09:00:00+09:00','COLLECTED','SENT'),
('M04','2026-10-25T09:01:00+09:00','STORED','SENT')
)
SELECT id, status, notice,
(status = 'STORED' AND unixepoch(arrived) <=
unixepoch('2026-10-28T09:00:00+09:00', '-72 hours'))
AS overdue,
(status = 'STORED' AND notice = 'FAILED') AS resend
FROM mail
ORDER BY id;
실행 결과의 1은 해당 목록의 대상, 0은 비대상입니다.
id status notice overdue resend
--- --------- ------ ------- ------
M01 STORED SENT 1 0
M02 STORED FAILED 0 1
M03 COLLECTED SENT 0 0
M04 STORED SENT 0 0
M01은 통지가 성공했어도 여전히 보관 중이며 정확히 72시간이 지나 장기 보관 대상입니다. M04는 71시간 59분이므로 아직 대상이 아닙니다. M02는 하루 전 입고된 건이라 장기 보관은 아니지만 알림 실패를 재처리해야 합니다. M03은 오래전에 입고됐어도 수령 완료라 두 목록에서 모두 빠집니다. 입고 4건 중 현재 보관은 3건, 수령 완료는 1건이며 장기 보관과 재알림은 각각 1건입니다.
M02의 통지만 재발송에 성공하면 resend는 0이 되지만 보관 3건과 M01의 장기 보관은 그대로입니다. 이 쿼리는 정상 시각과 정해진 상태값을 가진 예제에 한정됩니다. 운영 입력에서는 누락·잘못된 시각과 미래 입고 시각을 별도 검수하고, 실제 조회 시각은 서버가 정하도록 해야 합니다. 조회 결과만으로 발송·인계·승인 권한이 구현되지는 않습니다.
반송보다 먼저 정할 운영 기준
총무 책임자는 장기 보관 목록에서 담당자 확인, 수취인 재배정, 반송 검토를 선택하도록 합니다. 72시간은 이 글의 내부 확인 기준일 뿐 법정 보관기간이나 자동 반송 기한이 아닙니다. 반송에는 승인자와 사유를 남기고, 운송사에 실제로 넘긴 시각을 기록한 뒤 RETURNED로 닫습니다. 물품 이력 보존기간과 라벨 사진 접근 범위도 회사의 취급 기준에 맞춰 별도로 정해야 합니다.
구축 범위는 입고 등록, 수취인 확인, 보관 위치 조회, 대리수령 승인, 인계 정정, 실패 알림 재처리를 먼저 연결하는 정도로 잡을 수 있습니다. 수령 장소와 확인 책임자가 정해지지 않은 상태에서 OCR이나 자동 메시지부터 붙이면 전산 기록과 실물의 차이는 남습니다. 서비스 안내는 소프트모아 홈페이지에서 확인할 수 있습니다.
SQL 확인 자료: [1] SQLite 날짜·시간 함수, [2] WITH 절. 문법과 시간 비교 기준을 확인하는 데만 사용했습니다.
소프트모아는 해당 시스템을 구축합니다. 문의하기
