# 機能設計書 8-記事削除

## 概要

本ドキュメントは、LEGACY CMSにおける記事削除機能の設計を記述したものである。記事をデータベースから削除する仕様を定義する。

### 本機能の処理概要

**業務上の目的・背景**：不要になった記事をシステムから完全に削除するための機能である。記事の削除は取り消しができない操作のため、確認ダイアログによる誤操作防止が実装されている。削除時には関連するタグ、コメント、検索インデックスも合わせて削除される。

**機能の利用シーン**：管理者が記事管理画面から削除対象の記事を選択し、「削除」ボタンをクリックすると確認ダイアログが表示される。確認後に削除が実行され、関連データも含めてシステムから完全に削除される。

**主要な処理内容**：
1. 削除確認ダイアログの表示
2. 関連タグの削除
3. 関連コメントの削除
4. 検索インデックスからのエントリ削除
5. 記事レコードの削除

**関連システム・外部連携**：Zend_Search_Luceneを使用した検索インデックスからの削除。

**権限による制御**：`aarticles`（記事モジュールアクセス）および`aarticledelete`（記事削除）権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 35 | 記事管理画面 | 遷移元 | 記事削除ダイアログへの遷移 |

## 機能種別

CRUD操作（Delete） / データ削除

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | int | Yes | 記事ID | isset, is_numeric |
| confirm | string | Yes | 確認フラグ（'1'で実行） | 値が'1'の場合のみ削除実行 |

### 入力データソース

URLパラメータ（GETリクエスト）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| HTML | string | Ajaxダイアログ用HTML（確認画面または完了画面） |

### 出力先

- データベース削除（articles, tags, commentsテーブル）
- 検索インデックス削除
- Ajaxダイアログ（確認画面/完了画面）

## 処理フロー

### 処理シーケンス

```
1. 権限チェック
   └─ aarticles + aarticledelete 権限を確認
2. レイアウト・ビュー無効化
   └─ Ajaxダイアログとして表示
3. パラメータ取得
   └─ id（記事ID）とconfirm（確認フラグ）
4. 確認フラグの判定
   ├─ confirm != '1': 確認ダイアログを表示
   └─ confirm == '1': 削除処理を実行
5. 削除処理
   └─ deleteArticle()で以下を実行
       ├─ 関連タグの削除
       ├─ 関連コメントの削除
       ├─ 検索インデックスの削除
       └─ 記事レコードの削除
6. 完了画面の表示
```

### フローチャート

```mermaid
flowchart TD
    A[削除リクエスト] --> B{権限チェック}
    B -->|権限なし| C[権限エラー画面]
    B -->|権限あり| D{confirm == 1?}
    D -->|No| E[確認ダイアログ表示]
    E --> F[ユーザー操作]
    F -->|確認| G[confirm=1で再リクエスト]
    G --> D
    F -->|キャンセル| H[ダイアログを閉じる]
    D -->|Yes| I[関連タグ削除]
    I --> J[関連コメント削除]
    J --> K[検索インデックス削除]
    K --> L[記事レコード削除]
    L --> M[完了画面表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 確認必須 | 削除前に確認ダイアログを表示 | 常時 |
| BR-002 | カスケード削除 | 関連するタグ・コメントも削除 | 常時 |
| BR-003 | 検索インデックス削除 | 検索インデックスからもエントリを削除 | 常時 |
| BR-004 | 物理削除 | 論理削除ではなく物理削除を行う | 常時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| タグ削除 | tags | DELETE | tag_type='A' AND tag_slave=記事ID |
| コメント削除 | comments | DELETE | comment_type='A' AND comment_slave=記事ID |
| 記事削除 | articles | DELETE | article_id=記事ID |

### テーブル別操作詳細

#### tags（DELETE）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | tag_type | 'A'（Article） | 削除条件1 |
| DELETE | tag_slave | 記事ID | 削除条件2 |

#### comments（DELETE）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | comment_type | 'A'（Article） | 削除条件1 |
| DELETE | comment_slave | 記事ID | 削除条件2 |

#### articles（DELETE）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | article_id | パラメータのid | 削除条件 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 権限エラー | aarticles または aarticledelete 権限がない | 権限エラー画面へフォワード |

### リトライ仕様

特になし

## トランザクション仕様

明示的なトランザクション制御は実装されていない。削除処理の途中で失敗した場合、部分的に削除された状態になる可能性がある。

## パフォーマンス要件

- レスポンス時間: 1秒以内

## セキュリティ考慮事項

- 管理者権限（aarticles + aarticledelete）が必要
- 確認ダイアログによる誤操作防止
- IDのis_numericチェックによるSQLインジェクション対策

## 備考

- 削除は取り消しができない
- 添付ファイルは削除されない（別管理）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | database.sql | `database.sql` | articlesテーブル（5-20行目）、tagsテーブル（335-341行目）、commentsテーブル（87-97行目）の構造と関連 |

**読解のコツ**: tagsとcommentsはそれぞれtag_type/comment_typeとtag_slave/comment_slaveで記事と関連付けられている。'A'はArticleを示す。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ArticlesController.php | `application/modules/admin/controllers/ArticlesController.php` | deleteAction()メソッド（78-118行目） |

**主要処理フロー**:
1. **80行目**: 権限チェック（`aarticles` + `aarticledelete`）
2. **82-83行目**: レイアウトとビューの無効化
3. **85-86行目**: パラメータ取得（confirm, id）
4. **88行目**: 確認フラグとIDの検証
5. **90-91行目**: 削除処理の実行
6. **93-98行目**: 完了画面HTML出力

#### Step 3: モデル層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Articles.php | `application/models/Articles.php` | deleteArticle()メソッド（260-277行目） |

**主要処理フロー**:
- **262行目**: IDの検証
- **264-265行目**: タグの削除（Tags::deleteSlaveTag()）
- **267-268行目**: コメントの削除（Comments::deleteSlaveComment()）
- **270-271行目**: 検索インデックスの削除（Search::deleteEntry()）
- **273行目**: 記事レコードの削除

#### Step 4: 関連モデルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Tags.php | `application/models/Tags.php` | deleteSlaveTag()メソッド |
| 4-2 | Comments.php | `application/models/Comments.php` | deleteSlaveComment()メソッド |
| 4-3 | Search.php | `application/models/Search.php` | deleteEntry()メソッド（81-97行目） |

### プログラム呼び出し階層図

```
Admin_ArticlesController::deleteAction()
    │
    ├─ ACL権限チェック
    │
    └─ Articles::deleteArticle($id)
           │
           ├─ Tags::deleteSlaveTag('A', $id)
           │      └─ DELETE tags WHERE tag_type='A' AND tag_slave=$id
           │
           ├─ Comments::deleteSlaveComment('A', $id)
           │      └─ DELETE comments WHERE comment_type='A' AND comment_slave=$id
           │
           ├─ Search::deleteEntry('a'.$id)
           │      └─ Luceneインデックスから削除
           │
           └─ Zend_Db::delete('articles', 'article_id = '.$id)
```

### データフロー図

```
[入力]               [処理]                    [出力]

id (記事ID)    ───▶ deleteAction()       ───▶ 確認ダイアログ
confirm (確認)       │                        または
                     │                        完了画面
                     ▼
              deleteArticle($id)
                     │
              ┌──────┼──────┬──────────┐
              ▼      ▼      ▼          ▼
           DELETE  DELETE  DELETE   DELETE
           tags   comments Lucene   articles
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ArticlesController.php | `application/modules/admin/controllers/ArticlesController.php` | コントローラー | 削除処理（78-118行目: deleteAction） |
| Articles.php | `application/models/Articles.php` | モデル | 記事削除と関連データ削除（260-277行目: deleteArticle） |
| Tags.php | `application/models/Tags.php` | モデル | タグ削除 |
| Comments.php | `application/models/Comments.php` | モデル | コメント削除 |
| Search.php | `application/models/Search.php` | モデル | 検索インデックス削除（81-97行目: deleteEntry） |
| database.sql | `database.sql` | DDL | articles, tags, commentsテーブル定義 |
