콘텐츠로 이동

change_requests 스키마 (근로자 현장 변경 요청)

이미 특정 현장(from_site_id)에 소속된 근로자가 같은 회사 내 다른 현장(to_site_id)으로 이동 요청하는 문서. 승인되면 출발 현장 membersresign=True(reason="site_change")로 마킹되고 도착 현장에 새 members 문서가 생성됩니다.

저장 위치

companies/{company_id}/sites/{to_site_id}/change_requests/{request_id}

주의: 변경 요청 문서는 도착 현장(to_site_id) 하위에 저장됩니다. 출발 현장(from_site_id)이 아닙니다.

  • request_id: Firestore 자동 생성 ID
  • 요청자 UID의 users/{uid}/requests 문서와 1:1 쌍으로 연결 (user_notification_id)

상태 흐름

pending ──(관리자 승인)──► approved   → from 현장 resign + to 현장 members 생성 + membership 갱신
   ├──(관리자 거절)──────► rejected
   └──(요청자 취소)──────► rejected   (approvalUID = 요청자 본인)
상태 설명 영향
pending 요청 등록 직후 같은 사용자의 site_change pending 요청은 1개만 허용
approved 관리자 승인 출발 members resign=True, 도착 members 생성/복구, users/{uid}/membership/{cid}_{sid} 문서의 site_id/site_name 업데이트, FCM 승인 알림
rejected 관리자 거절 또는 요청자 취소 members 변경 없음. 거절 시 FCM 거절 알림

문서 필드

필드 타입 설명
UID string 요청자(근로자) UID
status string pending | approved | rejected
company_id string 회사 ID
from_site_id string 출발 현장 ID (현재 소속)
to_site_id string 도착 현장 ID (이동 희망) — 요청 문서가 저장되는 사이트
requester_name string 요청자 이름 (스냅샷)
requester_phone_masked string 마스킹된 전화번호
requester_phone_enc string 암호화된 전화번호
requester_email_enc string 암호화된 이메일
main_address string 주소
sub_address_enc string 암호화된 상세 주소
requester_birth timestamp 생년월일
requester_sex string "male" | "female"
requester_wage_rate number 출발 현장 당시의 단가 (참고용 스냅샷)
user_notification_id string 사용자 쪽 users/{uid}/requests/{id} 문서 ID
created_at timestamp 요청 생성 시각
approved_at timestamp | null 승인/거절/취소 시각
approvalUID string | null 처리자 UID (요청자 취소 시 요청자 본인)

모든 requester_* / main_address / sub_address_enc 필드는 출발 현장의 members 문서에서 복사된 스냅샷입니다.

요청 생성 시 선검사

_site_change_request는 다음을 검사 후 실패 시 거부합니다:

  • 요청자가 from_site_id의 members에 존재해야 함 (PERMISSION_006)
  • to_site_id 현장이 존재하고 status="activate" 이어야 함 (SITE_001/SITE_003)
  • 동일 사용자의 site_change pending 요청이 이미 있으면 중복 거부 (REQUEST_003)
  • 출발 현장에서 이미 퇴사(resign=True) 상태면 거부 (MEMBER_008)
  • 출발 현장에서 현재 출근 상태(check_in)면 거부 (SITE_006)
  • 출발 현장 출석 요청(site_attendance) pending이 있으면 거부 (SITE_007)

승인 시 생성/갱신되는 문서

  1. 출발 현장 members/{uid} 업데이트members.md
  2. resign: True, resign_at, resign_UID=관리자UID, resign_reason="site_change" 세팅
  3. 도착 현장 members/{uid} 생성 또는 복구
  4. 기존 문서가 있으면 스냅샷으로 업데이트(복구)
  5. 없으면 database.write(doc_id=UID)로 신규 생성
  6. field/labor_supplier/wage_rate출발 현장의 값을 그대로 이관
  7. users/{uid}/membership/{cid}_{from_site_id} 업데이트common/_schema/membership.md
  8. site_idto_site_id, site_name → 도착 현장명으로 갱신 (문서 ID는 유지)
  9. users/{uid}/requests/{notification_id} 갱신
  10. status: "approved"common/_schema/requests.md
  11. FCM 알림 전송
  12. 제목: [현장변경] 현장 변경 승인
  13. notification_type: "site_change_approved"

거절/취소 시 동작

경우 처리
관리자 거절 status="rejected" + approvalUID=관리자UID. 사용자 쪽 requestsrejected. FCM 거절 알림 (notification_type: "site_change_rejected")
요청자 취소 status="rejected" + approvalUID=요청자UID. 사용자 쪽 requestsrejected. FCM 알림 없음

관리자 강제 변경 (요청 없이 이동)

관리자용 _site_change는 change_requests 문서를 만들지 않고 곧바로 members/membership을 업데이트합니다 (승인 단계 스킵). 이 경우 이 컬렉션에는 아무 문서도 생성되지 않습니다.

예시 문서 (pending)

{
  "UID": "uid_worker",
  "status": "pending",
  "company_id": "company_abc",
  "from_site_id": "site_old",
  "to_site_id": "site_new",
  "requester_name": "홍길동",
  "requester_phone_masked": "010-****-1234",
  "requester_phone_enc": "base64...",
  "requester_email_enc": "base64...",
  "main_address": "서울시 강남구",
  "sub_address_enc": "base64...",
  "requester_birth": "1990-01-15T00:00:00Z",
  "requester_sex": "male",
  "requester_wage_rate": 180000,
  "user_notification_id": "notif_abc",
  "created_at": "2026-04-20T09:00:00Z",
  "approved_at": null,
  "approvalUID": null
}

관련 엔드포인트

  • _site_change_request (con24/site/HR/worker_site_change.py) — 요청 생성
  • _site_change_request_cancel — 요청자 취소
  • _site_change_request_approval — 관리자 승인/거절 (모든 사이트 change_requests를 순회하며 request_id 검색)
  • _site_change — 관리자 강제 변경 (요청 없이 즉시 처리)

관련 스키마