상태 variant 토글 (8화면 연동)

현재 상태: default — 화면마다 해당 variant가 있을 때만 내용이 바뀌고 없으면 default 유지 (핵심: 002·004·007·008)

SCR-FSM-001로그인·프로젝트 선택

진입점 · 인증(첫 로그인 또는 PIN 잠금) → 프로젝트 목록·선택 → 도면·개소·섹션 다운로드·오프라인 캐싱(홈 요약 포함)

  1. 로그인 폼 — Phase 1 공통 인증 IF-CM-AUTH-001(POST /api/auth/login)을 그대로 쓴다. 기기에 저장된 로그인 정보가 있으면 이 폼을 건너뛰고 PIN 잠금부터 연다 — 앱을 완전히 껐다 켜도 로그인이 풀리지 않는다 (②·③·⑦)
  2. PIN 잠금 (pin-lock 상태) — 저장된 로그인 정보가 있으면 프로젝트 목록보다 먼저 PIN 숫자 4~6자리를 받는다. NFR-SC-FS-002 「앱 시작 시 매번 인증」을 이 관문이 받는다. 기기 안에서만 확인하고 서버로 보내지 않는다. 5회 틀리면 30초 잠금 (②·③·⑤)
  3. PIN 설정 (최초 1회) — 아이디·비밀번호로 로그인한 직후 그 자리에서 PIN 을 두 번 받아 저장한다. 건너뛰지 못한다 (③·⑤)
  4. 다른 계정으로 로그인 — PIN 을 잊었을 때의 유일한 길이다. 저장된 로그인 정보를 지우고 로그인 폼으로 되돌린다. PIN 만 따로 되찾는 길은 두지 않는다 (③·⑤)
  5. 프로젝트 카드 목록 — Project.project_id·Project.name 바인딩. 카드를 탭하면 도면·개소·섹션을 다운로드한 뒤 SCR-FSM-007로 자동 진입한다 (③·⑤)
  6. 캐시 상태 배지 — Drawing.cached_path 유무. 도면 본문을 받아 두었는지 보여준다 — 받아 둔 도면만 오프라인에서 열린다 (③)
  7. 최근 동기화 표시 — Project.last_sync_at (③)
  8. 로컬 저장 용량 표시 — "로컬 저장된 데이터 크기 표시"(FR-FS-006) 요구는 있으나 구체 필드는 소스에 없어 미확정이다 (③)
  9. 로그아웃 — 프로젝트 목록 머리에 [동기화 현황]과 나란히 둔다. 누르면 확인 창이 뜨고, 못 보낸 실측이 있으면 몇 건인지 알리되 로그아웃을 막지는 않는다. 생김새는 시안(#882)·구현(#892)이 정하고 여기서는 자리만 잡는다 (③·⑤)
관련 API Swagger UI ↗
  • POST/api/auth/login — 로그인 인증. Phase 1 공통 인증 IF-CM-AUTH-001 을 그대로 쓴다(앱 실측, §12 ⑦)
  • POST/api/auth/refresh — 저장된 재발급 토큰으로 인증을 갱신한다. 서버가 400·401·403 으로 물리치면 저장된 로그인 정보를 지우고 로그인 폼으로 되돌린다(§12 ⑤)
  • GET/api/pm/projects — 참여 중인 프로젝트 카드 목록 조회, 다운로드 대상 선정
  • GET/api/fs/projects/{projectId}/sections?updatedAfter=&cursor=&limit= — 프로젝트 부호(섹션)·설계 기준값을 오프라인 캐시로 받는다 — IF-FS-SECTION-001 (§5.9.5). 응답은 {projectId, items[], serverTimestamp, nextCursor, hasMore, payloadSha256} 이고 항목마다 designBaseline·baselineSource 가 온다(2026-08-17 서버 대조 — §5.9.5 응답 예시와 같다). 한꺼번에 받는 번들 주소는 두지 않는다 — 프로젝트는 IF-PM-PRJ-001, 도면은 IF-FS-DRAWING-001 로 나눠 받는다
오프라인

2PIN 잠금 — 앱을 켤 때마다 거치는 관문

저장된 로그인 정보가 있을 때 프로젝트 목록보다 먼저 뜬다. 아이디·비밀번호는 다시 묻지 않는다

PIN 입력 자리 — 숫자 4~6자리 (● ● ● ● ○ ○)

장갑 낀 손을 고려해 숫자판을 크게 둔다 — 생김새는 시안(#882)이 정하고 여기서는 자리만 잡는다

숫자판 자리 (1~9 · 0 · 지우기)

틀렸을 때 (pin-error 상태)

PIN 이 맞지 않습니다 — 3회 남았습니다

5회 틀렸을 때 (pin-locked 상태) — 입력칸이 막힌다

5회 틀렸습니다 — 30초 뒤 다시 시도할 수 있습니다 (남은 시간 표시)

4다른 계정으로 로그인

PIN 을 잊었을 때의 유일한 길이다 — 저장된 로그인 정보를 지우고 로그인 폼으로 되돌린다. PIN 만 따로 되찾는 길은 두지 않는다

1로그인

저장된 로그인 정보가 있으면 이 폼을 건너뛰고 PIN 잠금(pin-lock 상태)부터 연다

아이디 입력 자리
비밀번호 입력 자리
로그인

3로그인에 성공하면 그 자리에서 PIN 을 정한다 (최초 1회, 건너뛰지 못한다)

PIN 설정 자리 — 숫자 4~6자리
PIN 확인 자리 — 한 번 더 입력

5프로젝트 선택 — 카드 목록

동기화 현황 9로그아웃
프로젝트 A6캐시 완료

7최근 동기화자리

프로젝트 B다운로드 중

최근 동기화자리

프로젝트 C오프라인 · 캐시 없음

최근 동기화자리

8로컬 저장 용량 표시 자리


로그아웃 확인 창 — 위 [로그아웃] 을 누르면 뜬다

아직 서버로 보내지 못한 실측이 N건 있습니다 — 값은 폰에 그대로 남고, 다시 로그인하면 이어서 보냅니다
취소
로그아웃

프로젝트 다운로드 중

도면 · 개소 · 섹션(기준값 포함) 다운로드 중 — 완료 후 SCR-FSM-007로 자동 진입

프로젝트 선택

참여 중인 프로젝트가 없습니다
오프라인신규 다운로드 불가

프로젝트 선택 (로컬 캐시만 표시)

프로젝트 A캐시 완료
프로젝트 C캐시 완료
다운로드 (오프라인 · 비활성)
SCR-FSM-002BLE 페어링·연결전역

전역(프로젝트 무관) · 측정기 페어링·배터리·자동재연결 · 모든 화면 상태바의 BLE 칩에서 진입

  1. 상태바 BLE 칩(현재) — 프로젝트 진입 전후 어디서나 하단(상태바) 칩으로 접근하는 전역 화면이다 (①)
  2. BLE 스캔 목록 — 신호 강도 30dBm 이상인 근처 측정기만 표시한다 (③, FR-FS-001)
  3. 연결 상태 카드(device_id) — 연결됨·끊김·약함 표시. 장치 선택 → 자동 페어링, 앱 재시작 시 이전 장치 자동 재연결 (③·⑤)
  4. 배터리 레벨 — 20% 이하 주황 "배터리 부족", 5% 이하 빨강 "배터리 거의 없음" 경고 (⑤, FR-FS-009)
관련 API Swagger UI ↗
  • N/A이 화면은 안드로이드 BLE 스캔·페어링 SDK로 기기와 직접 통신하며 서버 REST API를 호출하지 않는다. 페어링 이력·기기 등록을 서버에 남길지는 §12 미확정.
1BLE(현재) 오프라인

2BLE 스캔 목록 (신호 30dBm 이상만 표시)

레이저 측정기 #1신호 4/5
레이저 측정기 #2신호 3/5

3연결 상태 (device_id)

연결됨 · device_id 자리연결됨

4배터리 82%

신호 강도 4/5 바

단말 Bluetooth 꺼짐 — 설정에서 켜주세요
설정으로 이동 (자리)

연결 끊김

자동 재연결 시도 중… (최대 3회 · 2초 간격 — 재확인 필요, ⑤ 참조)

3회 실패 시 사용자 개입 요청

수동으로 다시 연결 시도
SCR-FSM-003개소 선택·목록

프로젝트 하위 · 개소별 업무상태 리스트 — SCR-FSM-007 도면 뷰어의 리스트형 대체 진입(fallback)

  1. 필터 칩(부호별) — Section.section_code 기준 동(섹션)별 필터, 다중 선택 가능, 기본값 "전체" (③·⑤, FR-FS-003)
  2. 개소 리스트 행 — Area.label. 행을 한 번 탭하면 곧장 SCR-FSM-004로 이동한다. 목적지는 SCR-FSM-007 마커 탭과 같으나 걸음 수가 다르다 — 도면 뷰어는 두 걸음이고 이 목록은 한 걸음이다. 목록에는 겹쳐 눌릴 마커가 없어 헛짚을 자리가 없기 때문이다(#1370) (③·⑤)
  3. 업무상태 배지 — Area.biz_status. 배색은 SCR-FSM-007이 정한 규칙을 재인용한다 — 업무상태 여섯을 색 셋으로 옮기고 재측정은 빨강이 아니라 회색이다(다시 재야 하므로, 2026-08-14 앱 실물 확정). 앱이 「재측정」을 실측대기와 같은 묶음으로 옮겨 그린다(bizStatusBadge). AN12-1 FR-FS-008 이 적던 「앱 내 빨강 배지」도 이 회색으로 바로잡았다(2026-08-22, #1361) (⑤)
  4. 정렬 옵션 — 개소명·진행 상태·측정 시간순 정렬을 제공한다 (③, FR-FS-003)
  5. 진행률 바 자리 — 프로젝트별·동별 진행률(파생 표시) — "진행률 바 표시" 요구만 있고 구체 필드는 소스에 없다 (③, FR-FS-003)
관련 API Swagger UI ↗
  • GET/api/fs/projects/{projectId}/areas?updatedAfter=&cursor=&limit= — 개소 목록·업무상태 증분 동기화 — IF-FS-AREA-001 (§5.4.5 승격 절). 주소에 프로젝트 축이 들어간다 — 승격 전 잠정 표기와 다르다(DE24-1 §5.4.5 「경로가 placeholder 와 다르다」, 2026-08-17 서버 대조)
오프라인
1전체 AW01 AW02

4정렬: 개소명순(자리) · 필터: 업무상태별 · 동(섹션)별

2AW01-13실측대기
AW01-2측정중
AW01-3완료
AW01-4재측정

5진행률 바 자리

등록된 개소가 없습니다
오프라인
AW01-1 (로컬 캐시)실측대기
AW01-3 (로컬 캐시)완료

네트워크 복구 시 최신 목록으로 갱신

SCR-FSM-004실측 입력·결과

개소 하위 · 재는 쪽(내측만·외측만·둘 다) 먼저 고르기 + W·H 기본 + 보조 라벨 자유 추가, 선택→측정→자동입력(BLE) 순차, 수동 입력 상시 병행, ±10% 검증(도면값 있는 항목), 재측정 · 미서기 개소는 환풍구 유무·위치(모듈→코너) 지정 + 환풍구 가로·세로 자동 항목 · 항목마다 사진·도면 위치 남기기(선택)

  1. 재는 쪽 고르기 (#842) — 측정 항목 목록보다 먼저 「내측만·외측만·둘 다」를 고른다(fs_measurement.side_mode). 고른 값에 따라 항목 목록이 만들어진다 — 「둘 다」면 W·H·보조 항목이 두 벌로 늘고 환풍구 가로·세로는 한 벌 그대로다. 개소 단위로 남기는 까닭은 「둘 다 재기로 했는데 한쪽이 아직 안 왔다」와 「애초에 한쪽만 재기로 했다」를 사무실이 가를 수 있어야 해서다 (③·⑤)
  2. 항목별 쪽 배지 (#842) — 항목 줄마다 내측·외측 배지가 붙는다(fs_meas_dim.dim_side). 도면값은 안팎 구분 없이 한 벌이고 두 줄이 그것을 나눠 쓴다 — 도면값은 「만들 창호의 치수」라 개구부를 어느 면에서 쟀느냐와 축이 다르기 때문이다. 편차는 두 줄에서 각각 계산돼 각각 ±10% 경고를 받는다. 내측값과 외측값이 다른 것 자체는 경고가 아니다 — 어느 쪽을 쓸지는 사무실 검토(SCR-FS-002)가 정한다 (③·⑤)
  3. 사진·위치 열 — 항목 줄마다 붙은 사진·메모 수와 도면 위치 표시 여부를 한 자리에서 보인다. 붙은 것이 없으면 📷0, 위치를 안 찍었으면 다. 둘 다 선택이다 — 없어도 저장·전송된다 (③·⑤)
  4. 도면 위치 찍기 (2026-08-07 결정)📍 를 누르면 도면 태깅 전용 화면(SCR-FSM-009)이 전체화면으로 열린다. 개소에 달린 도면 가운데 하나를 골라 원도면 그대로 위에 찍는다. 저장 전에도 찍을 수 있고 로컬에 쌓였다가 측정과 함께 올라간다. ⛔ 종전 「그림틀」(앱이 그리는 창호 사각형에서 상·중앙·하를 고르던 방식, #843)은 폐기했다 — 그 그림은 미서기 연창 격자로만 그려져 커튼월 같은 다른 구조에서 쓸 수 없다 (③·⑤)
  5. 측정 항목 리스트 — W(폭)·H(높이) 기본 상시 + 보조 라벨(사용자 추가). 데이터 바인딩 MEAS_DIM.dim_type을 사용자 정의 라벨로 확장(기존 W/H/대각선 고정 라벨에서 확장 — 구조설계 반영 후속 필요) (③)
  6. 항목 선택(arming) — 행을 탭하면 그 항목이 "측정 대기"로 하이라이트된다(한 번에 하나만 선택) (③·⑤)
  7. 측정 버튼 — 선택된(armed) 항목에 대해 BLE 측정을 트리거하고, 수신값(StandardMeasurement{dimType,value_mm,ts})이 그 항목에 자동 입력된다. 다음 항목을 다시 선택→측정→자동입력하는 순차 흐름이다 (⑤, FR-FS-002)
  8. 수동 입력 필드 — 어느 항목이든 BLE 연결 여부와 무관하게 키보드 또는 음성으로 항상 입력할 수 있다(BLE는 보조 수단) (③·⑤, FR-FS-002)
  9. + 보조 수치 추가 — 사용자가 라벨을 직접 입력해 행을 늘리거나 삭제한다(예: 대각선·W1·W2·H1·H2). 도면 기준값이 없는 보조 항목은 편차를 표시하지 않는다(도면값을 별도 입력하면 계산 — 확정 필요) (③·⑤)
  10. 재측정 이력 자리 — 동일 개소 재측정 시 새 측정 세션으로 이력이 누적된다 — 덮어쓰기가 아니다 (③·⑤)
  11. 되돌아온 개소 띠와 반려 사유 (#1449 신설)returned 갈래다. Area.biz_status = 재측정 인 개소로 들어오면 3열 표 위에 되돌아온 건임을 알리는 띠를 두고 사무실이 적은 반려 사유를 그대로 보인다. 현장에서 다시 잴 때 읽어야 하는 글이라 동기화 현황(SCR-FSM-008)에만 두지 않는다 — 두 화면을 오가며 외우게 하지 않으려는 것이다. 낫표로 묶어 그대로, 석 줄까지 보이고 넘치면 그 줄을 눌러 편다. 사유가 없으면 띠는 그대로 두고 사유 줄만 비운다. 입력도 저장도 막지 않는다 (③·④·⑤)
  12. 환풍구 유무 토글 — 개소 제품이 미서기창일 때만 노출. 기본 꺼짐, 켜면 아래 위치 지정 2단계가 열리고 측정 항목에 환풍구 가로·세로가 자동 추가된다 (③·⑤)
  13. 환풍구 위치 STEP 1(모듈) — 미서기 연창 격자(OPT-LAY, 제품 설계정보)를 그리드로 보여주고 환풍구가 들어갈 모듈을 고른다 (③·⑤)
  14. 환풍구 위치 STEP 2(코너) — 선택 모듈의 편창 칸(좌창/우창, 3편창이면 좌·중·우)별 4코너(좌상·좌하·우상·우하)를 체크박스로 지정한다. 여러 곳 동시 가능, 2편창=8·3편창=12 선택지. 편창 칸 수·격자는 제품 설계정보에서 온다 — 스키마 확정 후속 갭 (③·⑤)
관련 API Swagger UI ↗
  • POST/api/fs/measurements — BLE·수동으로 입력한 실측값(재는 쪽·항목별 쪽·도면 위치·W·H·보조항목·환풍구 치수) 서버 전송
오프라인
1재는 쪽
내측만 외측만 둘 다 ✓
5라벨2도면값실측값편차3사진·위치
W(폭)내측1800mm1795mm-0.3%📷2 4
6H(높이)내측1500mm측정 대기(자리)📷0 ○
대각선(보조)내측도면값 없음2338mm— (도면값 없음)📷1
W(폭)외측1800mm1812mm+0.7%📷1
H(높이)외측1500mm수동입력 자리📷0 ○
대각선(보조)외측도면값 없음수동입력 자리📷0 ○
환풍구 가로자동구분 없음측정/수동📷0 ○
환풍구 세로자동구분 없음측정/수동📷0 ○
7측정(BLE)
8실측값 수동 입력
9+ 보조 수치 추가
11환풍구 (미서기 개소 전용) ✓ 환풍구 있음
12STEP 1 · 모듈 선택2×2
1 2 ✓ 3 4
13STEP 2 · 코너 체크여러 곳 가능
좌창
우창
저장

10재측정 이력 자리

BLE 미연결 — 수동 입력 모드 (BLE는 보조 수단, 수동은 항상 가능)
라벨도면값실측값편차입력방식
W(폭)1800mm수동입력 자리(자리)수동
H(높이)1500mm수동입력 자리(자리)수동
실측값 수동 입력 (강조 — BLE 미수신 상태, 모든 항목 키보드로 입력)
저장
라벨도면값실측값편차입력방식
W(폭)1800mm1795mm-0.3%BLE
H(높이)1500mm1650mm+10.5% 초과BLE
편차 ±10% 초과 — 확인 후 저장하시겠습니까?
취소
그래도 저장

되돌아온 개소 — 사무실이 반려한 건 (#1449 신설)Area.biz_status = 재측정 · SCR-FSM-008 「되돌아온 건」 카드로 들어온 자리

11사무실이 반려했습니다 — 다시 재 주세요재측정
「내측 높이가 도면값과 150mm 차이납니다. 창틀 안쪽에서 다시 재 주세요」사무실이 적은 글 그대로 · 석 줄까지 · 넘치면 눌러 편다 · 사유가 없으면 이 줄만 비운다(띠는 그대로)
라벨도면값실측값편차입력방식
W(폭)1800mm1795mm-0.3%BLE
H(높이)1500mm1650mm+10.5%BLE
저장

입력도 저장도 막지 않는다 — 띠와 사유를 보이기만 한다(§4-1 원칙)

SCR-FSM-005사진·메모 첨부

측정 하위 · 개소·측정 부속정보(선택) · 개소 완료(들어온 자리로 되돌림)·뒤로(실측 입력)

  1. 사진 썸네일 슬롯 — PHOTO. 최대 5장, 업로드 전 최대 2MB/장으로 자동 압축한다. 썸네일을 누르면 크게 보기 겹창이 뜬다 (#1417 신설) — 어두운 전체 바탕에 사진 한 장(긴 변 1440화소)과 [지우기]·[닫기] 를 두고, 사진 바깥을 눌러도 닫힌다. ➕ 캡션 줄 아래·단추 줄 위에 「무엇이 문제인가」 칩 넷과 「한 줄 설명」 입력칸(최대 500자)을 둔다 (#1517 확정) — 지금 보는 사진의 값을 보이고, 고치면 그 사진에만 담기며, 좌우로 넘기면 두 칸도 그 사진의 값으로 바뀐다. 화면 번호를 따로 주지 않고 이 화면의 상태(photo-viewer)로 둔다. 지우기는 크게 보기 안에만 있고 한 번 되묻는다 — 목록 칸에는 지우기를 두지 않는다(장갑 낀 손으로 잘못 눌러 사진을 잃는 것을 막는다) (③·④·⑤, FR-FS-010)
  2. 개소 완료·뒤로 버튼 (#1417 확정)[개소 완료](종전 「저장」)는 이 개소를 마치고 들어온 자리로 되돌린다 — 개소 목록(SCR-FSM-003)에서 들어왔으면 목록으로, 도면 뷰어(SCR-FSM-007)에서 들어왔으면 뷰어로 간다. [← 뒤로]는 측정값을 고치러 실측 입력(SCR-FSM-004)으로 돌아간다. 이 화면에는 저장할 것이 남아 있지 않아 「저장」이라는 이름을 걷었다 — 측정값은 SCR-FSM-004 가 이미 저장했고, 사진은 붙일 때마다 곧바로 담기며, 메모는 어느 쪽으로 나가도 담긴다. 부속정보는 선택이라 사진·메모 없이 눌러도 된다 (③·⑤)
  3. 카메라·갤러리 버튼 — 촬영 또는 갤러리에서 선택한다 (③, FR-FS-010)
  4. 메모 입력 — MEMO. 최대 500자, 텍스트 또는 음성→텍스트 변환을 지원한다(장갑 착용 대응) (③·⑤, FR-FS-011)
  5. 무엇이 문제인가 — 태그 고르기 (#847) — 「손상」·「불균형」·「기타」 셋 가운데 하나를 고른다(fs_attachment.issue_tag, 저장 값은 DAMAGE·IMBALANCE·OTHER). 비워 둘 수 있다 — 기본값이 「없음」이라 안 골라도 저장·전송된다. ➕ 사진 크게 보기에도 같은 칩을 그대로 둔다 — 이름을 나누지 않는다 (#1517 확정). 찍기 전(이 자리)과 찍은 뒤(크게 보기) 어느 쪽에서도 값을 보고 바꿀 수 있고 두 자리가 같은 값을 함께 쓴다. 셋을 고정하고 늘리지 않으며, 안 맞는 것은 「기타」가 받는다. 둘이 함께 보이면 사진을 한 장 더 붙인다 — 여러 개를 받으려면 중간 표가 필요한데 검토자가 「무엇이 문제인가」를 아는 데는 하나로 충분하다. 사진과 메모가 같은 칸을 쓴다. 사무실 검토(SCR-FS-002)가 이 태그로 목록을 거른다 (③·⑤, FR-FS-011)
  6. 촬영 시간 메타 자리 — 사진 메타정보로 촬영 시간을 자동 기록한다(fs_attachment.taken_at, 단말 로컬 시각). 서버가 받은 시각은 created_at 에 따로 남는다 (③)
  7. 사진 한 줄 설명 (#847 · #1417 확정 · #1517 로 자리 옮김) — 사진마다 한 줄 적는 칸을 둔다. 자리는 이 화면 아래 입력 칸이 아니라 사진 크게 보기(photo-viewer) 안이다 (#1517 확정) — 아래 칸에 두면 [촬영]을 누르는 그 순간의 값만 붙어 찍은 뒤에 적은 글이 사라진다. 크게 보기 안의 칸은 지금 보는 사진의 값을 보이고 좌우로 넘기면 그 사진의 값으로 바뀐다. 칸은 태그와 상관없이 늘 보인다 — 태그가 「기타」일 때만 「무엇인지 한 줄 적어 주세요」 안내 문구가 더 붙는다. 갈리는 것은 안내이지 칸이 아니다(#1417). 「기타」일 때만 칸을 보이면 「손상」·「불균형」을 고른 사진에 설명을 붙일 자리가 없어진다. 비어 있어도 저장된다 — 사진 자체가 이미 무엇을 찍었는지 보여 준다. 새 칸을 만들지 않고 메모가 쓰던 fs_attachment.memo_text 를 사진 행에서도 쓴다 — 2000자 칸이 이미 있고 검사 제약이 사진 행의 메모 글을 막지 않는다. 글자 수 제한은 메모와 같은 500자다 (③·⑤)
  8. 무엇을 찍었나 — 측정 항목 잇기 (#843) — 사진·메모 하나에 측정 항목 하나를 잇는다(fs_attachment.meas_dim_id). 고르개에는 그 개소의 측정 항목이 화면에 보이는 그대로(항목 이름 + 쪽 배지) 나열되고 맨 위에 「개소 전체(항목 없음)」가 있다. 기본값이 「개소 전체」라 아무것도 고르지 않아도 종전과 똑같이 저장된다. 사진 한 장은 항목 하나만 가리키고, 한 항목에 사진 여러 장은 된다. 사진 위에 화살표·동그라미를 찍지 않는다 — 좌표 칸을 새로 만들어야 하고 장갑 낀 손으로 사진 위 한 점을 찍는 것이 느리다. SCR-FSM-004 의 편차 초과 줄에서 [사진]을 눌러 들어오면 그 항목이 미리 골라진 채 열린다 — 강제가 아니라 권함이다 (③·⑤)
  9. 동기화 대기열 등록 — 네트워크가 연결되면 사진·메모가 측정 자료와 함께 자동으로 동기화 대기열에 들어간다 (⑤)
  10. 항목별 모아보기 (2026-08-07 신설) — 개소 전체 사진 묶음 위에 그 개소의 측정 항목(fs_meas_dim)을 줄줄이 늘어놓고 줄마다 📷 붙은 사진·메모 수📍 도면 위 위치 여부를 붙인다. 비어 있는 줄은 「비었음」으로 눈에 띄게 한다 — 어느 항목이 비었는지 현장을 뜨기 전에 채우라고 두는 자리다(사무실에서 되묻는 것을 줄이는 것이 이 요구의 목적이다). 줄을 누르면 그 항목이 「무엇을 찍었나」 고르개에 골라진 채로 사진을 붙일 수 있다. 강제는 아니다 — 비어 있어도 저장·전송된다(「저장을 막지 않는다」 원칙). 측정 항목이 하나도 없으면 상태 empty 로 「아직 잰 항목이 없습니다」를 적고 개소 전체 사진 묶음만 보인다 (③·④·⑤)
관련 API Swagger UI ↗
  • POST/api/fs/measurements/{measurementId}/attachments — 사진·메모 첨부 — 측정 등록 뒤 별도 주소로 올린다(최대 5장·500자). 어느 측정 항목을 찍은 것인지도 함께 보낸다(선택, measDimId). 특이사항 갈래(선택, issueTag = DAMAGE·IMBALANCE·OTHER)와 사진 한 줄 설명(선택, memoText — #847 로 사진 행에도 받는다)을 함께 보낸다 (IF-FS-ATTACH-001 §5.9.4, 설계선행)
오프라인

10항목별 모아보기이 개소의 측정 항목

내측 W(폭)내측📷 2장 · 📍 있음
외측 W(폭)외측📷 1장 · 📍 있음
내측 H(높이)내측📷 비었음 · 📍 없음

1사진 첨부개소 전체 · 최대 5장

사진1
사진2
빈 슬롯
빈 슬롯
빈 슬롯
3카메라
갤러리

8무엇을 찍었나선택

개소 전체 (기본) 내측 W(폭) 외측 W(폭)

4메모최대 500자

메모 입력 자리
128/500자
음성 입력

5무엇이 문제인가선택

없음 (기본) 손상 불균형 기타

7한 줄 설명은 이 자리에 없다 — 사진을 눌러 뜨는 크게 보기 안에서 사진마다 따로 적는다 (#1517 확정)

6촬영 시간 메타 자리

2← 뒤로 (실측 입력)
2개소 완료
오프라인 (로컬 저장)

10항목별 모아보기로컬 자료

내측 W(폭)내측📷 1장 · 📍 있음
내측 H(높이)내측📷 비었음 · 📍 없음
사진1
빈 슬롯
빈 슬롯
메모 입력 자리 (로컬 저장 중)
← 뒤로
로컬 저장

10항목별 모아보기이 개소의 측정 항목

아직 잰 항목이 없습니다 — 측정값을 먼저 넣으면 항목마다 사진·메모 수가 여기에 모입니다

1사진 첨부개소 전체 · 최대 5장

사진1
빈 슬롯
빈 슬롯

잰 항목이 없어 「무엇을 찍었나」 고르개는 두지 않는다 — 개소 전체 사진만 붙는다

2← 뒤로 (실측 입력)
2개소 완료
SCR-FSM-005사진 크게 보기 — 겹창(photo-viewer)

위 005 프레임의 사진 썸네일을 누르면 뜨는 겹창 · 화면 번호를 따로 두지 않고 005 의 한 상태로 둔다(§12 ④ photo-viewer) · [닫기]·사진 바깥 누르기로 005 로 되돌아간다 — 제 항법 자리가 없어 「→ 화면 이동」 존도 두지 않는다

  1. 사진 한 장 (#1417 신설) — 어두운 전체 바탕에 사진 한 장을 긴 변 1440화소로 띄운다. 크게 볼 때 원본을 그대로 쓴다 — 서버가 큰 판을 따로 만들지 않는다 (④)
  2. 「사진 N / M」 셈 · 좌우로 넘기기 (#1468 확정) — 머리에 「사진 N / M」을 적고 좌우로 쓸어 다른 사진으로 넘긴다. 넘기는 범위는 그 개소의 사진 전부다 — 항목별로 가르지 않는다. 붙일 자리의 기본값이 「개소 전체」라 그쪽이 더 흔한데, 항목별로 가르면 가장 흔한 갈래에서 넘길 것이 늘 한 장뿐이 된다 (④·⑤)
  3. 캡션 — 무엇에 붙은 사진인가 (#1468 확정) — 사진 바로 아래 한 줄이다. 항목에 매단 사진은 「내측 W(폭)에 붙은 사진」, 아무 항목에도 안 매단 사진은 「개소 전체 사진」 이다(fs_attachment.meas_dim_id). 지우기를 누르기 직전에 읽는 줄이라 비우지 않는다 (③)
  4. 무엇이 문제인가 — 칩 넷 (#1517 확정) — 「없음」·「손상」·「불균형」·「기타」 가운데 하나를 고른다(fs_attachment.issue_tag, 저장 값은 DAMAGE·IMBALANCE·OTHER). 자리는 캡션 줄 아래·단추 줄 위다. 위 005 화면 아래 칸과 같은 칩을 그대로 두고 두 자리가 같은 값을 함께 쓴다 — 사진용·메모용으로 이름을 갈라 두 칸을 세우지 않는다. 이름을 나누면 「아까 골랐는데 왜 또 물어보지」가 된다. 지금 보는 사진의 값을 보이고, 좌우로 넘기면 그 사진의 값으로 바뀐다 (③·④)
  5. 한 줄 설명 입력칸 (#1417 확정 · #1517 로 자리 옮김) — 최대 500자이고 자리는 칩 줄 아래·단추 줄 위다(fs_attachment.memo_text 를 사진 행에서도 쓴다). 자리를 005 아래 칸에서 이 겹창으로 옮겼다 — 아래 칸에 두면 [촬영]을 누르는 그 순간의 값만 붙어 찍은 뒤에 적은 글이 사라진다. 칸은 태그와 상관없이 늘 보인다 — 태그가 「기타」일 때만 「무엇인지 한 줄 적어 주세요」 안내 문구가 더 붙는다. 갈리는 것은 안내이지 칸이 아니다. 비어 있어도 저장된다 (③·④)
  6. 지우기 — 한 번 되묻는다 (#1417 확정)지우기는 이 겹창 안에만 있다 — 위 005 목록 칸에는 두지 않는다(장갑 낀 손으로 잘못 눌러 사진을 잃는 것을 막는다). 누르면 한 번 되묻는다. 콘솔 쪽 겹창(§11)에는 이 단추를 두지 않는다 — 검토자는 현장 사진을 지우는 사람이 아니다 (③·⑤)
  7. 닫기 · 사진 바깥 누르기 (#1417 신설) — [닫기] 를 누르거나 사진 바깥을 눌러도 닫히고 위 005 로 되돌아간다. 화면 번호를 따로 주지 않은 까닭은 제 데이터도 항법 자리도 없는 겹창이어서다 — 번호를 주면 SCR 매트릭스·와이어프레임·권한 표가 한 줄씩 늘어나는데 그만한 몫이 없다 (④·⑤)
관련 API Swagger UI ↗
  • GET/api/fs/measurements/{measurementId}/attachments — 그 세션의 첨부 목록 — 넘기기 범위·「사진 N / M」 셈·캡션이 이 응답을 읽는다 (IF-FS-ATTACH-001 §5.9.4)
  • POST/api/fs/measurements/{measurementId}/attachments — 사진·메모 첨부 — 붙일 때 특이사항 갈래(issueTag)와 사진 한 줄 설명(memoText)을 함께 보낸다 (IF-FS-ATTACH-001 §5.9.4)
  • DELETE/api/fs/measurements/{measurementId}/attachments/{attachmentId} — 첨부 1건 하드삭제 — [지우기] 가 되묻고 나서 부른다 (IF-FS-ATTACH-001 §5.9.4)
  • PATCH/api/fs/measurements/{measurementId}/attachments/{attachmentId}이미 올린 첨부 고치기 — 겹창에서 고친 태그(issueTag)와 한 줄 설명(memoText)을 담는다. 몸통은 application/json 이고 보내지 않은 항목은 그대로 두고 null 로 보낸 항목은 비운다 — 태그를 「없음」으로 되돌리는 길이다. 사진 자체는 건드리지 않는다 (IF-FS-ATTACH-001 §5.9.4, ✅ 서버 구현 완료 — #1553 이 계약을 세우고 #1567 이 만들었다)

2사진 2 / 5

7닫기
2 1사진 자리 — 긴 변 1440화소, 원본 그대로

3내측 W(폭)에 붙은 사진항목에 안 매단 사진이면 「개소 전체 사진」

4무엇이 문제인가선택 · 005 아래 칸과 같은 값

없음 (기본) 손상 불균형 기타

5한 줄 설명최대 500자 · 이 사진에만 담긴다

한 줄 설명 입력 자리
42/500자 태그가 「기타」일 때만 「무엇인지 한 줄 적어 주세요」 안내가 더 붙는다 — 칸 자체는 늘 보인다
6지우기
7닫기
6되묻기 — 「이 사진을 지웁니다. 되돌릴 수 없습니다」 [지운다]·[그만두기]
7사진 바깥 자리 — 여기를 눌러도 닫힌다
SCR-FSM-006오프라인 저장·동기화

단말 설정 · 로컬 저장·배치 push 동작·정책 · SCR-FSM-008 동기화 현황의 [저장·동기화 설정] 에서 진입 (#881 4단계 결정)

  1. 동기화 상태 표시 — MEASUREMENT.sync_status(draft/pending/synced/failed) (③)
  2. 로컬 저장 건수 표시 자리 — 최소 500건 이상 보관 — 구체 표시 필드는 소스에 없어 미확정이다 (③, FR-FS-004)
  3. 로컬 저장 항목 리스트 — 전송완료 항목을 보여준다 (③)
  4. 일괄 전송 버튼(배치 push) — 네트워크 복구 시 백그라운드에서 자동 동기화하며, gzip 압축 배치 최대 500건을 30초 이내 완료 목표로 한다 (⑤, NFR-PF-FS-003)
  5. [보낸 자료 정리] (#1436 확정) — 손으로 지우는 자리를 이 화면에 둔다. 누르면 전송이 끝난 건의 사진만 지우고 측정값·메모는 남긴다. 지우기 전에 한 번 되묻고, 그 창에 「사진 N장을 지웁니다 · 측정값과 메모는 그대로 둡니다」를 적는다. 시안 f006 의 「더보기에서 고릅니다」는 따르지 않는다 — 이 화면 위 막대에 더보기 단추가 없다 (③·⑤)
  6. 저절로 지우기 (#1436 확정) — 사진은 전송이 끝나고 30일이 지나면 저절로 지운다. 측정값과 메모는 저절로 지우지 않는다 — 지우면 앞 회차 값 되살리기와 재측정 이력이 함께 없어진다. 이쪽은 되묻지 않고 규칙을 이 화면에 글로 적어 둔다 (③·⑤)
  7. 지워진 사진 자리 (#1436 확정) — 사진을 지운 자리는 비우지 않고 「기기에서 지웠습니다 — 사무실에서 볼 수 있습니다」로 적는다. 빈 자리로 두면 「사진을 안 찍었다」로 읽힌다 (③)
  8. 재시도 정책 — 전송이 실패하면 간격을 늘려 가며 최대 5회까지 다시 보낸다(지수 백오프). 실제 값은 착수 시 확정한다 (⑤)
관련 API Swagger UI ↗
  • POST/api/fs/measurements — 네트워크 복구 시 쌓인 실측 전송 — 배치·gzip 지원 여부는 서버 계약 확인 필요
오프라인
1동기화 상태synced

2로컬 저장 건수 표시 자리

로컬 저장 항목

3AW01-2 측정전송완료
AW02-1 측정전송완료
4일괄 전송 (배치 push)
5보낸 자료 정리

6전송이 끝나고 30일이 지난 사진은 저절로 지웁니다. 측정값과 메모는 그대로 둡니다.

오프라인 — 로컬 DB(암호화) 저장 중, 측정 흐름은 계속됩니다
AW01-2 측정로컬 저장

온라인 복구 시 자동 백그라운드 동기화

동기화 상태대기 12건
AW01-2 측정전송 대기
AW02-1 측정전송 대기
일괄 전송 (배치 push)
SCR-FSM-007-1도면 목록·선택

프로젝트 하위, 허브 진입 · 프로젝트 도면 여러 장(층별 평면도·입면도·창호일람표·보조 도면)에서 먼저 도면을 고른다 — 측정대상 도면과 참조 전용 도면이 섞여 있다

  1. 도면 유형 필터 — Drawing.drawing_kind. 전체 / 평면도 / 입면도 / 창호일람표 / 기타. 유형별로 좁혀 본다. 값은 도면을 올릴 때 고르고, 안 고르면 서버가 기타(OTHER)로 담는다 (③)
  2. 측정대상 도면 행 — Drawing.drawing_kind·Drawing.file_name. 이름은 「종류 + 파일 이름」으로 보인다 — 사람이 붙이는 이름 칸은 두지 않는다. "측정 대상 N개소" 배지가 붙은 도면만 위치 측정 대상이고, 그 여부는 앱이 개소로 센다. 탭하면 도면 뷰어로 이동한다 (③·⑤)
  3. 측정 진행 배지 — 도면별 개소 측정 진행(완료/전체). 측정 위치(개소)와 갯수는 견적설계 대조검증(PRC-ES-08 · SCR-ES-019)에서 설계자가 평면도에 사전 마킹·확정한 값이다 — 측정자는 위치를 새로 만들지 않는다 (⑤)
  4. 참조 도면 행 — 창호일람표·입면도·보조 도면 등 측정에 관여하지 않는 도면(개소 0건). "참조 전용" 배지, 탭하면 뷰어에서 열람만(측정 마커 없음). 딱지는 「측정 대상 N개소」와 「참조 전용」 둘뿐이다 — 「측정 없음」은 개소 0건이라 참조 전용과 갈리지 않는다 (③·⑤)
  5. 캐시 상태 — Drawing.cache_status. 오프라인 조회 가능 여부 (③)
  6. 상태 — 오프라인 목록 — 캐시된 도면만 목록에 보이고 캐시되지 않은 도면은 흐리게 둔다. 조회 자체는 계속된다 (③·⑤)
  7. 목록 하단 단축 버튼(「{도면 이름} 열기」) — 측정대상 도면 중 맨 위(첫 번째) 도면을 곧장 여는 단축 버튼. 목적지는 그 행을 탭한 것과 같다(도면 뷰어). 화면 하단은 장갑 낀 손으로 엄지가 닿는 유일한 자리라, 스크롤·행 조준 없이 들어가는 경로를 하나 둔다. 글자 차례는 「열기 · 이름」 — 이름이 길면 반대 차례로는 "열기"가 먼저 잘린다 (⑤, #1341)
관련 API Swagger UI ↗
  • GET/api/es/projects/{projectId}/drawings — 프로젝트 도면 목록 조회 후보 — ES 대조검증이 쓰는 도면 소스 재사용 가능성(FS 전용 Pull API는 미구현이라 확정 아님)
  • GET/api/fs/projects/{projectId}/drawings — 도면 목록 조회 — 모바일 증분 동기화(updatedAfter/cursor)·캐시 파라미터는 아직 없다
오프라인

1도면 유형 필터

전체 평면도 입면도 창호일람표 보조

2측정대상 도면 (탭 → 도면 뷰어)


4참조 도면 (측정 없음 · 열람만)

5도면별 캐시됨 — 오프라인 조회 가능


목록으로 보기
7열기 · 1층 평면도

도면 목록 불러오는 중…

아직 내려받은 도면이 없습니다 — 프로젝트를 다시 선택하거나 동기화하세요

오프라인
SCR-FSM-007-2도면 뷰어·위치 선택

도면 목록에서 고른 한 장 · 도면 위 측정 위치(개소) 마커 — 설계자가 대조검증(PRC-ES-08)에서 사전 확정한 위치. 마커 탭 두 걸음(고르기 → 다시 눌러 들어가기) → 실측 입력. 섹션(부호) 필터·핀치줌

  1. 선택 도면 헤더 — Drawing.name(예: 1층 평면도). [← 도면 목록]으로 돌아가 다른 도면을 고른다 (③·⑤)
  2. 측정 위치 출처 — 도면 위 개소 마커는 설계자가 견적설계 대조검증(PRC-ES-08 · SCR-ES-019)에서 평면도에 사전 마킹·확정한 설치 위치다. 측정자는 이 위치를 탭해 실측만 입력한다 — 위치·갯수를 바꾸지 않는다 (⑤)
  3. 섹션 필터 바 — Section.section_code. 칩 다중 선택, 기본값 "전체" — 선택한 부호의 개소 마커만 도면 위에 남긴다 (③·⑤)
  4. 도면 캔버스(선 도면) — Drawing.cached_path(받아 둔 본문 파일)·Drawing.bounds_*(도면 범위 mm). 서버가 미리 그려 둔 그림이 아니라 선 도면(벡터) 본문을 받아 앱이 직접 그린다(#1018). 받아 두면 오프라인에서도 조회할 수 있다 (③)
  5. 개소 마커(오버레이) — Area.marker_x/marker_y·Area.label·Area.biz_status(마커 색·모양). 탭은 두 걸음이다 — 처음 누르면 그 마커가 골라지고 개소 정보판이 뜨며, 정보판이나 같은 마커를 다시 누르면 SCR-FSM-004로 이동한다. 겹쳐 있는 마커에서 헛짚어 엉뚱한 개소로 들어가는 것을 막는 걸음이다(#1370). 골라진 마커는 뒤집어 그린다 — 흰 채움에 3dp 테두리다. 도면의 빈 자리를 누르면 골라 둔 것을 놓는다 (③·⑤)
  6. 개소 정보판(고른 마커 위 카드) — 첫 줄은 개소 부호·개소 이름(예: AW01-2 · 1층 로비), 둘째 줄은 섹션 부호·업무상태·잰 항목 수(예: AW01 · 측정중 · 측정 3항목)다. 잰 기록이 없으면 그 칸을 아예 비운다. 누르면 SCR-FSM-004로 간다. 화면 밖으로 나가지 않게 가두고, 마커 위에 자리가 없으면 아래로 뒤집는다 (③·⑤, #1370) — 마커 6
  7. 핀치줌 제스처 — 두 손가락으로 확대·축소, 더블탭하면 기본 배율로 되돌아간다 (③·⑤)
  8. 하단 전역 칩(BLE·동기화) — SCR-FSM-002·SCR-FSM-008이 소유한 상태만 노출하고, 탭하면 해당 화면으로 이동한다 (③)
  9. 상태 — 오프라인 — 로컬 캐시로 조회를 계속하고 마커 탭·실측 진입을 막지 않는다 (③·⑤)
  10. 상태 — 본문 못 받음대신 보여 줄 낮은 화질 그림이 없다. 앱이 선 도면을 직접 그리므로 본문을 못 받으면 도면 자체를 그리지 못한다. 마커 좌표는 그대로 남아 개소 목록에서는 계속 보인다 (③·⑤)
  11. 상태 — 그릴 것이 없는 도면 — 본문은 받았으나 도면 범위(bounds)가 없거나 무한대다. 변환기가 시작값을 그대로 둔 원래 빈 도면이라 앱 결함이 아니다. 이런 도면은 받아 두지 않는다 (④)
  12. 마커 색과 동기화 상태는 다른 축 — 마커 색은 업무 상태를 뜻하므로 동기화가 밀려도 색이 바뀌지 않는다 (③·⑤)
  13. 마커 색·모양 규칙 — 여섯을 셋으로, 그 위에 모양 하나 — 측정중은 파란색(#1B6F8D·찬 동그라미), 완료·검증완료·승인완료는 초록색(#2F7A51·체크), 실측대기·모르는 값은 회색(#5D737B·빈 동그라미), 재측정은 같은 회색에 느낌표다. 재측정은 빨강이 아니라 회색 — 다시 재야 하는 개소라 아직 안 잰 개소와 할 일이 같고, 갈라 보이는 것은 색이 아니라 모양이다. 잠정안이 아니라 앱 실물이다(2026-08-22 확인, #892). 이 그림은 흑백이라 두 회색이 같은 명암으로 그려져 있다 (⑤)
관련 API Swagger UI ↗
  • GET/api/es/drawings/{drawingId}/json — 고른 도면의 선 도면 본문을 받아 갈 주소(IF-ES-DRAWING-JSON-001 · §5.4.23). 본문은 이 주소가 알려 준 저장소 주소에서 따로 내려받고, 도면 범위(bounds)는 그 본문 안에서 읽는다 — 응답에는 배율·범위 칸이 오지 않는다(2026-08-14 실측). 목록은 SCR-FSM-007 이 부르는 /api/fs/projects/{projectId}/drawings 를 그대로 쓴다
  • GET/api/fs/projects/{projectId}/areas?updatedAfter=&cursor=&limit= — 도면 위 개소 마커(좌표·라벨·업무상태) — IF-FS-AREA-001 (§5.4.5). 마커 좌표 정본은 section_placement
오프라인
1전체 AW01 AW02 AW03
2 도면 자리 (앱이 그린 선 도면) AW01-1 대기 AW01-2 측정중 ◉고름 6AW01-2 · 1층 로비AW01 · 측정중 · 측정 3항목 AW01-3 완료 AW01-4 재측정 3

4손가락 두 개로 확대·축소 · 더블탭으로 원래 배율


5하단 전역 칩

오프라인
도면 자리 (받아 둔 본문으로 그림) AW01-1 대기 AW01-3 완료
도면 받는 중…
도면을 못 받았습니다 — 다시 시도하세요 (대신 보일 그림 없음) AW01-1 대기 AW01-3 완료
전체 AW01
도면 자리 (앱이 그린 선 도면) AW01-2 측정중 AW01-3 완료
SCR-FSM-007-2도면 뷰어·위치 선택 — 가로(landscape) 모드

앱 전체는 세로 고정, 도면 뷰어(007)만 가로 회전 허용(Android sensorLandscape) · 위 세로 007 프레임과 동일 데이터 — 배치만 재구성(캔버스 확대 + 필터·전역 칩 상단 이동)

  1. 상단 필터·전역 칩 바 — 가로 모드에서는 섹션 필터·전역 칩(BLE·동기화)이 상단/측면으로 재배치된다 (⑤, 2026-07-07 Approach A)
  2. 도면 캔버스(확대) — 가로 회전 시 도면 캔버스가 넓어진다. 앱 나머지는 세로 고정이고 007만 예외로 가로 회전을 허용한다(Android sensorLandscape) (⑤)
  3. 개소 마커 — 위 세로 007 프레임과 동일 데이터, 배치만 재구성한 것이다 (③·⑤)
  4. 복귀 안내 — 세로로 되돌려도 축소된 배치로 계속 동작한다 — 화면 방향 규정은 현재 AN12-1 요구사항·NFR 어디에도 없어 이식성(NFR-PT)·사용성(UX) NFR 후속 반영 후보로만 남긴다 (⑤)
  5. 상태 — 가로 보기 — 핀치줌으로 확대·축소하고 더블탭으로 되돌린다. 세로로 되돌려도 위 007 프레임처럼 도면이 축소된 배치로 계속 동작한다. 지금 AN12-1 요구와 NFR 이 이 동작을 규정하지 않아 이식성·UX NFR 후속 반영이 남았다 (③·⑤)
관련 API Swagger UI ↗
  • GET/api/fs/projects/{projectId}/areas?updatedAfter=&cursor=&limit= — 가로 모드도 007-view 와 같은 개소 데이터를 쓴다 — IF-FS-AREA-001 (§5.4.5)
1전체 AW01 AW02 AW03
2 도면 자리 — 가로 확대 표시 AW01-1 대기 AW01-2 측정중 AW01-3 완료 AW01-4 재측정 3
SCR-FSM-009도면 태깅

측정 항목 하위 · 2026-08-07 신설 — 측정 항목 하나가 원도면 어디를 잰 값인지 도면 위에 직접 찍는 전체화면. SCR-FSM-004 항목 줄의 📍 로 들어와 찍거나 그만두면 그 자리로 되돌아온다 · 개소에 달린 도면 가운데 하나를 골라 길게 눌러 한 점 · 찍은 자리는 도면 mm 로 보인다

  1. 머리말 — 무엇을 찍는 중인가 — SCR-FSM-004 가 넘긴 항목 이름과 쪽 배지를 그대로 잇는다(예 「내측 W(폭)」). 어느 줄에서 눌러 들어왔는지 잊지 않게 하는 자리다 (③)
  2. 도면 고르개 — Drawing.drawing_id·Drawing.file_name. 개소에 달린 도면에서 한 장을 고르고 그것이 fs_meas_dim.tag_drawing_id 가 된다. SCR-FSM-007 도면 목록이 쓰는 그 목록을 그대로 쓴다 — 이 화면 전용 조회를 새로 만들지 않는다. 처음 열 때는 그 개소 마커가 찍혀 있는 도면을 미리 골라 둔다 (③·⑦)
  3. 도면 캔버스(전체화면) — Drawing.cached_path(받아 둔 선 도면 본문)·Drawing.bounds_*(도면 범위 mm). 원도면 그대로 그리고 개소 마커를 함께 얹어 「이 개소가 어디인가」를 잃지 않게 한다 — 앱이 선 도면을 직접 그리는 것이고 서버가 미리 그려 둔 그림을 얹는 것이 아니다. 손가락 두 개로 확대·축소, 더블탭으로 기본 배율 — SCR-FSM-007 도면 뷰어와 같은 조작이다 (③·⑤)
  4. 찍은 점 — 길게 눌러 찍는다 — fs_meas_dim.tag_x_mm·tag_y_mm. 짧게 누르기와 끌기는 팬·줌이 이미 쓰고 있어 길게 누르기 하나만 찍기에 배정한다. 한 항목에 한 점이고 다시 찍으면 앞의 점이 옮겨 간다 — 여러 자리를 남기려면 측정 항목을 줄로 늘려 각각 찍는다 (③·⑤)
  5. 찍은 자리 좌표 — 도면 mmX 12,340 Y 8,720 처럼 도면 mm 로만 적는다. 화면 픽셀은 사용자에게 보이지 않는다 — 확대 배율에 매달린 값이라 적어 두면 뜻이 없다. ⚠️ 좌표계는 도면좌표이고 개소 마커·부호 배치와 같은 축이다. 견적설계가 영속 저장에 쓰는 배치 좌표(ESTIMATE_LINE.canvas_x_mm)도 같은 도면좌표라 섞어도 밀리지 않는다(#962 결정). 섞지 말아야 할 상대는 화면 픽셀(캔버스좌표) 이다 — 줌·팬에 매달린 값이라 도면 mm 로 환산하지 않고 쓰면 줌 배율만큼 어긋난 자리에 찍힌다. 다만 눈금자 section_dimension.offset_mm 는 섹션좌표로 영속하는 예외다 (③·⑤)
  6. [지우기]·[확인] — [지우기]는 도면 번호·X·Y 셋을 함께 지운다. [확인]은 찍은 자리를 그 항목 줄에 붙이고 004 로 돌아가며, 점을 안 찍었으면 잠근다 — 도면만 고른 상태는 찍은 자리가 없는 것과 같다 (③·⑤)
  7. [✕ 닫기] — 아무것도 바꾸지 않고 004 로 돌아간다. 찍다 만 점은 버린다. 이 화면은 저장하지 않는다 — 좌표는 로컬에 쌓였다가 004 의 저장·전송 때 측정과 한 요청으로 함께 올라간다 (②·⑤)
  8. 왜 전용 전체화면인가 — 폰에서 측정 표와 도면을 함께 띄우면 창 한 짝이 점 하나만 하게 그려져 장갑 낀 손으로 못 찍는다. 전체화면이면 크게 확대해 찍을 수 있어 터치 대상 최소 48dp 요구(NFR-US-FS-001)를 지킨다 — 그것이 이 화면을 따로 세운 유일한 까닭이다 (①)
  9. 상태 — loading — 고른 도면의 본문을 아직 받는 중. 「도면 받는 중…」 (④)
  10. 상태 — offline — 네트워크 단절(NFR-RL-FS-001, 5초 내 자동 감지). 캐시된 도면만 고르개에 남기고 안 받아 둔 도면은 「내려받지 않음」으로 잠근다. 캐시된 도면에서는 찍기가 그대로 된다 (④)
  11. 상태 — empty — 이 개소에 딸린 도면이 0건. 찍을 자리가 없으므로 캔버스를 그리지 않고 [✕ 닫기]만 둔다 (④)
  12. 상태 — error(도면 범위 없음) — 받아 둔 본문에 도면 범위(bounds)가 없거나 무한대라 mm 를 낼 수 없다. 찍기를 잠근다 — 그럴듯한 엉뚱한 mm 를 내놓는 것보다 못 찍는 편이 낫다. 절취 사각형·배율 메타는 어느 응답에도 오지 않아 막는 조건이 아니다(2026-08-14 실측) (④·⑤)
관련 API Swagger UI ↗
  • GET/api/fs/projects/{projectId}/drawings — 도면 고르개가 쓰는 목록(IF-FS-DRAWING-001 · §5.9.2) — SCR-FSM-007 이 이미 부르는 그 조회를 그대로 쓴다. 변환이 끝난 도면만 내려와 못 그릴 도면이 섞이지 않는다
  • POST/api/fs/measurements — 찍은 좌표(dims[].tagDrawingId·tagXMm·tagYMm)가 실려 가는 계약(IF-FS-MEAS-001 · §5.9.1) — 이 화면이 직접 부르지 않는다. SCR-FSM-004 가 저장·전송할 때 측정과 함께 올린다
오프라인
1내측 W(폭)
21층 평면도 ▾
3 원도면 그대로 · 길게 눌러 찍기 AW01-3 개소 4

5찍은 자리 — X 12,340mm · Y 8,720mm (도면 mm)

6지우기
1층 평면도 ▾
9도면 받는 중…
10오프라인
1층 평면도캐시됨
창호 상세도내려받지 않음 · 잠김
원도면 그대로 (로컬 캐시) AW01-3 개소

찍은 자리 — X 12,340mm · Y 8,720mm

내측 W(폭)

11이 개소에 달린 도면이 없습니다

창호 상세도 ▾
12이 도면은 위치를 잴 수 없습니다
도면 범위 없음 — 찍기 잠김. 다른 도면을 고르세요
확인 (잠김)
SCR-FSM-008동기화 현황전역

전역 · pending/failed 목록·수동 재시도 · 모든 화면 상태바의 동기화 칩에서 진입

  1. 상태바 동기화 칩(현재) — 모든 화면 상태바의 동기화 칩에서 진입하는 전역 화면이다 (①)
  2. pending 목록 — MEASUREMENT.sync_status=pending. 서버에 아직 전송되지 않은 대기 중 실측 건을 보여준다 (③)
  3. failed 목록 + 재시도 버튼 — sync_status=failed(5회 재시도 후 실패). 버튼을 누르면 해당 건을 즉시 재전송한다 (③·⑤, NFR-RL-FS-003)
  4. 재측정 배지 자리 — Area.biz_status=재측정. 서버 검증 실패·거절(FCM 수신) 시 완료→재측정으로 역행한다. 배지 색은 회색(#9E9E9E)이다 — 「다시 재야 하는 개소」는 「잘못된 개소」가 아니라 「할 일이 남은 개소」라 실측대기와 같은 색으로 둔다(SCR-FSM-007 ⑤ 마커 색 표) (③·⑤, FR-FS-008)
  5. 되돌아온 건 카드 (#1449 신설)Area.biz_status = 재측정 인 개소를 카드로 보인다. 줄 차례는 ① 개소 이름과 「재측정」 딱지 ② 「사무실이 반려했습니다 · 다시 재 주세요」 ③ 마지막 회차의 편차 ④ 반려 사유 다. 사유는 GET /api/fs/measurements/{measurementId}rejectReason 이고 낫표로 묶어 그대로 보인다 — 앱이 줄이거나 바꿔 적지 않는다. 사유가 없으면 그 줄을 비운다(「사유 없음」을 넣지 않는다). 카드를 누르면 그 개소의 실측 입력(SCR-FSM-004)으로 가고 그 화면이 returned 갈래로 열린다 — 화면이 「다시 재 주세요」라고 하면서 그리로 가는 길을 주지 않던 자리다 (②·③·⑤)
  6. 위쪽 요약 카드 (#881 3단계 신설) — 아래 두 목록의 건수를 위쪽에 모아 보인다(전송 대기 N건 · 전송 실패 N건). 목록을 끝까지 내리지 않고도 「얼마나 남았나」를 읽는 자리다. 새로 세는 값이 아니라 두 목록의 길이를 그대로 보인다 (③)
  7. [모두 다시 보내기] (#881 3단계 신설)대기와 실패를 함께 보낸다. 실패만 보내면 대기 건이 남아 사람이 두 번 눌러야 하고, 이 화면의 이름이 이미 「모두」다. 5회 재시도로 실패한 건도 사람이 손으로 누른 것이므로 다시 보낸다. 누르는 동안 이 단추와 각 줄의 [재시도] 를 함께 잠근다 (③·⑤)
  8. 묶음 전송 진행 막대 (#881 3단계 신설) — [모두 다시 보내기] 를 누른 동안에만 보인다. 세는 것은 건수(보낸 건수 / 보낼 건수)이지 바이트가 아니다 — 사진이 섞여 크기가 들쭉날쭉해 바이트로 세면 막대가 멈춘 것처럼 보인다 (③·⑤)
  9. [저장·동기화 설정] (#881 4단계 신설) — 탭하면 SCR-FSM-006 오프라인 저장·동기화로 들어간다. 이 화면은 「지금 무엇이 안 갔나」(건별 목록·재시도)를 보이고, 그쪽은 「이 단말이 어떻게 담고 보내나」(동기화 단계·로컬 저장 용량·동기화 뒤 로컬 삭제)를 보인다. 동기화에 관한 문을 하나로 둔다 — 전역 칩 → 008 → 006 한 길이다 (②·③)
관련 API Swagger UI ↗
  • MISSING— (만들지 않음) — 수동 재시도 전용 주소는 두지 않는다 — fs_measurement.client_uuid UNIQUE(V250)가 재전송 멱등을 이미 담당한다. 같은 POST 를 다시 보내면 된다 (§5.9.1)
  • POST/api/fs/notification/token — 푸시 수신 단말 등록·갱신 — IF-FS-NOTIF-REGISTER-001 (본문은 §6.5.2, 자리 신호는 §5.4.3). 응답은 {tokenId, userId, deviceId, registeredAt, active} 로 정본 §6.5.2 예시와 같다(2026-08-17 서버 대조). 해지는 같은 주소의 DELETE ?deviceId= 이고 줄을 지우지 않고 active=false 로 끈다
오프라인 1동기화(현재)

동기화 현황 — pending·failed 동시 예시(참고용 기본 화면 · 문서 ④의 3개 variant sync-pending/sync-failed/synced 중 하나가 아님)

5전송 대기12건
전송 실패2건
2AW01-2 측정전송 대기
3AW02-5 측정
전송 실패
재시도

4재측정 배지 자리 — 회색(#9E9E9E)

되돌아온 건 카드 (#1449 신설)Area.biz_status = 재측정 · 누르면 그 개소의 실측 입력(SCR-FSM-004)으로 간다

9① AW01-4재측정
② 사무실이 반려했습니다 · 다시 재 주세요
③ 마지막 회차 편차 — H(높이) +10.5%
④ 「내측 높이가 도면값과 150mm 차이납니다. 창틀 안쪽에서 다시 재 주세요」

넷째 줄 = 반려 사유. 낫표로 묶어 사무실이 적은 글을 그대로 보인다 — 앱이 줄이거나 바꿔 적지 않는다. 사유가 없으면 이 줄을 비운다 — 「사유 없음」 같은 대신 글을 넣지 않는다

6모두 다시 보내기
8저장·동기화 설정

7묶음 전송 진행 막대 — 보낸 건수 / 보낼 건수 (누르는 동안에만 보인다)

전송 대기 12건

AW01-2 측정전송 대기
AW01-3 측정전송 대기

전송 실패 2건 (5회 재시도 후)

AW02-5 측정
전송 실패
재시도
AW03-1 측정
전송 실패
재시도
미전송 · 실패 항목이 없습니다