- Docker Compose, Dockerfile, Vite 프로젝트 초기 세팅 - 메인 페이지: 택배 목록, 필터 탭, 운송장 등록 폼 - 상세 페이지: 배송 타임라인, 별칭 수정, 삭제 - 택배사 로고/컬러 배지, 커스텀 드롭다운 - framer-motion 애니메이션 적용 - PC/모바일 반응형 대응 - 계획서에 carriers 테이블, RustFS 로고 저장 반영 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8.3 KiB
8.3 KiB
Traeon (트래온) - 택배 배송조회 웹 구현 계획서
개요
개인용 택배 배송조회 웹 애플리케이션. 운송장 번호를 등록하면 배송 상태를 조회하고, 백그라운드에서 자동 갱신하며, 상태 변경 시 알림을 보내는 서비스다. 기존 Docker 인프라와 fromis_9 프로젝트의 기술 스택/패턴을 따른다.
기술 스택
| 영역 | 기술 |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS, Zustand, React Query |
| Backend | Fastify 5, MySQL2, node-cron |
| 배송조회 | delivery-tracker 셀프호스팅 (GraphQL API) |
| DB | MariaDB (기존 인프라) |
| 인프라 | Docker Compose, Caddy 리버스 프록시 |
프로젝트 구조
/docker/traeon/
├── docker-compose.yml
├── .env
├── docs/
│ └── plan.md # 이 문서
├── frontend/
│ ├── Dockerfile
│ ├── package.json
│ ├── vite.config.js
│ ├── tailwind.config.js
│ ├── postcss.config.js
│ └── src/
│ ├── main.jsx
│ ├── App.jsx
│ ├── index.css
│ ├── api/
│ │ └── parcels.js # API 클라이언트 함수
│ ├── components/
│ │ ├── ParcelForm.jsx # 운송장 등록 폼
│ │ ├── ParcelList.jsx # 택배 목록
│ │ ├── ParcelCard.jsx # 개별 택배 카드
│ │ ├── TrackingTimeline.jsx # 배송 추적 타임라인
│ │ └── CarrierSelect.jsx # 택배사 선택 드롭다운
│ └── stores/
│ └── useParcelStore.js # Zustand 상태관리
│
└── backend/
├── Dockerfile
├── package.json
└── src/
├── server.js # 진입점
├── app.js # Fastify 앱 빌드
├── config/
│ └── index.js # 환경변수 설정
├── plugins/
│ ├── db.js # MySQL2 연결
│ └── tracker.js # delivery-tracker GraphQL 클라이언트
├── routes/
│ ├── index.js # 라우트 통합
│ ├── parcels.js # CRUD + 조회 라우트
│ └── carriers.js # 택배사 목록 라우트
├── services/
│ ├── parcel.js # 택배 비즈니스 로직
│ ├── tracker.js # delivery-tracker API 호출
│ ├── cron.js # 자동갱신 스케줄러
│ └── notification.js # 알림 서비스 (Discord/Telegram webhook)
└── utils/
└── error.js # 에러 처리
데이터베이스 스키마
CREATE TABLE parcels (
id INT AUTO_INCREMENT PRIMARY KEY,
carrier_id VARCHAR(50) NOT NULL, -- 택배사 코드
carrier_name VARCHAR(100) NOT NULL, -- 택배사 이름
tracking_number VARCHAR(100) NOT NULL, -- 운송장 번호
label VARCHAR(200), -- 사용자 별칭
status VARCHAR(50) DEFAULT 'pending', -- 배송 상태
last_detail TEXT, -- 최근 배송 상세 (JSON)
last_checked_at DATETIME, -- 마지막 조회 시각
delivered_at DATETIME, -- 배송 완료 시각
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uq_carrier_tracking (carrier_id, tracking_number)
);
CREATE TABLE carriers (
id VARCHAR(50) PRIMARY KEY, -- 택배사 코드 (예: kr.cjlogistics)
name VARCHAR(100) NOT NULL, -- 택배사 이름
short_name VARCHAR(20) NOT NULL, -- 약칭 (로고 없을 때 이니셜용)
color VARCHAR(7) NOT NULL, -- 브랜드 컬러 (#hex)
logo_url VARCHAR(500), -- RustFS에 저장된 로고 이미지 URL
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE tracking_events (
id INT AUTO_INCREMENT PRIMARY KEY,
parcel_id INT NOT NULL,
status VARCHAR(50),
description TEXT,
location VARCHAR(200),
event_time DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (parcel_id) REFERENCES parcels(id) ON DELETE CASCADE
);
API 설계
| Method | Path | 설명 |
|---|---|---|
GET |
/api/parcels |
전체 택배 목록 (상태별 필터) |
POST |
/api/parcels |
운송장 등록 |
GET |
/api/parcels/:id |
개별 택배 상세 + 추적 이벤트 |
PUT |
/api/parcels/:id |
별칭 수정 |
DELETE |
/api/parcels/:id |
운송장 삭제 |
POST |
/api/parcels/:id/refresh |
수동 새로고침 |
GET |
/api/carriers |
지원 택배사 목록 (로고 URL 포함) |
구현 단계
1단계: 프로젝트 초기 세팅
docker-compose.yml작성traeon-frontend: node:20-alpine, 포트 80, 네트워크apptraeon-backend: node:20-alpine, 포트 80, 네트워크app+dbdelivery-tracker: 셀프호스팅 컨테이너, 네트워크app- Watchtower 제외 레이블
.env파일 작성 (DB 접속정보 등)- Caddy에
traeon.caadiq.co.kr도메인 추가
2단계: Frontend 구현 (더미 데이터)
- Vite + React + Tailwind 초기 세팅
- 더미 데이터 준비 (택배사 목록, 배송 중/완료 샘플 데이터)
- 메인 페이지
- 운송장 등록 폼 (택배사 선택 + 운송장 번호 + 별칭)
- 택배 목록 (카드형, 상태별 그룹핑: 배송중 / 배송완료)
- 각 카드에 현재 상태, 마지막 위치, 경과 시간 표시
- 상세 페이지
- 배송 추적 타임라인 (세로 타임라인 UI)
- 수동 새로고침 버튼
- 삭제/수정 기능
- Zustand로 UI 상태 관리 (필터, 정렬)
- 디자인 확인 후 피드백 반영
3단계: Backend 구현 + 연동
- Fastify 앱 세팅 (app.js, server.js) — fromis_9 패턴
- DB 플러그인 + 테이블 자동 생성 (parcels, tracking_events, carriers)
- 택배사 로고 이미지를 RustFS에 업로드하고 carriers 테이블에 logo_url 저장
- delivery-tracker GraphQL 클라이언트 플러그인
- API 라우트 구현 (위 API 설계 참고)
- Frontend를 더미 데이터에서 실제 API로 전환
- Vite 프록시 설정 (
/api/→ backend) - React Query로 데이터 페칭 + 자동 리페칭
- Vite 프록시 설정 (
- 자동갱신 cron 서비스 (node-cron)
- 배송 중인 택배: 30분 간격 자동 조회
- 배송 완료된 택배: 조회 중단
- 상태 변경 감지 시 알림 트리거
- 알림 서비스
- Discord Webhook 또는 Telegram Bot API
- 설정 가능한 Webhook URL (.env)
4단계: Docker 배포
- Frontend Dockerfile (node:20-alpine, 개발모드)
- Backend Dockerfile (node:20-alpine, 개발모드)
docker compose up -d --build로 실행 확인- Caddy 리버스 프록시 설정 확인
delivery-tracker 셀프호스팅 연동
delivery-tracker는 GraphQL API를 제공한다. Backend에서 GraphQL 쿼리로 배송 정보를 조회:
query Track($carrierId: ID!, $trackingNumber: String!) {
track(carrierId: $carrierId, trackingNumber: $trackingNumber) {
lastEvent {
time { datetime }
status { code name }
description
}
events {
edges {
node {
time { datetime }
status { code name }
description
}
}
}
}
}
참조할 기존 파일
| 파일 | 용도 |
|---|---|
/docker/fromis_9/docker-compose.yml |
Docker 서비스 구성 패턴 |
/docker/fromis_9/frontend/vite.config.js |
Vite 프록시 설정 |
/docker/fromis_9/backend/src/app.js |
Fastify 플러그인 로드 패턴 |
/docker/fromis_9/backend/src/plugins/db.js |
MySQL2 연결 패턴 |
/docker/fromis_9/backend/src/routes/index.js |
라우트 통합 패턴 |
/docker/fromis_9/backend/src/server.js |
서버 진입점 패턴 |
/docker/caddy/Caddyfile |
Caddy 도메인 추가 위치 |
검증 방법
docker compose up -d --build로 전체 서비스 기동docker compose logs -f로 에러 확인- 브라우저에서
traeon.caadiq.co.kr접속, 운송장 등록/조회 테스트 - cron 자동갱신 로그 확인
- 알림 Webhook 수신 테스트