# 画面設計書 18-スケジュール編集画面（モバイル）

## 概要

本ドキュメントは、Actual Budgetアプリケーションにおけるモバイル向けスケジュール編集画面の設計仕様を定義する。

### 本画面の処理概要

スケジュール編集画面（モバイル）は、定期取引スケジュールの新規作成および編集を行うモバイル最適化画面である。スケジュールの基本情報（名前、日付、金額、支払先、口座等）の設定と、関連取引のリンク管理を提供する。

**業務上の目的・背景**：モバイルデバイスから定期取引スケジュールを作成・編集できるようにすることで、外出先でも支払いスケジュールの管理が可能になる。家賃、光熱費、サブスクリプションなどの定期支払いを登録し、自動取引生成や予定取引としてのプレビュー表示を設定できる。

**画面へのアクセス方法**：
- スケジュール一覧画面（モバイル）の「+」ボタンをタップ（新規作成）
- スケジュール一覧画面（モバイル）のスケジュール項目をタップ（編集）
- URLパターンは `/schedules/new`（新規）または `/schedules/:id`（編集）

**主要な操作・処理内容**：
1. スケジュール基本情報の入力（名前、日付、繰り返し設定）
2. 取引情報の設定（金額、支払先、口座、カテゴリ）
3. 自動取引生成の有効/無効設定
4. 関連取引のリンク/リンク解除
5. スケジュールの保存

**画面遷移**：
- 遷移元：スケジュール一覧画面（モバイル）
- 遷移先：スケジュール一覧画面（モバイル）、ルール編集画面

**権限による表示制御**：特になし。認証済みユーザーであれば全機能を利用可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | 定期取引スケジュール | 主機能 | モバイルでのスケジュール編集 |
| 60 | レスポンシブUI | 補助機能 | モバイル最適化表示 |

## 画面種別

編集

## URL/ルーティング

- 新規作成：`/schedules/new`
- 編集：`/schedules/:id`

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | 型 | 必須 | 説明 |
|--------|--------|----------|-----|------|------|
| スケジュールID | id | 入力 | string | No | 編集時のスケジュールID（URLパラメータ） |
| スケジュール名 | name | 入力 | string | No | スケジュール名 |
| 日付/繰り返し設定 | date | 入力 | RecurConfig | Yes | 次回日付と繰り返し設定 |
| 金額 | amount | 入力 | number | Yes | 取引金額 |
| 支払先 | payee | 入力 | string | No | 支払先ID |
| 口座 | account | 入力 | string | Yes | 口座ID |
| カテゴリ | category | 入力 | string | No | カテゴリID |
| 自動取引生成 | posts_transaction | 入力 | boolean | No | 自動で取引を生成するか |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| ページタイトル | 「Create Schedule」または「Edit Schedule」 | i18n |
| スケジュールフォーム | 各種入力フィールド | schedule |
| 保存ボタン | フッターに配置 | - |
| 関連取引一覧 | リンクされた取引 | transactions |

### 初期値（新規作成時）

| 項目 | 初期値 |
|------|--------|
| 日付 | 現在日 |
| 繰り返し | monthly（月次） |
| 自動取引生成 | false |

## イベント仕様

### 1-保存ボタン押下

フッターの「Save」ボタンを押下すると、入力内容のバリデーションを行い、スケジュールを保存する。

**バリデーション**：
1. スケジュール名の重複チェック（同名スケジュールが存在する場合はエラー）
2. 日付条件の更新（updateScheduleConditions）

**保存処理**：
- 新規の場合：`schedule/create`を呼び出し
- 編集の場合：`schedule/update`を呼び出し

保存成功後、Undo通知を表示し、`/schedules`に遷移する。

### 2-戻るボタン押下

ヘッダー左側の戻るボタンを押下すると、前の画面に戻る（navigate(-1)）。

### 3-ルール編集

スケジュールに関連付けられたルールを編集する場合、`/rules/:ruleId`に遷移する。

### 4-取引リンク

関連取引リストで取引を選択し、スケジュールにリンクする。`transactions-batch-update`を呼び出してscheduleフィールドを更新。

### 5-取引リンク解除

リンクされた取引を選択し、リンク解除する。`transactions-batch-update`を呼び出してscheduleフィールドをnullに更新。

### 6-取引表示モード切替

linked（リンク済み）とmatched（マッチング）の表示モードを切り替える。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示（編集時） | schedules | SELECT | 指定IDのスケジュールを取得 |
| 保存（新規） | schedules | INSERT | 新規スケジュールを作成 |
| 保存（編集） | schedules | UPDATE | スケジュールを更新 |
| 取引リンク | transactions | UPDATE | 取引のscheduleフィールドを更新 |
| 取引リンク解除 | transactions | UPDATE | 取引のscheduleフィールドをnullに更新 |

### テーブル別更新項目詳細

#### schedules

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | id | スケジュールID | - |
| INSERT/UPDATE | name | スケジュール名 | - |
| INSERT/UPDATE | posts_transaction | true/false | 自動取引生成フラグ |
| INSERT/UPDATE | _conditions | 条件配列 | 日付、金額等の条件 |

#### transactions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | schedule | スケジュールID/null | リンク/リンク解除時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|------------|
| M001 | 成功 | Schedule created successfully | 新規作成成功時（Undo通知） |
| M002 | 成功 | Schedule saved successfully | 編集保存成功時（Undo通知） |
| M003 | エラー | There is already a schedule with this name | スケジュール名重複時 |
| M004 | エラー | An error occurred while saving. Please visit https://actualbudget.org/contact/ for support. | 保存失敗時 |
| M005 | 情報 | Loading... | ローディング中 |
| M006 | 情報 | Schedule not found | スケジュールが見つからない場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| スケジュール名重複 | フォームエラーを表示、保存を中止 |
| スケジュール未検出（編集時） | 「Schedule not found」画面を表示 |
| 保存エラー | エラーメッセージを表示 |
| ローディング中 | ローディング画面を表示 |

## 備考

- useScheduleEditフックでスケジュール状態を管理
- 新規作成時はadding=true、編集時はadding=false
- 初期スケジュールの繰り返し設定はmonthly（月次）
- useSelectedフックで関連取引の選択状態を管理
- updateScheduleConditionsで日付条件を更新
- showUndoNotificationでUndo通知を表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models/index.d.ts | `packages/loot-core/types/models/` | ScheduleEntity、RecurConfigの型定義 |

**読解のコツ**: _conditions, _actions, posts_transaction, _dateフィールドに注目。RecurConfigのfrequency, patterns, skipWeekend等の設定項目を確認。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MobileScheduleEditPage.tsx | `packages/desktop-client/src/components/mobile/schedules/MobileScheduleEditPage.tsx` | メインコンポーネント |

**主要処理フロー**:
1. **行27-33**: コンポーネント初期化（useParams, useNavigate, useUndo）
2. **行33**: adding判定（id未指定または'new'の場合true）
3. **行36-56**: 新規作成時の初期スケジュール生成（RecurConfig設定）
4. **行58-63**: useScheduleEditフックでスケジュール状態管理
5. **行67-130**: onSave関数（名前重複チェック、条件更新、API呼び出し）
6. **行132-134**: onEditRule関数（ルール編集画面遷移）
7. **行136-151**: onLinkTransactions/onUnlinkTransactions（取引リンク管理）
8. **行155-158**: onSwitchTransactions（表示モード切替）

#### Step 3: フォームコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ScheduleEditForm.tsx | `packages/desktop-client/src/components/schedules/ScheduleEditForm.tsx` | スケジュール編集フォーム |
| 3-2 | schedule-edit-utils.ts | `packages/desktop-client/src/components/schedules/schedule-edit-utils.ts` | updateScheduleConditions |

#### Step 4: カスタムフックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | useScheduleEdit.ts | `packages/desktop-client/src/hooks/useScheduleEdit.ts` | スケジュール編集状態管理 |

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

```
MobileScheduleEditPage (エントリーポイント)
    |
    +-- Page
    |       +-- MobilePageHeader
    |       |       +-- Text (Create Schedule / Edit Schedule)
    |       |       +-- MobileBackButton --> navigate(-1)
    |       |
    |       +-- ScheduleEditForm
    |       |       +-- 名前入力
    |       |       +-- 日付/繰り返し設定
    |       |       +-- 金額入力
    |       |       +-- 支払先選択
    |       |       +-- 口座選択
    |       |       +-- カテゴリ選択
    |       |       +-- 自動取引生成トグル
    |       |       +-- 関連取引リスト
    |       |
    |       +-- View (フッター)
    |               +-- Button (Save) --> onSave()
    |
    +-- isLoading: true --> Loading画面
    +-- schedule: null --> Schedule not found画面
```

### データフロー図

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

URLパラメータ id  --->  useParams                    --->  スケジュールID
(編集時)

                   --->  useScheduleEdit              --->  state (schedule, fields,
                         (フック)                           transactions, upcomingDates)

User input        --->  dispatch                     --->  fields更新
(フォーム入力)           (type: 'set-field')

Save button       --->  aqlQuery                     --->  名前重複チェック
                        (重複チェック)

                  --->  updateScheduleConditions     --->  conditions更新

                  --->  sendCatch                    --->  スケジュール保存
                        ('schedule/create' or
                         'schedule/update')

                  --->  showUndoNotification         --->  成功通知

                  --->  navigate('/schedules')       --->  一覧画面遷移

Transaction link  --->  send                         --->  取引リンク更新
                        ('transactions-batch-update')
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MobileScheduleEditPage.tsx | `packages/desktop-client/src/components/mobile/schedules/MobileScheduleEditPage.tsx` | ソース | メインコンポーネント |
| ScheduleEditForm.tsx | `packages/desktop-client/src/components/schedules/ScheduleEditForm.tsx` | ソース | 編集フォーム |
| schedule-edit-utils.ts | `packages/desktop-client/src/components/schedules/schedule-edit-utils.ts` | ソース | 条件更新ユーティリティ |
| useScheduleEdit.ts | `packages/desktop-client/src/hooks/useScheduleEdit.ts` | ソース | スケジュール編集フック |
| useSelected.ts | `packages/desktop-client/src/hooks/useSelected.ts` | ソース | 選択状態管理フック |
| useUndo.ts | `packages/desktop-client/src/hooks/useUndo.ts` | ソース | Undo機能フック |
| MobileBackButton.tsx | `packages/desktop-client/src/components/mobile/MobileBackButton.tsx` | ソース | 戻るボタン |
