-- 010_temp_upload.sql -- 프로젝트 생성 전 임시 보관함 (2026-08-08) -- -- 라이다 원본은 업로드에 오래 걸린다. 프로젝트 정보가 확정되기 전에 계정에 묶어 -- 자료를 먼저 올려 두고, 나중에 만든 프로젝트로 옮겨 쓴다. -- 파일은 storage/tmp/{user_id}/{batch_id}/ 아래에 프로젝트와 같은 구조로 둔다. USE aislo_db; -- 보관함 묶음 = 프로젝트 하나에 넣을 입력 파일 한 세트. CREATE TABLE IF NOT EXISTS temp_upload_batches ( id CHAR(36) PRIMARY KEY, user_id INT NOT NULL, name VARCHAR(200) NOT NULL, memo VARCHAR(500) NULL, status ENUM('uploading', 'completed', 'failed', 'linked') NOT NULL DEFAULT 'uploading', completed_at TIMESTAMP NULL, -- 파일 세트가 다 찬 시각 (만료 기준점) expires_at TIMESTAMP NULL, -- completed_at + TEMP_UPLOAD_RETENTION_DAYS linked_project_id CHAR(36) NULL, -- 프로젝트로 옮긴 뒤 이력 보존용 created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_temp_batches_user (user_id), INDEX idx_temp_batches_status (status), INDEX idx_temp_batches_expires (expires_at), CONSTRAINT fk_temp_batches_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 묶음 안의 개별 파일. 프로젝트의 input_files와 같은 항목을 담아 두었다가 그대로 옮긴다. CREATE TABLE IF NOT EXISTS temp_upload_files ( id BIGINT AUTO_INCREMENT PRIMARY KEY, batch_id CHAR(36) NOT NULL, file_type VARCHAR(20) NOT NULL, original_filename VARCHAR(255) NOT NULL, relative_path VARCHAR(500) NOT NULL, -- 묶음 폴더 기준 상대 경로 file_size_bytes BIGINT NOT NULL, crs_epsg INT NULL, metadata JSON NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uq_temp_files_batch_type (batch_id, file_type), INDEX idx_temp_files_batch (batch_id), CONSTRAINT fk_temp_files_batch FOREIGN KEY (batch_id) REFERENCES temp_upload_batches(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 청크 업로드 세션을 보관함에서도 그대로 쓰기 위한 완화. -- project_id는 프로젝트 업로드에서만 채우고, 보관함 업로드는 temp_batch_id를 채운다. -- FK가 걸린 컬럼은 제약을 먼저 떼야 NULL 허용으로 바꿀 수 있다(MariaDB 1832). -- 제약 이름이 환경마다 다를 수 있어(수동 생성분은 upload_sessions_ibfk_1) 실제 이름을 -- 조회해 떼고, 없으면 아무 것도 하지 않는다. SET @fk_name := ( SELECT CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'upload_sessions' AND COLUMN_NAME = 'project_id' AND REFERENCED_TABLE_NAME = 'projects' LIMIT 1 ); SET @drop_fk := IF( @fk_name IS NULL, 'SELECT 1', CONCAT('ALTER TABLE upload_sessions DROP FOREIGN KEY `', @fk_name, '`') ); PREPARE drop_fk_stmt FROM @drop_fk; EXECUTE drop_fk_stmt; DEALLOCATE PREPARE drop_fk_stmt; ALTER TABLE upload_sessions MODIFY COLUMN project_id CHAR(36) NULL; ALTER TABLE upload_sessions ADD CONSTRAINT fk_upload_sessions_project_id FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; ALTER TABLE upload_sessions ADD COLUMN temp_batch_id CHAR(36) NULL AFTER project_id; ALTER TABLE upload_sessions ADD INDEX idx_upload_sessions_temp_batch (temp_batch_id);