feat(B01,B03): 프로젝트 생성 전 임시 보관함 (temp upload)
라이다 원본은 업로드에 오래 걸려 프로젝트 정보 확정 전에 미리 올릴 수 있어야 한다.
계정에 묶인 임시 보관함을 만들고, 나중에 만든 프로젝트로 자료를 옮겨 쓴다.
저장·DB
- storage/tmp/{user_id}/{batch_id}/ 아래에 프로젝트 저장소와 동일한 구조를 써서
청크 저장·병합 엔진(resolve_upload_destination/merge_upload_chunks)을 그대로 재사용
- 010_temp_upload.sql: temp_upload_batches / temp_upload_files 신설,
upload_sessions.project_id NULL 허용 + temp_batch_id 추가(FK명 조회 후 재생성)
- config: TEMP_UPLOAD_DIR_NAME / TEMP_UPLOAD_RETENTION_DAYS(30) /
TEMP_UPLOAD_CLEANUP_INTERVAL_HOURS(6)
백엔드
- B03_FileInput_Router_Temp.py: 묶음 생성·목록·삭제, 일반/청크 업로드, finalize,
이어올리기 상태 조회, 프로젝트 연결(attach)
- attach: 파일 이동 후 input_files 등록, stage 0 완료, WF1·자동 설계 체인 트리거
- common_util_temp_cleanup.py: 완료 시각 기준 만료분 주기 삭제(서버 시작 시 1회 포함)
프론트엔드
- B01 대시보드 임시 보관함 섹션: 프로젝트 등록과 같은 폼 + 보관 목록.
진행률은 모달이 아니라 리스트 행에 표시, 새로고침 후 이어올리기 지원
- B03 업로드 컨테이너 내부 불러오기 버튼과 선택 모달.
완료된 묶음만 노출하고, 선택 후 업로드를 누르면 이동과 분석으로 이어짐
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,10 @@ from A09_Security.A09_Security_Router import router as a09_security_router
|
||||
from B01_Dashboard.B01_Dashboard_Router import router as b01_dashboard_router
|
||||
from B02_ProjRegister.B02_ProjRegister_Router import router as b02_proj_register_router
|
||||
from B03_FileInput.B03_FileInput_Router import router as b03_file_input_router
|
||||
from B03_FileInput.B03_FileInput_Router_Temp import (
|
||||
attach_router as b03_temp_attach_router,
|
||||
)
|
||||
from B03_FileInput.B03_FileInput_Router_Temp import router as b03_temp_upload_router
|
||||
from B04_PreProcess.B04_PreProcess_Router import router as b04_surface_router
|
||||
from B04_PreProcess.B04_PreProcess_Router_Basins import router as b04_basins_router
|
||||
from B04_PreProcess.B04_PreProcess_Router_Contour import router as b04_surface_contour_router
|
||||
@@ -44,6 +48,7 @@ from B07_Quantity.B07_Quantity_Router import router as b07_quantity_router
|
||||
from B08_DesignDetail.B08_DesignDetail_Router import router as b08_design_router
|
||||
from common_util.common_util_auth import require_company, verify_session
|
||||
from common_util.common_util_resource_monitor import sample_resources_loop
|
||||
from common_util.common_util_temp_cleanup import cleanup_expired_temp_uploads_loop
|
||||
from config.config_db import close_db_pool, get_db_pool, init_db_pool
|
||||
|
||||
# 설정 import
|
||||
@@ -259,6 +264,7 @@ async def lifespan(app: FastAPI):
|
||||
await connection.commit()
|
||||
cleanup_task = asyncio.create_task(cleanup_expired_sessions())
|
||||
resource_task = asyncio.create_task(sample_resources_loop())
|
||||
temp_cleanup_task = asyncio.create_task(cleanup_expired_temp_uploads_loop())
|
||||
|
||||
yield
|
||||
|
||||
@@ -266,6 +272,7 @@ async def lifespan(app: FastAPI):
|
||||
logger.info("앱 종료 중...")
|
||||
cleanup_task.cancel()
|
||||
resource_task.cancel()
|
||||
temp_cleanup_task.cancel()
|
||||
stop_frontend_dev()
|
||||
await close_db_pool()
|
||||
logger.info("✓ DB 풀 종료 완료")
|
||||
@@ -349,6 +356,8 @@ app.include_router(b02_proj_register_router)
|
||||
protected = [Depends(verify_session)]
|
||||
protected_with_company = [Depends(verify_session), Depends(require_company)]
|
||||
app.include_router(b03_file_input_router, dependencies=protected_with_company)
|
||||
app.include_router(b03_temp_upload_router, dependencies=protected)
|
||||
app.include_router(b03_temp_attach_router, dependencies=protected_with_company)
|
||||
app.include_router(b04_surface_router, dependencies=protected_with_company)
|
||||
app.include_router(b04_surface_contour_router, dependencies=protected_with_company)
|
||||
app.include_router(b04_surface_gis_router, dependencies=protected_with_company)
|
||||
|
||||
Reference in New Issue
Block a user