diff --git a/.jules/palette.md b/.jules/palette.md index bd0f73248..ab0630a44 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -57,3 +57,6 @@ ## 2026-07-30 - Add window.confirm for destructive actions **Learning:** Destructive actions like deleting groups and edge relationships previously occurred immediately without user confirmation. **Action:** Always wrap delete operations with window.confirm() dialogs and ensure corresponding tests successfully mock window.confirm. +## 2026-08-14 - Confirm destructive actions like table deletion +**Learning:** Destructive actions such as deleting a table require explicit user confirmation to prevent accidental data loss. +**Action:** Always wrap delete operations with window.confirm() dialogs and ensure corresponding tests successfully mock window.confirm. diff --git a/CHANGELOG.md b/CHANGELOG.md index 35613431a..2df20800c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ # Changelog ## Unreleased + +- [FE] πŸ›‘οΈ **ν…Œμ΄λΈ” μ‚­μ œ 확인**: νŽΈμ§‘ λͺ¨λ‹¬μ—μ„œ ν…Œμ΄λΈ” 이름을 ν¬ν•¨ν•œ 확인 λŒ€ν™”μƒμžλ₯Ό ν‘œμ‹œν•˜κ³ , μ‚¬μš©μžκ°€ λͺ…μ‹œμ μœΌλ‘œ ν™•μΈν•œ κ²½μš°μ—λ§Œ κΈ°μ‘΄ μ‚­μ œ 경둜λ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€. μ·¨μ†Œν•˜λ©΄ ν…Œμ΄λΈ”μ„ κ·ΈλŒ€λ‘œ λ³΄μ‘΄ν•©λ‹ˆλ‹€. + - [BE] πŸ”’ **Cryptography 50+ λ³΄μ•ˆ 경계 κ°±μ‹ **: `pyproject.toml`κ³Ό 두 hash-locked μš”κ΅¬μ‚¬ν•­ νŒŒμΌμ„ λ™μΌν•œ Cryptography 50+ ν•΄μ„μœΌλ‘œ μ •ν•©ν™”ν•˜μ—¬ PKCS#7 였λ₯˜Β·νƒ€μ΄λ° κ΅¬λΆ„μœΌλ‘œ μΈν•œ CVE-2026-69247 μ™„ν™”λ₯Ό μ‹€μ œ μ„€μΉ˜Β·κ²€μ¦ κ²½λ‘œμ— λ°˜μ˜ν–ˆμŠ΅λ‹ˆλ‹€. + - [FE] ⚑ **검색 λ…Έλ“œ μ°Έμ‘° μ•ˆμ •ν™” 및 순차 μŠ€λƒ…μƒ· 폴링**: 같은 μ •κ·œν™” 검색어와 원본 ν…Œμ΄λΈ” λ°μ΄ν„°μ—λŠ” μž₯μ‹λœ `node.data` μ°Έμ‘°λ₯Ό μž¬μ‚¬μš©ν•˜μ—¬ λ“œλž˜κ·Έ 쀑 λΆˆν•„μš”ν•œ ν•˜μœ„ λ Œλ”λ§κ³Ό 할당을 μ€„μž…λ‹ˆλ‹€. μŠ€λƒ…μƒ· 폴링은 이전 μš”μ²­μ΄ λλ‚œ λ’€μ—λ§Œ λ‹€μŒ μš”μ²­μ„ μ˜ˆμ•½ν•˜λ©°, 선택 λ³€κ²½Β·μ–Έλ§ˆμš΄νŠΈ ν›„ λ„μ°©ν•œ 였래된 성곡 λ˜λŠ” μ‹€νŒ¨ 응닡을 λ¬΄μ‹œν•©λ‹ˆλ‹€. - [BE] πŸ”’ **곡유 export μ „ 경둜 redaction**: 곡개 share의 SQL / index-design / reversing-spec exportμ—μ„œ μ½”λ©˜νŠΈΒ·`example_value`λ₯Ό μ œκ±°ν•©λ‹ˆλ‹€. λ‹¨μœ„ ν…ŒμŠ€νŠΈλ‘œ λˆ„μΆœμ„ μ°¨λ‹¨ν•©λ‹ˆλ‹€. - [BE] πŸ› οΈ **ν•¨μˆ˜ 인덱슀 쀑볡 μ˜€νƒ μˆ˜μ •**: `lower(email)` λ“± expression indexλ₯Ό 평문 컬럼 인덱슀의 μ€‘λ³΅μœΌλ‘œ 잘λͺ» νŒλ‹¨ν•˜μ§€ μ•Šλ„λ‘ κ΄„ν˜Έ νŒŒμ„œλ₯Ό κ°•ν™”ν–ˆμŠ΅λ‹ˆλ‹€. diff --git a/frontend/src/components/modals/EditTableModal.test.tsx b/frontend/src/components/modals/EditTableModal.test.tsx index 1a8c9af5e..c492797b6 100644 --- a/frontend/src/components/modals/EditTableModal.test.tsx +++ b/frontend/src/components/modals/EditTableModal.test.tsx @@ -46,6 +46,54 @@ describe('EditTableModal', () => { expect(screen.getByRole('checkbox', { name: 'test_col NN μ„€μ •' })).toBeInTheDocument(); }); + it('deletes a table when ν…Œμ΄λΈ” μ‚­μ œ is clicked and confirmed', async () => { + const onDeleteTableMock = vi.fn(); + const editingNode = { + id: 'table-1', + type: 'table', + position: { x: 0, y: 0 }, + data: { + title: 'test_table', + comment: '', + columns: [] + } + }; + + vi.spyOn(window, 'confirm').mockReturnValue(true); + + render(); + + const user = userEvent.setup(); + await user.click(screen.getByRole('button', { name: 'ν…Œμ΄λΈ” μ‚­μ œ' })); + + expect(window.confirm).toHaveBeenCalledWith("'test_table' ν…Œμ΄λΈ”μ„ μ‚­μ œν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?"); + expect(onDeleteTableMock).toHaveBeenCalled(); + }); + + it('does not delete a table when ν…Œμ΄λΈ” μ‚­μ œ is clicked and canceled', async () => { + const onDeleteTableMock = vi.fn(); + const editingNode = { + id: 'table-1', + type: 'table', + position: { x: 0, y: 0 }, + data: { + title: 'test_table', + comment: '', + columns: [] + } + }; + + vi.spyOn(window, 'confirm').mockReturnValue(false); + + render(); + + const user = userEvent.setup(); + await user.click(screen.getByRole('button', { name: 'ν…Œμ΄λΈ” μ‚­μ œ' })); + + expect(window.confirm).toHaveBeenCalled(); + expect(onDeleteTableMock).not.toHaveBeenCalled(); + }); + it('returns null if not open or no editingNode', () => { const { container } = render(); expect(container.firstChild).toBeNull(); diff --git a/frontend/src/components/modals/EditTableModal.tsx b/frontend/src/components/modals/EditTableModal.tsx index 998929d44..cfb61d1b1 100644 --- a/frontend/src/components/modals/EditTableModal.tsx +++ b/frontend/src/components/modals/EditTableModal.tsx @@ -189,7 +189,10 @@ export function EditTableModal({