Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 35 additions & 29 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Source of truth

- Status: Active
- Last refreshed: 2026-09-01
- Last refreshed: 2026-09-08
- Primary product surfaces: DSV 배송원 인증, 배송, 지도
- Evidence reviewed: `docs/project-brief.md`, `docs/technology-stack.md`,
`docs/code-organization.md`, `src/ui/auth/AuthEntryScreen.tsx`,
Expand All @@ -29,11 +29,13 @@ Shopify, 상점 관리자 또는 Routes 전용 인증 개념은 화면에 노출

- 배송원이 로그인 직후 오늘의 배송지와 그 배송지에 속한 주문을 확인한다.
- 일반 화면에서는 SellerOrderKey 기준 주문을 조밀한 행 목록으로 확인한다.
- 별도 순서 편집 모드에서는 SellerOrderKey 주문 1건씩 방문 순서를 결정한다.
- 배송지 묶음은 배정 변경의 단위이며 방문 순서 편집 단위와 구분한다.
- 별도 순서 편집 모드에서는 배송지 묶음별 방문 순서를 결정한다.
- 배송지 묶음은 배정 변경과 방문 순서 편집의 단위이며 두 동작의 서버 권위는
서로 구분한다.
- 결정한 순서를 목록과 지도에서 같은 번호로 확인한다.
- 경로 선은 서버가 OSRM/VWorld로 생성한 geometry가 있을 때만 그대로 표시한다.
- 서버 계약이 확정되기 전에는 미리보기 데이터와 화면 메모리 상태만 사용한다.
- 배차·배송·수동 순서는 승인된 서버 계약을 사용하고, 배송지 정보 UI Preview만
명시된 로컬 fixture와 화면 메모리 상태를 사용한다.
- 플랫폼에 따라 앱 경고·확인 화면의 모양과 행동이 달라지지 않게 한다.
- 배송원이 배송지명·주소 영역에서 고정 배송지 정보를 확인하고, 일반 메모,
점심시간, 점심시간 입장 가능 여부와 필수 도착 시간을 기록한다.
Expand All @@ -56,7 +58,7 @@ Success signals: 확인·경고·오류·성공 메시지가 같은 카드, 버

연결된 배송원으로 인증되면 하단 탭은 두 개만 제공한다.

1. `배송`: 주문 목록 확인, `순서 편집` 액션으로 주문별 순서 편집 전환,
1. `배송`: 주문 목록 확인, `순서 편집` 액션으로 배송지별 순서 편집 전환,
`주문 목록` 액션으로 배송지 묶음 반납·확보 페이지 진입
2. `지도`: 동일한 주문 순서와 서버 제공 경로 geometry를 MapLibre 지도에서
확인
Expand All @@ -80,11 +82,11 @@ Success signals: 확인·경고·오류·성공 메시지가 같은 카드, 버
- 주문 조회와 주문 순서 편집을 화면 상태로 분리한다.
- 주문 목록은 배송처, SellerOrderKey, 운송조건, 박스 수, 고객 코드, 주소를
우선하고 수령인·전화번호·시간대·물품명처럼 배차 원본에 없는 값을 만들지 않는다.
- SellerOrderKey 주문 1건을 순서 변경의 최소 단위로 표현한다.
- 같은 `destinationId`의 주문을 묶은 배송지 1곳을 순서 변경의 최소 단위로 표현한다.
- 배정 변경과 방문 순서 변경을 같은 개념으로 취급하지 않는다.
- 미리보기 데이터와 서버 확정 데이터를 혼동하지 않도록 명확히 표시한다.
- 배송지 정보 UI Preview의 배송일은 `2026-08-26`으로 표시하고, 서로 다른
배송지 8곳의 주문 편집 결과는 화면 메모리에만 유지해 서버 상태로 전달하지 않는다.
- 배송지 정보 UI Preview의 배송일은 `2026-08-26`으로 표시하고, 메모·점심시간·
필수 도착 시간 편집 결과는 화면 메모리에만 유지해 서버 상태로 전달하지 않는다.
- 앱은 배송지 좌표를 임의로 직선 연결하거나 경로를 계산·보간하지 않는다.
- 필수 도착 시간은 첫 버전에서 배송원이 참고하는 정보이며 서버 ETA, 시간창 또는
경로 최적화를 변경하지 않는다.
Expand All @@ -110,10 +112,10 @@ Success signals: 확인·경고·오류·성공 메시지가 같은 카드, 버
- 현재 배송지의 `배송 중` Pill은 행 우측 상단에 두고, 운송조건과 박스 수는
같은 열의 하단에 정렬한다.
- 순서 편집 지도: 화면 위쪽 전체 폭, 높이 고정, 지도 이동만 허용
- 순서 편집 주문 카드: 흰색, 1px 회색 테두리, 12px 모서리, 고정 높이
- 주문 순서 번호는 목록과 지도에서 같은 파란색 표식을 사용한다. 같은 배송지의
여러 주문은 좌표를 바꾸지 않고 한 표식 안에 순서들을 함께 표시한다.
- 모션: 핸들을 누른 채 주문 카드가 슬롯 경계를 넘는 순간 주변 주문만 220ms
- 순서 편집 배송지 카드: 흰색, 1px 회색 테두리, 12px 모서리, 고정 높이
- 배송지 순서 번호는 목록과 지도에서 같은 파란색 표식을 사용한다. 같은 배송지의
여러 주문은 하나의 배송지 표식과 방문 순서를 공유한다.
- 모션: 핸들을 누른 채 배송지 카드가 슬롯 경계를 넘는 순간 주변 카드만 220ms
cubic-out으로 자리를 비운다. 드래그 카드는 별도 레이아웃 애니메이션 없이
손가락을 따르고, 손을 놓을 때까지 재정렬을 미루지 않는다.
- 앱 다이얼로그: 화면 중앙 흰색 카드, 24px 모서리, 어두운 반투명 배경,
Expand All @@ -135,11 +137,11 @@ Success signals: 확인·경고·오류·성공 메시지가 같은 카드, 버
두 목록에 공통으로 적용되는 기준 정보로 표시한다.
- 배송지 묶음 행: 배송처, 주소, 주문 수, 박스 수, 운송조건, 반납·가져오기 액션
- 주문 행: 배송처, SellerOrderKey, 운송조건, 박스 수, 고객 코드, 주소
- 순서 편집 지도: MapLibre 주문 순서 미리보기, 서버 경로, 이동 전용 제스처
- 순서 편집 주문 카드: 왼쪽 드래그 핸들, 순서 번호, 배송처, SellerOrderKey,
- 순서 편집 지도: MapLibre 배송지 순서 미리보기, 서버 경로, 이동 전용 제스처
- 순서 편집 배송지 카드: 왼쪽 드래그 핸들, 순서 번호, 배송처, 주소, 주문 수,
운송조건, 박스 수
- 순서 제어: 왼쪽 핸들을 홀드·드래그해 주문 1건 이동
- 편집 완료/취소: 완료 시 화면 메모리 순서를 반영하고 취소 시 원래 순서 복원
- 순서 제어: 왼쪽 핸들을 홀드·드래그해 배송지 묶음 1곳 이동
- 편집 완료/취소: 완료 시 서버 정본 순서를 반영하고 취소 시 원래 순서 복원
- MapLibre 지도: 서버 제공 경로 선, 번호 표식, 서버 경로 대기 상태 안내
- 하단 탭: `배송`, `지도`
- 새로고침 상태: 화면에 상시 영역이나 버튼을 두지 않고, 당기는 동안에만
Expand Down Expand Up @@ -179,7 +181,7 @@ Success signals: 확인·경고·오류·성공 메시지가 같은 카드, 버

- 휴대전화 세로 화면을 기준으로 한다.
- 기본 주문 목록은 세로 스크롤한다.
- 순서 편집 화면은 상단 지도와 하단 목록을 분리해 지도는 고정하고 주문 카드
- 순서 편집 화면은 상단 지도와 하단 목록을 분리해 지도는 고정하고 배송지 카드
영역만 세로 스크롤한다.
- 지도는 남은 화면을 채우고 작은 화면에서도 요약 카드와 하단 탭이 보인다.
- 태블릿 전용 레이아웃은 이번 범위에 포함하지 않는다.
Expand All @@ -191,12 +193,15 @@ Success signals: 확인·경고·오류·성공 메시지가 같은 카드, 버
않는다.
- 상태 전환: 다른 배차 상태 그룹으로 이동할 때 날짜 선택과 작업 화면을 비운다.
- 기본: SellerOrderKey 기준 주문 행 표시
- 순서 편집 진입: 현재 주문 순서를 편집 초안으로 복사
- 핸들 탭: 이동 대상 주문을 선택 상태로 표시
- 핸들 홀드·드래그: 카드가 다음 슬롯의 절반을 넘는 즉시 주문 1건의 초안 순서를
- 순서 편집 진입: 현재 배송지 순서를 편집 초안으로 복사
- 핸들 탭: 이동 대상 배송지를 선택 상태로 표시
- 핸들 홀드·드래그: 카드가 다음 슬롯의 절반을 넘는 즉시 배송지 묶음 1곳의 초안 순서를
갱신하고 주변 주문을 애니메이션으로 이동
- 지도 이동: 지도 패닝만 허용하고 확대·회전·기울이기와 배송 편집은 허용하지 않음
- 완료: 편집 초안을 화면 메모리에 반영하고 기본 주문 목록으로 복귀
- 완료: 완료 배송지를 포함한 전체 stop 순열과 현재 `expectedVersion`을 서버에
저장하고, 서버가 반환한 새 버전과 정본 순서를 채택한 뒤 기본 목록으로 복귀
- 순서 저장 중: 편집 화면을 유지하며 Android 뒤로가기, 환경설정, 로그아웃과
하단 탭 전환을 막고 성공 또는 실패 결과가 끝난 뒤에만 상위 이동을 허용
- 취소: 편집 초안을 버리고 기본 주문 목록으로 복귀
- 배송 반납: 확인 후 같은 배송지의 모든 주문을 공용 배송으로 이동
- 공용 배송 확보: 서버 선착순 결과를 적용하고 충돌 시 최신 목록으로 갱신
Expand Down Expand Up @@ -232,22 +237,25 @@ Success signals: 확인·경고·오류·성공 메시지가 같은 카드, 버
- fixture 필드는 DSV 배차 원본과 서버 `dsv_dispatch_import_rows`의
`destinationName`, `conditionCode`, `shippedBoxes`, `address`, `customerCode`,
`sellerOrderKey`, `notes`, `destinationId` 구조를 따른다.
- 일반 목록과 순서 편집 모두 SellerOrderKey 주문 1건을 한 행·카드로 유지한다.
- 일반 목록과 순서 편집 모두 같은 `destinationId`의 주문을 배송지 한 행·카드로
묶고 주문 수와 총 박스 수를 함께 표시한다.
- 배차 상태는 서버의 `companyGuidance.executionStatus`를 그대로 사용한다.
클라이언트가 주문 ID, 주문 상태, 배열 순서 또는 날짜로 배차 상태를 추측하지
않는다.
- 같은 `destinationId`의 주문도 각각 독립적인 방문 순서를 가진다. 단, 배정 변경은
기존 제품 계약대로 배송지 묶음 단위다.
- 서버 저장 계약이 정해지면 편집 결과는 `route_plan_stops.sequence`와 revision
정책을 통해 저장하며 클라이언트는 예상 엔드포인트를 만들지 않는다.
- 같은 `destinationId`의 주문은 하나의 방문 순서로 함께 이동한다. 배정 변경도
배송지 묶음 단위지만, 순서 저장과 배정 변경은 서로 다른 서버 명령이다.
- 수동 순서는 승인된 `PATCH /driver/routes/:routePlanId/order` 계약으로 저장한다.
클라이언트는 완료 배송지를 포함한 전체 `deliveryStopId` 순열, 서버에서 받은
`expectedVersion`, 재시도에도 유지하는 `commandId`를 보내고 정본 응답만 채택한다.
`routeVersionId: null`인 레거시 배차에서는 순서 저장을 제공하지 않는다.
- 클라이언트는 경로를 계산하지 않는다. DSV 서버가 OSRM/VWorld로 생성해 응답한
GeoJSON `LineString` geometry만 수정 없이 MapLibre source에 전달한다.
- 서버 geometry가 없거나 stale/unavailable 상태면 경로 선을 그리지 않는다.
- 위치·카메라·사진 앨범 권한 요청은 OS API를 사용한다. OS 소유 권한 창과 외부
앱 선택기는 커스텀 스타일을 적용하지 않으며 그 전후의 앱 안내만 `AppDialog`로
통일한다.
- 앱 코드에서 Android 기본 `Alert.alert`를 사용하지 않는다.
- 주문 순서 변경은 배정이나 배송지 연결을 변경하지 않고 sequence만 바꾼다.
- 배송지 순서 변경은 배정이나 배송지 연결을 변경하지 않고 sequence만 바꾼다.
- 시스템의 동작 줄이기 설정이 켜져 있으면 정착·레이아웃 애니메이션을 생략하고
순서만 즉시 반영한다.
- 서버 계약 전 Preview는 배송지 정보를 화면 메모리에만 저장한다. Preview UI는
Expand All @@ -259,9 +267,7 @@ Success signals: 확인·경고·오류·성공 메시지가 같은 카드, 버

- [ ] 완료·취소 배차 기록을 계정 인증으로 조회할 서버 계약
- [ ] 배송원별 배정 배송지와 주문을 제공할 DSV API 계약
- [ ] 순서 확정의 저장 단위, 낙관적 잠금과 충돌 응답 계약
- [ ] 배송원 계정에 배정된 경로 geometry를 제공할 driver-scoped DSV API 계약
- [ ] 서버 geometry의 fresh/stale/unavailable 상태와 순서 확정 revision 계약
- [ ] 배송 시작 이후 순서 재확정 허용 정책
- [ ] 배송원 route-access 범위에서 고정 배송지 정보를 읽고 수정하는 서버 계약
- [ ] 배송지 정보의 revision 충돌과 항목별 `updatedAt` 저장 계약
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ npx expo install --check

## 현재 범위

현재 DSV 계정 가입·로그인과 연결 상태 확인, 배송지 묶음 순서 변경·확정
미리보기, MapLibre 지도 미리보기를 제공합니다. 인증은 승인된 DSV API를
호출하며 배송지·주문과 순서 확정은 아직 로컬 예시 데이터입니다. 지도 경로는
클라이언트가 만들지 않으며 서버가 OSRM/VWorld로 생성한 geometry가 있을 때만
표시합니다. 배송 조회, 서버 경로, 순서 저장과 배정 변경은 후속 DSV API 계약이
승인된 뒤 연결합니다.
현재 DSV 계정 가입·로그인과 연결 상태 확인, 서버 배차·배송 조회, 배송지별
수동 순서 저장과 MapLibre 지도를 제공합니다. 수동 순서는 `routeVersionId`가
있는 배차에서 전체 stop 순열과 현재 서버 버전을 승인된 DSV API에 보내고 정본
응답을 채택합니다. 레거시 배차처럼 버전이 없으면 저장을 제공하지 않습니다.
지도 경로는 클라이언트가 만들지 않으며 서버가 OSRM/VWorld로 생성한 geometry가
있을 때만 표시합니다. 배송지 묶음 반납·확보도 승인된 DSV API를 사용합니다.
4 changes: 2 additions & 2 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "CLEVER Driver",
"owner": "evandsolution",
"slug": "clever-driver-app",
"version": "0.1.13",
"version": "0.1.14",
"icon": "./assets/branding/driver-app-icon.png",
"orientation": "portrait",
"userInterfaceStyle": "automatic",
Expand All @@ -19,7 +19,7 @@
"android": {
"package": "com.evnsolution.clever.driver",
"predictiveBackGestureEnabled": true,
"versionCode": 13,
"versionCode": 23,
"googleServicesFile": "./.private/google-services.json",
"adaptiveIcon": {
"foregroundImage": "./assets/branding/driver-app-icon-foreground.png",
Expand Down
7 changes: 5 additions & 2 deletions docs/project-brief.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,11 @@ localhost 또는 `127.0.0.1` 개발을 위한
발급한 경로 범위 토큰으로 `/driver/assigned-route`를 조회해 표시한다. 화면의
배송일은 기기 날짜가 아니라 응답의 `deliveryDate`를 사용한다. 앱은 배송지
좌표를 임의로 연결하거나 경로를 계산하지 않으며, 서버의 `routeGeometry`가
있을 때만 그 좌표를 수정 없이 표시한다. 순서 저장은 별도 API 계약이 승인된
뒤 연결한다.
있을 때만 그 좌표를 수정 없이 표시한다. `routeVersionId`가 있는 배차의 수동
순서는 경로 토큰으로 `PATCH /driver/routes/:routePlanId/order`에 완료 배송지를
포함한 전체 `deliveryStopId` 순열, `expectedVersion`, `commandId`를 보내 저장한다.
앱은 서버가 반환한 새 버전과 순서만 채택하며 `routeVersionId: null`인 레거시
배차에서는 수동 순서 저장을 제공하지 않는다.

주문 목록은 본 화면에서 선택한 배송일·배차 ID·배차명·경로 범위 토큰을 함께 받는다.
배차나 배송일이 바뀌면 목록 상태를 새로 만들고, 화면에는 선택한 배송일과 배차명을 표시한다.
Expand Down
Loading