콘텐츠로 이동

tasks 스키마 (작업 관리 마스터)

현장별 일일 작업(Task) 마스터 문서와 그 하위 서브컬렉션을 정리합니다. 작업(Task) 1개 = 현장에서 특정 날짜/시간대에 수행되는 단위 작업이며, 자재/폐기물 사용량, 위험성 평가, 특이사항 메모, 근로자·장비 출석이 모두 이 문서를 중심으로 연결됩니다.

저장 위치 및 서브컬렉션 트리

companies/{company_id}/sites/{site_id}/tasks/{task_id}              # 작업 본문
 ├─ risk_assessment/{risk_assessment_id}                            # 작업 위험성 평가 (TBM)
 ├─ material_usage/{daily_usage_id}                                 # 자재 일일 사용량
 ├─ waste_amount/{daily_amount_id}                                  # 폐기물 일일 배출량
 ├─ memo/{memo_id}                                                  # 특이사항 메모
 └─ attendance/{supervisor|worker|equipment}                        # 작업별 출석 집계 문서 (고정 ID 3개)

첨부파일과 자재/폐기물 품목 마스터는 별도 컬렉션에 저장됩니다.

companies/{company_id}/sites/{site_id}/files/{file_id}              # 작업 첨부파일 메타 (related_doc_id == task_id)
companies/{company_id}/sites/{site_id}/material/{material_id}       # 자재 품목 마스터 (material_usage.material_id가 참조)
companies/{company_id}/sites/{site_id}/waste/{waste_id}             # 폐기물 품목 마스터 (waste_amount.waste_id가 참조)
companies/{company_id}/sites/{site_id}/dashboard/{YYYYMM}           # 월별 작업 수 대시보드 (task: int[31])
companies/{company_id}/sites/{site_id}/task_summary/{YYYYMM}        # 월별 자재/폐기물 사용량 집계

연결 관계 참고:

  • sites/{sid} 본문의 task_name_list(배열)와 task_management_layout(배열)은 작업 관리 프론트 설정값입니다. 자세한 내용은 sites.md 참조.
  • 출석 로그(attendance_logs / equipment_attendance_logs)는 task_id 필드로 이 문서를 참조하며, 트리거가 tasks/{tid}/attendance/{role} 문서의 members 배열을 자동 갱신합니다.

tasks/{task_id} 문서 필드

작업 본문. create_task 호출 시 생성되고, 날짜/시간/공수/타입/작업내용/공지사항이 점진적으로 채워집니다.

필드 타입 설명
task_name string 작업명 (sites.task_name_list 중 하나와 일치)
task_start_datetime timestamp 작업 시작 일시 (KST) — 같은 날 같은 현장에 1시간 이내 중복 시작 불가, 하루 최대 5개
task_end_datetime timestamp? 작업 종료 일시 (생성 시 None, update_task_end_datetime에서 채움)
man_days float 해당 작업의 기본 공수 (해당 작업에 배정된 출석 로그의 man_days로 전파)
type string 작업 시간대. "없음" \| "주간" \| "야간" \| "오전" \| "오후" \| "철야"
task string 작업 상세 내용 (리치 텍스트). <오전> / <오후> / <주간> / <야간> / <철야> 태그 허용
notice string 공지사항 (리치 텍스트)
opinion string? 근로자 의견 (edit_task_worker_opinion으로 업데이트)
content_attachments object[]? Firebase Storage 직접 업로드 첨부(레거시) — 삭제 시 storage_path로 blob 제거
created_at timestamp 생성 시각 (SERVER_TIMESTAMP)
created_by string 생성자 UID

저장/업데이트 흐름

엔드포인트 동작
create_task 문서 생성. task_end_datetime=null, task="", notice=""로 초기화
update_task_name_start_datetime task_name, task_start_datetime, man_days, type 수정 (날짜 변경은 불가, 시간만 변경 가능)
update_task_end_datetime task_end_datetime 만 업데이트
update_task_details task 업데이트. <...> 태그는 허용된 5종만 가능
update_notice notice 업데이트
edit_task_worker_opinion opinion 업데이트
copy_task_details_from_previous 이전 작업의 task, notice를 현재 작업에 복사
delete_task 본문 + 첨부파일 + attendance 서브 문서 + 대시보드 집계 정리

삭제 시 연쇄 처리:

  1. content_attachments에 있는 Firebase Storage blob 제거
  2. files 컬렉션에서 related_doc_id == task_id인 파일을 휴지통으로 이동
  3. tasks/{tid}/attendance/{supervisor|worker|equipment} 문서의 members에 기록된 각 출석 로그의 task_idnull로 초기화
  4. dashboard/{YYYYMM}task[day-1] 카운트를 -1

서브컬렉션: risk_assessment/{risk_assessment_id}

작업별 TBM용 일일 위험성 평가. 작업의 상세 화면에서 노출되며, safety/_schema/risk_assessment의 사이트 레벨 위험성 평가와는 별개입니다.

필드 타입 설명
place string 장소
supervisor_name string 담당자 이름 (문자열 스냅샷)
type string 공종
work string 작업명
danger_level string 위험도 등급 (예: "상", "중", "하")
frequency string 발생빈도 (예: "상", "중", "하")
source string 유해/위험 요인
preventive_measures string 예방대책
created_at timestamp 생성 시각
created_by string 생성자 UID

엔드포인트: add_task_risk_assessment, edit_task_risk_assessment, delete_task_risk_assessment, copy_task_risk_assessment_from_previous (이전 작업의 모든 항목 복사).

서브컬렉션: material_usage/{daily_usage_id}

작업 일자의 자재 사용량. 같은 material_id에 대한 중복 등록은 금지됩니다.

필드 타입 설명
material_id string 참조할 자재 품목 ID (sites/{sid}/material/{material_id})
daily_usage float 해당 작업에서의 일일 사용량
updated_at timestamp 생성/수정 시각
updated_by string 생성/수정자 UID

트리거 _task_material_updatetask_summary/{YYYYMM}.material_usage[material_id][day-1] 배열에 증감을 반영합니다.

서브컬렉션: waste_amount/{daily_amount_id}

작업 일자의 폐기물 배출량. 같은 waste_id에 대한 중복 등록은 금지됩니다.

필드 타입 설명
waste_id string 참조할 폐기물 품목 ID (sites/{sid}/waste/{waste_id})
daily_amount float 해당 작업에서의 일일 배출량
updated_at timestamp 생성/수정 시각
updated_by string 생성/수정자 UID

트리거 _task_waste_updatetask_summary/{YYYYMM}.waste_amount[waste_id][day-1] 배열에 증감을 반영합니다.

서브컬렉션: memo/{memo_id}

작업의 특이사항 메모. 여러 사용자가 여러 개 등록할 수 있으며, 삭제는 작성자 본인만 가능합니다.

필드 타입 설명
memo string 메모 본문
created_at timestamp 작성 시각
created_by string 작성자 UID

엔드포인트: add_task_memo, delete_task_memo.

서브컬렉션: attendance/{role}

작업에 자동 배정된 출석 로그를 역할별로 모아주는 고정 3개 문서 컬렉션입니다. 문서 ID는 아래 3가지로 고정됩니다.

문서 ID 대상 참조하는 상위 로그 컬렉션
supervisor 회사 감독자(owner/admin/manager 등) companies/{cid}/attendance_logs/{log_id}
worker 현장 근로자 companies/{cid}/sites/{sid}/attendance_logs/{log_id}
equipment 현장 장비 companies/{cid}/sites/{sid}/equipment_attendance_logs/{log_id}

각 문서의 필드:

필드 타입 설명
members string[] 이 작업에 배정된 출석 로그 ID 배열 (ArrayUnion/ArrayRemove로 원자적 업데이트)

출석 로그가 생성/변경/삭제될 때 auto_assign.py의 트리거 3종이 해당 작업/역할 문서의 members를 갱신하고, 동시에 출석 로그 본문의 task_idman_days를 함께 업데이트합니다.

첨부파일 연결

작업에는 세 가지 용도의 첨부가 있습니다. 모두 files/{file_id} 메타 문서의 tags.type으로 구분합니다 (related_doc_id == task_id).

용도 tags.type 발급 함수 저장 경로 prefix
작업 상세 이미지 details get_task_details_attachment_upload_token tasks/{task_id}/details_attachments
공지사항 첨부 notice get_task_notice_attachment_upload_token tasks/{task_id}/details_attachments
그룹별 일반 첨부 attachment (+ group, folder_id) get_task_attachment_upload_token tasks/{task_id}/files/{group_name}

attachment 타입은 동일 폴더로 여러 파일을 묶어 업로드할 수 있도록 tags.folder_id(UUID)와 tags.group(그룹명)을 함께 저장합니다. folder_id가 요청에 포함되면 기존 폴더에 추가, 없으면 신규 UUID를 발급합니다.

대시보드/집계 문서

dashboard/{YYYYMM}

작업 개수 월별 집계. delete_task에서 감소, create_task에서는 (현재 코드 기준) 직접 업데이트하지 않음.

{
  "task": [0, 0, 1, 2, 0, ...]   // 31칸, 인덱스 = day - 1
}

task_summary/{YYYYMM}

자재/폐기물의 월별·일별 사용량 집계. material_usage/waste_amount 서브컬렉션의 트리거가 원자적으로 갱신합니다.

{
  "material_usage": {
    "{material_id}": [0, 0, 10, 5, ...]     // 31칸, 인덱스 = day - 1
  },
  "waste_amount": {
    "{waste_id}": [0, 0, 2, 1, ...]
  }
}

예시 문서

tasks/{task_id}

{
  "task_name": "철근 배근",
  "task_start_datetime": "2026-04-23T08:00:00+09:00",
  "task_end_datetime": null,
  "man_days": 1.0,
  "type": "주간",
  "task": "<주간> 2층 슬라브 철근 배근 작업",
  "notice": "안전모 미착용 시 작업 불가",
  "created_at": "2026-04-22T17:00:00+09:00",
  "created_by": "uid_manager"
}

tasks/{task_id}/attendance/worker

{
  "members": ["log_abc123", "log_def456"]
}