Skip to content

refactor: 登録・編集フォームを共通化する(重複解消) - #45

Merged
hduehgw0 merged 1 commit into
mainfrom
refactor/#41/consolidate-bottle-form
Jul 24, 2026
Merged

refactor: 登録・編集フォームを共通化する(重複解消)#45
hduehgw0 merged 1 commit into
mainfrom
refactor/#41/consolidate-bottle-form

Conversation

@hduehgw0

@hduehgw0 hduehgw0 commented Jul 23, 2026

Copy link
Copy Markdown
Owner

関連 issue

resolve #41

やったこと

概要

登録・編集でほぼ同一だったフォーム(約 180 行の重複)を、共有コンポーネント bottles/bottle-form.tsx に集約した。登録/編集の差分(初期値・送信先/メソッド・文言・成功時遷移・null 正規化の有無)は、各ページの薄いクライアントラッパーが props / onSubmit で注入する。純粋なリファクタで挙動は不変。

変更点

  • 共有フォーム src/app/bottles/bottle-form.tsx(新設):useForm+全フィールド JSX+serverError 表示+submit ボタンを一元化。region の「未選択」クリアを常設。props=defaultValues / submitLabel / submittingLabel / errorLabel / onSubmit。送信の実処理(fetch・遷移)は持たず、onSubmit(data) を呼び出し元に委ねる。
  • 登録ラッパー new/create-bottle-form.tsx(新設):空の初期値・登録文言・POST(生 data、null 正規化なし)→ /bottles
  • 編集ラッパー [id]/edit/edit-bottle-form.tsx230→50 行):既存値・更新文言・PATCH(null 正規化は当ラッパーに閉じ込め)→ /bottles/[id]
  • new/page.tsxCreateBottleForm を使うよう import 変更。旧 new/bottle-form.tsx は削除(共有フォームへ移設)。

受け入れ条件(セルフチェック)

  • 登録・編集が単一の共有フォームコンポーネントを使う(フォーム定義を二重に持たない)
  • 差分(初期値・送信先/メソッド・ボタン/エラー文言・成功時遷移先・null 正規化の有無)を props / 各ページの onSubmit で吸収する
  • 登録の送信・保存挙動は不変(POST の body は生 data のまま=作成の Route Handler 結合テストが不変)
  • 編集の挙動は不変(空→null 正規化で任意項目を消せる/region の「未選択」クリア)

動作確認

  • pnpm lint が通る
  • pnpm test が通る(23 本・不変。ルートテストは共通化の影響を受けない)
  • pnpm build が通る
  • 手動:登録・編集の両画面が従来どおり動作する/登録でも region に「未選択」が出る(フォーム UI は E2E 領域のためユニット未実施・要ローカル確認)

Issue 要件外の対応(あれば)

備考

  • mode フラグは使わず props 注入で差分を吸収。共有フォームは登録/編集を意識しない。
  • onSubmit は boolean を返す契約(成功=true/想定内の失敗=false)。想定内の失敗(サーバ !ok)は例外にせず false で通知し、共有フォームは文言のみ表示。console.error は想定外の例外(catch)だけに限定(レビュー対応。「例外を制御フローに使わない」result パターン)。
  • onSubmit は関数のためサーバ→クライアントに渡せない。よって各ページの "use client" ラッパーが onSubmit を定義し共有フォームに渡す(refactor: 登録・編集フォームを共通化する(重複解消) #41 本文の「各ページ」=この薄いラッパー)。

@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mycellar Ready Ready Preview, Comment Jul 24, 2026 4:23am

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The bottle registration and editing forms now share BottleForm. Create and edit wrappers provide defaults, labels, request handling, normalization, and post-submit navigation independently.

Changes

Bottle Form Refactor

Layer / File(s) Summary
Shared form contract and controls
src/app/bottles/bottle-form.tsx
BottleForm now accepts typed defaults, labels, and an onSubmit callback, handles validation and rendering, supports an explicit “未選択” region value, and uses configurable submit labels.
Registration submission flow
src/app/bottles/new/create-bottle-form.tsx, src/app/bottles/new/page.tsx
CreateBottleForm posts raw form data to /api/bottles, then navigates to /bottles and refreshes the router; NewBottlePage renders the wrapper.
Editing submission flow
src/app/bottles/[id]/edit/edit-bottle-form.tsx
EditBottleForm derives defaults from the bottle, converts optional values to null, PATCHes the bottle endpoint, and navigates to the updated bottle page.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy #41 by sharing one form component, parameterizing differences, preserving create POST payloads, and keeping edit null-clearing behavior.
Out of Scope Changes check ✅ Passed No unrelated code changes are evident; the added region clear UI and error logging are consistent with the issue context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title is concise and accurately summarizes the main refactor: consolidating the registration and edit forms.
Description check ✅ Passed The description follows the template well, covering issue link, summary, changes, self-checks, verification, out-of-scope notes, and remarks.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/#41/consolidate-bottle-form

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/app/bottles/bottle-form.tsx (1)

53-71: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider logging the caught error before showing the generic message.

The catch block swallows any error thrown by onSubmit (network failures, unexpected runtime errors) and only surfaces errorLabel. If a non-network bug occurs in a wrapper's onSubmit, there's no trace to diagnose it.

♻️ Suggested addition
   const submit = handleSubmit(async (data) => {
     setServerError(null);
     try {
       await onSubmit(data);
-    } catch {
+    } catch (error) {
+      console.error(error);
       setServerError(errorLabel);
     }
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/bottles/bottle-form.tsx` around lines 53 - 71, Update the submit
callback’s catch block in the form’s submit flow to capture the thrown error and
log it before setting the generic serverError message. Preserve the existing
errorLabel shown to users while ensuring unexpected onSubmit failures are
retained for diagnosis.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/app/bottles/bottle-form.tsx`:
- Around line 53-71: Update the submit callback’s catch block in the form’s
submit flow to capture the thrown error and log it before setting the generic
serverError message. Preserve the existing errorLabel shown to users while
ensuring unexpected onSubmit failures are retained for diagnosis.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0c6d82da-70c2-4eb7-b812-9345799a9f4f

📥 Commits

Reviewing files that changed from the base of the PR and between 83ce8d5 and 8acf73a.

📒 Files selected for processing (4)
  • src/app/bottles/[id]/edit/edit-bottle-form.tsx
  • src/app/bottles/bottle-form.tsx
  • src/app/bottles/new/create-bottle-form.tsx
  • src/app/bottles/new/page.tsx

@hduehgw0 hduehgw0 changed the title refactor: 登録・編集フォームを共通化する(重複解消) #41 refactor: 登録・編集フォームを共通化する(重複解消) Jul 23, 2026
@hduehgw0
hduehgw0 force-pushed the refactor/#41/consolidate-bottle-form branch from 8acf73a to de3ff3a Compare July 23, 2026 16:43
@hduehgw0

Copy link
Copy Markdown
Owner Author

Consider logging the caught error before showing the generic message.

対応しました(de3ff3a)。共有フォームの catchconsole.error(error) を追加し、ユーザー向けの表示は errorLabel のまま維持しています。想定外の失敗(ネットワーク・実行時バグ)の痕跡がブラウザのコンソールに残り、診断できるようになりました。集約した 1 箇所なので登録・編集の両方に効きます。

- src/app/bottles/bottle-form.tsx を共有フォーム(純粋な UI+検証、region「未選択」常設)として新設
- 登録・編集は薄いラッパー(create-bottle-form / edit-bottle-form)で defaultValues・文言・onSubmit を渡す
- null 正規化は編集ラッパーの onSubmit に閉じ込め、登録は生 data を送る(作成の挙動・route テスト不変)
- #41
@hduehgw0
hduehgw0 force-pushed the refactor/#41/consolidate-bottle-form branch from de3ff3a to d926689 Compare July 24, 2026 04:22
@hduehgw0
hduehgw0 merged commit 9c97371 into main Jul 24, 2026
4 checks passed
@hduehgw0
hduehgw0 deleted the refactor/#41/consolidate-bottle-form branch July 24, 2026 04:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: 登録・編集フォームを共通化する(重複解消)

1 participant