# 課題5 自主課題 # Qiita記事投稿ヘルパーアプリ(仮名) JISOUが推奨しているQiitaへの記事投稿に関して、筆者の方法としては、記事の内容を作成した後にChatGPTなどの生成AIを利用して文章のおかしいところを修正したり、何を書けばよいかのアドバイスを受けながら執筆している。しかし、毎回生成AIのページを開いて質問を書くのが面倒であるため、入力された記事の内容に対し、ボタンを押すと生成AIへのAPIが呼び出され、文章を構成したりアドバイスを表示するアプリを作成することを考えている。さらに、Qiita APIを利用し、アプリからQiitaへの記事投稿機能を追加することで、より使いやすいアプリにする予定。 ## **機能** - **設定画面** - Qiitaアクセスキーを設定するための機能を実装する。 - アクセスキーはcryptoを使って暗号化してから登録するものとする。 - 画面上部のメニュー欄に、記事一覧、記事編集、設定画面へのリンクを表示する。 - **記事一覧画面** - 記事を一覧表示する機能を実装する。 - 画面上部のメニュー欄に、記事一覧、記事編集、設定画面へのリンクを表示する。 - **記事編集画面** - メイン画面として、Qiitaへの記事を投稿するための記事を編集する画面を提供する(UIはQiitaの記事投稿画面に似せる)。 - 入力項目には、記事のタイトル、タグの入力欄、記事の本文がある。 - Markdownファイルの編集機能とプレビュー機能を搭載する。 - 「生成AIに聞く」ボタンを押下するとモーダルを表示する。 - モーダルにはセレクトボックスと「送信」ボタンが表示され、セレクトボックスには問い合わせる内容が表示されてユーザーに選択させる。 - セレクトボックスには「記事のアドバイス」、「その他問い合わせ」を表示する。 - 「記事のアドバイス」は編集中の記事のアドバイスを問い合わせる依頼をAPI経由でAIに投げる。 - 「その他問い合わせ」は、別途表示されるテキストボックスにAIに問い合わせる内容を設定し、そのままAIに投げる。 - 生成AIとしてはGemini APIを使用する予定である(無料のため)。 - 「記事を投稿」ボタンを押下するとモーダルを表示する。 - 記事を投稿するための情報(組織等)をモーダル上で設定し、「投稿」ボタンを押下するとQiita API経由で記事を投稿する(別途Qiitaのページを別タブで開く)。 - 「保存」ボタンを押下すると記事の内容をアプリに保存する(一覧画面の表示対象)。 - 「削除」ボタンを押下すると記事の内容をアプリに保存する(一覧画面の表示対象)。 - 画面上部のメニュー欄に、記事一覧、記事編集、設定画面へのリンクを表示する。 # MVP1 アプリ開発の準備をする ## TODO - [x] React+TypeScriptの開発環境をViteで用意する - [x] Fireabseにデプロイする(新規プロジェクトを作成) - [x] Makefileを作成(make deployでデプロイできる) # MVP2 開発者はCI/CDを利用して快適に開発を行うことができる ## TODO - [x] Jestとreact-testing-libraryを導入する - [x] サンプルのテスト(関数とコンポーネント)が動く - [x] Makefileでテストを実行できる(make test) - [x] Github ActionsでPushでパイプラインが動くように設定する - [x] ビルドステップが実行される - [x] 自動テストが実行される - [x] 自動デプロイが実行される # MVP3 最低限のページを作成する ## TODO - [x] ChakuraUIを導入する - [x] 以下の通りページを作成 - [x] (アプリURL)/ でログイン画面を表示する - [x] (アプリURL)/settings で設定画面を表示する - [x] (アプリURL)/articles で一覧画面を表示する - [x] (アプリURL)/article/:id で記事編集画面を表示する - [x] 上記以外の不正なURLで404ページを表示する - [x] 各画面にて画面上部にメニュー欄を作成し、設定画面、一覧画面へのリンクを表示する # MVP4 テーブルの準備を行う ## TODO - [x] ChakuraUIを導入する - [x] 以下のテーブルを作成する - [x] RLSを無効にする ### userテーブル table: articles |Name|Type|option| |---|---|---| |id |uuid|| |title|varchar|non-null| |tag|varchar|non-null| |main_text|text|non-null| |posted|bool|false| |updated_at|timestanptz|now()| |created_at|timestanptz|now()| table: api_tokens |Name|Type|option| |---|---|---| |token|varchar|null| |created_at|date|null| - [x] supabaseを使えるようにセットアップする # MVP5 ユーザーはアクセスキーを登録することができる ## TODO - [x] 設定画面にQiitaアクセスキーのインプットフォームを作成する - [x] 登録ボタン押下で、api_tokensテーブルに対してアクセスキーが登録されること(cryptoを使って暗号化してからDBに登録する) - [x] 登録したキーを取得し、console.logで複合化できることも合わせて確認する # MVP6 ユーザーは記事一覧を表示することができる ## TODO - [x] 一覧画面で、編集画面にて保存した記事の一覧を表示する - [x] 一覧は編集した日時の降順とする - [x] 画面上部にスイッチを表示し、ON/OFFの切り替えをすることでQiitaに投稿済/未投稿の記事を表示するかのフィルターをかける - [x] 記事をクリックすることで編集画面に遷移させる # MVP7 ユーザーは記事を編集することができる ## TODO - [x] 編集画面にて、markDown形式で記事を編集する項目と、プレビュー表示させる項目を表示する(<a href="https://zenn.dev/rinka/articles/b260e200cb5258">こちら</a>を参考にする) - [x] 画面上に「生成AIに聞く」、「投稿」、「保存」、「削除」ボタンを表示する - [x] 保存ボタンを押下するとarticlesテーブルに対し、記事の内容を保存することができる - [x] 削除ボタンを押下するとarticlesテーブルに対し、記事の内容を削除することができる # MVP8 ユーザーは記事を投稿することができる ## TODO - [x] 投稿ボタンを押下すると投稿画面用のモーダル画面を表示させる - [x] モーダル画面にはユーザーに紐づく組織を選択させるセレクトボックスを表示する(画面表示時に組織一覧を取得しておく) - [x] モーダル上の「Qiitaに投稿」ボタンを押下するとQiita APIを使って記事の投稿を行う - [x] 投稿完了後、別タブで投稿した記事のURLを表示する # MVP9 ユーザーは記事の内容を生成AIに問い合わせることができる ## TODO - [x] 生成AIに聞くボタンを押下すると生成AI問い合わせ用のモーダル画面を表示させる - [x] モーダル画面には問い合わせる内容のセレクトボックスを表示し、そこには「記事のアドバイス」、「その他問い合わせ」を表示する。 - [x] 「記事のアドバイス」は編集中の記事のアドバイスを問い合わせる依頼をAPI経由でAIに投げる。 - [x] 「その他問い合わせ」は、別途表示されるテキストボックスにAIに問い合わせる内容を設定し、そのままAIに投げる。 - 問い合わせる内容のテキストはそれぞれのセレクトボックスの値と紐づかせてjsonに保存しておく(DBでもよい?実装の時考える)。 - [x] モーダル上の「問い合わせる」ボタンを押下するとGemini APIを使って問い合わせを行う - [x] 問い合わせた結果はモーダル上の問い合わせ結果の項目上に表示する # MVP10 それぞれのページにテストを実装して安心してCDができるようにする (実際実装を進めるときに追加が出てくると思うので一旦仮置き) ページごとにテストのファイルは分けること ## TODO - [x] 設定画面のテストを書く - [x] タイトルが表示されている - [x] アクセスキーの入力項目の必須エラーを確認する - [x] アクセスキーの暗号化処理が正常に機能することを確認する - [x] アクセスキーの登録処理が正常に機能することを確認する ※外部処理はモック化したうえで引数の検証を行う - [x] 一覧画面のテストを書く - [x] タイトルが表示されている - [x] 記事一覧が表示されていることを確認する - [x] 記事一覧に表示されている内容が仕様通りであることを確認する - [x] 記事本文を押下すると編集画面に遷移することを確認する ※外部処理はモック化したうえで引数の検証を行う - [x] 記事編集画面のテストを書く - [x] タイトルが表示されている - [x] 「保存」ボタンを押下すると記事の内容が保存されること - [x] 「削除」ボタンを押下すると記事の内容が削除されること - [x] 「投稿」ボタンを押下すると投稿画面用のモーダルが表示されること - [x] 投稿画面用モーダルには組織一覧のセレクトボックスが表示されること - [x] 「Qiitaに投稿」ボタンを押下するとQiita APIが呼び出されること - [x] 「投稿」ボタンを押下すると投稿画面用のモーダルが表示されること - [x] 投稿画面用モーダルには問い合わせ内容のセレクトボックスが表示されること - [x] 各セレクトボックスで選択された問い合わせ内容がGemini APIに投げられることÏÏ ※外部処理はモック化したうえで引数の検証を行う # MVP11 - [ ] 記事を書く - [ ] READMEを書く