# 機能設計書 46-cacheTag

## 概要

本ドキュメントは、Next.jsの`cacheTag()`関数の設計を記述する。`"use cache"`関数内でキャッシュタグを付与し、オンデマンド再検証の対象を識別するためのAPIである。

### 本機能の処理概要

**業務上の目的・背景**：キャッシュされたデータの一部だけを選択的に無効化（再検証）したい場合がある。`cacheTag()`は`"use cache"`関数内でタグを付与し、後から`revalidateTag()`で該当タグを持つキャッシュエントリを一括無効化できるようにする。

**機能の利用シーン**：特定のデータカテゴリに紐づくキャッシュの無効化（例: `cacheTag("product-123")`で特定商品関連のキャッシュを一括再検証）。

**主要な処理内容**：
1. `"use cache"`関数内での呼び出しバリデーション
2. タグのバリデーション（`validateTags()`）
3. WorkUnitStore（UseCacheStore）のtagsフィールドにタグを追加

**関連システム・外部連携**：WorkUnitStore、patch-fetch.tsのvalidateTags

**権限による制御**：なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面に直接関連しない |

## 機能種別

設定 / キャッシュ制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tags | ...string[] | Yes | 付与するタグ（可変長引数） | validateTagsでバリデーション（文字列であること、最大長制限等） |

### 入力データソース

関数の引数から直接取得。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| （なし） | void | 戻り値なし。副作用としてUseCacheStoreを更新 |

### 出力先

WorkUnitStore（UseCacheStore）のtagsフィールドにタグを追加。

## 処理フロー

### 処理シーケンス

```
1. cacheTag(...tags) 呼び出し
2. __NEXT_USE_CACHE環境変数チェック
3. WorkUnitStoreの型チェック（'cache'または'private-cache'のみ許可）
4. validateTags(tags, 'cacheTag()')でバリデーション
5. workUnitStore.tagsにタグを追加（初回はnew array、以降はpush）
```

### フローチャート

```mermaid
flowchart TD
    A[cacheTag呼び出し] --> B{__NEXT_USE_CACHE?}
    B -->|No| C[エラースロー]
    B -->|Yes| D{use cache内?}
    D -->|No| E[エラースロー]
    D -->|Yes| F[validateTags]
    F --> G{tags初期化済み?}
    G -->|No| H[tags = validTags]
    G -->|Yes| I[tags.push...validTags]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-46-01 | use cache内限定 | cacheTag()は"use cache"関数内でのみ呼び出し可能 | 常時 |
| BR-46-02 | タグバリデーション | validateTagsにより文字列以外や不正な長さのタグは除外 | 常時 |
| BR-46-03 | 累積的追加 | 同一スコープ内で複数回呼ばれた場合、タグは累積される | 常時 |

### 計算ロジック

特になし。

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

本機能はデータベースを操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | cacheComponents設定なし | エラーメッセージで設定方法を案内 |
| - | Error | "use cache"関数外での呼び出し | エラースロー |

### リトライ仕様

不要。

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

不要。

## パフォーマンス要件

即座に完了する同期処理のため特に要件なし。

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

特になし。

## 備考

- `cacheComponents`設定（experimental）が必要
- タグはcollectResult()（use-cache-wrapper.ts）でCacheEntryに収集される
- implicitTagsとは異なり、ユーザーが明示的に付与するタグ

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cache-tag.ts | `packages/next/src/server/use-cache/cache-tag.ts` | 全40行の小さなファイル。`cacheTag()`関数全体を読む |

**主要処理フロー**:
1. **5-9行目**: __NEXT_USE_CACHEチェック
2. **11行目**: WorkUnitStore取得
3. **13-30行目**: 型チェック（cache/private-cacheのみ許可）
4. **32行目**: validateTagsでバリデーション
5. **34-38行目**: tagsフィールドへの追加

#### Step 2: バリデーション処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | patch-fetch.ts | `packages/next/src/server/lib/patch-fetch.ts` | `validateTags()`関数の実装。タグの文字列チェック・長さ制限 |

#### Step 3: タグの利用箇所を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | use-cache-wrapper.ts | `packages/next/src/server/use-cache/use-cache-wrapper.ts` | collectResult()の432-455行目: innerCacheStore.tagsの収集 |

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

```
cacheTag(...tags)
    │
    ├─ workUnitAsyncStorage.getStore()
    ├─ validateTags(tags, 'cacheTag()')
    └─ workUnitStore.tags.push(...validTags)
```

### データフロー図

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

tags ───▶ cacheTag() ───▶ UseCacheStore.tags
                                │
                          collectResult()で参照
                                │
                          CacheEntry.tags
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cache-tag.ts | `packages/next/src/server/use-cache/cache-tag.ts` | ソース | cacheTag()の実装 |
| patch-fetch.ts | `packages/next/src/server/lib/patch-fetch.ts` | ソース | validateTags()の提供元 |
| use-cache-wrapper.ts | `packages/next/src/server/use-cache/use-cache-wrapper.ts` | ソース | collectResult()での値利用 |
| work-unit-async-storage.external.ts | `packages/next/src/server/app-render/work-unit-async-storage.external.ts` | ソース | UseCacheStore型定義 |
