오프라인 우선
개념 정의
오프라인 우선은 PDA가 네트워크에 항상 연결되어 있지 않아도 현장 작업을 일정 범위 안에서 계속할 수 있도록 설계하는 방식입니다. 모든 기능을 오프라인으로 허용한다는 뜻은 아닙니다. 스캔처럼 현장에서 멈추면 안 되는 작업은 로컬에 먼저 기록하고, 확정처럼 서버 검증이 필요한 작업은 온라인 상태에서 처리하도록 경계를 나누는 것입니다.
창고 PDA는 일반 웹 관리 화면과 환경이 다릅니다. 작업자 는 이동하면서 스캔하고, 무선 신호가 약한 구역이 있으며, 같은 바코드가 짧은 시간에 반복 입력됩니다. 따라서 서버 요청 실패를 곧바로 작업 실패로 처리하면 현장이 멈춥니다.
실제 업무 흐름
오프라인 우선 PDA의 기본 흐름은 다음과 같습니다.
- 작업 시작 전 작업 목록, 상품, 바코드, 로케이션 정보를 내려받습니다.
- 작업자가 로케이션 또는 상품을 스캔합니다.
- PDA는 스캔 이벤트를 로컬 큐에 저장합니다.
- 화면은 로컬 큐 기준으로 진행률을 즉시 보여줍니다.
- 네트워크가 가능하면 큐를 서버에 전송합니다.
- 서버는 멱등 키로 중복 여부를 확인하고 업무 검증을 수행합니다.
- 성공한 이벤트는
SYNCED, 실패한 이벤트는FAILED또는CONFLICT로 표시합니다. - 충돌이 있으면 작업자가 해결할 수 있는 업무 메시지를 보여줍니다.
이 흐름에서 중요한 점은 "작업자 경험은 끊기지 않게", "서버 확정은 엄격하게" 가져가는 것입니다.
화면/기능 관점 설명
PDA 화면은 네트워크 상태와 동기화 상태를 작업자가 이해할 수 있어야 합니다.
| 기능 | 설 명 |
|---|---|
| 작업 목록 캐시 | 온라인일 때 내 작업을 내려받아 오프라인에서도 표시 |
| 스캔 즉시 반영 | 로컬 큐 저장 후 화면 진행률 증가 |
| 동기화 배지 | 대기, 전송중, 완료, 실패 표시 |
| 충돌 해결 화면 | 서버와 수량이 달라진 이벤트를 확인하고 재처리 |
| 수동 재전송 | 실패 이벤트를 작업자가 다시 전송 |
| 작업 잠금 안내 | 서버 검증이 필요한 확정 버튼은 오프라인에서 제한 |
예를 들어 피킹 화면에는 "지시 10개 / 로컬 스캔 8개 / 서버 반영 6개"처럼 표시할 수 있습니다. 이 차이를 숨기면 작업자는 완료됐다고 생각하지만 서버에는 일부만 반영된 상태가 됩니다.
백엔드 API 관점 설명
서버 API는 오프라인 큐의 재전송을 전제로 설계해야 합니다.
| API | 역할 |
|---|---|
GET /api/pda/bootstrap | 작업에 필요한 기준정보 내려받기 |
GET /api/pda/tasks | 작업 목록 조회 |
POST /api/pda/scan-events/bulk | 여러 스캔 이벤트 일괄 전송 |
GET /api/pda/sync-status?taskId=... | 서버 반영 상태 조회 |
POST /api/pda/events/{eventId}/retry | 실패 이벤트 재처리 |
POST /api/outbound-tasks/{id}/complete-picking | 서버 검증 후 피킹 완료 |
스캔 이벤트 전송 예시는 다음과 같습니다.
{
"deviceId": "PDA-17",
"workerId": "worker-17",
"events": [
{
"scanEventId": "PDA-17-20260616-000001",
"taskId": "PICK-10001",
"scanType": "ITEM",
"barcode": "8800000000012",
"quantity": 1,
"scannedAt": "2026-06-16T09:10:00+09:00"
}
]
}
서버는 scanEventId를 유니크 키로 저장합니다. 같은 이벤트가 다시 오면 재반영하지 않고 기존 처리 결과를 반환해야 합니다.
데이터베이스 테이블 관점 설명
오프라인 우선 설계에는 로컬 저장소와 서버 테이블이 모두 필요합니다.
PDA 로컬 저장소 예시:
| store | 역할 |
|---|---|
cached_tasks | 내려받은 작업 목록 |
cached_items | 상품/바코드 기준정보 |
scan_queue | 전송 대기 중인 스캔 이벤트 |
sync_log | 동기화 시도와 오류 기록 |
서버 테이블 예시:
| 테이블 | 주요 컬럼 |
|---|---|
pda_device | device_id, warehouse_id, last_seen_at |
pda_scan_event | scan_event_id, task_id, barcode, qty, status |
pda_sync_batch | batch_id, device_id, status, received_at |
outbound_task_progress | task_id, picked_qty, synced_qty, version |
상태값 예시
스캔 이벤트 상태는 다음처럼 나눌 수 있습니다.
| 상태 | 의미 |
|---|---|
PENDING | 로컬에 저장됐지만 아직 서버 전송 전 |
SYNCING | 서버 전송 중 |
SYNCED | 서버 반영 완료 |
FAILED | 네트워크 또는 서버 오류 |
CONFLICT | 서버 업무 상태와 충돌 |
IGNORED_DUPLICATE | 이미 처리된 이벤트 |
작업 완료 상태와 스캔 동기화 상태를 섞지 않는 것도 중요합니다. 작업은 PICKING인데 일부 스캔은 FAILED일 수 있습니다.