Add debugging scripts and enhance UI features#91
Conversation
* feat: デバッグ用スクリプトを追加し、測定データの作成と削除機能を実装 * feat: become more sophisticated debug script
…yle (#5) * feat: エコ店舗のマーカー色を緑に変更し、残り時間の計算方法を修正 * feat: マップ情報ウィンドウのスタイルを改善し、ヘッダーにバッジとクローズボタンを追加 * feat: 測定データの応答ボタンのセレクタを修正し、デバッグ出力を削除
…se translations (#6) * feat: フォームのラベルとプレースホルダーを国際化し、英語と日本語の翻訳を追加 * feat: うどんシェアの新規作成フォームの国際化を追加
WalkthroughマップのInfoWindow/UI再構成とエコマーカー対応をJS/CSSで追加。管理画面うどんシェア新規画面をI18n化し、対応するテストとロケールを追加。計測値UIに希釈ツールチップ表示を条件導入。本番起動スクリプトとデバッグ用スクリプト/Rakeタスクを新設。ドキュメント軽微更新。 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as ユーザー
participant M as MapsController
participant G as Google Maps API
participant D as DOM/InfoWindow
U->>M: マーカーをタップ/クリック
M->>M: 店舗データ評価(eco/foodshare, 営業/住所/シェア情報)
M->>D: ヘッダー/バッジ/詳細/住所/営業時間/アクション要素組み立て
M->>G: InfoWindowを開く
G-->>U: InfoWindow表示
U->>D: 住所/営業時間トグル
D->>D: 折りたたみ/展開クラス切替
U->>D: 閉じるボタン
D->>G: InfoWindowクローズ
sequenceDiagram
autonumber
participant S as bin/prod
participant E as 環境変数/TTY
participant R as Rails(script/debug_bootstrap.rb)
participant F as Foreman
S->>E: SEED_DEBUG_USERS判定(yes/no/ask/AUTO_CONFIRM_SEED)
alt シード実行
S->>R: デバッグブートストラップ実行(ユーザー/オペレーター整備)
R-->>S: 成功/警告出力
else スキップ
S-->>S: スキップメッセージ
end
S->>F: Procfile.productionで起動
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (6)
app/views/measurements/_measurement_item.html.erb (1)
34-54: ビューロジックの複雑さと重複コードに注意が必要です。現在の実装には以下の改善点があります:
- 定数アクセス: Line 35で
UserSetting::DEFAULT_SETTINGSをビューから直接参照していますが、ヘルパーメソッドまたはプレゼンターに移動することを推奨します。- コード重複: フォームが3箇所(lines 40-42, 46-48, 51-53)で重複しています。
以下のようにヘルパーメソッドでリファクタリングすることを検討してください:
# app/helpers/measurements_helper.rb def dilution_ratio_for(measurement) return nil unless measurement.predicted_bod.present? && measurement.submitter.present? limit = measurement.submitter.bod_upper_limit || UserSetting::DEFAULT_SETTINGS[:bod_upper_limit] return nil unless limit.to_f > 0 (measurement.predicted_bod.to_f / limit.to_f * 10).round / 10.0 endビューでの使用例:
<% ratio = dilution_ratio_for(measurement) %> <% if ratio %> <div class="tooltip__container"> <%= render_respond_form(measurement) %> <div class="tooltip__text">※ <%= ratio %>倍に希釈してください</div> </div> <% else %> <%= render_respond_form(measurement) %> <% end %>lib/tasks/debug_measurements.rake (1)
146-150: メソッドの存在チェックが防御的です。Line 146で
store.respond_to?(:revoke_eco_mark!)を使用してメソッドの存在を確認していますが、これはrevoke_eco_mark!メソッドがオプショナルであることを示唆しています。すべてのStoreモデルで利用可能にする方が一貫性があります。Storeモデルで
revoke_eco_mark!メソッドが常に定義されていることを確認してください:#!/bin/bash # revoke_eco_mark!メソッドの定義を確認 ast-grep --pattern $'def revoke_eco_mark! $$$ end'app/assets/stylesheets/main.scss (2)
1398-1422: 無限アニメーションの使用について。
pulseAttentionアニメーションが無限ループ(infinite)で実行されます。ユーザーにとって注意を引く効果がありますが、長時間の使用では気が散る可能性があります。以下を検討してください:
- アニメーションの繰り返し回数を制限(例:
3回)- ユーザー設定で無効化可能にする
prefers-reduced-motionメディアクエリでアニメーションを無効化アクセシビリティを考慮した実装例:
&--emphasis { animation: pulseAttention 1.4s ease-in-out 3; // 3回のみ繰り返し box-shadow: 0 0 0 0 rgba(248, 113, 113, 0.5); @media (prefers-reduced-motion: reduce) { animation: none; // モーション削減設定時は無効化 } &:hover { animation-play-state: paused; } }
796-810: 複数のmax-height指定による競合の可能性。Lines 796-810で複数の
max-heightルールが定義されています(95vh,400px)。これらのルールの優先順位と適用条件を明確にしてください。より明確なクラス命名または詳細なコメントで、各ルールの適用条件を文書化することを推奨します。
bin/prod (1)
6-12: Foremanインストールが二重実行になっています
set -e配下で 1 回目のgem install foremanが成功しても、直後のif ! gem install foreman; thenが同じコマンドを再度実行するため、毎回 2 度ダウンロード/インストールされてしまいます。また 1 回目が失敗するとset -eによって即座にスクリプトが終了するため、用意したカスタムエラーにも到達できません。以下の差分でインストールを 1 度に統合しつつ、エラー処理を生かせます:
- gem install foreman - if ! gem install foreman; then + if ! gem install foreman; thenconfig/locales/ja.yml (1)
50-66: flash配下のフォーム文言は削除してください
flash.admin.udon_sharesはフラッシュメッセージ専用のはずですが、ここにnew/form/actionsを置くと用途が混在し、将来メンテ時に誤参照を誘発します。同内容は直下のadmin.udon_sharesにすでに定義されているため、flash側の重複ブロックを落とす方が整然と保てます。- # UI / form labels and placeholders - new: - title: "うどんシェアを設定" - errors: - header: "%{count}個のエラーがあります" - form: - item_name: "シェアするもの" - item_name_placeholder: "うどん麺" - description: "内容" - description_placeholder: "30円/玉 合計100玉 先着順" - take_down_time: "締め切り日時" - photo_url: "写真URL" - photo_placeholder: "https://example.com/photo.jpg" - photo_help: "※任意項目です。画像URLを直接入力してください" - actions: - submit: "設定する" - cancel: "キャンセル"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
.github/copilot-instructions.md(1 hunks)README.md(9 hunks)app/assets/stylesheets/main.scss(5 hunks)app/javascript/controllers/maps_controller.js(9 hunks)app/views/admin/udon_shares/new.html.erb(3 hunks)app/views/measurements/_measurement_item.html.erb(1 hunks)bin/prod(2 hunks)config/locales/en.yml(1 hunks)config/locales/ja.yml(1 hunks)lib/tasks/debug_measurements.rake(1 hunks)script/debug_bootstrap.rb(1 hunks)script/debug_create_measurement.rb(1 hunks)test/controllers/admin/udon_shares_controller_test.rb(1 hunks)test/system/measurements_test.rb(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-09T15:40:02.442Z
Learnt from: CR
PR: anmoti/UNDO#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-09T15:40:02.442Z
Learning: Railsのファイルを作成する際には、必ず`rails generate`等のRailsコマンドを用いて生成すること(例: `rails generate model User ...` / `rails generate controller Users ...`)
Applied to files:
.github/copilot-instructions.md
🧬 Code graph analysis (1)
app/javascript/controllers/maps_controller.js (1)
app/javascript/controllers/comments_controller.js (1)
triggerHideComments(185-188)
🔇 Additional comments (7)
.github/copilot-instructions.md (1)
7-8: LGTM!本番環境を意識したコード生成の指示が明確に追加されており、開発方針として適切です。
README.md (1)
296-321: ドキュメントが明確で有用です。デバッグ用スクリプトのドキュメントが追加され、使用例も含まれているため、開発者にとって非常に分かりやすい内容になっています。
test/system/measurements_test.rb (1)
81-84: UI変更に対応したテスト更新が適切です。ボタンからinput要素への変更に合わせてテストが正しく更新されています。より具体的なセレクタを使用しているため、テストの信頼性が向上しています。
app/assets/stylesheets/main.scss (2)
412-422: エコマーカーのスタイリングが適切に追加されています。緑色のマーカーとホバー効果が明確に定義されており、ユーザーがエコ店舗を識別しやすくなっています。
461-462: 古いブラウザ向けにフォールバックを追加
min()は Chrome 79+、Edge 79+、Firefox 75+、Safari 13.1+ でサポートされていますが、Internet Explorer や古い Safari では未対応です。以下のように先にフォールバックを宣言してください:max-height: 900px; max-height: min(85vh, 900px);script/debug_create_measurement.rb (1)
1-37:UserSetting::DEFAULT_SETTINGSが定義されていることを確認しました
デバッグスクリプトは適切に動作します。lib/tasks/debug_measurements.rake (1)
97-152: デフォルトフォールバック値の存在確認をお願いします。
purge_measurements_for_futabaタスクのデフォルト値(okemal@example.com/ID:2、ふたばうどん)がシード/テストフィクスチャや本番DBに登録されているか手動でご確認ください。
| # UI / form labels and placeholders | ||
| new: | ||
| title: "Set Udon Share" | ||
| errors: | ||
| header: "%{count} errors found" | ||
| form: | ||
| item_name: "Item" | ||
| item_name_placeholder: "Item: udon noodles" | ||
| description: "Details" | ||
| description_placeholder: "30 JPY/pcs Total 100 pcs First-come, first-served" | ||
| take_down_time: "Take down time" | ||
| photo_url: "Photo URL" | ||
| photo_placeholder: "https://example.com/photo.jpg" | ||
| photo_help: "Optional. Enter an image URL" | ||
| actions: | ||
| submit: "Save" | ||
| cancel: "Cancel" |
There was a problem hiding this comment.
🧩 Analysis chain
翻訳キーの追加を確認しました。
Udon Shares機能のための翻訳キーが適切に追加されています。ただし、日本語版(ja.yml)との整合性を確認してください。
以下のスクリプトで日本語翻訳との整合性を確認できます:
🏁 Script executed:
#!/bin/bash
# 英語版と日本語版の翻訳キーの構造を比較
echo "=== English keys ==="
rg -A 20 'udon_shares:' config/locales/en.yml
echo "=== Japanese keys ==="
rg -A 20 'udon_shares:' config/locales/ja.ymlLength of output: 3960
config/locales/ja.ymlのudon_shares定義を修正してください
- en.ymlで追加された form.photo_placeholder、form.photo_help、actions.submit、actions.cancel を ja.yml に追加
- ja.yml 内で重複している udon_shares ブロックを 1 箇所に統合
- take_down_time などの翻訳文言を en.yml と整合性を取って統一
🤖 Prompt for AI Agents
In config/locales/ja.yml (where udon_shares is defined), consolidate any
duplicated udon_shares blocks into a single block, add the missing keys from
en.yml under udon_shares: form.photo_placeholder, form.photo_help,
actions.submit, and actions.cancel with appropriate Japanese translations, and
ensure form keys like take_down_time, item_name_placeholder,
description_placeholder, and others match the same structure and semantic
alignment as en.yml (translate values into Japanese and keep the same key
hierarchy).
| def ensure_user(id:, name:, email:, is_company:, password: "PASSWORD") | ||
| user = User.find_by(id: id) || User.find_by(email: email) | ||
|
|
||
| if user | ||
| # Update attributes if they differ | ||
| user.update!( | ||
| name: name, | ||
| email: email, | ||
| is_company: is_company, | ||
| ) | ||
| # ensure password is set to known token for local login (has_secure_password) | ||
| user.password = password | ||
| user.password_confirmation = password | ||
| user.save! | ||
| puts "[debug_bootstrap] Updated user id=#{user.id} (#{email})" | ||
| else | ||
| user = User.new( | ||
| id: id, | ||
| name: name, | ||
| email: email, | ||
| is_company: is_company, | ||
| password: password, | ||
| password_confirmation: password | ||
| ) | ||
| user.save!(validate: true) | ||
| puts "[debug_bootstrap] Created user id=#{user.id} (#{email})" | ||
| end | ||
|
|
||
| user | ||
| end | ||
|
|
||
| ActiveRecord::Base.transaction do | ||
| ensure_user( | ||
| id: 1, | ||
| name: "詫間太郎", | ||
| email: "takuma@example.com", | ||
| is_company: false, | ||
| ) | ||
|
|
||
| u2 = ensure_user( | ||
| id: 2, | ||
| name: "桶丸水産", | ||
| email: "okemal@example.com", | ||
| is_company: true, | ||
| ) | ||
|
|
||
| # Make user 2 an operator of Store 1 if exists | ||
| store = Store.find_by(id: 1) | ||
| if store | ||
| unless StoreOperator.exists?(user_id: u2.id, store_id: store.id) | ||
| StoreOperator.create!(user: u2, store: store) | ||
| puts "[debug_bootstrap] Added StoreOperator user=#{u2.id} store=#{store.id}" | ||
| else | ||
| puts "[debug_bootstrap] StoreOperator already exists user=#{u2.id} store=#{store.id}" | ||
| end | ||
| else |
There was a problem hiding this comment.
致命的: 既存ユーザーの認証情報が固定パスワードに上書きされます
このスクリプトは User.find_by(id: ...) などで既存ユーザーを取得した場合でも password = "PASSWORD" に強制更新します。bin/prod を RAILS_ENV=production で起動し、SEED_DEBUG_USERS=yes(あるいは対話で y)にすると、本番のユーザーID 1/2 の名前・メール・パスワードが既知値で上書きされ、誰でもログインできる状態になります。
少なくとも本番環境では即座に中断するガードを入れてください。開発DBで使う際は RAILS_ENV=development bin/prod のように環境を切り替えれば同じ効果が得られます:
require "active_record"
+if Rails.env.production?
+ abort "[debug_bootstrap] Production環境では安全のため実行を停止します。"
+end
+
puts "[debug_bootstrap] Starting... (RAILS_ENV=#{Rails.env})"🤖 Prompt for AI Agents
In script/debug_bootstrap.rb around lines 13 to 68, the script unconditionally
overwrites existing users' passwords with the fixed "PASSWORD" which can
compromise production accounts; add an early guard that aborts unless the
environment is non-production or an explicit allow flag is present (e.g. check
Rails.env.production? and ENV['SEED_DEBUG_USERS'] or a confirmation prompt) and
modify ensure_user so it only sets password for newly created users (or when an
explicit force_password flag is true), leaving existing users' passwords
untouched unless explicitly permitted; ensure the guard is evaluated before any
user modifications and log/raise clearly when running in production without
explicit consent.
Introduce debugging scripts for measurement data management, enhance button animations and tooltips for measurement items, update eco store marker colors, and internationalize form labels and placeholders in both English and Japanese.
Summary by CodeRabbit
新機能
スタイル
ドキュメント
テスト
バグ修正
雑務