콘텐츠로 이동

equipments / contracts / attendance 스키마 (장비대)

현장에 배정된 장비의 장비 정보, 임대 계약, 월별 가동 공수(출역)를 관리하는 스키마. 장비대 화면은 equipments 문서(장비/임대인 정보) + 하위 contracts(임대 계약) + 하위 attendance(월별 공수)로 구성됩니다.

저장 위치

companies/{company_id}/sites/{site_id}/equipments/{equipment_id}
companies/{company_id}/sites/{site_id}/equipments/{equipment_id}/contracts/{contract_id}
companies/{company_id}/sites/{site_id}/equipments/{equipment_id}/attendance/{YYYYMM}
  • equipments/{equipment_id}: 현장에 배정된 장비 단위 문서. equipment_idusers/{UID}/equipments의 장비 문서 ID를 그대로 사용.
  • contracts: 임대 기간 단위 계약. 하나의 장비에 여러 계약(기간/금액)이 시간 순으로 쌓임.
  • attendance/{YYYYMM}: 월별 가동 공수 배열 문서 (labor_ledger와 동일한 월 단위 패턴).

상위: equipments/{equipment_id}

장비 배정(equipment_assign_request_approval 승인) 시 site_equipment_data로 최초 생성되고, 장비대 페이지의 여러 엔드포인트가 이 문서를 수정합니다.

필드 타입 설명
UID string 장비 소유(운전자) UID
name string 소유자 이름 (스냅샷)
phone_enc string 소유자 전화번호 AES 암호화
phone_masked string "010-****-XXXX"
email_enc string 소유자 이메일 AES 암호화
main_address string 소유자 주소 (평문)
sub_address_enc string 상세주소 AES 암호화
birth timestamp 생년월일
sex string "male" | "female"
equipment_type string 장비 종류 (예: "굴착기", "덤프트럭")
equipment_name string 장비명
equipment_number string 장비 번호/차량번호
resign bool 해제 여부 (true면 이 현장에서 해제됨)
resign_at timestamp? 해제 시각
resign_UID string? 해제 처리자 UID
resign_reason string? 해제 사유 (예: "manual_resign")
assigned_by string 배정한 관리자 UID
assigned_at timestamp 배정 시각
lessor_company_name string? 임대인 회사명 (임대 장비인 경우)
lessor_registration_number string? 임대인 사업자등록번호 (edit_equipment_lessor_info)

임대인 정보 업데이트 (edit_equipment_lessor_info)

장비 문서의 main_address, sub_address_enc, phone_enc를 임대인 정보로 덮어쓰는 구조입니다(초기 소유자 정보와 동일 필드 공유).

lessor_company_name, main_address, sub_address_enc, phone_enc, lessor_registration_number

직영/임대 구분

스키마에 명시적 플래그는 없으나 lessor_company_name / lessor_registration_number의 존재 여부와 contracts의 유무로 임대 장비를 구분합니다.

하위: contracts/{contract_id}

장비의 임대 계약 단위 문서. add_equipment_contractdatabase.write로 자동 ID를 부여해 생성합니다.

{
  "start_date": "2026-01-01T00:00:00Z",
  "end_date":   "2026-03-31T00:00:00Z",
  "amount":     10000000,
  "tax":        1000000,
  "created_at": "server timestamp",
  "created_by": "uid_admin",
  "updated_at": "server timestamp?",
  "updated_by": "uid?"
}
필드 타입 단위 설명
start_date timestamp - 계약 시작일
end_date timestamp - 계약 종료일 (반드시 start_date보다 뒤)
amount number 공급가액 (세액 제외). 입력 시 계산식 참조
tax number 부가세 (자동 계산)
created_at timestamp - firestore.SERVER_TIMESTAMP
created_by string - 작성자 UID
updated_at timestamp? - 수정 시각
updated_by string? - 수정자 UID

금액 계산: 클라이언트는 amount(총액)와 is_tax_included를 전송. - is_tax_included=true: tax = amount / 11, amount = amount - tax (포함가에서 10% 부가세 역산) - is_tax_included=false: tax = amount * 0.1, amount = amount (공급가액이 그대로, 부가세 별도)

즉 저장되는 amount항상 공급가액(세전) 기준.

계약서 첨부

get_equipment_contract_upload_token으로 Cloudflare 업로드 토큰을 발급받고, 파일 메타는 companies/{cid}/sites/{sid}/files/ 컬렉션에 다음과 같이 저장:

related_doc_id = contract_id
doc_type = "safe"
doc_page = "equipment"
folder_path = companies/{cid}/sites/{sid}/equipments/{equipment_id}/contracts/{contract_id}

하위: attendance/{YYYYMM}

장비 가동 공수 월 단위 문서. 근로자와 달리 장비 1대당 month 문서 1개 구조이며, 배열(31칸)에 일자별 공수가 직접 누적됩니다.

{
  "man_days": [0, 0, 1, 0.5, 0, "... (31 길이)"],
  "attendance_id": {
    "0": [],
    "1": [],
    "2": ["log_id_eq_1"],
    "3": ["log_id_eq_2"]
  }
}
필드 타입 설명
man_days number[31] 일자별 공수 (인덱스 i = i+1일)
attendance_id map 일자별 equipment_attendance_logs 문서 id 배열. 키 "0"~"30"

갱신 로직 (add_equipment_attendance_data / delete_equipment_attendance_data): - _equipment_task_attendance_auto_assignequipment_attendance_logs 생성 시 호출. - 문서가 없으면 man_days=[0]*31, attendance_id={str(i): [] for i in range(31)}로 초기화. - 공수 추가 시 해당 날 man_days[day-1] += man_days, attendance_id[str(day-1)]에 log_id append (중복 방지). - 삭제 시 man_days는 0 미만으로 내려가지 않도록 보정.

상태/흐름

장비 문서의 라이프사이클:

(배정 요청) equipment_assign_requests (pending)
  → 승인 → equipments 문서 생성/갱신 (resign=false)
  → contracts 추가/수정 (선택)
  → equipment_attendance_logs 생성 → attendance/{YYYYMM} 갱신 (트리거)
  → 해제 → equipments.resign=true (문서 삭제 X, 플래그만 갱신)

첨부파일 (files) 연결

용도 related_doc_id doc_page
임대 계약서 contract_id equipment

예시 문서

equipments/{equipment_id}

{
  "UID": "uid_driver_1",
  "name": "김장비",
  "phone_enc": "AES(...)",
  "phone_masked": "010-****-1234",
  "email_enc": "AES(...)",
  "main_address": "서울특별시 구로구",
  "sub_address_enc": "AES(...)",
  "birth": "1978-06-10T00:00:00Z",
  "sex": "male",
  "equipment_type": "굴착기",
  "equipment_name": "06W",
  "equipment_number": "서울12가3456",
  "resign": false,
  "assigned_by": "uid_admin",
  "assigned_at": "2026-01-05T09:00:00Z",
  "lessor_company_name": "대한중기",
  "lessor_registration_number": "123-45-67890"
}

contracts/{contract_id}

{
  "start_date": "2026-01-10T00:00:00Z",
  "end_date":   "2026-02-10T00:00:00Z",
  "amount":     9090909,
  "tax":        909091,
  "created_at": "2026-01-05T09:30:00Z",
  "created_by": "uid_admin"
}

attendance/202601

{
  "man_days": [0, 0, 1, 1, 0.5, 0, "... (31 길이)"],
  "attendance_id": { "0": [], "1": [], "2": ["eq_log_1"], "3": ["eq_log_2"], "4": ["eq_log_3"] }
}