# 🗑️ Agent Meeting: InsuWiki 휴지통(Trash) 기능 설계

**날짜**: 2026-02-24 01:24  
**주제**: 소프트 삭제된 문서를 관리자/작성자가 조회·관리할 수 있는 휴지통 UI 구현 방향  
**참석자**: PM, UX, Frontend, Backend, Data, QA, Legal, Planner, Reflect (9명 전원)  
**회의 형식**: 문제 정의 → 현황 진단 → 솔루션 브레인스토밍 → 우선순위 결정

---

## 📋 안건 브리핑 (PM)

**PM**: 오너로부터 다음과 같은 문제 제기가 있었습니다.

> "문서를 삭제하면 휴지통에 남아있다고 했는데, 정작 휴지통에 뭐가 있는지 볼 수도 없고 관리하는 화면이 없잖아요. 복원하려면 URL을 직접 알아야 하나요?"

**현재 문제**:
- 소프트 삭제 시 `isDeleted: true` 로 Firestore에 보관되지만
- 해당 문서를 목록에서 확인할 방법이 없음
- URL을 직접 입력해야만 삭제된 문서에 접근 가능
- 실수로 삭제한 문서를 복원하려면 docId를 기억해야 함

**목표**: 관리자/작성자가 삭제된 문서를 조회하고 복원/영구삭제할 수 있는 휴지통 UI

---

## 1️⃣ UX 에이전트 발언

**UX**: 사용자 경험 관점에서 핵심 Pain Point와 해결 방향을 제안합니다.

### 현재 삭제 UX의 문제점

| 문제 | 영향 | 심각도 |
|-----|------|-------|
| 삭제 후 복원 경로 없음 | 실수 삭제 시 복구 불가 | 🔴 치명적 |
| 휴지통 목록 없음 | 삭제된 항목 파악 불가 | 🔴 치명적 |
| URL 직접 접근만 가능 | 일반 사용자 복원 사실상 불가 | 🟡 높음 |
| 영구삭제 여부 판단 불가 | 불필요한 데이터 축적 | 🟢 낮음 |

### 추천 UX 패턴 (벤치마크)

**Gmail 휴지통**: 별도 탭 또는 사이드바 메뉴 → 목록 조회 → 개별 복원/영구삭제  
**Notion**: 사이드바 하단 "휴지통" → 제목 검색 → 복원  
**Google Drive**: 좌측 메뉴 "휴지통" → 30일 후 자동 삭제 경고

### InsuWiki 추천 UX

```
[메인 헤더 또는 설정 메뉴]
    → "휴지통" 버튼/링크
    
[휴지통 페이지 /trash]
    ├── 내 삭제 문서 목록 (작성자용)
    │   ├── 문서 제목
    │   ├── 삭제된 날짜
    │   ├── 문서 타입 (Wiki/My/Daily)
    │   └── [복원] [영구삭제] 버튼
    │
    └── 전체 삭제 문서 목록 (관리자 추가 표시)
        ├── 위와 동일 + 삭제한 사람 표시
        └── [영구삭제] 버튼
```

**자동 삭제 안내 (선택사항)**: "30일 후 자동 영구삭제" 경고 표시  
**빈 상태**: "휴지통이 비어있습니다" 친절한 안내

---

## 2️⃣ Frontend 에이전트 발언

**Frontend**: 구현 방식을 두 가지로 제안합니다.

### 옵션 A: 별도 페이지 `/trash`

```
nextapp/src/app/trash/
    ├── page.tsx         (서버 컴포넌트, 기본 레이아웃)
    └── TrashClient.tsx  (클라이언트 컴포넌트, Firestore 쿼리 및 인터랙션)
```

- **장점**: 깔끔한 URL, 독립적인 페이지, GlobalHeader 재사용 가능
- **단점**: 페이지 전환 필요

### 옵션 B: 메인 대시보드에 "휴지통" 탭 추가

- **장점**: 기존 UI 패턴(Wiki/My/Daily)과 일관성
- **단점**: 탭이 4개로 늘어 모바일 레이아웃 복잡해짐

### 옵션 C: 설정/프로필 페이지 내 하위 섹션

- **장점**: 자주 쓰지 않는 기능에 적합한 위치
- **단점**: 접근성 낮음

**Frontend 추천**: **옵션 A** (별도 `/trash` 페이지) — GlobalHeader 우측에 아이콘 버튼으로 접근

### 핵심 컴포넌트 설계

```tsx
// TrashClient.tsx 주요 로직
const trashQuery = query(
  collection(db, 'documents'),
  where('isDeleted', '==', true),
  where(isAdmin ? /* 전체 */ : 'authorId', isAdmin ? /* skip */ : '==', user.uid),
  orderBy('deletedAt', 'desc'),
  limit(50)
);
```

> ⚠️ Firestore 복합 인덱스 필요 여부 Backend에게 확인 필요

---

## 3️⃣ Backend 에이전트 발언

**Backend**: Firestore 쿼리 및 API 설계를 검토합니다.

### Firestore 쿼리 이슈 분석

**일반 사용자용 쿼리**:
```
where('isDeleted', '==', true) + where('authorId', '==', uid) + orderBy('deletedAt', 'desc')
```
→ Firestore 복합 인덱스 필요: `isDeleted + authorId + deletedAt`  
→ 현재 없으면 Firestore Console에서 수동 생성 필요

**관리자용 쿼리**:
```
where('isDeleted', '==', true) + orderBy('deletedAt', 'desc')
```
→ 단순 쿼리 — 인덱스 자동 생성

### 기존 Purge API 확장 고려사항

현재 `DELETE /api/admin/purge?docId={docId}` 는:
- 단건 처리만 지원
- `isDeleted === true` 체크 (안전장치)

**추가 필요 API 없음**: 기존 API 재사용 가능  
복원은 클라이언트에서 직접 Firestore update 가능 (`isDeleted: false`)

### 자동 영구삭제 (30일) 옵션

- Vercel Cron Job 또는 Firebase Scheduled Functions 필요
- 현재 인프라로 즉시 구현 가능 여부: 🟡 추가 설정 필요
- **PM 판단 필요**: 당장 필요한 기능인지?

---

## 4️⃣ Data 에이전트 발언

**Data**: 스키마 및 인덱스 관점에서 분석합니다.

### 현재 필드 상태

```typescript
// types/firestore.ts - Document 인터페이스
isDeleted?: boolean    // ✅ 존재
deletedAt?: Timestamp  // ✅ 존재 (saveDelete 시 설정)
deletedBy?: string     // ✅ 존재 (uid)
```

**문제**: 레거시 문서 일부는 `deletedAt`, `deletedBy` 필드가 없을 수 있음  
→ 휴지통 UI에서 `deletedAt` null 처리 필요

### Firestore 인덱스 예상 필요 목록

| 인덱스 | 필요 여부 |
|-------|---------|
| `isDeleted ASC, authorId ASC, deletedAt DESC` | 일반 사용자용 필수 |
| `isDeleted ASC, deletedAt DESC` | 관리자용 (자동 생성 가능) |

### 삭제 이력(Revision) 보존 여부

- 소프트 삭제 상태: `revisions` 서브컬렉션 그대로 보존
- 휴지통 목록에서 "변경 이력 N개" 정보 표시 가능 → 복원 결정에 도움

---

## 5️⃣ QA 에이전트 발언

**QA**: 품질 및 보안 관점에서 검토합니다.

### 권한 시나리오 테스트 케이스

| 시나리오 | 기대 결과 |
|---------|---------|
| 일반 유저가 `/trash` 접근 | 본인 삭제 문서만 표시 |
| 일반 유저가 타인 삭제 문서 URL 접근 | 하단 버튼 비표시 또는 403 처리 |
| 관리자가 `/trash` 접근 | 전체 삭제 문서 목록 표시 |
| 비로그인 사용자가 `/trash` 접근 | 로그인 페이지로 리다이렉트 |
| 이미 영구삭제된 docId로 복원 시도 | 에러 처리 |

### 위험 요소

1. **관리자 권한 노출**: ADMIN_EMAILS 리스트가 클라이언트 코드에 하드코딩되어 있음  
   → 휴지통 관리자 기능은 서버 검증 추가 권장  
2. **대량 삭제 문서**: limit(50) 초과 시 페이지네이션 필요  
3. **동시 복원/삭제**: Firestore 트랜잭션 사용 권장

---

## 6️⃣ Legal 에이전트 발언

**Legal**: 법적·정책적 관점에서 검토합니다.

### 데이터 보존 정책

- **개인정보 보호**: 사용자가 삭제 요청 시 실제 데이터도 삭제되어야 할 수 있음 (GDPR 관련)
- **현재 소프트 삭제**: 데이터 보존 기간 정책 미정의 → `docs/decisions/`에 데이터 보존 정책 결정 문서 필요
- **30일 자동 삭제**: 명확한 사용자 고지 필요 (삭제 시 안내 문구)

### 추천 정책

```
삭제 시 확인 메시지에 추가:
"문서는 30일 후 자동으로 영구 삭제됩니다. 복원하려면 휴지통을 방문하세요."
```

---

## 7️⃣ Planner 에이전트 발언

**Planner**: 전체 범위와 우선순위를 정리합니다.

### 기능 범위 (MoSCoW)

**Must Have (즉시 필요)**:
- [ ] `/trash` 페이지 생성
- [ ] 본인 삭제 문서 목록 조회
- [ ] 복원 버튼 (일반 사용자)
- [ ] GlobalHeader에 휴지통 접근 버튼

**Should Have (중요)**:
- [ ] 관리자 전체 목록 조회
- [ ] 영구삭제 버튼 (관리자)
- [ ] 삭제 날짜 / 문서 타입 표시

**Could Have (선택)**:
- [ ] 30일 후 자동 영구삭제 및 경고 표시
- [ ] 휴지통 내 검색
- [ ] 선택 삭제 (체크박스 + 일괄 처리)

**Won't Have (이번 버전 제외)**:
- 삭제 이력(Revision) 별도 복원
- 첨부파일 복원(Google Drive 연동 복잡도)

### 구현 예상 공수

| 항목 | 예상 시간 |
|-----|---------|
| `/trash` 페이지 + 기본 목록 | 2~3시간 |
| 관리자 전체 목록 + 필터 | 1시간 |
| Firestore 인덱스 설정 | 30분 |
| GlobalHeader 진입점 | 30분 |
| **합계** | **약 4~5시간** |

---

## 8️⃣ Reflect 에이전트 발언

**Reflect**: 기존 패턴 및 학습된 지식 연결을 제안합니다.

### 기존 코드 재사용 포인트

- `DocumentClient.tsx`의 `handleRestore()` / `handlePurge()` 함수 → 그대로 재사용 가능
- `GlobalHeader.tsx` → 우측 아이콘 영역에 휴지통 아이콘 추가
- `page.tsx` 카드 렌더링 패턴 → TrashClient.tsx에 동일 패턴 적용
- 기존 `tabAccent` 색상 시스템 → 휴지통 시각 테마 정의

### 주의사항 (과거 버그 학습)

- `isDeleted` 필드가 없는 레거시 문서 처리 (`undefined !== true` → 정상 문서로 취급)
- Firestore 복합 쿼리 시 인덱스 누락 에러 → 배포 전 Console에서 미리 생성
- 관리자 이메일 하드코딩 → 일관성 위해 `lib/admin.ts` 등 단일 상수 파일로 관리 권장

### 관련 기존 결정사항

- `docs/specs/document-delete-flow.md` (오늘 작성) — 삭제 플로우 전체 구조 참고
- `isDeleted` 클라이언트 필터링 vs Firestore 쿼리 전략 — 휴지통은 반드시 `where('isDeleted', '==', true)` Firestore 쿼리 사용

---

## 9️⃣ PM 에이전트 최종 정리

**PM**: 각 에이전트 의견을 종합하여 결정사항을 정리합니다.

### ✅ 합의된 결정사항

1. **구현 방식**: 별도 페이지 `/trash` (옵션 A) — 전원 동의
2. **진입점**: GlobalHeader에 🗑️ 아이콘 버튼 추가
3. **일반 사용자**: 본인 삭제 문서만 조회, 복원 가능
4. **관리자**: 전체 삭제 문서 조회, 영구 삭제 가능
5. **자동 삭제**: 이번 버전 제외 (Could Have)
6. **파일 첨부 복원**: 이번 버전 제외

### 📋 구현 전 필요한 사전 작업

- [ ] Firestore Console에서 복합 인덱스 생성 확인  
  (`isDeleted + authorId + deletedAt` 인덱스)
- [ ] 데이터 보존 정책 결정 문서 작성 (`docs/decisions/`)
- [ ] 관리자 이메일 상수 중앙화 검토

### 🔜 다음 단계

사용자 승인 후 `/dev-workflow` 절차에 따라 구현 진행

---

## 📊 최종 아키텍처 다이어그램

```
[GlobalHeader]
    └── 🗑️ 휴지통 아이콘 버튼 (로그인 시 표시)
            ↓
[/trash 페이지]
    ├── <TrashClient> (클라이언트 컴포넌트)
    │   ├── Firestore 쿼리: isDeleted=true + authorId=uid (일반)
    │   │                   isDeleted=true (관리자)
    │   ├── 정렬: deletedAt 최신순
    │   └── 문서 카드 목록
    │       ├── 제목, 타입(Daily/My/Wiki), 삭제일
    │       ├── [복원] → handleRestore() 재사용
    │       └── [영구삭제] → handlePurge() 재사용 (관리자만)
    │
    └── 빈 상태: "휴지통이 비어있습니다 🗑️"
```

---

**회의 종료**: 2026-02-24 01:40 (예상)  
**다음 Action**: 사용자 승인 → `/dev-workflow` 절차 진행
