| name | survey_alert |
| description | RedashのアラートURLを受け取り、ダッシュボードクエリで原因を調査してSlack用レポートを生成する |
| disable-model-invocation | true |
アラート調査コマンド
注意事項
- 食材名・商品名などシステム上の名称はそのまま使うこと
- 食材名と商品名を混ぜた表記(例:「レモネードベース(シロップ レモン 1L)」)は使わない
- ユーザーが質問文でそのような表記を使っていても、回答では使わない
起動時の動作
$ARGUMENTS に Redash の URL が含まれている場合はそれを使って調査を開始する。
含まれていない場合は以下を聞く:
調査したいアラートの Redash URL を教えてください。
調査フロー
Step 1: Redash からアラートデータを取得
URL からクエリIDを抽出し、Redash API でクエリ情報・結果を取得する:
API_KEY=$(fish -c 'source ~/.config/fish/secrets.fish; echo $REDASH_API_KEY')
curl -s "https://redash.hanzo.cloud/api/queries/{query_id}?api_key=$API_KEY"
curl -s "https://redash.hanzo.cloud/api/queries/{query_id}/results?api_key=$API_KEY"
result_id が URL に含まれている場合:
curl -s "https://redash.hanzo.cloud/api/query_results/{result_id}?api_key=$API_KEY"
Step 2: パラメータを抽出する
クエリ結果の行データから以下を抽出する:
| パラメータ | 取得元 |
|---|
company_id | 結果の company_id 列、またはURLの p_company_id |
shop_id | 結果の shop_id 列、またはURLの p_shop_id |
master_ingredient_id | 結果の master_ingredient_id 列、またはURLの p_master_ingredient_id |
purchase_date | 結果の purchase_date 列、またはURLの p_purchase_date。なければ CURRENT_DATE |
複数行ある場合は全行を対象とし、行ごとに調査して1つの総合レポートにまとめる。
Step 3: アラート種別を自動判定する
クエリ名・SQL・結果データから以下の観点でアラート種別を判断する:
| 手がかり | 判断 |
|---|
| クエリ名に「異常値」「z_score」など | サジェスト異常値 |
| クエリ名に「販促」「限定食材」 | 販促食材過剰検知 |
| クエリ名に「未サジェスト」「missing」 | 最遅発注日計算不可 |
| クエリ名に「削除」「delete」 | サジェスト削除検知 |
| クエリ名に「納品不可」「delivery_ng」 | 納品不可日発注 |
| 不明な場合 | クエリ名とSQLをそのまま記載し「不明なアラート種別」として調査 |
Step 4: ダッシュボードで調査する
調査ダッシュボード: サジェスト調査系ダッシュボード(Redash #27 / slug: -_6)
パラメータを指定してダッシュボードのクエリ結果を取得する。抽出したパラメータで Redash API を叩いて調査する。
curl -s -X POST "https://redash.hanzo.cloud/api/queries/{query_id}/results" \
-H "Content-Type: application/json" \
-d '{"max_age": 0, "parameters": {"company_id": "<company_id>", "shop_id": "<shop_id>", "master_ingredient_id": "<master_ingredient_id>", "purchase_date": "<purchase_date>"}}' \
"?api_key=$API_KEY"
調査に使うダッシュボードクエリ一覧
必ず取得するクエリ(全アラート共通)
| Query ID | 名称 | 内容 |
|---|
| 1874 | 最新データのサマリ | サジェスト数・発注パターン・OUT比率・推定在庫・発注点・補充点を1行で確認。調査の起点 |
| 1168 | 食材情報1行 | 食材名・商品名・仕入先・発注設定(発注パターン・発注点・補充点・安全量・スケジュール・OUT比率など)を1行で確認 |
サジェスト異常値・発注量がおかしい場合
| Query ID | 名称 | 内容 |
|---|
| 1941 | サジェスト数の分解 | サジェスト数がどのように算出されたかのフロー図付き詳細分解。「なぜこの量になったか」を追う |
| 1224 | 食材別安全在庫(参考値) | predict_diff_average・deviationから安全在庫の算出根拠を確認(係数1.65/2.33) |
| 1157 | 自動調整のレベル別グラフ | 自動調整レベルの推移グラフ。レベル変化が発注量に影響していないか確認 |
| 1327 | 自動調整の履歴 | 発注点の変更履歴を時系列で確認。直近の変更が影響していないか |
| 1239 | OUT比率履歴 | OUT比率の変化履歴(bitemporal管理)。OUT比率の急変を確認 |
未サジェスト調査
| Query ID | 名称 | 内容 |
|---|
| 1879 | 未サジェスト原因調査(stackingグラフ) | 各時刻でのサジェスト計算中間値をスタックグラフで可視化。どの要素でゼロになったか一目でわかる |
| 850 | 未サジェスト原因調査(テーブル) | 同上の表形式版。purchase_recommend_quantity_resultsの中間値を詳細確認 |
| 1170 | 締め時間設定 | ext_supplier_schedulesの締め時間・cannot_deliver・cannot_purchaseを確認。締め切り過ぎでサジェストが消えた可能性 |
| 1222 | 店舗情報1行(休業日付き) | 店舗の運用開始日・日付切替時刻・精算モード・休業日設定を確認。休業日が影響していないか |
在庫・OUT関連の調査
| Query ID | 名称 | 内容 |
|---|
| 1288 | ダッシュボード用IN/OUT | IN/OUTのledger集計グラフ。在庫の増減パターンを視覚的に把握 |
| 932 | 在庫推移(指定日から2ヶ月前) | 2ヶ月分の在庫推移グラフ。在庫ゼロ・急増急減などの確認 |
| 1518 | ledger_analyze_stocks | OUT比率計算に使われるレコードの一覧。有効/無効な訂正かも確認できる |
| 934 | 在庫訂正の一覧 | 在庫訂正の操作ログ。異常な在庫訂正が起点になっていないか確認 |
| 1056 | ledgerの元ネタ(OUT) | OUTエントリの内訳(売上・ロス・廃棄など)。OUT量の根拠確認 |
| 1167 | ledgerの元ネタ(IN) | INエントリの内訳(仕入・在庫訂正など)。IN量の根拠確認 |
| 879 | 点検の連携ラグ調査 | 5分ごとの在庫・IN・OUT時系列。データ連携の遅延確認 |
出数・売上・需要予測関連
| Query ID | 名称 | 内容 |
|---|
| 880 | 食材別出数予実(直近2ヶ月) | 消費量予測 vs 実績の乖離グラフ。予測精度の確認 |
| 1768 | 食材別出数実績YoY(5年分) | 前年同期比の出数実績グラフ。季節性・イレギュラーな需要変化の確認 |
| 883 | 売上予実(直近2ヶ月) | 売上予測 vs 実績グラフ。売上変動が発注量に影響していないか確認 |
イベント・販促・他店舗比較
| Query ID | 名称 | 内容 |
|---|
| 1799 | 店舗イベントチェック | その店舗のイベント日一覧。イベント起因の出数変化を確認 |
| 1825 | 店舗販促チェック | その店舗の販促設定一覧。販促食材として設定されていないか確認 |
| 1609 | 他店舗の発注点 | 同食材の他店舗での発注点を一覧表示。設定の相場感を把握 |
発注精度・成功判定
| Query ID | 名称 | 内容 |
|---|
| 933 | success_judgementの一覧 | 下書き発注量 vs 実発注量 vs 実消費量の比較。発注精度・サジェストの妥当性評価 |
リンク集
| Query ID | 名称 | 内容 |
|---|
| 1827 | 関連リンク集 | AIダッシュボード等、調査に使える関連Redashダッシュボードへのリンク集 |
アラート種別や状況に応じて必要なクエリを選んで取得する。不要なクエリは取得しない。
Step 5: DB で追加調査(必要な場合のみ)
ダッシュボードクエリで不足している情報がある場合のみ DB に直接クエリを実行する。
DB接続情報・手順は「共通:DB接続情報」セクションを参照。
Step 6: レポート作成
総合レポートのファイル名
~/alert_log/reports/YYYYMMDD/<NNN>_<アラート名>_<識別情報>.txt
NNN: 当日ディレクトリ内の連番(001, 002, ...)
アラート名: アラート種別の日本語名(例: サジェスト異常値, 販促過剰, 未サジェスト, 削除検知, 納品不可)
識別情報: 食材名・取引先名・店舗名など識別しやすい補足
例:
~/alert_log/reports/20260313/001_削除検知_串カツ田中_別注不織布おしぼり.txt
~/alert_log/reports/20260313/002_未サジェスト_デリカフェ_レモネードベース.txt
連番の決め方
ls ~/alert_log/reports/YYYYMMDD/ 2>/dev/null | grep -oE '^[0-9]+' | sort -n | tail -1
ファイルが存在しない場合は 001 から始める。
総合レポートのフォーマット
Slack にそのままコピペできる形式で書く。マークダウン記法ではなく Slack の mrkdwn 記法を使う。
*[アラート種別] 総合レポート* Redash #XXXX / YYYY-MM-DD
━━━━━━━━━━━━━━━━━━━━━━━
*📊 総括*
対象: X件 | 要対応: X件 | 正常動作: X件
━━━━━━━━━━━━━━━━━━━━━━━
*✅ Case 1 — 正常動作* (または *🔴 Case 1 — 設定問題(CS対応要)* など)
*<店舗名> / <食材名>*
• 取引先: <取引先名>
• kind: `<kind値>`
• <調査で判明した重要な数値・設定を箇条書き>
> <根拠の説明を1〜3文で>
*→ <アクション>*
━━━━━━━━━━━━━━━━━━━━━━━
(Case 2 以降も同様)
━━━━━━━━━━━━━━━━━━━━━━━
*📋 対応サマリ*
1. <店舗名> / <食材名> → <アクション>
2. <店舗名> / <食材名> → <アクション>
記法のルール:
*テキスト* → Slack で太字
`コード` → Slack でインラインコード
> テキスト → Slack で引用ブロック(根拠説明に使う)
• → 箇条書き(ハイフンより視認性が高い)
━━━ → セクション区切り
- 判断の絵文字: ✅ 正常動作 / 🔴 要対応 / 🟡 要確認
共通:alert_log ディレクトリ構造
調査結果・クエリ・知見は ~/alert_log/ に蓄積する。
~/alert_log/
├── INDEX.md # 調査ログの一覧・クイックリファレンス
├── reports/ # 調査レポート(日付別)
│ └── YYYYMMDD/
│ └── <NNN>_<アラート名>_<識別情報>.txt
└── knowledge/ # 繰り返し発生するパターン・知見
└── patterns.md
初回実行時
ディレクトリが存在しない場合、自動的に作成する:
mkdir -p ~/alert_log/reports
mkdir -p ~/alert_log/knowledge
INDEX.md が存在しない場合は以下の内容で作成する:
# Alert Log Index
## 調査ログ
<!-- 調査のたびに追記 -->
## 知見・パターン
- [patterns.md](knowledge/patterns.md) - よくある異常パターンまとめ
共通:情報ソース
1. 蓄積済み知見(最優先)
~/alert_log/knowledge/patterns.md - 過去の調査から蓄積したパターン
2. プロダクトソースコード・ドキュメント(必要に応じて参照)
~/work/foodies/ - プロダクトリポジトリ(ロジックの詳細確認)
~/work/foodies/hanzo-docs/ - HANZOのドキュメント(仕様確認)
foodies リポジトリが見つからない場合
~/work/foodies/ が見つかりませんでした。プロダクトリポジトリはどこにありますか?
ユーザーが正しいパスを教えてくれたら、このコマンドファイル内の ~/work/foodies/ を正しいパスに自動で書き換える。
共通:DB接続情報(本番DB)
| 項目 | 値 |
|---|
| Host | localhost |
| Port | 15432 |
| User | table_plus |
| Password | 実行時にユーザーへ確認(「いつものやつです」と添えて聞く) |
| Database | foodies |
接続手順(VPN不要・AWS SSM経由)
1. AWS SSO ログイン
aws sso login --profile goals-hanzo
2. SSHトンネル確認・起動
lsof -iTCP:15432 -sTCP:LISTEN
未接続の場合はバックグラウンドで起動する:
ssh -f -N \
-L 15432:readerdatabase.production.internal.foodies.jp:5432 \
ssm-prod
3. 接続確認
PGPASSWORD=<password> psql -h localhost -p 15432 -U table_plus -d foodies -c "SELECT 1;"
トラブルシューティング
| エラー | 対処 |
|---|
| SSO認証エラー | aws sso login --profile goals-hanzo を再実行 |
| SSHトンネル接続失敗 | AWS SSOの有効期限切れの可能性。SSO再ログイン後にリトライ |
| psql接続失敗 | トンネルが起動しているか lsof -iTCP:15432 で確認 |
パスワードは毎回ユーザーに確認する:「DBのパスワードを教えてください(いつものやつです)」
共通:アウトプット後処理
INDEX.md の更新
~/alert_log/INDEX.md の調査ログセクションに1行追記する:
- [YYYY-MM-DD] #NNN <アラート名> <食材/取引先/商品名> / <店舗名> - <総合判断> → [レポート](reports/YYYYMMDD/<NNN>_<アラート名>_<識別情報>.txt)
knowledge/patterns.md の更新
新たなパターンや知見が得られた場合に追記する。
パーミッション
- 読み取り専用: DBへの書き込みは行わない
- 自動書き込み可能な場所:
~/alert_log/ 配下のみ
- このコマンドファイル自体は、foodiesリポジトリのパスが変わった場合や、ユーザーから仕様変更の指示があった場合に書き換える