0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初心者】「一旦保存」のつもりが最終保存になっていた問題を、処理フローから見直した話

0
Last updated at Posted at 2026-02-03

はじめに

こちらの商品管理アプリでUXの課題として挙げているデータ保存部分の処理を修正しました。

修正の概要

修正対象は商品を新規登録するメニューです。ここでは、商品画像と商品名を元にAIが説明文を生成する機能を実装しています。

問題点は、AIによる商品の説明文生成後、保存ボタンを押していないにも関わらず商品情報の修正ができなくなる点でした。
(画像は説明文を生成した状態。商品情報の入力欄がグレーアウトしています。)

localhost_8080_productcreate(Nest Hub) (1).png

修正前
修正前の操作と処理のフローです。

修正後
保存ボタンを押すまでは入力内容すべての修正ができる流れになるよう修正を行いました。

修正の詳細

修正前の問題点の整理

説明文生成ボタンを押すと、以下の処理が同時に行われていました:

  1. AIが説明文を生成
  2. 商品情報と説明文をDBに保存
  3. 商品情報の入力フォームをロック(編集不可に)

この実装では、ユーザーが説明文を確認する前に商品情報が確定されてしまい、「やっぱり商品名や価格を変えたい」と思っても修正できないという問題がありました。

修正後内容の検討

以前検討した2つの案のうち、以下の理由から 案2(説明文生成時にDB保存、保存ボタンでUPDATE) を採用しました:

  • AI生成された説明文の原文をDBに保持するため、商品レコードが先に必要
  • 商品情報は非公開フラグで管理し、保存ボタン押下で公開

詳細はこちらの記事に書きました。


修正後の処理は以下のようになります。

説明文生成ボタン押下

  1. AIが説明文を生成
  2. 商品情報と説明文をDBに保存
    3. 商品情報の入力フォームをロック(編集不可に)

保存ボタン押下
1.商品情報を最新の内容でUPDATE
2.修正後の説明文を保存

〈商品登録のデータフロー〉

コードの変更点

説明文生成ボタン押下時の変更

変更前(フロントエンド)

this.isLocked = true; // 商品情報の編集を不可にしていた

変更後

//this.isLocked = true; 👈削除(編集可能のまま)

その他の処理(DB保存など)は変更なし

保存ボタン押下時の変更

変更前:説明文のみ保存

DTO:

DescriptionUpdateRequest.java
public class DescriptionUpdateRequest {
    private Long descId;
    private String description;
    // 商品情報(name, price, stock)は受け取っていない
}

サービス:

productService.java
public void updateDescriptionAndPublish(Long descId, String newDescription) {
    AIDescription desc = aiDescriptionRepository.findById(descId).orElseThrow();
    desc.setEdited_description(newDescription);
    Product product = desc.getProduct();
    product.setPublished(true); // 公開フラグのみ更新
    aiDescriptionRepository.save(desc); // 修正後の説明文を保存
    productRepository.save(product); 
}

変更後:商品情報もUPDATE

フロントエンド:

await axios.post('/api/product/update-description', {
    descId: parseInt(this.aiDescriptionId),
    description: this.aiDescription,
    name: this.name,        // 👈 追加
    price: parseInt(this.price),   // 👈 追加
    stock: parseInt(this.stock)    // 👈 追加
}, {
    headers: {'Content-Type': 'application/json'}
});

DTO:

DescriptionUpdateRequest.java
public class DescriptionUpdateRequest {
    @JsonProperty("descId")
    private Long descId;
    @JsonProperty("description")
    private String description;
    @JsonProperty("name")
    private String name;           // 👈 追加
    @JsonProperty("price")
    private int price;             // 👈 追加
    @JsonProperty("stock")
    private int stock;             // 👈 追加
    
    // getter/setter
}

サービス:

ProductService.java
public void updateDescriptionAndPublish(Long descId, String newDescription, 
                                       String name, int price, int stock) {
    AIDescription desc = aiDescriptionRepository.findById(descId).orElseThrow();
    Product product = desc.getProduct();
    
    // 説明文を保存
    desc.setEdited_description(newDescription);
    aiDescriptionRepository.save(desc);
    
    // 商品情報をUPDATE 👈 この部分を追加
    product.setProduct_name(name);
    product.setPrice(price);
    product.setStock(stock);
    product.setPublished(true);
    productRepository.save(product);
}

操作感の変化

まあまあのお寿司の情報を入力し、説明文を生成しました。
image.png


その後、この商品が素晴らしいお寿司であったことに気づき、商品情報を修正。説明文も併せて修正し、最新の状態で保存ボタンを押しました。

image.png

無事、素晴らしいお寿司の情報を正しく保存することができました。
image.png

おわりに

今回の修正を通して、フロントエンドからDB保存までの一連の流れを見直すことを学びました。
Qiita記事に修正内容をまとめつつコードを編集したことで、処理フローを見失わずスムーズに修正できました。気になっていた部分が自然な操作感になり嬉しいです。
メソッド名についても処理の変更内容に合わせて修正を行おうと思います。

※追記
記事を見直していたら、商品情報のUPDATEの中に商品画像が含まれていないことに気がつきました。説明文生成の基盤になっている商品画像についても、(登録後に編集画面で画像変更は可能ですが)この場で変更できてしまっていいのか?と言う疑問が残りました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?