1. はじめに
本ドキュメントは、「メモ編集機能 要件定義書」に基づき、機能を実現するための基本的な設計を定義するものである。
2. 設計方針
- アーキテクチャ: 既存のMVVMアーキテクチャを踏襲します。UI(Compose)、ViewModel、Repository、Local DataSource(Room)の責務を明確に分離します。
- UI実装: UIの構築はすべてJetpack Composeで行い、Fragmentは使用しません。
-
画面遷移: 画面間のナビゲーションは
Navigation Composeライブラリを用いて実装します。 -
エラーハンドリング: DB操作の失敗など、ユーザーに通知すべきエラーはSnackbarを用いて表示します。ViewModelからUIへは、既存の
UiEventの仕組みを流用して通知し、UI全体で一貫したエラー体験を提供します。
3. 画面設計
3.1. 画面一覧
| 画面ID | 画面名 | ファイル名 | 責務 |
|---|---|---|---|
| SC-001 | メモ一覧画面 | MemoListScreen.kt |
保存されているメモを更新日時順に一覧表示する。 |
| SC-002 | メモ詳細・編集画面 | MemoDetailScreen.kt |
新規メモ作成と既存メモ編集の両方の機能を提供する。 |
3.2. ナビゲーショングラフ
-
画面遷移の定義:
MemoDetailScreenは、渡されるmemoIdの値によって「新規作成モード」と「編集モード」を切り替えます。 -
memoIdの規約:-
memoId > 0: 編集モード -
memoId = -1L: 新規作成モード
-
-
MemoListScreen->MemoDetailScreen-
【編集フロー】:
- 遷移トリガー: メモリストのアイテムをタップする。
-
受け渡す引数:
memoId: Long(タップされたメモの実ID)。
-
【新規作成フロー】:
-
遷移トリガー: 画面右下の
FloatingActionButtonをタップする。 -
受け渡す引数:
memoId: Long = -1L(新規作成を示す固定値)。
-
遷移トリガー: 画面右下の
-
【編集フロー】:
-
MemoDetailScreen->MemoListScreen-
遷移トリガー:
- 保存アイコンをタップし、DB更新/追加が成功した後。
- 画面左上の戻るアイコン、またはシステムの「戻る」ナビゲーションを実行した時。
-
遷移トリガー:
3.3. 各画面の詳細設計
3.3.1. メモ一覧画面 (MemoListScreen)
-
レイアウト:
-
TopAppBar: アプリ名を表示。 -
LazyColumn: メモのリストを縦方向にスクロール表示。各アイテムにはメモの「タイトル」と「更新日時」を表示する。 -
FloatingActionButton:memoId = -1Lを引数としてMemoDetailScreenへ遷移するための「+」ボタン。 -
MemoInputSectionは本改修で削除する。
-
-
表示項目:
- メモのタイトル
- メモの更新日時
-
操作:
- メモアイテムのタップ:
MemoDetailScreenへ遷移する(引数:memoId)。 - FABのタップ:
MemoDetailScreenへ遷移する(引数:-1L)。
- メモアイテムのタップ:
3.3.2. メモ詳細・編集画面 (MemoDetailScreen)
-
レイアウト:
-
TopAppBar:- 左端に「←」アイコン(一覧画面へ戻る)。
- 右端に「保存」アイコン。
- コンテンツエリア:
- タイトル入力用の
TextField。 - 本文入力用の
TextField(複数行入力可)。
- タイトル入力用の
-
-
状態管理:
-
ViewModelは画面初期化時に渡されたmemoIdをチェックします。 -
memoId > 0の場合:DBから該当メモを取得し、タイトルと内容をTextFieldに表示します。 -
memoId = -1Lの場合:TextFieldを空の状態で表示します。 - 「保存」アイコンは、タイトルまたは本文に変更があった場合のみ活性化(クリック可能)させます。
-
-
操作:
- 「←」アイコンタップ: 変更を破棄して一覧画面へ戻ります。
- 「保存」アイコンタップ:
MemoDetailViewModelの保存処理を呼び出します。成功したら一覧画面へ戻り、失敗時はSnackbarでエラーを表示します。
4. データ設計
4.1. ER図
4.2. テーブル定義(data/model/Memo.kt)
要件に基づき、title と updatedAt カラムを Memo エンティティに追加します。
| カラム名 | データ型 | 説明 | 制約 |
|---|---|---|---|
id |
Long |
メモID | Primary Key, Auto Increment |
title |
String |
メモのタイトル | Not Null |
content |
String |
メモの内容 | Not Null |
createdAt |
LocalDateTime |
作成日時 | Not Null |
updatedAt |
LocalDateTime |
更新日時 | Not Null |
4.3. データベースマイグレーション
既存のテーブルスキーマに変更が加わるため、Roomの Migration を実装する必要があります。
- バージョン: 1 -> 2
-
変更内容:
memosテーブルにtitle(TEXT) とupdatedAt(INTEGER) カラムを追加する。
5. コンポーネント設計 (MVVM)
5.1. ViewModel
-
MemoListViewModel.kt(既存のMemoViewModelから改名)- 責務: メモの一覧を取得し、UIに公開します。
-
主なロジック:
memoRepository.getMemos()を監視し、MemoUiStateとしてUIに公開します。
-
MemoDetailViewModel.kt(新規作成)-
責務: 単一のメモの状態管理。渡された
memoIdに応じて、新規作成モードと編集モードの処理(データ取得、保存/更新)を分岐させる。 -
保持する状態:
- メモのID、タイトル、内容
- UIの状態(ローディング、成功、エラーなど)
-
公開するメソッド:
-
onTitleChange(title: String): タイトルの変更をハンドルする。 -
onContentChange(content: String): 内容の変更をハンドルする。 -
saveMemo():memoIdを判定し、新規追加 (addMemo) または更新 (updateMemo) を実行する。
-
-
責務: 単一のメモの状態管理。渡された
5.2. Repository
-
MemoRepository.kt-
追加するメソッド:
-
getMemoById(id: Long): Flow: 指定されたIDのメモを1件取得する。 -
updateMemo(memo: Memo): 既存のメモを更新する。
-
-
追加するメソッド:
5.3. DAO
-
MemoDao.kt-
変更・追加するメソッド:
-
@Query("SELECT * FROM memos ORDER BY updatedAt DESC"):getAllMemos()のクエリを更新日時順に変更する。 -
@Query("SELECT * FROM memos WHERE id = :id"):getMemoById(id: Long): Flowを追加する。 -
@Update:updateMemo(memo: Memo)を追加する。
-
-
変更・追加するメソッド:
