attendance_requests 스키마 (근로자 출퇴근 요청)
현장 근로자의 출퇴근 승인 요청을 담는 컬렉션. 근로자가 앱에서 출근/퇴근 버튼을 누르면 여기에
pending문서가 생성되고, 관리자가 승인/거절하면 문서가 업데이트됩니다. 승인된 출근 요청은attendance_logs에 새 로그를 만들고, 승인된 퇴근 요청은 기존 출근 로그를 페어링하는 방식입니다.
저장 위치
request_id: Firestore 자동 생성 ID- 하나의 근로자는 같은 현장에 동시에 하나의
pending요청만 가질 수 있습니다 (코드에서 선검사).
상태 흐름
[근로자 요청] status=pending
↓ (관리자 승인) ↓ (관리자 거절) ↓ (근로자 취소)
status=approved status=rejected status=rejected
+ attendance_logs 문서 생성/페어링
pending: 근로자가 출/퇴근 요청한 상태 (승인 대기 중)approved: 관리자가 승인한 상태. 출근이면attendance_logs에 새 문서 생성, 퇴근이면 기존link=False인 로그가 페어링(link=True)됨rejected: 관리자가 거절했거나 요청자(근로자)가 취소한 상태
승인/거절/취소 후에도 문서 자체는 보존됩니다 (감사 이력). 다만 승인된
check_in요청의 경우 실제 출근 기록은 별도의attendance_logs문서에 저장됩니다.
문서 필드
공통 필드
| 필드 | 타입 | 설명 |
|---|---|---|
UID |
string | 요청자(근로자) UID |
name |
string | 근로자 이름 (당시 스냅샷) |
type |
string | "check_in" | "check_out" |
company_id |
string | 회사 ID |
site_id |
string | 현장 ID |
created_at |
timestamp | 요청 생성 시각 (= 버튼 누른 시각) |
check_at |
timestamp | 출/퇴근 체크 시각 (created_at과 동일, 승인 시 attendance_logs.check_in_at / check_out_at에 복사됨) |
status |
string | "pending" | "approved" | "rejected" |
approvalUID |
string | null | 승인/거절 처리자 UID (pending 상태에서는 null) |
approval_at |
timestamp | null | 승인/거절 시각 (pending 상태에서는 null) |
check_in 타입에서만 저장되는 필드
_site_check_in_request 호출 시 현장 멤버 스냅샷이 함께 복사됩니다. 승인 시 attendance_logs에 그대로 복사되어 당시 직종/직급이 보존됩니다.
| 필드 | 타입 | 설명 |
|---|---|---|
member_type |
string | "site" (고정, 회사 출근과 구분) |
position |
string | 직급 (당시 스냅샷) |
field |
string | 공종 (당시 스냅샷) |
labor_supplier |
string | 인력 공급처 (당시 스냅샷) |
memo |
string | 메모 (기본 "") |
check_out 타입에서만 저장되는 필드
퇴근 요청 문서는 공통 필드만 저장합니다 (멤버 정보는 페어링 대상인 출근 로그에서 이미 보존됨).
관련 컬렉션
- 승인 시 생성/업데이트되는 로그: attendance_logs.md
- 사용자 쪽 요청 미러: users/{uid}/requests —
request_type="site_attendance",request_path에 본 컬렉션 경로 저장 - 장비 출퇴근 요청: equipment_attendance_requests.md
생성/수정 경로
_site_check_in_request→ 새pending문서 생성 (type=check_in)_site_check_out_request→ 새pending문서 생성 (type=check_out)_site_check_in_request_approval→status업데이트(approved/rejected) + check_in 승인 시attendance_logs생성_site_check_out_request_approval→status업데이트(approved/rejected) + check_out 승인 시 기존attendance_logs페어링_site_attendance_request_cancel→ 근로자가 자체 취소 (status=rejected)
예시 문서
출근 요청 (pending)
{
"UID": "uid_worker",
"name": "홍길동",
"type": "check_in",
"member_type": "site",
"company_id": "company_abc",
"site_id": "site_001",
"created_at": "2026-04-23T08:00:00Z",
"check_at": "2026-04-23T08:00:00Z",
"position": "작업반장",
"field": "철근",
"labor_supplier": "대한인력",
"memo": "",
"status": "pending",
"approvalUID": null,
"approval_at": null
}
퇴근 요청 (approved)
{
"UID": "uid_worker",
"name": "홍길동",
"type": "check_out",
"company_id": "company_abc",
"site_id": "site_001",
"created_at": "2026-04-23T17:30:00Z",
"check_at": "2026-04-23T17:30:00Z",
"status": "approved",
"approvalUID": "uid_admin",
"approval_at": "2026-04-23T17:35:00Z"
}
거절된 요청
{
"UID": "uid_worker",
"name": "홍길동",
"type": "check_in",
"member_type": "site",
"company_id": "company_abc",
"site_id": "site_001",
"created_at": "2026-04-23T08:00:00Z",
"check_at": "2026-04-23T08:00:00Z",
"position": "작업반장",
"field": "철근",
"labor_supplier": "대한인력",
"memo": "",
"status": "rejected",
"approvalUID": "uid_admin",
"approval_at": "2026-04-23T08:10:00Z"
}