Toodo의 작업 및 워크스페이스용 소프트 삭제 아카이브 시스템
README 링크에서 발견 · today
작업과 워크스페이스를 삭제하면 이제 보관 처리되며, 복원 및 영구 삭제 기능이 제공됩니다.
What they did
작성자는 행을 지우는 대신 Toodo 스택 전반에 걸쳐 소프트 삭제 아카이빙을 구현했습니다. 이제 작업이나 워크스페이스를 삭제하면 `archived_at`이 설정됩니다(스키마 버전 41). 아카이브된 항목은 목록과 의존성 DAG에서 빠지므로, 의존 항목들이 더 이상 이를 기다리지 않게 되며, 히스토리, 커밋, 노트, 기준, 링크는 보존됩니다. 리뷰(`review_period`)는 여전히 아카이브된 작업을 포함하며, 각 항목에는 "Archived" 칩으로 렌더링되는 `archived` 플래그가 함께 표시되고, 리뷰는 아카이브된 워크스페이스를 명시합니다. 새로운 Settings > Archive 섹션은 아카이브된 워크스페이스와 작업을 나열하며, Restore(`restore_task`, `restore_workspace`)와 영구 삭제(`purge_task`, `purge_workspace`, 아카이브된 항목만, 먼저 확인) 기능을 제공합니다. 의존성 사이클을 닫게 되는 복원은 거부되며 해당 사이클이 명시됩니다. 워크스페이스의 작업 중 하나에 대한 실행이 대기 중이거나 활성 상태인 동안에는 워크스페이스 아카이빙이 거부되고, 열려 있는 런타임 워크스페이스는 닫힙니다. MCP `delete_task` 텍스트, 문서(`workflow.md`, `architecture.md`, `agents.md`), 그리고 에이전트 스킬이 아카이빙을 설명하도록 업데이트되었습니다.
How it went
검증은 철저했습니다. `cargo test --lib`는 876개 테스트를 통과했고(이 호스트에서 멈추는 `runtime::plain`의 `remote_stop_*` 테스트는 건너뜀), `-D warnings`를 적용한 clippy와 `cargo fmt --check`는 깨끗했으며, `npm run typecheck`와 `npm test`는 새 `archive-panel.test.tsx`를 포함한 393개 테스트를 통과했습니다. 임시 `toodo-server`를 `/api/rpc`를 통해 실행하며 SQLite 검사로 다음을 확인했습니다: 행이 `archived_at`과 함께 유지되고 숨겨짐, 종속 항목의 블록이 해제됨, 리뷰에서 보관된 작업이 `archived`로 표시됨, 복원 시 의존성 엣지가 되살아남, 잘못된 복원과 purge는 다음 단계 안내와 함께 거부됨, purge는 행과 리뷰 항목을 제거함. 데스크톱 1280px와 휴대폰 390px에서의 브라우저 검사로 Archive 섹션이 항목을 나열하고, 영구 삭제가 확인을 요청하며, Restore가 항목을 제거하고, 리뷰에 Archived 칩이 표시됨을 확인했습니다.
Worth knowing
`runtime::plain`의 `remote_stop_*` 테스트는 이 호스트에서 멈춰서 건너뛰었기 때문에, 해당 경로는 여기서 검증되지 않았습니다. 검증은 전체 CI 실행이 아니라 임시 서버와 수동 브라우저 확인에 의존했습니다. archive/purge 동작은 RPC와 MCP 텍스트를 통해 노출되며, 스키마 버전 41 외에 기존 행에 대한 마이그레이션 백필 세부 사항은 설명되어 있지 않습니다.
Wiring
스키마 마이그레이션이 버전 41에서 `archived_at`을 추가합니다. 서버 RPC 엔드포인트에 `restore_task`, `restore_workspace`, `purge_task`, `purge_workspace`가 추가되며, 삭제 핸들러는 `archived_at`을 설정합니다. 목록 및 DAG 쿼리는 `archived_at IS NULL`로 필터링합니다. 리뷰 쿼리는 아카이브된 행을 포함하고 `archived` 불리언을 프로젝션합니다. 프론트엔드는 확인 대화상자와 함께 restore 및 purge RPC를 호출하는 Archive 설정 패널을 추가하고, 리뷰 항목은 Archived 칩을 렌더링합니다. MCP 도구 텍스트와 문서도 이에 맞게 업데이트됩니다. 검증은 `cargo test --lib`, `cargo clippy --all-targets -- -D warnings`, `cargo fmt --check`, `npm run typecheck`, `npm test`를 실행하고, 추가로 SQLite 검사와 1280px 및 390px에서의 브라우저 검사를 통해 `/api/rpc`로 스크래치 `toodo-server`를 실행합니다.
Try it yourself
# Task: Replace hard deletes with archiving ## 1. Schema (bump to 41) Add an `archived_at` column to both `tasks` and `workspaces`: ```sql ALTER TABLE tasks ADD COLUMN archived_at TEXT; ALTER TABLE workspaces ADD COLUMN archived_at TEXT; ``` Bump `SCHEMA_VERSION` to `41` and add the migration step. ## 2. Delete becomes archive - `delete_task` / `delete_workspace` now set `archived_at = now()` instead of `DELETE FROM ...`. - Keep all related rows intact: history, commits, notes, criteria, links. ## 3. Exclude archived from lists and DAG - All list queries filter `WHERE archived_at IS NULL`. - The dependency DAG builder skips archived tasks, so dependents of an archived task are unblocked. ## 4. `review_period` results - Include archived work in results with an `archived: bool` flag. - UI renders an "Archived" chip on those entries. ## 5. Settings > Archive panel New panel listing archived workspaces and tasks with per-item actions: - **Restore** → `restore_task`, `restore_workspace` - **Delete permanently** → `purge_task`, `purge_workspace` (archived only, confirmed first) ### Restore validation - Reject a restore that would close a dependency cycle; name the cycle in the error. ### Archive validation (workspace) - Reject archiving a workspace while a run of one of its tasks is queued or active. - On successful archive, close its open runtime workspaces. ## 6. Docs - Update MCP `delete_task` description text. - Update `workflow.md`, `architecture.md`, `agents.md`, and the agent skill. ## 7. Tests - Add tests covering archive/restore/purge, DAG unblocking, cycle rejection, and the archive panel. - Run: `cargo test`, `cargo clippy`, `cargo fmt`, typecheck, `npm test`.