From b3d83718820c883dac07bfb03e6d6ba8e1a6494a Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 8 Aug 2026 20:00:12 +0900 Subject: [PATCH] =?UTF-8?q?feat(B01,B03):=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=EC=97=90=20=EC=97=B0=EA=B2=B0=EB=90=9C=20=EB=B3=B4?= =?UTF-8?q?=EA=B4=80=ED=95=A8=EC=9D=84=20=EB=AA=A9=EB=A1=9D=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=A0=9C=EC=99=B8=20(E2E=20=EA=B2=B0=ED=95=A8=205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 연결된 묶음은 파일이 프로젝트로 옮겨져 내용이 비어 있는데도 목록에 남아, 파일 0건·용량 0·만료 없음·버튼 없음인 빈 껍데기가 영구히 쌓였다(2026-08-08 사용자 지시로 제외). - list_temp_batches: status <> 'linked' 만 조회. 행 자체는 이력용으로 DB에 남긴다 — 어느 자료가 어느 프로젝트로 갔는지 추적할 근거다. - 대시보드 UI: 목록에 연결된 묶음이 오지 않으므로 "연결됨" 배지·삭제 버튼 숨김·파일 행 비활성 분기를 걷어냈다(죽은 코드). 검증: 서버 재시작 후 목록 응답 0건, DB 보관 행 3건 유지. typecheck·prettier·ruff 통과, 정적 번들 재빌드. Co-Authored-By: Claude Opus 5 (1M context) --- B01_Dashboard/B01_Dashboard_UI_TempUpload.ts | 53 ++++++++----------- .../B03_FileInput_Repository_Temp.py | 9 +++- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/B01_Dashboard/B01_Dashboard_UI_TempUpload.ts b/B01_Dashboard/B01_Dashboard_UI_TempUpload.ts index 0e193503..77337176 100644 --- a/B01_Dashboard/B01_Dashboard_UI_TempUpload.ts +++ b/B01_Dashboard/B01_Dashboard_UI_TempUpload.ts @@ -113,16 +113,14 @@ export function buildTempUploadSection(): HTMLElement { function fileRows(batch: TempBatchItem): HTMLElement[][] { const rows: HTMLElement[][] = []; - const linked = batch.status === "linked"; for (const file of batch.files) { - const action = linked - ? text("-") - : createButton({ - label: L("Common_Btn_Delete"), - variant: "danger", - onClick: () => void removeFile(batch, file.file_type, file.original_filename), - }); + // 목록에는 아직 프로젝트에 안 쓴 묶음만 온다 — 항상 지울 수 있다. + const action = createButton({ + label: L("Common_Btn_Delete"), + variant: "danger", + onClick: () => void removeFile(batch, file.file_type, file.original_filename), + }); rows.push([ text(file.file_type.toUpperCase()), text(file.original_filename), @@ -192,12 +190,9 @@ export function buildTempUploadSection(): HTMLElement { title.textContent = batch.name; const badge = document.createElement("span"); badge.className = "b01-temp__badge"; - badge.textContent = - batch.status === "linked" - ? L("B01_Temp_Status_Linked") - : batch.required_complete - ? L("B01_Temp_Status_Ready") - : L("B01_Temp_Status_Uploading"); + badge.textContent = batch.required_complete + ? L("B01_Temp_Status_Ready") + : L("B01_Temp_Status_Uploading"); const meta = document.createElement("span"); meta.className = "b01-temp__group-meta"; @@ -205,9 +200,7 @@ export function buildTempUploadSection(): HTMLElement { `${batch.files.length}${L("B01_Temp_Meta_FileCount")}`, formatTempBytes(batch.total_size_bytes), ]; - if (batch.status === "linked") { - parts.push(L("B01_Temp_Meta_Linked")); - } else if (batch.expires_at) { + if (batch.expires_at) { parts.push(`${L("B01_Temp_Meta_Expires")} ${formatDate(batch.expires_at)}`); } meta.textContent = parts.join(" · "); @@ -217,20 +210,18 @@ export function buildTempUploadSection(): HTMLElement { actions.className = "b01-dashboard__actions"; // 버튼 클릭이 접기/펼치기까지 건드리지 않게 막는다. actions.addEventListener("click", (event) => event.stopPropagation()); - if (batch.status !== "linked") { - actions.append( - createButton({ - label: L("B01_Temp_Btn_Add"), - variant: "ghost", - onClick: () => openAddModal(batch), - }), - createButton({ - label: L("Common_Btn_Delete"), - variant: "danger", - onClick: () => void removeBatch(batch), - }), - ); - } + actions.append( + createButton({ + label: L("B01_Temp_Btn_Add"), + variant: "ghost", + onClick: () => openAddModal(batch), + }), + createButton({ + label: L("Common_Btn_Delete"), + variant: "danger", + onClick: () => void removeBatch(batch), + }), + ); head.append(titleRow, actions); head.setAttribute("aria-expanded", String(opened)); head.addEventListener("click", () => { diff --git a/B03_FileInput/B03_FileInput_Repository_Temp.py b/B03_FileInput/B03_FileInput_Repository_Temp.py index efb3b70c..eda9942b 100644 --- a/B03_FileInput/B03_FileInput_Repository_Temp.py +++ b/B03_FileInput/B03_FileInput_Repository_Temp.py @@ -70,14 +70,19 @@ async def list_temp_batches( *, user_id: int, ) -> list[dict[str, Any]]: - """내 보관함 묶음 목록(최신순). 프로젝트로 옮긴 묶음도 이력으로 함께 준다.""" + """내 보관함 묶음 목록(최신순) — **아직 쓰지 않은 자료만**. + + 프로젝트에 연결된 묶음은 파일이 프로젝트로 옮겨져 내용이 비어 있다. 목록에 남겨 두면 + 빈 껍데기가 영구히 쌓여 화면만 지저분해진다(2026-08-08 사용자 지시로 제외). + 행 자체는 이력용으로 DB에 남긴다 — 어느 자료가 어느 프로젝트로 갔는지 추적할 근거다. + """ async with connection.cursor(aiomysql.DictCursor) as cursor: await cursor.execute( """ SELECT id, name, memo, status, completed_at, expires_at, linked_project_id, created_at FROM temp_upload_batches - WHERE user_id = %s + WHERE user_id = %s AND status <> 'linked' ORDER BY created_at DESC """, (user_id,),