# バッチ設計書 6-draft-blog-post.js

## 概要

本ドキュメントは、Prettierのリリースブログ記事のドラフトを自動生成するスクリプト `scripts/draft-blog-post.js` の設計仕様を記載したものです。

### 本バッチの処理概要

本バッチは、changelog_unreleasedディレクトリ内の変更エントリを読み込み、構造化されたブログ記事形式に変換して、websiteのblogディレクトリに出力します。

**業務上の目的・背景**：Prettierの各リリースでは、変更内容を紹介するブログ記事を公開しています。変更エントリは開発中に個別のMarkdownファイルとして蓄積されますが、リリース時にはこれらを統合してブログ記事形式にまとめる必要があります。本バッチは、この統合作業を自動化し、一貫したフォーマットのブログ記事を効率的に生成します。

**バッチの実行タイミング**：リリース準備段階で実行されます。changelogエントリが揃った後、リリースブログ記事のレビュー前に実行します。

**主要な処理内容**：
1. changelog_unreleasedディレクトリからカテゴリ別にエントリを読み込み
2. イントロテンプレートの読み込み（存在しない場合はテンプレートからコピー）
3. エントリをセクション（Highlights, Breaking Changes, Formatting Improvements, Other Changes）に分類
4. バージョン番号の置換処理（前バージョン、新バージョン）
5. 日付付きのブログ記事ファイルを生成

**前後の処理との関連**：リリースプロセス（run.js）の一部として実行される場合があります。生成されたブログ記事は、PRとしてレビュー・マージされます。

**影響範囲**：website/blog/ディレクトリ配下のブログ記事ファイル。既存の同バージョンの記事があれば削除されます。

## バッチ種別

コンテンツ生成 / ドキュメント自動化

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（リリース準備時） |
| 実行時刻 | 任意 |
| 実行曜日 | 任意 |
| 実行日 | 任意 |
| トリガー | 手動 / リリースプロセス |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Node.js環境 | Node.jsがインストールされていること |
| 依存パッケージ | yarn installにより依存パッケージがインストール済みであること |
| changelogエントリ | changelog_unreleased/配下にエントリファイルが存在すること |

### 実行可否判定

changelogエントリが存在しない場合でも、空のセクションとしてブログ記事が生成されます。

## 入力仕様

### 入力パラメータ

本バッチはコマンドライン引数を受け取りません。

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | - |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| changelog_unreleased/{category}/*.md | Markdown | 変更エントリファイル |
| changelog_unreleased/blog-post-intro.md | Markdown | ブログ記事のイントロダクション |
| changelog_unreleased/BLOG_POST_INTRO_TEMPLATE.md | Markdown | イントロのテンプレート |
| node_modules/prettier/package.json | JSON | 前バージョン番号 |
| package.json | JSON | 新バージョン番号 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| website/blog/YYYY-MM-DD-{version}.md | Markdown | リリースブログ記事 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | YYYY-MM-DD-{version}.md（実行日とバージョン） |
| 出力先 | website/blog/ |
| 文字コード | UTF-8 |
| 区切り文字 | N/A（Markdownファイル） |

## 処理フロー

### 処理シーケンス

```
1. バージョン情報の取得
   └─ node_modules/prettier/package.jsonから前バージョンを取得
   └─ package.jsonから新バージョンを取得
2. イントロファイルの準備
   └─ blog-post-intro.mdが存在しない場合はテンプレートからコピー
3. カテゴリ別エントリの読み込み
   └─ changelog_unreleased/{category}/からエントリを取得
   └─ 各エントリにセクション情報（highlight, breaking, improvement）を付与
4. 既存記事の削除
   └─ 同バージョンの既存ブログ記事をglob検索して削除
5. ブログ記事の生成
   └─ セクション別にエントリを分類・出力
   └─ バージョン番号を置換
6. ファイル出力
   └─ 日付付きファイル名で出力
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[バージョン情報取得]
    B --> C{blog-post-intro.md存在?}
    C -->|No| D[テンプレートからコピー]
    C -->|Yes| E[イントロファイル読み込み]
    D --> E
    E --> F[カテゴリループ]
    F --> G[getEntriesでエントリ取得]
    G --> H{次のカテゴリ?}
    H -->|Yes| F
    H -->|No| I[既存記事削除]
    I --> J[セクション別エントリ分類]
    J --> K[Highlights出力]
    K --> L[Breaking Changes出力]
    L --> M[Formatting Improvements出力]
    M --> N[Other Changes出力]
    N --> O[バージョン置換]
    O --> P[ファイル出力]
    P --> Q[バッチ終了]
```

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

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

本バッチはデータベースを使用しません。

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

N/A

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Unknown category | 未定義のカテゴリディレクトリが存在 | カテゴリ定義を確認 |
| - | File read error | エントリファイルの読み込み失敗 | ファイルの存在とアクセス権を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

エラー発生時は例外がスローされます。エラーメッセージに基づきカテゴリ定義やファイル構造を確認してください。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイルシステム操作のみ） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数十〜数百のchangelogエントリ |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | Node.jsデフォルト制限に依存 |

## 排他制御

同時実行による問題は発生しにくいですが、同一ファイルへの書き込みが競合する可能性があります。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| なし | - | 本バッチは標準出力へのログを出力しません |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| なし | - | エラー時は例外として伝播 |

## 備考

- fast-globパッケージで既存ブログ記事を検索・削除
- 4つのセクション（Highlights, Breaking Changes, Formatting Improvements, Other Changes）で構造化
- useFriendlyHeadingIdオプションで読みやすい見出しIDを生成
- TRUNCATE_COMMENT（<!-- truncate -->）でブログプレビューの切り取り位置を指定
- semverパッケージでバージョン番号のmajor/minor/patchを分解
- esm-utilsパッケージでCommonJS互換の__dirnameとrequireを取得
