edm유학센터 · 세부 파일럿

자사몰 · 백오피스
주문 관리 시스템 PRD

자사몰에서 받은 주문을 접수부터 정산까지 관리하는 시스템의 제품 요구사항 — 백오피스 우선

대상 edm유학센터 유학본부 · 개발팀 · 필리핀 지사 / 개정 2판

02/29

SECTION 01 · CONTEXT

이 문서가 정하는 것

앞선 문서들이 무엇을 할지를 정했습니다. 이 문서는 그중 주문 인프라만 골라 어떻게 만들지를 정합니다. 이번 개정에서 프런트가 자사몰로 바뀌었고 데이터 저장 방식이 확정됐습니다.

문서정한 것이 PRD 와의 관계
운영 안내서7대 서비스와 현장 운영 기준 품목·마감 시각·안전 재고 등 업무 규칙의 출처
추가 제안서현지인 풀타임 고용 확정안시스템을 쓸 현지 사용자 2명의 근거
기능 정의서8개 모듈 57개 기능 상위 문서. 이 PRD 는 M1·M2·M7 을 구현 수준으로 펼침
액션 플랜9/1 착수 5주, 10/6 오픈맞물려야 하는 바깥 일정
가격 가안품목·판매가·마진 초안기준 정보에 넣을 품목 마스터의 원본
이 PRD자사몰 + 백오피스 화면·데이터·상태·권한·릴리스를 개발 착수 가능한 수준으로

1판과 달라진 곳 — ① 주문 유입이 자사몰(쇼핑몰) 프런트로 확정, ② 회원은 비회원 우선, ③ 데이터는 edm Open Database 대행 API, ④ 백오피스를 먼저 만든다.

03/29

SECTION 01 · GIVENS

확정된 전제 여섯 가지

설계를 가르는 갈림길입니다. 이 여섯이 바뀌면 아래 요구사항의 상당 부분이 함께 바뀝니다.

#항목 결정설계에 미치는 영향
1프런트자사몰(쇼핑몰) 형태 상품·장바구니·주문 흐름이 필요. 디자인은 edmuhak.com 스타일 가이드를 따름
2회원비회원 우선 고객 계정 체계를 만들지 않음. 멤버십은 추후 연동이라 식별 키를 갈아끼울 수 있게 설계
3결제계좌 이체 · 한화(KRW) 입금 확인이 주문 확정의 기준. 계좌번호는 임시값, 가상계좌 발급 후 교체
4데이터 저장edm Open Database
(MySQL 9 · 서버 대행 API)
DB 컨테이너를 직접 띄우지 않음. HTTPS 로 SQL 을 대행시키므로 API 키를 가진 서버 측 코드가 반드시 필요
5배포 위치이 저장소에 함께 문서·자사몰은 정적, 백오피스와 주문 API 는 앱 서비스로 분리
6작업 순서백오피스 먼저 자사몰 UI 는 나왔지만 주문을 받아서 처리할 곳이 없음. 받는 쪽을 먼저 만든다

04/29

SECTION 01 · ORDER OF WORK

왜 백오피스를 먼저 만드는가

자사몰 화면은 이미 있습니다. 없는 것은 들어온 주문을 처리하는 쪽입니다.

이유 01

주문은 받는 순간이 아니라
처리하는 순간에 돈이 된다

신청 폼만 있으면 지금도 구글폼으로 됩니다. 손해가 나는 곳은 입금 대조·발주 수량·검수 누락이고 전부 백오피스입니다.

이유 02

자사몰이 붙을 곳이
먼저 있어야 한다

주문을 저장할 테이블과 상태 규칙이 없으면 프런트가 보낼 데이터의 모양을 정할 수 없습니다. 백오피스가 스키마의 주인입니다.

이유 03

오픈은 백오피스만으로
가능하다

10/6 오픈 시점에는 주문서 화면 + 백오피스로 운영이 됩니다. 자사몰은 고객 접점을 넓히는 것이지 오픈의 조건이 아닙니다.

단계이때 고객은이때 담당자는
지금 ~ R1카카오톡·전화로 신청 백오피스에 직접 입력해 접수 — 주문서 화면으로도 가능
R2자사몰에서 직접 주문들어온 주문을 백오피스에서 확인·처리
R4멤버십으로 로그인해 내역 조회동일

05/29

SECTION 02 · PROBLEM

지금 방식이 깨지는 지점

접수는 지금도 됩니다. 깨지는 곳은 접수 다음이고, 그래서 백오피스가 먼저입니다.

깨지는 지점지금 무슨 일이 생기는가 남는 비용
입금과 주문이 따로 주문은 시트에, 입금은 통장에 있어 사람이 눈으로 대조 미입금 발송, 입금 후 누락 발송. 둘 다 클레임
수요 취합이 수기요일별 주문을 학원 단위로 손으로 합산 수량 오류가 그대로 손해. 재발주로 배송 하루 지연
재고가 장부에만판매·대여로 나간 수량이 실시간 반영되지 않음 품절 상태로 주문 접수. 수요일 실사까지 모름
인도 증빙이 흩어짐검수 사진이 담당자 휴대폰에 남음 분실·파손 분쟁에서 근거 부재
이력이 안 남음시트를 덮어써 변경 내역이 사라짐 정산 불일치의 원인 추적 불가

공통점은 하나입니다 — 기록이 한 곳에 모이지 않는다. R1 의 목표는 기능 수가 아니라 주문 한 건의 전 생애가 한 줄로 남는 것입니다.

06/29

SECTION 02 · SUCCESS

성공했다고 말할 조건

기능 완성이 아니라 측정되는 결과로 씁니다. 파일럿 3개월 시점에 판정합니다.

ORDER TRACE

100%

접수된 주문이 DB 에 남는 비율 — 시트 이중 입력 없이

PAYMENT MATCH

1영업일

입금 확인부터 배송 확정까지 걸리는 시간

STOCKOUT

0

재고 없는 품목을 접수해 취소한 건수

HANDLING

5

주문 한 건 처리에 담당자가 쓰는 시간

판정 항목측정 방법통과 기준
주문 누락DB 건수 vs 통장 입금 건수월 단위 차이 0건
정산 일치일별 기록 합계 vs 월 집계차이 발생 시 원인 추적 가능
담당자 전환현지 담당자가 시트를 다시 쓰는지 관찰 시트 없이 하루를 마감할 수 있음

07/29

SECTION 03 · USERS

쓰는 사람과 하는 일

자사몰이 생기면서 고객이 시스템 안으로 들어옵니다. 다만 로그인은 하지 않습니다.

사용자인원 인증하는 일주 화면
현지 담당자2사내 게이트 입고 검수·사진 첨부·인도 체크·재고 실사. 휴대폰으로 현장에서 오늘 할 일, 검수
본사 운영1~2사내 게이트 입금 확인, 발주 승인, 주문 대리 입력, 학생 안내입금 대기, 주문 목록
본사 관리자1사내 게이트 품목·단가·권한 설정, 정산 열람기준 정보, 리포트
고객 (비회원)-없음 자사몰에서 상품을 담고 이름·어학원·연락처로 주문 자사몰 스토어·장바구니·주문
고객 (회원)-멤버십 R4 예정 — 로그인 후 주문 내역 조회주문 조회

비회원이라 고객을 무엇으로 식별할지가 문제가 됩니다. R1~R3 은 주문번호 + 연락처 뒤 4자리를 조회 키로 쓰고, 멤버십이 붙는 R4 에서 회원 고유번호로 갈아끼울 수 있게 주문 테이블에 빈 칼럼을 미리 둡니다.

08/29

SECTION 03 · FLOW

주문 한 건의 전체 흐름

아홉 단계입니다. 초록은 R1 백오피스가 만드는 구간, 파란 글씨는 R2 자사몰 연동에서 붙습니다.

#단계 주체하는 일다음으로 가는 조건
1상품 담기고객 자사몰에서 품목·수량 선택 R2장바구니 확정
2주문 제출고객 이름·어학원·연락처·배송 시작일 입력 R2제출
3접수시스템 주문 생성, 마감 시각·단위·재고 검증, 주문번호 발급검증 통과
4입금 확인본사 입금자명·금액 대조 후 확인 처리입금 확인 = 주문 확정
5수요 취합시스템 마감 시각 기준으로 학원·품목별 합산마감 도달
6발주현지 공급업체별 발주·결제 기록, 단가 이력 보관발주 완료 입력
7입고 검수현지 박스 수 검수, 사진 첨부, 보관소 입고검수 완료
8배송·인도현지 학원별 배송, 인도 체크. 과일은 3시간 초과 표시인도 완료
9정산 기록시스템 일별 매출·원가·기여마진 기록-

R1 에서는 1·2 번을 담당자가 대신 합니다 — 고객이 카카오톡으로 보낸 내용을 백오피스에 입력합니다. R2 에서 자사몰이 붙으면 3번부터가 자동으로 시작됩니다.

09/29

SECTION 04 · ARCHITECTURE

시스템 구성

데이터 저장이 원격 관리형 DB로 확정되면서 구조가 단순해졌습니다. 다만 API 키를 가진 서버가 반드시 필요해졌습니다.

FRONT

자사몰

정적 페이지. 상품·장바구니·주문 폼. DB 를 직접 부르지 않는다 — 키가 노출되므로

API

주문 API

얇은 서버. 자사몰의 주문을 받아 검증하고 DB 에 넣는다. 공개 경로 필요

BACK

백오피스

사내 게이트 뒤. 접수·입금·취합·발주·검수·인도·리포트. R1 의 전부

DATA

Open Database

MySQL 9. HTTPS 로 SQL 을 대행. 컨테이너·볼륨·포트 개방이 필요 없다

결정 사항선택이유
DBedm Open Database 대행 API 1판의 "DB 컨테이너 분리 + _data 볼륨" 계획을 대체. 재배포 때 데이터가 사라질 위험이 원천적으로 없어짐
API 키 위치서버 환경변수만 EDM_OPENDATA_API_KEY브라우저로 절대 내려가지 않음. 그래서 자사몰과 DB 사이에 서버가 한 겹 필요
배포 단위정적(문서·자사몰) + 앱(API·백오피스) 문서 한 줄 고칠 때 앱이 재시작되면 안 됨
파일(검수 사진)앱 볼륨 저장 + 경로만 DB 사진을 DB 에 넣으면 1000행 조회 상한과 용량에 걸림
실시간성폴링게이트가 WebSocket 과 90초 초과 연결 미지원

10/29

SECTION 04 · DATA LAYER

Open Database 대행 API 의 제약

일반 MySQL 드라이버와 다릅니다. 제약을 알고 짜야 나중에 고칠 일이 없습니다.

제약내용설계에서 대응
SQL 한 문장세미콜론으로 여러 문 금지 트랜잭션을 쓸 수 없음 → 단일 문장으로 원자성 확보 (INSERT ... ON DUPLICATE KEY, 조건부 UPDATE ... WHERE status=?)
조회 1000행 상한초과 시 truncated:true 목록은 반드시 LIMIT. 전량 순회는 커서(마지막 id 기준)로 이어 읽기
호출 한도동시 10 · 분당 300 · 일 5000
(키마다 다름 — 헤더로 확인)
클라이언트가 동시 5개로 묶고, 429 면 Retry-After 만큼 멈춤. 화면 진입마다 전체 재조회 금지 — 캐시 + 증분
키 노출 금지헤더 X-API-KEY 만, 쿼리스트링 금지 .env 에서 읽고 서버에서만 호출. 코드·로그에 남기지 않음
slug 소유권등록된 내 앱 slug 만 (403) slug = philippines-service. 최초 provision 1회(멱등)
트랜잭션 없음여러 표를 함께 바꿀 수 없음 상태 전이를 한 문장으로 만들고, 두 표를 바꿔야 하면 먼저 기록 → 나중에 집계 순서로 짜서 중간에 끊겨도 복구 가능하게

클라이언트 모듈은 server/edm-opendata.mjs 한 파일입니다 — provisionDatabase / runSql / listDatabases / dropDatabase 에 동시 5개 제한, 429 대기, 5xx 지수 백오프, 읽기 캐시가 들어 있습니다.

11/29

REQUIREMENT · R1

기준 정보

여기가 비면 나머지가 전부 막힙니다. 가격 가안 문서가 이 화면의 입력값입니다.

ID요구사항 상세 · 판정 기준릴리스
M-01품목 마스터 품목명·구분(구매/대여)·단위·판매가·보증금·안전 재고·현재 수량·노출 여부. 자사몰 상품 목록도 이 표에서 나온다 R1
M-02학원 마스터 학원명·주소·보관 장소·담당자 연락처·배송 요일 R1
M-03학생 마스터 이름·학원·체류 기간·귀국 예정일·보호자 연락처·카카오톡 ID R1
M-04공급업체 업체명·품목·연락처·주/예비 구분 R1
M-05마감 규칙 품목별 마감 요일·시각과 배송 요일. 접수 검증의 기준값 (생수 월·목 09시 / 과일 화·금 09시) R1
M-06단가 이력 품목·업체·날짜별 매입 단가. 판매가 재산정의 근거 R1
M-07사용자 역할 게이트 사용자 고유번호에 역할을 지정 R1

12/29

REQUIREMENT · R1

주문 접수

접수에서 막지 못한 잘못은 발주 수량 오류로 끝납니다. 검증을 접수에 몰아 넣습니다.

ID요구사항 상세 · 판정 기준릴리스
O-01주문 생성 (대리 입력) 담당자가 고객 대신 입력. 학생·품목·수량·배송 시작일 → 주문번호 발급 R1
O-02마감 시각 자동 적용 마감 이후 접수는 다음 회차로 자동 배정하고 화면에 알림 R1
O-03주문 단위 검증 생수는 박스 단위만, 과일은 규격 패키지만. 단위 외 수량 저장 거부 R1
O-04재고 확인 재고형 품목은 가용 재고 초과 접수를 차단하고 대체 안내 표시 R1
O-05수정·취소 마감 전 자유 수정. 마감 후에는 취소만 되고 이력이 남음 R1
O-06변경 이력 누가 언제 무엇을 바꿨는지 전 필드 기록 R1
O-07자사몰 주문 수신 공개 API 로 들어온 주문을 같은 검증을 거쳐 저장. 출처(web/manual)를 구분해 기록 R2
O-08중복·스팸 차단 같은 연락처의 짧은 시간 반복 제출 제한, 봇 방지 R2

13/29

REQUIREMENT · R1

입금 확인과 미입금 처리

계좌 이체이므로 입금과 주문을 잇는 일이 사람 손에 남습니다. 그 손을 줄이는 것이 목표입니다.

ID요구사항 상세 · 판정 기준릴리스
P-01입금 대기 목록 미입금 주문을 배송 시작일 임박 순으로 한 화면에. 본사의 하루 시작점 R1
P-02입금 확인 처리 입금자명·금액·입금일 입력 → 주문이 확정으로 넘어가 취합 대상에 들어감 R1
P-03금액 불일치 표시 합계와 입금액이 다르면 차액과 방향을 표시하고 확정을 막음 R1
P-04입금자명 불일치 신청자명과 다른 경우가 흔함. 별칭을 학생에 매핑해 다음부터 자동 인식 R3
P-05미입금 자동 보류 마감까지 미입금이면 자동 보류. 기간·처리 방식은 본사 확정 필요 R3
P-06보증금 분리 대여 보증금은 매출이 아니라 예수금으로 따로 집계하고 환급 상태 관리 R3
P-07계좌 명세 대조 은행 거래내역 CSV 업로드로 미확인 입금 자동 후보 매칭 R4

R1 은 수동 확인으로 시작합니다. 월 50건 규모에서는 수동이 더 빠르고, 매칭 규칙은 실제 입금 데이터를 본 뒤에 정해야 정확합니다.

14/29

REQUIREMENT · R1

수요 취합과 발주

손으로 하는 합산을 시스템이 대신합니다. 확정된 주문만 집계 대상입니다.

ID요구사항 상세 · 판정 기준릴리스
A-01회차별 취합표 마감 후 학원 × 품목 격자로 합산표 생성. 발주서의 원본 R1
A-02발주 기록 공급업체별 발주 수량·단가·결제 금액·결제 수단 기록 R1
A-03단가 이력 반영 발주 시 매입 단가를 남겨 판매가 재산정 근거로 사용 R1
A-04취합 후 변경 잠금 취합표 생성 시 해당 회차는 수량 수정 불가. 취소만 가능하고 손실로 기록되며 취합표에서 사라지지 않음 R1
A-05예비 업체 전환 주 업체 발주 실패 시 예비 업체 전환 기록 R3
A-06발주서 내보내기 업체에 보낼 내역을 텍스트·이미지로 생성 (현지 업체는 채팅으로 받음) R3

15/29

REQUIREMENT · R1

입고 검수와 배송·인도

이 구간은 학원 현장에서 휴대폰으로 처리됩니다. 화면 수와 터치 수가 요구사항의 일부입니다.

ID요구사항 상세 · 판정 기준릴리스
D-01입고 검수 도착 박스 수 입력 + 사진 첨부. 발주 수량과 다르면 차이·사유 필수 R1
D-02사진 처리 업로드 전 압축, 실패 시 재시도. 통신이 끊겨도 입력값 유지 R1
D-03오늘 할 일 화면 오늘 검수·배송·인도 대상을 한 화면에. 현지 담당자의 기본 화면 R1
D-04인도 처리 학생별 인도 완료 체크. 과일은 수령 후 3시간 초과 시 자동 경고 R1
D-05지연 기록 예정일 대비 지연 일수·사유 기록 → 배송 지연률의 원천 데이터 R1
D-06보관소 관리 학원별 보관 장소·담당자를 기준 정보로 두고 인도 대기 현황 표시 R3
D-07인도 안내 생성 인도 준비 완료 시 카카오톡 문안 자동 생성 R3

16/29

REQUIREMENT · R1

일별 기록과 내보내기

집계는 뒤로 미루되 원천 기록은 R1 부터 남깁니다. 기록이 없으면 어떤 집계도 만들 수 없습니다.

ID요구사항 상세 · 판정 기준릴리스
L-01일별 주문 기록 건당 매출·원가·기여마진을 일별로 계산해 남김 (가격 가안 기준 건당 20,000원 · 마진 8,000원) R1
L-02시트 내보내기 구글시트 형식으로 내보내 기존 보고 방식을 그대로 유지 R1
L-03기간·학원 필터 기간·학원·품목·상태로 걸러 보기. 목록은 반드시 LIMIT(1000행 상한) R1
L-04월별 손익 집계 월 고정비 대비 기여마진과 월 순부담 R3
L-05KPI 자동 판정 5대 KPI 와 확장 트리거 판정 R4

L-02 를 R1 에 넣는 이유 — 내보내기가 없으면 담당자가 시스템과 시트에 두 번 입력하게 되고, 그러면 시스템을 쓰지 않게 됩니다. 시트를 당장 없애지 않고 병행합니다.

17/29

SECTION 05 · STATE

주문 상태 정의

상태는 일곱 개입니다. 화면·알림·집계가 이 값으로 움직이므로 임의로 늘리지 않습니다.

상태DB 값 의미이 상태로 만드는 행동할 수 있는 일
접수received주문은 들어왔고 입금은 아직 자사몰 제출 / 담당자 입력수정·취소 자유
확정paid입금 확인되어 취합 대상 본사 입금 확인취합 전까지 수정 가능
취합batched회차 합산에 포함 마감 시각 도달수량 수정 불가 · 취소만
발주ordered업체에 주문됨 현지 발주 완료 입력취소 시 손실 기록
입고received_stock검수 통과해 보관 중 검수 완료 (사진 필수)인도 처리
인도delivered학생에게 전달 완료 인도 체크정산 대상 · 이후 변경 불가
취소cancelled진행 중단 단계별 취소사유 필수 · 손실 여부 기록

되돌리기 규칙 — 인도 이후에는 상태를 되돌리지 않습니다. 잘못 처리한 경우는 되돌림이 아니라 보정 기록으로 남깁니다. 트랜잭션이 없으므로 상태 전이는 UPDATE ... WHERE id=? AND status=? 한 문장으로 만들어 중복 실행을 막습니다.

18/29

SECTION 05 · SCHEMA

데이터 모델

MySQL 9 테이블 기준입니다. 초록이 R1 에서 만드는 표입니다.

테이블주요 칼럼 관계 · 인덱스릴리스
itemid · name · kind(buy/rent) · unit · price · deposit · safety_stock · stock · visible 자사몰 상품 목록의 원본R1
schoolid · name · address · storage · contact · delivery_days student.school_idR1
studentid · name · school_id · stay_from · stay_to · return_date · guardian · kakao idx(school_id), idx(return_date)R1
ordersid · order_no · student_id · member_no(NULL) · source(web/manual) · status · total · deposit_total · start_date · created_by uniq(order_no), idx(status,start_date)R1
order_itemid · order_id · item_id · qty · unit_price · amount · deposit idx(order_id) · orders 1:NR1
paymentid · order_id · payer_name · amount · paid_at · confirmed_by · diff idx(order_id) · 분할 입금 대비 1:NR1
batchid · cycle_date · item_id · school_id · qty · locked_at uniq(cycle_date,item_id,school_id)R1
purchaseid · batch_cycle · supplier_id · item_id · qty · cost_unit · cost_total · paid_by idx(batch_cycle)R1
inspectionid · purchase_id · qty_arrived · diff · reason · photo_path · by · at purchase 1:1R1
audit_logid · table_name · row_id · field · before · after · user_no · at idx(table_name,row_id)R1
stock_moveid · item_id · kind(in/out/adjust) · qty · reason · at idx(item_id,at)R3
rentalid · student_id · item_id · out_at · due_at · in_at · deposit · refund_state · damage_cut idx(student_id), idx(due_at)R3

orders.member_no지금 NULL 로 넣어 두는 것이 핵심입니다. 비회원으로 시작하지만 R4 에서 멤버십이 붙을 때 테이블을 바꾸지 않고 회원 주문을 이어붙일 수 있습니다. source 칼럼도 같은 이유입니다 — 자사몰 주문과 대리 입력을 나중에 구분해 분석할 수 있습니다.

19/29

SECTION 06 · BACK OFFICE

백오피스 화면 목록

R1 은 화면 여덟 개로 끝냅니다. 현지용은 휴대폰, 본사용은 데스크톱 기준입니다.

#화면 사용자기기 담는 것
1오늘 할 일현지모바일 오늘 검수·배송·인도 대상. 진입 후 첫 화면
2입금 대기본사데스크톱 미입금 주문, 입금 확인 입력, 금액 불일치 표시
3주문 목록 · 상세본사데스크톱 상태·기간·학원 필터, 주문 1건의 전 이력과 변경 로그
4주문 등록양쪽모바일 대리 입력. 마감·단위·재고 검증 즉시 표시
5회차 취합 · 발주현지데스크톱 학원 × 품목 합산표, 발주 기록 입력
6검수현지모바일 수량 입력, 사진 첨부, 차이 사유. 3 터치 이내
7기준 정보관리자데스크톱 품목·학원·학생·공급업체·마감 규칙·권한
8일별 기록 · 내보내기본사데스크톱 일별 주문·매출·원가, 구글시트 형식 내보내기

화면마다 진입 시 전체 재조회를 하지 않습니다. 목록은 LIMIT 을 걸고 캐시를 두며, 갱신은 만료 시점이나 사용자가 새로 고칠 때만 합니다 — API 호출 한도 때문입니다.

20/29

SECTION 06 · STOREFRONT

자사몰 프런트

화면은 이미 만들어져 있습니다(index.html). 남은 것은 주문을 서버로 보내는 일이고 그것이 R2 입니다.

구성상태 지금 되는 것R2 에서 붙는 것
상품 목록완료 카테고리별 상품 카드, 가격·보증금 표시 item 표에서 실제 재고·가격을 불러오기
장바구니완료 담기·수량 조절·삭제, 합계와 보증금 분리 계산, 브라우저에 유지 재고 초과 시 담기 차단
비회원 주문 폼완료 이름·어학원·연락처·배송일·입금자명 입력, 필수값 검증 서버로 제출orders 저장, 주문번호 회신
주문 내역 생성완료 주문서 텍스트 생성 · 복사 · 인쇄. 지금은 카카오톡으로 보내면 접수 제출 즉시 접수되므로 복사 안내가 확인 화면으로 바뀜
이용 방법 · FAQ완료 3단계 안내, 6개 FAQ결제·환불 규정 확정 후 문구 교체
주문 조회R2 -주문번호 + 연락처 뒤 4자리로 상태 조회
멤버십 로그인R4 -회원 식별 후 member_no 연결, 내역 목록

디자인은 edmuhak.com 스타일 가이드를 따랐습니다 — Pretendard 계열 폰트, 0.9 배율 타입 스케일(14.4 · 16.2 · 18 · 28.8 · 36), 라운드 3.6 · 7.2 · 10.8 · 21.6, 파랑 #006BC8 과 그린 #1EC95B, 회색 섹션 #F5F5F7. 상단에 비회원 주문 안내 바를 상시 노출합니다.

21/29

SECTION 06 · LINEUP

자사몰 상품 라인업

경쟁사가 여섯 갈래로 팔고 있습니다. 우리 문서의 7대 서비스를 같은 축에 놓고 보면 비어 있는 두 칸이 보입니다 — 도착 시점과 귀국 시점입니다.

#라인 우리 상태담는 상품 메인 배치와 판단
1출국 준비 팩 신규 유심 · 생수 1박스 · 화장지 · 세면용품 맨 위. 도착 첫날을 잡는 상품이고 출국 전 선결제라 입금 확인 시간이 넉넉합니다
2정기 배송 판매 생수 1박스 · 과일 규격 패키지 둘째 칸. 매주 반복되는 핵심이라 재방문의 이유가 됩니다
3생활용품 판매 샤워헤드·필터 구매 / 멀티탭 대여 셋째 칸. 구매와 대여를 한 라인에서 구분 표시
4구독 일부 과일 4주 정기 (판매 중) · 반찬 4주 (2단계) 넷째 칸. 반찬은 운영 안내서에서 2단계 검토 품목이라 '준비 중'으로 노출
5택배 · 보관 판매 수령 대행 · 발송 대행 · 물품 보관 다섯째 칸. 경쟁사에 없는 우리 고유 라인입니다
6귀국 선물 팩 신규 건망고·간식 세트 · 대용량 박스 여섯째 칸. 연수 마지막 주를 잡는 상품. 마트가 그대로여서 마진은 낮지만 재구매 없이 끝나는 고객에게 마지막 접점
7액티비티 · 예약대행 숨김 투어 · 골프 · 마사지 지금은 숨김. 제휴처 정산가와 면책 문구가 정해지면 한 줄로 켭니다

라인을 늘리는 것이 목적이 아닙니다. 고객이 우리를 만나는 시점이 출국 전 · 연수 중 · 귀국 전 셋인데 지금은 가운데만 있습니다. 1번과 6번은 새 공급망이 필요해 R3 이후지만, 메인에 자리를 먼저 잡아 두고 '준비 중'으로 노출해 수요를 봅니다.

경쟁사 상품명·구성·문구는 쓰지 않습니다. 참고한 것은 어떤 시점에 어떤 상품군이 팔리는지이고, 상품 구성과 가격은 우리 손익 기준으로 다시 짭니다.

22/29

SECTION 06 · ROLES

권한과 접근 경로

백오피스는 사내 게이트 뒤, 자사몰은 게이트 밖입니다. 이 둘을 한 앱에서 가르는 것이 요점입니다.

역할판별 방법 할 수 있는 일할 수 없는 일
관리자게이트 헤더 X-Edm-User-Role = super-admin 품목·단가·안전 재고·권한 설정, 전체 열람-
본사 운영관리자가 앱에서 지정 (X-Edm-User-Id 기준) 입금 확인, 발주 승인, 주문 취소, 내보내기단가·권한 변경
현지 담당자관리자가 앱에서 지정 접수·취합·발주 기록·검수·인도·실사 입력입금 확인, 가격 변경
고객 (비회원)인증 없음 — 공개 경로 상품 조회, 주문 제출, 주문번호+연락처로 조회 남의 주문 조회, 가격·재고 변경, 목록 열람
그 외 사내 사용자사내 계정으로 로그인한 나머지 본인 관련 내역 조회만모든 입력

주의 네 가지 — ① 관리자 판별은 Role 값으로만 하고 회원 등급(level)으로 하지 않습니다. ② 헤더 값은 URL 인코딩되어 오므로 디코딩 후 씁니다. ③ 사용자별 데이터는 사용자 고유번호를 키로 저장합니다 — 아이디와 이름은 바뀝니다. ④ 공개 경로는 쓰기만 열고 읽기는 열지 않습니다 — 주문 제출은 되지만 목록 조회는 안 됩니다.

23/29

REQUIREMENT · R3

재고와 대여

품목이 적어 실사로 버틸 수 있습니다. 다만 가용 재고 한 숫자는 R1 부터 필요합니다 — 없는 물건을 자사몰에 팔면 안 되기 때문입니다.

ID요구사항 상세 · 판정 기준릴리스
S-01가용 재고 계산 현재 수량 − 확정된 미인도 수량. 접수 차단(O-04)과 자사몰 품절 표시의 기준값 R1
S-02입출고 원장 구매 입고·판매 출고·대여 출고·반납 입고·폐기를 한 줄씩 남겨 현재 수량을 도출 R3
S-03안전 재고 감지 샤워헤드 5 · 샤워필터 20 · 멀티탭 5 이하 도달 시 발주 대상 자동 표시 R3
S-04주간 실사 수요일 실사 화면에서 실물 수량 입력, 장부 대비 차이와 조정 사유 기록 R3
R-01대여대장 누가·언제·무엇을 대여했고 반납 예정일이 언제인지 실시간 관리 R3
R-02보증금 현황 수령·보관·환불 상태 관리, 미반납 목록 별도 표시 R3
R-03반납 검수 정상 확인 후 환불, 파손 시 차감 금액·사유·사진 기록 R3
R-04귀국일 연동 알림 귀국 예정일 기준 미반납 사전 경고. 귀국 후에는 회수가 사실상 불가 R3

R-04 가 이 절의 핵심입니다. student.return_date 가 있으니 대여 회수는 자동으로 예측 가능한 유일한 리스크입니다. 놓치면 보증금 분쟁과 재고 손실이 동시에 발생합니다.

24/29

SECTION 07 · AUTOMATION

알림과 자동화

게이트가 실시간 푸시를 지원하지 않으므로 화면 폴링과 예약 작업으로 만듭니다.

알림 · 자동화시점 받는 사람방식 · 비고
마감 30분 전 미입금마감 −30분본사 화면 배지 + 목록 상단 고정. 가장 손해를 막는 알림
회차 취합 생성마감 시각현지 예약 작업이 취합표를 만들고 오늘 할 일에 표시
검수 미완료배송일 12시현지·본사 배송 예정인데 검수 기록이 없는 건
과일 3시간 초과수령 +3시간현지 인도 미완료 건에 경고 표시
자사몰 신규 주문제출 즉시본사 입금 대기 목록에 배지로 표시 R2
안전 재고 미달매일 09시현지 기준치 이하 품목을 발주 대상으로 R3
귀국 전 미반납귀국 −7일현지·본사 대여 물품 회수 경고 R3
주간 보고 초안금요일 17시본사 한 주 주문·매출·이슈 요약 R4

카카오톡 발송은 자동화하지 않습니다. 문안만 시스템이 만들고 사람이 보냅니다 — 채널 연동 비용이 크고, 초기에는 문구를 상황에 맞게 손보는 편이 낫습니다.

25/29

SECTION 07 · CONSTRAINTS

비기능 요건과 제약

플랫폼과 DB API 의 제약이 설계를 결정한 부분입니다. 어기면 데이터가 새거나 화면이 멈춥니다.

01 · 데이터

원격 관리형 DB

Open Database 가 앱 밖에 있어 재배포와 무관합니다. 1판의 컨테이너 분리 요건은 해소됐습니다.

02 · 비밀

키는 서버에만

EDM_OPENDATA_API_KEY.env 에서 읽고 브라우저로 내려보내지 않습니다. 코드·로그에 남기지 않습니다.

03 · 호출 한도

동시 5 · 캐시 필수

순간 burst 가 사고를 만듭니다. 병렬도를 올리지 않고 429 는 Retry-After 만큼 멈춥니다.

04 · 현장 사용성

모바일 우선

검수·인도는 학원 현장에서 휴대폰으로. 사진은 업로드 전 압축, 저장 실패 시 재시도.

05 · 통신

폴링만

WebSocket 과 90초 초과 연결 미지원. 긴 집계는 백그라운드로 돌립니다.

06 · 개인정보

보관 기한 필요

보호자 연락처·카카오톡 ID 의 보관 기한과 삭제 기준을 본사와 정해야 합니다. 미결 사항.

26/29

SECTION 08 · SCHEDULE

개발 일정

액션 플랜의 5주와 나란히 갑니다. 10/6 오픈에 시스템을 맞추지 않습니다 — 오픈은 주문서와 시트로 열고 백오피스를 그 뒤에 세웁니다.

구분기간 개발이때 실제 운영은
W1~W29/7 ~ 9/18 DB provision · 스키마 생성 · 기준 정보(M-01~M-07) · 주문 접수(O-01~O-06) 주문서 화면으로 접수, 시트에 옮김
W39/21 ~ 9/23 입금 확인(P-01~P-03) · 가용 재고(S-01)추석 연휴 — 실작업 3일
W49/28 ~ 10/2 취합·발주(A-01~A-04) · 검수·인도(D-01~D-05) 시범 운영과 병행해 실제 데이터로 검증
W510/5 ~ 10/9 일별 기록·내보내기(L-01~L-03) · 안정화 10/6 오픈 — 주문서·시트로 운영
R110월 중순 백오피스 전환 — 현지 담당자가 시스템으로 하루를 마감 시트 병행 유지
R211월 자사몰 연동 — 주문 API, 재고·가격 연동, 주문 조회 고객이 직접 주문
R311월 말 ~ 12월 재고 원장·실사·대여·보증금·월 집계시스템 단독
R412월 이후 멤버십 연동 · 계좌 명세 대조 · KPI 자동 판정-

이 일정의 전제 — 물품 내역과 확정 가격이 W1 안에 들어와야 합니다. 품목·단가가 없으면 기준 정보를 채울 수 없고, 그러면 주문 접수도 붙일 데이터가 없습니다. 가안은 준비돼 있으니 확정만 필요합니다.

27/29

SECTION 08 · SCOPE

릴리스 범위

R1 은 백오피스에서 주문 한 건이 끝나는 것까지입니다. 자사몰 연동은 그다음입니다.

R1 · 10월 중순

백오피스

  • DB 스키마 · 기준 정보
  • 주문 접수와 검증
  • 입금 확인
  • 가용 재고
  • 취합 · 발주
  • 검수(사진) · 인도
  • 일별 기록 · 내보내기

R2 · 11월

자사몰 연동

  • 주문 제출 API
  • 재고·가격 실시간 연동
  • 품절 표시
  • 주문 조회(번호+연락처)
  • 신규 주문 알림
  • 중복·스팸 차단

R3 · 11월 말~12월

재고와 대여

  • 입출고 원장
  • 안전 재고 · 주간 실사
  • 대여대장 · 보증금
  • 귀국 전 미반납 경고
  • 월별 손익 집계

R4 · 12월 이후

회원과 자동화

  • 멤버십 연동
  • 계좌 명세 자동 대조
  • KPI 자동 판정
  • 주간 보고 초안
  • 예약대행 · 응급 확장

R1 에서 빼는 것과 이유 — 예약대행·응급·정기방문은 기능 정의서의 확장 단계에 그대로 둡니다. 빈도가 낮아 시스템 없이도 관리됩니다. 자사몰에서도 예약대행은 숨겨 두었습니다(필요해지면 한 줄로 다시 켭니다).

28/29

SECTION 09 · OPEN

아직 정해지지 않은 것

개발 진행에 필요한 답입니다. 주황색은 W1~W2 안에 정해져야 막히지 않습니다.

#항목 정해야 하는 내용기한
1물품 내역과 가격 확정 가안은 준비됨. 대여 정책·단품 대응·수질 구분·후보 품목 채택 등 7건의 결정 필요 W1
2API 키 등록 .envEDM_OPENDATA_API_KEY비어 있음. 키가 없으면 DB provision 부터 막힘 즉시
3앱 slug 등록 확인 DB provision 은 apps.edmedu.com 에 등록된 내 앱 slug만 허용. philippines-service 가 배포·소유 확정 상태인지 확인 필요 즉시
4자사몰 공개 경로 고객은 사내 계정이 없음. 게이트 밖에서 접근 가능한 경로와 주문 제출 API 의 공개 방식 확정 필요 W2
5가상계좌 발급 지금은 임시 계좌번호. 발급 후 자사몰·주문서 두 곳 교체 R2
6미입금 처리 기준 며칠 뒤 자동 보류·취소할지, 부분 입금은 어떻게 볼지 W2
7취소·환불 규정 발주 후 취소 시 고객 부담 범위. 자사몰 FAQ 문구와 함께 확정 W2
8개인정보 보관 기한 보호자 연락처·카카오톡 ID 의 보관 기간과 삭제 기준 W2
9멤버십 연동 방식 회원 고유번호를 어디서 받는지, 비회원 주문을 회원에 사후 연결할지 R4

29/29

받는 쪽을 먼저 만든다

자사몰 화면은 이미 있습니다. 없는 것은 들어온 주문을 처리하는 곳이고, 손해가 나는 곳도 전부 거기입니다. R1 은 주문 한 건의 전 생애가 한 줄로 남는 것이 전부입니다. 데이터는 Open Database 로 확정됐고 클라이언트도 준비됐습니다. 지금 막혀 있는 것은 개발이 아니라 API 키, 앱 slug 확인, 그리고 확정 가격입니다.

← 문서 목록 1 / 29