files 스키마
Cloudflare R2에 업로드된 모든 파일의 메타데이터 문서. 업/다운로드, 삭제, 휴지통 관리의 기준이 되는 공통 컬렉션이며, 건설24의 거의 모든 서비스(작업, 재무, 안전 등)가 공유합니다.
저장 위치
현장 단위 파일 (기본):
현장이 지정되지 않은 회사 단위 파일:
_upload_report에서site_id가 비어 있으면 회사 레벨로 저장됩니다. 그 외 기본값은 현장 레벨입니다.file_doc_id는 Firestore 자동 생성 ID (database.write(..., doc_id=None)).
상태 흐름
(업로드 완료 보고) → files 문서 생성
→ move_to_trash → deleted_files 로 이동 (소프트 삭제)
→ delete_file → Firestore 문서 완전 삭제 + R2 객체 삭제
- 소프트 삭제:
_move_to_trash가files→deleted_files로 문서를 복사 후 원본 삭제. 이 때 drive_usage의trash_bytes가 증가하지만total_bytes는 변하지 않음. - 영구 삭제:
_delete_file이 R2 객체를 삭제하고files문서를 삭제.total_bytes가 감소.
문서 필드
| 필드 | 타입 | 설명 |
|---|---|---|
path |
string | R2 객체 키. {folder_prefix}/{ms_timestamp}_{safe_filename} 형식 |
filename |
string | 사용자에게 보이는 원본 파일명 |
mime |
string | MIME 타입 (허용 목록은 tools/cloudflare.py::ALLOWED_MIME) |
size |
int | 파일 크기 (바이트) |
uid |
string | 업로드한 사용자 UID |
doc_type |
string | 문서 대분류 (예: task, safe, finance) |
doc_page |
string | 문서 페이지/기능 식별자 (예: daily_report, realtime-communication) |
related_doc_id |
string | 이 파일이 속한 상위 문서 ID (예: task_id, suspension_work_id) |
tags |
object | 자유 형식 태그. tags.type이 stage 분류에 사용됨 — 아래 Tags 참조 |
target_date |
string | 대상 날짜 (자유 포맷 문자열, 예: 2026-04-23) |
uploaded_at |
timestamp | 업로드 보고 시각 (UTC, datetime.now(timezone.utc)) |
Tags
tags는 자유 형식 객체이지만 관례적으로 type 키가 stage 분류에 사용됩니다.
tags.type |
용도 | 연결 |
|---|---|---|
notice |
작업중지 통지서 첨부 | suspension_works.notice.attachment_ids |
end |
작업중지 해제 시점 사진 | suspension_works.ending.attachment_ids |
report |
작업중지 조치완료 보고서 사진 | suspension_works.report.attachment_ids |
그 외 다른 서비스에서는 자체 키/값 규칙을 tags에 추가해 사용합니다 (예: {"category": "progress"}).
related_doc_id 관계
업로드된 파일은 doc_type + doc_page + related_doc_id 조합으로 상위 도메인 문서와 연결됩니다.
| doc_type | doc_page | related_doc_id | 연결 대상 |
|---|---|---|---|
safe |
realtime-communication |
suspension_work_id |
companies/{C}/sites/{S}/suspension_works/{X} |
task |
(작업별) | task_id |
companies/{C}/sites/{S}/tasks/{X} |
finance |
(항목별) | expense_id, supplier_id, item_id 등 |
other_expenses, material_supplier |
safe |
agreement / document |
safe_doc_id, UID |
safety_agreements, safe_documents |
safe |
suggestion / emergency |
suggestion_id, alert_id |
suggestions, emergency_alert |
Suspension Works 자동 연결 (특수 케이스)
_upload_report 호출 시, 아래 조건을 모두 만족하면 suspension_works 문서의 stage별 attachment_ids 배열에 file_doc_id가 자동으로 추가됩니다 (firestore.ArrayUnion).
doc_type == "safe"doc_page == "realtime-communication"tags.type in {"notice", "end", "report"}
매핑은 tools/cloudflare.py::_SUSPENSION_STAGE_FIELD_MAP:
{
"notice": "notice.attachment_ids",
"end": "ending.attachment_ids",
"report": "report.attachment_ids",
}
실패해도 업로드 보고 자체는 성공 처리됩니다 (try/except pass).
드라이브 사용량 반영
files 컬렉션에 파일이 쓰일 때마다 companies/{company_id}/settings/drive_usage 문서가 갱신됩니다. 상세는 drive_usage.md 참조.
| 이벤트 | total_bytes | trash_bytes |
|---|---|---|
업로드 보고 (_upload_report) |
+size | 0 |
휴지통 이동 (_move_to_trash) |
0 | +size |
영구 삭제 (_delete_file) |
-size | 0 |
예시 문서 (작업중지 통지서 첨부)
{
"path": "companies/ACME/sites/S001/suspension_works/W001/1714000000000_notice.jpg",
"filename": "notice.jpg",
"mime": "image/jpeg",
"size": 204800,
"uid": "uid_worker",
"doc_type": "safe",
"doc_page": "realtime-communication",
"related_doc_id": "suspension_work_id_001",
"tags": { "type": "notice" },
"target_date": "2026-04-23",
"uploaded_at": "2026-04-23T01:12:34Z"
}