更新履歴
現在のバージョン:v0.99.185(2026-08-17)
一括メール作成で味付け(デフォルト)が反映されない不具合を修正。単体作成と同じく ai_instruction_default を渡す
v0.99.185 2026-08-17
🐛 **一括メール作成(v0.99.178)で『味付け(デフォルト)』が反映されず、過去の味付けが紛れ込む不具合を修正**(トライアル利用者 GENSHI WORKS 大矢さんの報告)。原因=単体のメール作成画面では味付け欄が `CompanyProfile.ai_instruction_default` で事前入力され、それが `custom_instruction` として `generate_personalized_email` に渡って生成に効くが、**一括ワーカー(`list_module._compose_batch_worker`)はこの既定の味付けを渡しておらず、味付けなしで生成していた**。そのため①設定した味付けが反映されない、②現在の味付けで方向づけされないぶんプロンプト内の Few-shot(過去に返信を得た成功メール例=昔の味付けで書かれた文面)に生成が引っ張られ、古い味付けが混入する、という2症状が出ていた。対応=一括ワーカーの冒頭で `company_module.get_profile(account_id).ai_instruction_default` を1回読み、全社共通の味付けとして各生成呼び出しに `custom_instruction=` で渡す(プレーン文字列なので並列スレッド間で安全)。単体作成と同じ味付けが一括にも効くようになった。※味付けは全プラン・全社共通の既定値で、ブリーフ(営業戦略・切り口)とは別レイヤー(ブリーフは従来どおり brief_id で反映)。app 起動・ワーカーE2E(味付けが custom_instruction に届くこと)を確認済み。
v0.99.184 2026-08-17
**レントラックス(ASPアフィリエイト)のタグを設置**(PID16103/SID11277)。成果地点は『決済完了』。①LPタグ=`templates/_rentracks_lp.html` を公開トップ(site_top.html の head_extra)に設置=アフィリエイト経由の着地をITP対策のfirst-partyストレージに記録。②成果タグ=`templates/_rentracks_cv.html` を決済完了ページに設置。**★成果タグはLPタグと同一ドメインで配信する必要があるため、`/billing/success` を『即リダイレクト』から自社ドメイン上の実ページ(`billing_success.html`)に変更**(Stripeの決済画面は checkout.stripe.com だが success_url は nudge-hq.co.jp なので条件を満たす)。オンボ未完了なら『初期設定の続きへ』、完了済なら『ダッシュボードへ』のCTAを出す。③`_rt.cinfo`(成果特定の識別記号)=StripeのCheckoutセッションID(1決済で一意)をURLエンコードして渡す。④**二重計上の防止**=同一 session_id での再読み込み/ブラウザバックでは成果タグ自体を出力しない(発火済みIDをFlaskセッションに直近20件保持)。⑤両タグとも本番ドメイン(nudge-hq.co.jp)でのみ出力=ローカル/プレビューのテスト決済で誤成果を送らない(_clarity.html と同じ方針)。⑥`_rt.cname/ctel/cemail` は提供タグのまま空=顧客の氏名・電話・メールをASPに渡すのは第三者提供にあたるため、先方の明確な要請が無い限り空を維持する。`_rt.price=0`/`_rt.reward=-1`(固定報酬)も提供タグのまま。**⚠運用上の注意=クリックから成果までのラグ**:現在の商品設計はクレカ不要の14日トライアルのため、登録から決済完了まで最短14日空く。レントラックスのクッキー/ITPストレージの有効期間を超えると成果が紐付かないので、先方に有効期間を要確認。
v0.99.183 2026-08-14
**カスタマーサポート/コンサルの役割分担を変更**(オーナー確定・前『全コースにコンサル標準込み』案は撤回)。**CS=守り・標準・無料(全プラン)**=オンボーディング/使い方の伴走/初期セットアップ支援(解約防止=質の下限)。**コンサル=攻め・有料オプション・希望者のみ**=営業戦略そのものへの伴走(Nudge HQの外側・福田担当)。LP反映:①Lightカード『導入サポート(伴走)つき』→『カスタマーサポート標準/使い方・初期設定を伴走』②料金下の帯から『上位プランでは定期レビューも』(プラン別コンサルの含意)を撤去しCS標準に統一+『営業戦略のコンサルは有料オプション(プロダクト利用に必須でない)』を別枠明記③導入の流れリードを『文面の方針(戦略)まで伴走』→CS範囲(初期設定サポート)に。鉄則=価格の本体価値はプロダクト・コンサルは追加オプション(価値の本体でない)、コンサルは収益の柱に数えない(3年40社/7000万はツール収益で成立)。3プラン価格・席課金なしは据え置き。
v0.99.182 2026-08-07
**ダッシュボードのキャラ(マスコット)アイコンと代理店ランクのバッジ絵文字も削除**し、ツールを絵文字なしで統一(絵文字一掃の仕上げ)。①ダッシュボードのキャラ表示から絵文字アイコンの div を削除(dashboard.html)+character_module のアイコン値の絵文字を除去(😭🎉🥺🚀💪👋😢🛑)。②代理店ランクの RANK_EMOJI(🟤🥉🥈🥇🔷💎)を空にし、referral_dashboard.html の `{{ rank_emoji }}` 出力を除去してランク名のみ表示に。システムメール本文のお祝い絵文字(🎁🚀)は歓迎メールのため引き続き残置。import app・主要テンプレの Jinja コンパイル確認済み。
v0.99.181 2026-08-07
**flashメッセージ等(Python側)の装飾絵文字も削除**(v0.99.180 テンプレ一掃の第2弾)。22ファイルから121個削除(成功✅/エラー❌の頭飾り・📞🔍等)。flashバナーは種類(success/error)で色分けされるので✅❌は色と重複した飾り=消しても成功/失敗は伝わる。**機能記号(✓ ✗ ⚠ ★ ☆)は温存**。削除後に import app で起動確認済み。**別扱い(今回は残置)**=システムメール本文の🎁🚀(resend/system_email/pre_register)、ダッシュボードのキャラ(マスコット)アイコン(character_module)、代理店ランクのバッジ🥇💎(referral_module)。これらは要否を別途判断。
v0.99.180 2026-08-07
**ツール(アプリ)内テンプレの装飾絵文字を一掃**(AIが作った感の低減。オーナー方針)。アプリ全テンプレ+公開LP(site_top.html)から装飾絵文字を計391個削除(73ファイル)。**機能記号(✓ ✗ ⚠ ★ ☆)は温存**(状態・警告・学習レベル表示のため)。アイコンのみだった要素(削除ボタン・ブロックボタン・HPを開くリンク)は空になるのを避けてLucideアイコン(trash-2 / ban / external-link)に置換。対象外=システムメール(emails/*)のお祝い絵文字、および Python の flash メッセージ(バナー)の絵文字は次フェーズで対応予定。全テンプレの Jinja コンパイル・空ボタン無しを確認済み。
v0.99.179 2026-08-07
✍️ **一括メール作成(v0.99.178)の完了後の導線を改善**。従来は完了→自動でリスト画面をリロードしていたが、完了時に自動リロードせず、進捗パネルに『📤 送信画面で下書きを確認する(/send/work へ)』『リストを更新して続ける』の2ボタンを表示し、ユーザーが次アクションを選べるようにした。『作った→そのまま確認して送る』も1クリック、『続けて別の会社も作る』もその場で継続できる(誠実設計=人が確認して送る、への導線も強化)。list_detail.html のみの変更。
v0.99.178 2026-08-07
✍️ **『AIでメール作成』の一括ボタンを追加**(トライアル利用者・GENSHI WORKS 大矢さんの要望)。全リスト/スマートリストで選択した会社に、AIがメール本文を一括生成して下書き保存する。★**送信はしない=生成だけ一括**。内容の確認・微調整・送信予約は従来どおり送信画面で人が1件ずつ行う(誠実設計=最後は人が承認を維持)。実装は既存の一括AI分析(full_prep)と同型:`list_module._compose_batch_worker`+route `/lists/compose-batch`。ユニット消費/DB書き込みはメインスレッド、`generate_personalized_email` の呼び出しは並列スレッド(読み取りのみ)、下書き保存はメインに集約(SQLiteロック回避)。既存の下書きがある会社は既定でスキップ(overwriteで作り直し)、再生成 soft limit・コンタクト単位のユニット消費も個別作成と同じ。ブリーフ選択・進捗ドックへの最小化(NudgeJobs)にも対応。並列数は env COMPOSE_BATCH_WORKERS(既定4・メール本文は出力トークンが大きいため full_prep より控えめ)。UI=list_detail.html にAI分析パネルと並ぶ緑の『✍️ AIでメール作成』パネル。
v0.99.177 2026-08-07
💬 **公開LP(site_top.html)の料金セクションに『全プランに導入サポート(伴走)が標準』を反映**(ポジション整理の確定=伴走は『質の土台』/価格差の軸はユニット量)。①Lightカードに『導入サポート(伴走)つき/担当者が初期設定をご一緒します』を追加。②料金カード直後に紫の帯を追加:『全プランに導入サポートが標準。最初のメール設定から運用の立ち上げまで担当者が伴走し、上位プランでは定期レビューも。“導入したのに使いこなせず終わる”を防ぎます』。上位プラン名・価格は非表示のまま(離脱回避の既存方針を維持)、濃度差だけ『上位プランでは定期レビューも』で示唆。デスクトップ/モバイルとも横はみ出しなし。
v0.99.176 2026-08-07
🎯 **公開LP(site_top.html)の過大表現を是正し、ポジショニングを『効率化+一定の質・誠実』に統一**(アポ・成約・売上といった最終成果は約束しない方針)。①ヒーローのキッカー『【増員なしで、売上を最大化する】』→『【増員なしで、新規開拓を広げ続ける】』(成果でなく活動の約束に)。②選ばれる理由の見出し『少人数でも成果が出る、…』→『少人数でも、営業の質が落ちない。…』。③同リード末尾『…ちゃんと成果が出るからです。』→『…一社一社に“行き届いた営業”ができるからです。』(開封・返信・取りこぼさない=前工程の質の裏づけ部分は維持)。背景=壁打ち結論『Nudge HQは効率化ツール(前工程の質)であって成果保証ツールではない。差別化は機能でなくCS伴走(人)』を文言に反映。課題描写(アポ0・売上激減等)や学習機能・掲載実績はセーフとして据え置き。
v0.99.175 2026-08-07
🐛 **SMTP設定でブラウザの自動入力がアプリパスワードを上書きする不具合を修正**(オンボの最大の詰まりどころ=SMTP接続摩擦の一因)。症状=トライアル利用者から『16桁のアプリパスワードを入れて保存すると以前の11桁に戻る/一度は成功、二回目以降 535 BadCredentials』の報告(GENSHI WORKS 大矢さん)。原因=`templates/smtp.html` のSMTPパスワード欄に autocomplete 指定が無く、Chrome が保存済みの『Googleログインパスワード(11桁)』を空欄のパスワード欄に自動入力→そのまま保存で正しいアプリパスワードを上書きしていた(サーバ側の保存ロジック `if password: encrypt...` は正常)。対応=(1)パスワード欄に `autocomplete=new-password`(+フォームに `autocomplete=off`)でブラウザの自動入力を抑止、(2)パスワード保存済みのときは『✓ パスワードは保存済み。変更する場合のみ16桁を入力(スペースなし)。空欄なら現在のを維持』の案内を表示して再入力での事故を防止。
v0.99.174 2026-08-07
🧹 **公開LP(site_top.html)のページ内アンカーナビ(『課題・解決策・動画・事例・比較・選ばれる理由・メディア・料金・よくある質問』の目次バー)を削除**。ヒーロー直後から本文セクションが始まる形に。連動していたスクロールスパイJSは `.site-anchornav` 不在時に早期 return するガードがあるため、マークアップ削除だけで安全に no-op(コンソールエラーなしを確認)。
v0.99.173 2026-08-07
🔎 **公開LP(site_top.html/site.css)を『全体的に大きく・見やすく』刷新**(v0.99.172 のヒーロー刷新の続き。enepal の公式サイトを参考にサイズ感を底上げ)。①**サイト全体の基準フォントサイズを 16px→17.5px(モバイルは16.5px)に引き上げ**、rem 指定の文字・余白(112箇所)をまとめて約+9%比例拡大。ヒーロー見出しは vw 基準なので大きさ据え置き=バランス維持。②**新着情報を白カードの枠から解放して全幅化**(背景・角丸・影を除去、幅940px→全幅)+見出し・日付・タイトルを一段拡大、区切り線を実線→点線に。③**FAQ(よくあるご質問)を enepal 風に刷新**:各質問を白カードで囲い(角丸・枠・開くと紫枠+影)、頭に丸い『Q』バッジ(自社ブランドの紫)を追加、幅760→900px・文字も拡大。④**各セクションのカード余白を拡大**(落とし穴/事例/選ばれる理由/料金/機能/お悩み/共有カード+比較表セル)。⑤**学習セクション『使うほど、精度が上がる設計』を拡大**(ステップ番号の丸32→42px・見出し/本文・比較カードの余白と文字)。※デスクトップ/モバイルとも新たな横はみ出しなしを確認(既存のモバイル右下フロートCTAのはみ出しは別件として残置)。
v0.99.172 2026-08-07
🎨 **公開LP(site_top.html)のヒーローを刷新+課題セクションの訴求をターゲットに合わせて修正**。①ヒーローを本文より広い幅(--container-wide を1400→1640px・ヒーロー専用コンテナも1640px)に広げ、メインコピーを左・製品モックアップを大きく右へ散らす(enepal の公式サイトを参考にワイドな構成へ)。見出し .site-h1 を最大3.5remに拡大、リードを1.12remに、帯(.site-hero)の上下パディングを調整して高さを enepal 相当(約713px→内容に合わせ調整)に。ロゴもヘッダーをワイド化してコピー左端と揃え左へ寄せた。ボタン下の『クレジットカード不要…』はボタン2つ分の幅に収めて中央そろえ(flexカラム化で全幅stretchしていたのを align-self:flex-start で修正)。サブコピーに改行を追加。②課題セクション(.nhq-pain のカラム図の説明文)を旧ターゲット(『100人の営業がいても』=大人数の営業組織を前提)から、新ターゲット『増員なしの少人数チーム』目線へ書き換え(数字の約65%とカラム図ビジュアルは資産として維持)。冒頭リードにも『少人数だからこそ』を追加。※デスクトップ/モバイルとも横はみ出しなしを確認(モバイルは1カラムに縦積み)。既存のモバイル右下フロートCTAのはみ出しは別件として残置。
v0.99.171 2026-08-04
🛠 **テスト送信の失敗メッセージを『初見でも自分で直せる日本語ガイド』に翻訳**(smtp_module.friendly_smtp_error)。きっかけ=トライアル利用者が Gmail の `534 5.7.9 Application-specific password required / InvalidSecondFactor` で詰まりサポート連絡が来た。生のSMTPエラーをそのまま出していたのを、①Gmailの2段階認証→アプリパスワード必須 ②認証失敗(535/5.7.8)③接続不可(ホスト/ポート/DNS)④送信拒否(5.7.1)を判定して平易な案内に置換。未知のエラーは原文のまま。オンボの最大の摩擦(SMTP接続でつまずいて活性化しない)を軽減する狙い。まずは test_send に適用(送信本フローへの展開は今後)。
v0.99.170 2026-08-04
🧭 **公開LP『導入の流れ』を刷新**(旧3→4ステップ・_site_steps.html はトップ/サービスで共用)。導入サポート(導入相談)が伝わる形に。①無料トライアル(14日・カード不要)②導入サポート(最初の1通目がしっかり送れるよう、メール設定などの初期設定をサポート。導入のご相談も承る)③運用開始(AIがリスト収集・メール作成・追客/送信は人が承認。※自社リストがある場合はCSVアップロードがおすすめ)④本利用スタート(トライアル終了後にクレジットカードを登録して継続)。見出し『導入の流れ』直下に『貴社のアプローチが最適な形で届くよう、メール設定から文面の方針(戦略)まで、私たちが伴走します』のリード文を追加(PCで意図した位置に改行)。
v0.99.169 2026-08-04
📣 **公開サイトの新着情報に『代表の創業ストーリーを公開しました』を追加**(site_module.NEWS の先頭に1件・category=other)。/corp/story への内部リンク(link_label『創業ストーリーを読む』)付き。トップページ下部の新着セクションと /site/news 一覧の両方に表示される。
v0.99.168 2026-08-04
📖 **会社紹介ページに代表の創業ストーリーを新設**(corp.story=/corp/story)。ZUUからの助言を受け、薄かった会社紹介の中核コンテンツに。語り手=創業メンバー・福田優生(一人称『私』)の証言構成で、代表・原和真の人物像(自分を語るのは不器用だが、実は誰より寛容)を外から描く。Prologue→SCENE 01〜07(起承転結)→Closing→CTA(『Nudge HQ を見る』→トップ)。site_base継承・中央ぞろえ・keep-allで中途半端な改行を防止・メタ/OGP(専用画像が無ければ代表写真ceo.pngを流用)。金銭/どん底の描写は柔らか版(金銭の語を抜き『自分の美学を守り続けた』の芯だけ残す)。挿絵は当面テキストのみ(漫画コマ差し込み用スロットの仕組みはコメントで温存)。/corp の代表挨拶から『創業ストーリーを読む』導線を追加。
v0.99.167 2026-08-04
🛡 **送信ワークでメアドの無いコンタクトを押し間違えないようにガード(案2)**。電話のみ収集・メアド未取得の会社(メール送信できない=📞架電向け)を、送信ワーク一覧でグレーアウト+『📞メアド無し・架電向け』バッジ表示にし、行クリックしてもメール作成パネルを開かないよう変更(data-has-email=0 で早期return)。操作列の『開く』ボタンは『📞架電へ』リンク(call.index=/call)に置換。v0.99.166 の送信前ガードと合わせ、誤クリック→意味不明なGmail 5.5.2 エラーを二重に防止。
v0.99.166 2026-08-04
🐛 **メアドの無いコンタクトにメール送信すると Gmail が『555 5.5.2 Syntax error, cannot decode response』という分かりにくいエラーを返す不具合を修正**。電話のみ収集・メアド未取得の会社(本来は📞架電タブ向け)に送信を押すと、宛先が空のまま SMTP に投げて上記エラーになっていた。send_draft_for_contact(即時/予約送信)の頭でメアド空を検知し、『メールアドレスがありません(この会社はメール送信できません/架電をご利用ください)』で止めるガードを追加(ユニット消費・SMTP接続の手前で停止)。旧テンプレ式の一括送信ループでもメアド無しはスキップして同じ穴を塞いだ。
v0.99.165 2026-08-04
⚡ **AI自動収集の終盤の遅さを軽減(案B・設定調整)**。目標件数の最後の数社を埋める工程が、遅くて回数制限のあるGemini再検索を過剰に叩いて重くなっていた(画面が『全然進まない』状態)。①DNSで落ちた会社の『会社名で再検索して救済』の試行数を need*2+2(残り6社でも14社試行)→ need+3 に、上限も RECOVER_MAX_CANDIDATES を 12→6 に短縮(低成果・高コストな工程を軽く)。②同一サイト内ページ間の礼儀待機 ACCESS_INTERVAL_SEC を 1.0→0.5秒に(別ドメインは並列なので体感高速化)。収集の歩留まり(取れる社数)はほぼ維持しつつ終盤の粘りだけを軽くする調整。※抜本策は案A(取れた分で早く完了し『もっと集める』で任意継続)=別途検討。
v0.99.164 2026-08-04
✉️ **資料DL(/lead/document)の自動送信メールを新ポジションに刷新**(leads_module._send_document_email)。件名を旧『資料【3分でわかるNudge HQ】をお送りします』→『ご請求の資料をお送りします(増員なしで、新規開拓を広げる)』に。本文を『今のチームのまま、新規開拓が広がり続ける会社へ』の紹介文+ボタン『資料を見る(PDF)』に更新し、カード不要の14日無料トライアルへの一押しを追加。差出人が noreply@ のため問い合わせ導線は info@nudge-hq.co.jp に集約(返信誘導はしない)。配布PDFのリンク・リード記録の挙動は不変。
v0.99.163 2026-08-04
🎨 **資料PDFの体裁を調整**(v0.99.162の作り直しに続く見た目の微修正)。①全ページの背景を薄紫→白地に(ごく薄い紫ドットのみ)。②表紙の端末モックアップを上で見切れないよう垂直中央へ移動。③落とし穴カードの番号(01〜05)が見出し文字に重なる問題を解消(番号を小さく&見出しの上に配置)。④各ページ見出しを塗り+わずかな縁取りで一段太く(draw_heavy)。※あわせて太字化の描画モードが本文に漏れて文字が薄くなる不具合を修正(テキスト描画モードを都度通常へ戻す)。
v0.99.162 2026-08-03
📄 **資料PDF(assets/nudge-hq-guide.pdf)を新ポジションで全面作り直し**(製品19p+セキュリティ編13p=計32p)。旧デッキの『年間8,300億円』『まるごと自動化』『AI営業代行』『すべて自動化』を全排除し、公開LPと同じ『増員なしで新規開拓を広げる=能力付与』フレームに統一(表紙『今のチームのまま、新規開拓が広がり続ける会社へ』→望ましい姿→問題(約65%が作業)→落とし穴5→解決策5→機能→学習→事例→比較→選ばれる理由→料金→FAQ→CTA)。v0.99.161 のLP調整(『下ごしらえ』→『事前準備』、落とし穴03/04・SOLUTION01・選ばれる理由の最新コピー)も反映。セキュリティ編13pは positioning-neutral のため元デッキから温存連結。reportlab生成・游ゴシック実ウェイト・960x540。
v0.99.161 2026-08-03
✍️ **公開LPの文言・改行をオーナーと1つずつ調整**(構成不変・文言のみ)。①見出しの意図的な改行(解決策/事例/選ばれる理由の3セクション。keep-all+PCは指定位置で改行・モバイルは自然折返し)+選ばれる理由の見出しに黄マーカー。②落とし穴カード:03を『せっかくの好反応を、活かせない。』+説明を『追客の目的=定期接触で関係を育て成約につなげる』軸に書換/04『売上が、安定しない。』/各見出しを1行化(フォント微調整)。③SOLUTION 01:『死にリストを掴まされない』の言い過ぎを削除し『リストがゼロでも収集・リサーチ時間を減らせる』へ+自社リストはCSV取込可の注記を追加。④選ばれる理由01も同じ言い過ぎを削除/02『脱・属人化の自動化プロセス』・03『専任なしで回る、シンプル設計』に短縮して1行化。⑤『下ごしらえ』を全7箇所『事前準備』に統一(1箇所は言い回しも調整)。あわせて run_preview.py にテンプレ/静的の自動リロードを追加(開発時にサーバー再起動不要・本番gunicornには無関係)。
v0.99.160 2026-08-03
✍️ **公開LP事例の『○倍』伏字を廃止**(誇大広告にならず未完成にも見えない形へ)。案2=結果値でなく『できるようになったこと』で語る定性表現に差し替え:事例1『手が回らなかった新規リストづくりが、毎週たまり続けるように。』/事例3『下ごしらえの時間が消え、3人のままでも“アプローチし続けられる”状態に。』。あわせて案3=事例グリッド下に『※参考:自社運用(ドッグフーディング)の開封率は56.3%』を実測proofとして追記(想定イメージの但し書きは維持)。実データが出たら該当事例だけ実数値+『導入事例』に切り替える方針。
v0.99.159 2026-08-03
✍️ **公開LPのコピーをオーナー指定の詳細案に沿って調整**(構成は不変・文言のみ)。①ヒーロー:キッカー『増員なしで、売上を最大化する』/見出し『今のチームのまま、新規開拓が広がり続ける会社へ。』/主CTAを『資料を無料でダウンロードする』(data-doc-open)に変更(副CTA=無料トライアル)。②ギャップ『なぜ、新規開拓はいつも後回しになるのか?』。③落とし穴『エースの属人化が生む、組織の限界。』。④解決策『営業マンがいなくても、アプローチの質が落ちない理由。』(トップ営業の思考を学習)。⑤比較『従来のやり方と、Nudge HQ の違い』。⑥選ばれる理由を3つの質フレーム(ターゲット抽出精度/属人化を排除する自動化/専任がいなくても回るシンプル設計)に。⑦事例:専任なし・少人数フレームに(★数値は伏せ字○倍+『想定イメージ』の但し書きを維持=実データが出るまで誇大広告を避ける)。⑧最終CTAの主ボタンを資料DL・マイクロを『1分で完了。しつこい営業電話は一切ありません』に。望ましい姿の見出しはヒーローと重複回避で『人を増やさなくても、新規開拓は積み上がっていく。』に変更。あわせて **v0.99.158 で version.py CHANGELOG 文字列に半角ダブルクォートを混入させ起動不能になっていた不具合も修正**(未pushのため本番影響なし)。
v0.99.158 2026-08-03
✍️ **公開LP(site_top.html)のポジショニング刷新**(オーナー指示・構成/タグ/CTA/リンクは不変、文言のみ差し替え)。ターゲットを『新規開拓を拡大したいが、営業マンを増やす予算・人員がない少人数チーム』に変更し、看板を『ひとりでも、行き届いた営業ができる。』=能力付与(『できるようになる』)フレームに統一。旧=作業削減/自動化・脱属人化(エース依存)フレームを撤去。■主な差し替え:ヒーロー(キッカー/見出し/サブ)/望ましい姿/ギャップ/痛み(65%)/落とし穴05/解決策(導入文/05)/機能見出し/比較(見出し/リード/結び)/選ばれる理由(リード/03)/事例(1・3)/最終CTA。トーンは肯定形・非ギラつき(『AI営業代行』『まるごと自動化』『○○億円』等の煽り語を排除)。『1社ずつ/1社ごと』は『一社ごと』に統一。★資料PDF(nudge-hq-guide.pdf)は旧ポジションのままなので、別途作り直しが必要([[deck-pdf-generation]])。
v0.99.157 2026-07-28
🐛 **コラム一覧(`/column`)が本番で 500 になる不具合を修正**。原因:テンプレが日付を `date.split('-')` して `{{ d[1]|int }}` 等で表示していたため、**管理画面で追加した記事の `sort_date` が空/不正(YYYY-MM-DD 以外)だと `UndefinedError`(list has no element 1)→ ページ全体が 500**。ローカルのシード記事は日付が正しいため再現せず、本番のデータでのみ発生していた(空日付記事で再現→修正後200を確認)。対応:app.py に安全な日付整形フィルタ `jp_date`(空/不正でも例外を投げず元文字列/空を返す)を追加し、`site_column_list`/`site_column_article`/`site_top`(コラム欄)/`site_news`/`_site_news` の日付表示を `{{ x.date|jp_date }}` に差し替え。教訓:ユーザー入力(CMS)由来の日付は必ず安全整形してから表示する。
v0.99.156 2026-07-28
🖼 会社ページ(/corp)の代表挨拶の写真(`static/site/ceo.jpg`)を、新しい笑顔の写真(撮影原本 20260707-0229)に差し替え。web用に 1600×1067(3:2)・185KB へ最適化(`.ceo-photo` の aspect-ratio:3/2 にそのまま収まる)。20MB超の撮影オリジナル(`static/site/20260707-*.jpg`)は誤コミット防止で `.gitignore` に追加。画像のみ・テンプレ不変。
v0.99.155 2026-07-28
🐛 **v0.99.153 で version.py の CHANGELOG 文字列内に半角ダブルクォートを混入させ SyntaxError→アプリ起動不能**になっていた不具合を修正(該当箇所を全角『』に修正)。未 push だったため本番は無事。教訓:文言のみの変更でも version.py 編集後は必ず import app で起動確認する。あわせて LP 紹介動画セクションのリードから『(3分で概要がわかります)』を削除(オーナー指示)。
v0.99.154 2026-07-28
✍️ LPの紹介動画セクション(#intro-movie)の見出しを『TV・メディアでも話題!』→**『メディア出演・ご紹介実績』**に変更(誇張表現を抑え、事実ベースの控えめな見出しに)。文言のみ。
v0.99.153 2026-07-28
🎬 **LP:紹介動画セクション(#intro-movie)の位置と文言を調整**(オーナー指示3点)。①製品デモ動画(#movie)の直後にあった紹介動画を、**メディア掲載ティッカーの直下(料金の直前)へ移動**(デモ動画→機能へ自然に繋げる/紹介動画は『メディア掲載』文脈の直後に置く)。②見出しを『Nudge HQ って、どんなサービス?』→**『TV・メディアでも話題!』**、リードを『AIが営業を変える新時代ツールとして、番組で特集されました。(3分で概要がわかります)』に変更。③アンカーナビに **『メディア』→#intro-movie** を『選ばれる理由』と『料金』の間に追加(既存の『動画』→#movieデモは維持)。スクロールスパイのハイライトも新項目に追従することを確認。テンプレのみ。
v0.99.152 2026-07-28
🏷 紹介動画(番組出演)の新着ニュースのカテゴリを `other`→`media`(メディア出演・掲載)に変更。既存の金沢シーサイドFM関連ニュース(Spotify出演回・収録)と分類を統一。データ1箇所のみ。
v0.99.151 2026-07-28
✍️ **紹介動画の文面を『番組出演』スタンスに修正**(オーナー指示)。動画は金沢シーサイドFMの番組『社長あなたの会社教えてください』への出演回のため、新着ニュースの見出し/本文を『番組に出演し、Nudge HQ をご紹介いただきました』に、LPの紹介動画セクションのリード文も『番組に出演し…その様子をぜひご覧ください』に書き換え。動画/クレジットのリンクは維持(link_label=出演動画を見る)。文言のみ。
v0.99.150 2026-07-28
🎬 **Nudge HQ 紹介動画(YouTube)を公開**。①公開LP(site_top.html)の既存デモ動画セクションの直後に『Nudge HQ って、どんなサービス?』紹介動画セクション(`#intro-movie`)を新設し、YouTube(`youtu.be/ZWLgGtWjO-s`)をレスポンシブ16:9 iframe で埋め込み(誕生の経緯・サービス内容・今後の展望・料金の背景を紹介)。②新着ニュース(`site_module.NEWS`)にカテゴリ『その他(お知らせ)』で先頭に追加。動画リンク(link=紹介動画を見る)+制作クレジットの相互リンク(link2=株式会社金沢シーサイドFM)を併記。文面は後から調整可。CSS/テンプレ/データのみ。
v0.99.149 2026-07-27
🎨 **公開LPのシェブロン矢印を微調整(本数を3に戻す+位置を下げる)**。v0.99.148で5連にしたが、オーナー意図は『3連のまま、下の“営業の時間のうち…”の文に近づける』だったため、本数を5→3に戻し `.nhq-gap__arrow` の `margin-top` を 18px→72px にして矢印を下方へ移動(65%の数字へ流れる導線に)。薄い赤(`#f1949d`)は維持。CSS/テンプレのみ。
v0.99.148 2026-07-27
🎨 **公開LPのシェブロン矢印を微調整**(オーナー指示)。色を `#e0475b`→`#f1949d`(薄い赤)に、本数を3→5に増やし、ボーダー5→4px・隣接 `margin-top:-6px`→`-2px` で下の『約65%』へ向けて長く伸びる下向きトレイルに。CSS/テンプレのみ。
v0.99.147 2026-07-27
🎨 **公開LPの下向き矢印を3連シェブロンに**(オーナー指示)。単一の大きな ▼+バウンスアニメ を廃止し、**アニメ無しの赤い下向きシェブロン(V字)を3つ縦に**(`.nhq-gap__chev`=20px四方に右・下ボーダー5px+45度回転、`+`隣接に `margin-top:-6px` で3連にネスト)。keyframes も削除。CSS/テンプレのみ。
v0.99.146 2026-07-27
🎨 **公開LPのメリハリ強化 その2**(オーナー選択:案A)。①各セクション見出しの背後にあった英字透かし(`.head-wm .wm-text`)を `display:none` で全消し(見出しを大きくした結果ノイズになっていたため)。②理想の見出し『エースがいなくても、営業が“仕組み”で回り続ける会社へ。』の**『“仕組み”で回り続ける』に蛍光ペン風マーカー**(`.nhq-mark`=下45%だけ黄色 `#ffe98a` を塗る linear-gradient)を追加し、Nudgeの核=“属人化しない・仕組み化”を一目で伝わるよう強調。CSS/テンプレのみ。
v0.99.145 2026-07-27
🎨 **公開LP(site_top.html)の見た目調整**(オーナー指示)。①各セクション上部の説明ラベル(『目指せる、望ましい姿』『動画で見る Nudge HQ』等の eyebrow 5箇所)を非表示に (`static/css/site.css` に `p.site-center:has(> .site-eyebrow){display:none}`。ヒーローの kicker `p.site-eyebrow` は対象外=残す)。②『でも、理想と現実には“ギャップ”がある。』下の赤い下向き矢印 `.nhq-gap__arrow` を `1.1rem`→`2.8rem`(実測 約18→45px)に拡大し軽い下バウンスのアニメを追加(`prefers-reduced-motion` で停止)。CSS/テンプレのみ・文言や構造は不変。
v0.99.144 2026-07-27
🎨 **公開LP(`/` = site_top.html)の見出しを大きく・強調**。他社LP(カオナビ等)と比べ見出しと本文のサイズ差が小さくチープに見える、というオーナー指摘への対応。`static/css/site.css` の `.site-h2` を `1.8rem`→`clamp(1.9rem,4vw,2.75rem)`(デスクトップ実測 約29px→44px)+`letter-spacing:-.02em`・行間詰め、モバイルも `1.5rem`→`1.72rem`。`.site-h3`(カード見出し)も `1.12rem`→`1.2rem`。本文16pxとの比が約2.75倍になり視覚のメリハリが出る。CSSのみ・構造やコピーは不変。
v0.99.143 2026-07-27
🔗 **『指定URLから集める』を寛容化+期待値提示**(結果が貼るページ次第で激変する“分かれ道”を緩和)。■(1)寛容化:ページに公式サイトが直リンクされていない社(社名だけのランキング/まとめ記事等)も、**会社名から公式URLを `lookup_url_by_company_name` でAI補完**して候補に加える(上限 `URL_COLLECT_NAME_RESOLVE_MAX`=25・`ThreadPoolExecutor`で並列4・既に候補が件数に足りていれば補完しない=無駄検索を抑制)。実URLで発見6→11社に拡大をE2E確認。■(2)期待値提示:UIに『相性の良いページ(会員一覧・出展社一覧・企業ディレクトリ・直リンクありの会社一覧=中小が並ぶページ)』と『不向き(大手ランキング記事=大企業ばかりで返信を得にくい)』を明記。完了メッセージに『(うち会社名から補完 N社)』を追加。■(3)結果の透明化(発見N・連絡先取得N・除外N)は既存のまま。既存の業種/フリーワード収集は不変。
v0.99.142 2026-07-27
🐛 **『指定URLから集める』が実行時に `NameError: name '_domain_of' is not defined` で落ちる不具合を修正**。`_domain_of` は `_auto_list_worker` 内の入れ子関数でモジュール直下に無く、新設の `_url_collect_worker`(モジュール直下)から呼べていなかった。→ 同名のモジュール直下版を追加(入れ子版とは別スコープで競合なし)。実URL(広告代理店のまとめ記事)で `extract_companies_from_page`+`_url_collect_worker` の**フルE2Eをローカル実行して確認**(ページから10社抽出→URL有6社をクロール→連絡先取得3社を登録、STATUS=done。捏造なし・リンク無しの社はurl空で正しく除外)。
v0.99.141 2026-07-27
🔗 **リスト自動収集に『指定URLから集める』を新設**(`auto_list.from_url` / `_url_collect_worker`)。プレスリリースの記事一覧・「おすすめ○選」などのまとめ記事・業界団体の会員一覧など、**会社が並ぶページのURLを1つ貼る → ページ本文+リンクを Claude が読み取り [会社名, 公式URL] を抽出 → 既存 `resolve_emails_by_crawl` で各社HPからメアド/電話を確定 → 全リストへ登録**。■既存の業種/フリーワード収集(`_auto_list_worker`)は一切変更せず、別ルート/別ワーカーで追加(事故防止)。■抽出は捏造禁止・自ページ/SNS/媒体/まとめサイト/既存プールのドメインは除外(`_is_junk_link_domain`)、連絡先(メール or 電話)が取れた社のみ登録=ユニットの無駄消費を防止。1社=1ユニット・重複/ブロック判定は既存と同じ。■UI:`auto_list.html` 下部に『🔗指定URLから集める』カード(URL+件数)。開始すると job を作り右下ドック(NudgeJobs)で進捗。■MVP範囲:貼られた1ページのみ(ページ送りは未対応)。会社の公式URLがページ上に無い(PR TIMES検索結果の記事リンク等)ケースはそのままでは拾えない=会社名→URL補完の多段クロールは将来課題。JS描画/ログイン必須ページは取得不可でgracefulに終了。■⚠ ローカルではAI抽出・実クロールを実行できないため未E2E。純粋関数(HTML圧縮`_condense_page_for_extraction`/JSON抽出`_parse_companies_json`/ドメイン除外)とルート登録・UIは検証済み。**当たり具合は本番で実URLを入れて要確認。**
v0.99.140 2026-07-27
🐛 **お知らせ管理(`/admin/announcements`)が本番で 500 になる不具合を修正**。原因:`announcements` テーブルは v0.99.138 のデプロイで先に作成され(メール配信列を持たない)、v0.99.139 でモデルに追加した `email_sent_at` / `email_recipient_count` は `db.create_all()` では既存テーブルに追加されないため、一覧の SELECT が『no such column』で落ちていた(ローカルは作り直していたため再現せず)。対応:`_migrate_legacy_db()` に、announcements の不足列を検出して `ALTER TABLE ... ADD COLUMN` する処理を追加(既存の列追加パターンと同方式・列が揃っていれば no-op)。本番と同じ9列スキーマから起動 → 2列が追加され一覧クエリが通ることを検証済み。
v0.99.139 2026-07-27
🔗 **お知らせを1本化(アプリ内+メールを統合)**。v0.99.136 の独立メール告知(/admin/announce)と v0.99.138 のアプリ内お知らせが二重で分かりにくかったため、**お知らせ(Announcement)1件から両方出せる**形に統合。■各お知らせの編集画面に『✉️ メールでも配信する』パネルを追加=**自分宛テスト送信/登録実ユーザー全員へ送信**(確認モーダル必須)。タイトル=件名、本文(**太字**対応)・CTAボタンをそのままメール化(会社ロゴ入り共通レイアウト)。送信すると `Announcement.email_sent_at`/`email_recipient_count` に記録し、一覧・編集画面に『送信済 N人』を表示(重複送信時は確認文で警告)。■メール配信ロジック(宛先=実ユーザーのみ・admin/オペレーター/BAN除外、レイアウト生成、レート配慮の逐次送信)を announcement_module に集約。■旧『お知らせ一斉送信』画面(admin_module の announce/announce_send+admin_announce.html)を撤去、ナビも『お知らせ管理(アプリ内+メール)』1本に。■新規作成後はメール配信パネルのある編集画面へ遷移。CTA未設定時に入力欄へ 'None' が出る不具合も修正。
v0.99.138 2026-07-27
🔔 **アプリ内お知らせを新設**(`announcement_module.py`)。テスターは Nudge を頻繁に見る習慣がないため、メール告知(v0.99.136)に加えて**ログイン中に Nudge HQ 内でもお知らせが出る**ようにした。■ユーザー:`/announcements` で一覧(開くと既読化)。未読があれば**全画面バナー**+**ナビの🔔ベルに未読件数バッジ**。■admin:`/admin/announcements` で作成・編集・公開/下書き・削除。本文は **〜** を太字にする軽量記法+『太字』ボタン(メール告知と同じ書き味)、任意のCTAボタン。■モデル:`Announcement`(title/body/cta/is_published/published_at)+`AnnouncementRead`(既読を**user_id 個人単位**で記録=オペレーターも各自の未読が正しく消える)。create_all で自動作成(ALTER不要)。■配線:app.py に blueprint 2つ登録+`inject_announcement_notice` context_processor(未読件数供給)、base.html にベル+バナー、style.css に `.nav-badge`。公開サイトの NEWS(未ログイン公開ページ)とは別物。メール告知の『お知らせ一斉送信』と併用可(将来は1画面から両方出す統合も検討)。
v0.99.137 2026-07-27
🅱 **お知らせ一斉送信(`/admin/announce`)で強調(太字)ができるように**。本文はプレーンテキストのまま、<code>**囲んだ部分**</code> を送信時に `<strong>`(メールで確実に太字)へ変換(`_fmt_announce_line`=**エスケープしてから** 太字変換するのでHTMLインジェクションの心配なし)。編集画面に**選択文字を `**` で囲む『太字』ボタン**(未選択なら見本を挿入)+ヒントを追加。プレーンテキスト版のメールは `**` マーカーを除去して読みやすく。既定の下書きにも要所の太字を投入済み。
v0.99.136 2026-07-27
📣 **admin『お知らせ一斉送信』(`/admin/announce`) を新設**。テスターは Nudge を頻繁に見る習慣がない前提で、新機能などをメールで直接届ける導線。既存の『事前登録者への一斉送信』と同じ流儀(Resend・1件ずつ0.6s間隔・失敗分は集計表示)。■仕様:件名・本文(プレーンテキスト=空行で段落・改行は<br>)・任意のCTAボタン(文言+リンク)を編集 → `_build_announcement_html` が会社ロゴ入り共通レイアウト(`emails/_dynamic_wrapper.html`)に包んで送信。**まず自分宛にテスト送信(確認モーダルなし)→ 全員送信は確認モーダル必須**(`action` hidden+テスト時のみ `confirmed=true` で main.js のモーダルをスキップ)。■送信先:`_announcement_recipients()`=実ユーザー(admin・オペレーター除外)かつ BAN 以外・メール重複除去。■既定の下書きに『📞架電機能の追加』『🧭ブリーフ/味付けの説明追加』を投入済み(そのまま送れる・毎回編集可)。ナビ(base.html)の管理グループに『お知らせ一斉送信』を追加。読み取り/送信のみ・既存ロジック変更なし。
v0.99.135 2026-07-27
📊 **admin『訪問アナリティクス』(`/admin/analytics`) に『登録後のアプリ内ファネル』カードを追加**。既存ファネルは LP訪問→登録→オンボ完了→有料 まででアプリ内の離脱が見えなかったため、**登録 → オンボ完了(`onboarding_completed_at`) → チュートリアル完了(`tutorial_completed_at`) → 初回送信(SentEmail≥1)** の4段と各段の**停止人数**(オンボで停止/チュートリアルで停止/完了後も送信ゼロ)を可視化。『①→②=オンボの摩擦/②→③=チュートリアルが原因/③→④=終えたのに本番で手が止まる』の読み方も明記=**チュートリアルに手を入れる前に本当の詰まり所を切り分けるため**。⚠ `tutorial_step` は途中経過を保持しない(完了時に8になるだけ)ので使わず完了フラグで段を区切った。分母は実ユーザー(admin・オペレーター除外)。読み取り専用・ロジック変更なし。
v0.99.134 2026-07-27
🧭 **『ブリーフ』と『味付け』が何なのかを製品内で説明**(トライアルで進まない=概念が分からず設定画面に放置されていた問題への対処)。3つの役割を『名刺/作戦/喋り方』の喩えで統一:📇**自社情報**=名刺(会社名・事業内容などの事実)、🧭**ブリーフ**=今回の営業作戦(誰に・どの切り口で・何をゴールに=**何を言うか**。相手/商材ごとに切替)、✉️**味付け**=喋り方の癖(トーン・禁止事項・P.S.=**どう言うか**。全メール共通)。■変更(説明の埋め込みのみ・ロジック変更なし):(1)`brief_form.html` 冒頭に3者の違いを示す説明カード追加、(2)`email_settings.html` の味付け欄に『味付け=喋り方/作戦はブリーフで』の一文+ブリーフへの導線追加、(3)`help_module.py` に `brief.index`/`brief.new`/`brief.edit` のヘルプ新設+`email_settings.index` に味付け・成功の定義の項目を追加。いずれも『空欄でもメールは作れる=まず1通送ってから調整』を明記して初回の摩擦を下げた。
v0.99.133 2026-07-24
✉️ **お問い合わせフォーム(`/site/contact`)で用件が『資料請求』のとき、資料PDFを自動送付するよう改修**。従来はお問い合わせ経由の資料請求が info@ 通知だけで、PDFは人が手動返信していた(LPの資料DLボタンは自動なのに導線で挙動が食い違っていた)。`contact_submit` で `topic=='資料請求'` のとき `leads_module._send_document_email` でPDFリンクを自動メール送信+`save_lead`/`save_lead_local`(source=`document_download`)でリード保存(admin『資料請求リスト』にも載る)。info@ への通知は従来どおり送るので人のフォローも可能=いいとこ取り。全て best-effort(失敗しても問い合わせ完了画面は表示)。
v0.99.132 2026-07-24
📰 **公開サイトの新着情報に架電機能の追加お知らせを掲載**。`site_module.NEWS` 先頭にカテゴリ『製品アップデート』で1件追記(2026-07-24付)。内容=『電話でのアプローチを管理できる架電機能を追加』(Zoomクリックトゥコール発信・通話結果記録・架電結果に応じたフォローメール自動生成・リスト収集で電話番号も取得)。表示のみ・機能変更なし。
v0.99.131 2026-07-24
⚡ **DNSで落ちた会社の『会社名で再検索して救済』(`_recover_dropped_by_name`)を高速化**(少件数の収集でも異常に遅かった原因)。■原因:落ちた会社を**1社ずつ逐次ループ**で処理し、各社で**Gemini再検索(`lookup_url_by_company_name`・遅いAPI)**+HPクロールを行っていたため、落ちた会社が数社あるとGemini呼び出しが全部足し算になり数十秒かかっていた。■対応:(1)候補を `need*2+2`(上限 `RECOVER_MAX_CANDIDATES`=12)に絞って全件は引き直さない、(2)Gemini再検索+クロールを **`ThreadPoolExecutor` で並列化**(`RECOVER_WORKERS`=4・Geminiレート上限に配慮した控えめ並列)、(3)ドメイン重複防止・need打ち切りは結果の逐次マージで担保(スレッド競合回避)。env `RECOVER_WORKERS`/`RECOVER_MAX_CANDIDATES` で調整可。■補足:Gemini の Google検索グラウンディング自体(初回検索・Refill)も1回あたり数秒〜十数秒かかるのは仕様(不可避)。遅い時は Render ログのタイムスタンプで `会社名で再検索して救済中…` 行の所要時間を確認できる。
v0.99.130 2026-07-24
📇 **『集める連絡先』を3択に整理**(分かりやすさ優先)。『どちらか片方』→**『どちらでも(ある方を取得)』**に改称(メアドか電話、公開されている方を取得=テレマもメール営業も両方やっていて、どちらのリストが増えても構わない人向け・無駄なく一番多く集まる)。件数が少なくなりがちな**『両方必須』はUIから削除**。最終3択=『メール(電話もあれば取得)〔既定〕/電話番号のみ/どちらでも(ある方を取得)』。■後方互換:バックエンドの採用判定キー(email/phone/either/both)とロジックは不変(`both` は未提供になっただけ)。UIのみの変更。
v0.99.129 2026-07-24
📞 **『集める連絡先』の既定を『メール(電話もあれば取得)』に変更**(コールシステムを既定でも活かす)。■狙い:HP直読みはメアドのため全社に既にアクセスしている=**電話番号を“ついで”に取るのはほぼタダ**。そこで**どのモードでも電話番号は常にベストエフォートで取得**するようにした(`resolve_emails_by_crawl` の `want_phone=True` 固定)。既定は従来どおり『メアド必須』なので**メール営業の人に無駄ユニットは出ない**(メアドが無い社は既定では入らない=採用可否は `_item_satisfies` がモード別に判定)。そのうえで、集めた会社に電話番号があれば一緒に保存=**架電タブがタダで育つ**(気が向いたらテレマも試せる)。■UI:ラベルを『メアドだけ→メール(電話もあれば取得)』『電話番号だけ→電話番号のみ』『両方→両方必須』に整理し、使い分けの説明を追記(テレマ中心=電話番号のみ/両手段=どちらか片方/両方必須は件数少)。■後方互換:モードのキー(email/phone/either/both)と採用判定は不変。既定 email の挙動が『電話も拾う』だけ強化された。
v0.99.128 2026-07-24
🐛 **v0.99.125 電話番号収集のバグ3件を修正**(『両方にチェックで20件→13件しか採れず電話が0件』の原因)。■バグ1(電話が1件も保存されない・最重要):`_add_items_to_succeeded` が採用アイテムを新dictに詰め直す際に**`phone` と `industry` を引き継いでいなかった**。`_item_satisfies` は電話ありで通すのにコピーで電話が消えるため、『両方モードで13件通ったのに電話0件』という矛盾が起きていた。→ phone/industry を必ず引き継ぐよう修正(副次的に、フリーワード収集で各社の業種が保存されず分類が効かなかった問題も同時に解消)。■バグ2(両方/電話モードで指定件数に届きにくい):発見のオーバーサンプルがメアド前提のままだった。→ `COLLECT_OVERSAMPLE`(email/either=1.0・phone=1.6・both=2.2)でモード別に多めに発見。■バグ3(指定件数まで粘らず早期終了):Refill が『Geminiが新しい会社を返したが電話が無く全部フィルタ→new_count=0→脱出』で早期終了していた。→ 終了条件を『Geminiが新しい会社(ドメイン)を返さなくなったら』に変更し、収集条件で落ちた社のドメインも次回の除外に加える(同じ会社を再クロールせず別の会社を探させる)。
v0.99.127 2026-07-24
🐛 **v0.99.125 フリーワード収集の重大バグ2件を修正**。■バグ1(フリーワードなのに無関係な会社=建築系等が混ざる):共有DB(`shared_companies`)は『業種+エリア』で引くキャッシュだが、**フリーワードのみ(業種空欄)だと空業種の部分一致 `ilike '%%'` で過去に蓄積した無関係な企業を大量に拾っていた**(例:過去収集の建築系ばかり・Geminiで属性検索する前に混入)。→ `_auto_list_worker` で **業種が空(or 電話/両方モード)なら共有DBを使わない**ようガード(`use_shared`)。あわせて Brave/Anthropic/推測の下位フォールバックも業種ベースでフリーワードを扱えないため、**業種があるときだけ**動かす(フリーワードのみで Gemini が空なら潔く0件=ゴミを混ぜない)。■バグ2(完了画面が『0社を追加しました』と誤表示):共有DBのみで完結した収集で `job.succeeded` が未更新のまま0だったため、ヘッダー『N社』(job.succeeded参照)と詳細『プールにN件追加』(job.message)が矛盾。→ 完了時に `job.succeeded = added`(実際の追加数)に揃える。
v0.99.126 2026-07-24
📞→✉️ **メール生成を『架電結果』で自動分岐**(架電タブ機能の仕上げ=電話とメールが繋がる)。`email_module.generate_personalized_email` に、コンタクトの `call_type`/`prospect_grade` に応じた『今回の状況』ブロックを最優先で注入: - **アポ獲得**(answered+grade=apo)→ 『先ほどはお電話にて…ありがとうございました』のお礼+日程確認+当日の予告。売り込み最小。 - **出た**(answered)→ 『先ほどお電話した』フォロー。電話で伝えきれなかった点を1点補足+次の一歩を軽く促す。 - **不在**(absent)→ 『お電話しましたが、ご不在のようでしたのでメールにて失礼します』の踏み込んだ文面。 - **未架電/断り/番号違い** → 従来どおり完全新規(コールド)。 いずれも『突然のご連絡失礼いたします』等の新規挨拶を状況に応じて置き換え、書き出し・締めを架電文脈に合わせる(既存の success_definition クロージングより優先)。メール作成画面の生成成功メッセージにも『📞架電結果=◯◯ → …の文面で作成しました』を表示(`list_module.compose_contact`)。■これで架電タブの一連(受け皿→電話番号収集→フリーワード→電話→メール分岐)が完成。架電タブの『この会社にメール作成』から compose に入ると、その会社の通話結果に応じた文面が生成される。
v0.99.125 2026-07-24
🔎 **リスト自動収集を『業種+フリーワード』の2軸に+『集める連絡先』の4択を追加**。■背景:業種指定は「その業種を提供している側の会社」を探すのに最適だが、VCが『スタートアップ』を探すような**属性・状況での検索**(例『最近資金調達したSaaS』『上場準備中』『従業員50名以下』)には向かない(現行プロンプトが『主力事業として提供side』に厳密に絞るため意味が破綻する)。■対応:フォームに **業種(任意)+フリーワード条件(任意)**(最低どちらか1つ必須・地域も任意に)。Geminiプロンプト(`_build_prompt`)を入力に応じて自動切替=業種あり→提供side厳密/フリーワードのみ→属性マッチ/両方→重ねる。■業種の振り分け問題を解決:分類器(`industry_classifier_module`)は `Contact.industry` のテキストを見るため、業種空欄収集だと3層分類が動かない。→ **Gemini の返却に各社の `industry` を追加**し、業種を入力しない収集でも各社に業種が付く(→AI分類/スマートリスト正常)。業種入力時は従来どおり入力値を保存、空欄時は Gemini の各社業種を採用。■**『集める連絡先』4択**(`collect_target`=メアドだけ/電話番号だけ/どちらも/どちらか片方)。電話番号は既存のHP直読み工程で同時抽出(`_extract_phones`=tel:リンク+区切り付き表記・日付/郵便/価格は誤検出しない)。電話番号はメアドより公開率が高く、メアドが取れない社の救済にもなる(→**架電タブ**で使える)。採用条件は `_item_satisfies` でモード別に判定(本番Gemini経路・Brave経路・会社名再検索の全経路に適用)。■メアド無し(電話のみ)の会社は `email=''`(空文字)で保存=スキーマ不変(NOT NULL 回避・既存の空メアド流儀)。重複判定は『メアドがあればメアド、無ければ電話番号』で行い、空メアド同士が誤って重複扱いにならないようガード。■後方互換:既定は『業種+メアドだけ』=従来と同じ挙動。フリーワード/電話は任意。
v0.99.124 2026-07-24
⚡ **リスト自動収集の並列数を 5→12 に増強**(Render メモリ 2GB 化に対応・収集時間の短縮)。対象=(1)`PARALLEL_WORKERS`(Brave/Anthropic経路のHPスクレイピング・環境変数 `SCRAPE_WORKERS`)、(2)`CRAWL_WORKERS`(v0.99.110 の『HP直読み=メアド確定』クロール=リスト収集で一番時間がかかる工程・環境変数 `CRAWL_WORKERS`)。いずれも**ネットワーク待ちが主でメモリが軽く、各ワーカーは別ドメインを叩く(同一サイトへの集中なし)・DBも触らない**ため増やしても安全。AIを呼ぶ工程(Gemini発見・AI分析)は**据え置き**(APIレート上限に当たるため並列は増やさない)。環境変数で調整/切り戻し可(重ければ `SCRAPE_WORKERS=8` 等に下げる)。
v0.99.123 2026-07-24
📞 **架電(電話営業)タブを新設**(法人営業の王道『電話してからメール/メールしてから電話』を1本の線にする)。■発信=**Zoom Phone のクリックトゥコール**(`zoomphonecall://+81…` リンク)。拡張機能・API・OAuth 不要、条件は『Zoom クライアントにログイン済み』だけ。★**Nudge は Zoom のサーバーと一切通信しない**・録音や通話ログは残さない(オーナー方針=余計なものをサーバーに残さない)。Zoom が無いユーザーは固定電話/スマホでかけて結果だけ記録すればよい。■Nudge がコンタクトに持つのは3つだけ=`Contact.call_type`(answered/absent/rejected/wrong・NULL=未架電)/`prospect_grade`(answered時のみ apo=アポ獲得〈ゴール〉/S/A/B/C=見込み度)/`called_at`。■画面=一覧→クリックで詳細→**通話結果を押すと自動で次の未架電へ**(連続架電のリズム)。『すべて/未架電のみ/見込みホット(アポ・S・A)』で絞り込み。詳細に**メール送信済バッジ**(双方向の布石)+『この会社にメール作成』導線。電話番号を持つコンタクトのみ表示(配信停止・成約済みは除外=誤架電防止)。■新規=`call_module.py`(`call_bp` /call・一覧+`/call/<id>/result` で結果記録)/`templates/call.html`/ナビに『架電』(リストと送信の間)。`Contact` に3列追加+マイグレーション(既存DBは起動時ALTER)。`to_e164_jp` で日本の番号を E.164 に変換して Zoom へ渡す。■同時に **リスト自動収集画面から『🏢会社規模で絞る(gBizINFO)』チェックを撤去**(規模ゲートは母集団を大きく削るため収集件数を優先。裏の size_keys ロジックは残置=size 未送信で自動 no-op)。■次の一手:④電話番号の自動収集(メアド/電話の4択・メアド無しは空文字保存=スキーマ不変)→ メール生成の cold/warm/不在/アポ 分岐。
v0.99.122 2026-07-23
🎨 **公開LP(`site_top.html`)『新規開拓の5つの落とし穴』上段の01・02カード間隔を微調整**。`nth-child(1)`に`margin-right:14px`・`nth-child(2)`に`margin-left:14px`を付けて2枚の間だけ少し広げた(下段3枚の間隔は据え置き)。860px以下は両マージンを0に戻す。CSSのみ・表示調整。
v0.99.121 2026-07-23
🎨 **公開LP(`site_top.html`)『新規開拓の5つの落とし穴』の上段・下段の間隔を微調整**。上段2枚と下段3枚の行間が詰まって見えたため、`row-gap`を`36px`に設定(列間は22pxのまま)。CSSのみ・表示調整。
v0.99.120 2026-07-23
🎨 **公開LP(`site_top.html`)『新規開拓の5つの落とし穴』を上段2枚・下段3枚の逆ピラミッド型に変更**。v0.99.119の『上段3枚・下段2枚(両端配置)』から、上段=01・02(中央寄せ)/下段=03・04・05(3枚)に組み替え。実装=`grid-template-columns`を`repeat(6,1fr)`にし各カードを2列幅(`span 2`)で配置。上段は`nth-child(1)→列2`・`nth-child(2)→列4`で中央寄せ、下段は`03→列1`・`04→列3`・`05→列5`で3枚。860px以下は全カード`grid-column:auto`で1列に戻す。CSSのみ・表示調整。
v0.99.119 2026-07-23
🎨 **公開LP(`site_top.html`)『新規開拓の5つの落とし穴』の下段レイアウトを修正**。3列グリッドに5枚のため下段(04・05)が左2列に寄り、右端が空いて不格好だった。`nth-child(4)`を列1・`nth-child(5)`を列3に固定して**04を下段左端・05を下段右端**に振り分け、右の空きを解消(両端配置)。860px以下は従来どおり1列に戻す(`grid-column:auto`)。CSSのみの変更・表示調整。
v0.99.118 2026-07-23
🧹 **公開LP(`site_top.html`)の空枠『導入企業(ロゴ帯)』セクションを撤去**。空の『LOGO』プレースホルダ5つ+『※掲載準備中です。』は、信頼を上げるどころか『実績ゼロ』を強調して逆効果(取締役の助言=空枠は弱く見える)。実際の導入企業ロゴが揃うまで非掲載とする(出たら再追加すればよい)。v0.99.117で撤去した『掲載準備中の導入事例』と同趣旨の掃除。これでLP本文の『準備中/空枠』系は一掃(残るヒーロー画像フォールバックの『写真は後日差し込み』は通常非表示の安全網のため据え置き)。セクションタグ20対20でバランス確認・表示のみ変更。
v0.99.117 2026-07-23
🎨 **公開LP(`site_top.html`)を『問題→解決→事例』の物語順に全面並び替え(大手術・仕上げ)**。新しい並び=ヒーロー→①望ましい姿→②問題(ギャップ)→痛み提起(65%)→③失敗例5→④解決策5→**🎥動画(先頭から移動)**→機能→学習→⑥成功事例→⑦ベネフィット比較→選ばれる理由→導入の流れ→メディア掲載→料金→導入企業→FAQ→パートナー→最終CTA→コラム→新着。**重複していた2セクションを撤去**=『こんなお悩み4カード→すべて解決』(失敗例→解決策と重複)/『導入事例(掲載準備中プレースホルダ)』(業界別の成功事例と重複・取締役の助言で空枠は廃止)。アンカーナビを新順序+有効IDに更新(課題/解決策/動画/事例/比較/選ばれる理由/料金/FAQ・死にリンク#caseを除去)。スクロールスパイはナビから動的生成のため自動追従。★実装はセクション単位で確実に並び替えるスクリプト(`{# ===== #}`コメント区切りでブロック化し目標順に再構成)で実施=手作業のcut/paste事故を回避。★検証=セクションタグのバランス(21対21)・重複残存なし・全ナビID実在・コンソールエラーなし・冒頭が物語順で開く/動画が解決策直後、を実機確認。表示のみでロジック変更なし。
v0.99.116 2026-07-23
🎨 **公開LP(`site_top.html`)のストーリー構成を追加実装**(v0.99.115の続き)。(1)**① 望ましい姿**(`#ideal`・薄紫背景)『エースがいなくても、営業が“仕組み”で回り続ける会社へ』=脱属人化の理想像。(2)**② 問題/理想と現実のギャップ**(`#problem`)『リストは動かず、メールは届かず、追客は止まり、売上はエース一人に握られる』+赤い▼で失敗例へ誘導。あわせて失敗例のイントロ文を重複しないよう調整。(3)**⑦ ベネフィット=比較表を『脱属人化』軸で強化**(`_site_compare.html`):列『人を雇う』→『採用・研修で育てる』にリネーム(研修会社との差別化)、『会社に残るもの(脱属人化)』のクライマックス行を追加(Nudge HQ=組織の資産/他ツール=人のスキル依存/外注=社外に残る/採用研修=辞めれば振り出し)。比較セクションの見出しを『他は“人”に依存する。Nudge HQ は“仕組み”を残す。』に、締め+CTAも追加。`static/css/site.css` に `.cmp-climax`/`.cmp-rowsub` を追加。★PC/モバイルで表示・横スクロール無し(表はラッパー内スクロール)を実機確認。表示のみでロジック変更なし。★残:動画の位置変更・既存『お悩み4カード』『掲載準備中の導入事例』の撤去・全体の並び替え/アンカーナビ更新は“最後の整理”で一括予定。
v0.99.115 2026-07-23
🎨 **公開LP(`site_top.html`)を「問題→解決→事例」のストーリー構成に強化**(アッタクスLPの構成を参考・読み手=BtoB企業の社長/営業責任者・軸=脱属人化)。(1)『なぜ Nudge HQ なのか』を成果ドリブンに刷新(開封率56.3%/追客自動/属人化解消の3枚+『SaaSでは数少ない料金体系』の補足ストリップ)。(2)**新セクション『新規開拓の、5つの落とし穴』**(`#pitfalls`・つかみ見出し+「経営リスク」のサブ+本文の5枚)=リスト/配信/追客/継続/属人化の失敗あるある。(3)**『その5つ、Nudge HQ が1つずつ潰します』**(`#solutions`・失敗例と1対1の解決策5つ・開封率56.3%は②配信に配置)。(4)**業界別の成功事例3つ**(`#cases`・IT/SaaS・Web/業界メディア・人材紹介/6要素=対象・課題・支援内容・改善した営業の導線・変化。※担当者コメントは想定のため付けず実顧客が出たら追加、『掲載準備中』枠は廃止)。★捏造ガード=実数字は自社運用56.3%のみ、事例は『想定イメージ』と明示、info@卒業/リスト精度で売る等の誇大表現は排除。★プレビュー実機でPC/モバイル表示・横スクロール無しを確認。既存の『お悩み4カード』『掲載準備中の導入事例』との重複整理・動画の位置変更・望ましい姿/問題/ベネフィットの追加は次段(構成が全部揃ってから一括で並び替え予定)。表示のみでロジック変更なし。
v0.99.114 2026-07-22
🏷 **メール作成画面のブリーフ選択の空選択肢の文言を、実挙動に合わせて是正**。従来は常に『(デフォルトを使用)』と表示していたが、デフォルトのブリーフを持たないユーザー(=旧・任意時代の既存ユーザーはブリーフ0件が普通)だと、実際には何も埋め込まれず自社情報ベースで生成しているのに『デフォルトを使用』=“何か既存のブリーフが使われている”と誤解させていた(利用者から質問あり)。`compose_contact.html` で `briefs` にデフォルト(is_default)があるかを判定し、**ある→『デフォルトのブリーフを使用』/無い→『ブリーフを指定しない(自社情報ベースで作成)』**と出し分け。空選択時のバックエンド挙動(get_default_brief=デフォルトがあれば使う・無ければ None で自社情報ベース)と文言が一致。★両分岐(0件/デフォルトあり)をプレビュー実機で確認。表示のみの変更で生成ロジックは不変。
v0.99.113 2026-07-22
🐛 **ブリーフ画面(/briefs)がブリーフ0件のとき500になるバグを修正**(トライアル利用者から報告)。`briefs.html` の空状態(ブリーフ未登録時)の『新規ブリーフを作成』ボタンが **存在しないエンドポイント `url_for('brief.create')` を参照**しており(正しくは `brief.new`)、`url_for` が BuildError を投げてページが500になっていた。ブリーフを1件でも持つユーザーは一覧テーブルが描画され空状態に入らないため踏まず、**ブリーフ必須化(v0.99.109)より前のユーザー=ブリーフ0件が普通**なので『ブリーフ(AI戦略指示)』を開いた既存ユーザーが軒並み500を踏んでいた。`brief.new` に1文字修正。★全テンプレートの `url_for` を機械的に総点検し、存在しないエンドポイント参照は他に無いことを確認。★ブリーフ0件ユーザーで再現→修正後200+空状態が正常表示、をプレビュー実機で確認。
v0.99.112 2026-07-22
🐛 **追いメール設定で『対象のテンプレが見つかりません』になるバグを修正**(チュートリアルの追いメール設定で必ず踏む・トライアル利用者から報告)。原因=`email_settings.index`(GET)が開かれると `get_user_followup_templates`/`get_default_sequence` が既定シーケンス+デフォルト追いメール2通を **`db.session.flush()` だけで作成**していた。flush はIDを採番して画面に表示はできるが **commit しないためリクエスト終了時にロールバックされ、DBには残らない**。結果、画面には2通出るのに実体が無く、その行を編集/削除/ON・OFFすると `FollowUpTemplate.query.filter_by(id=..).first()` が None =『対象のテンプレが見つかりません』になっていた。(プロフィール既存ユーザーだと `get_or_create_profile` も commit しないため、GET経由では既定が一度も永続化されない)。修正=両ヘルパーの**作成ブランチで `flush()`→`commit()` に変更**し、作った既定を確実に永続化。作成ブランチは初回のみ発火(スケジューラ送信時は既にシーケンスが在るため無害)。★再現・修正ともプレビュー実機で確認(GET後にDBへ Sequence1件/Template2件が残り、トグルが成功)。★調査メモ:健全な新規アカウントで大村さんと同じ状態(オンボ完了+チュートリアルStep5/6)を再現したら全ページ200で、『データ破損』ではなく『チュートリアルで実際にテンプレを操作する』条件を踏んで初めて出る一般バグだった。🛡 あわせて**メール作成のAI生成を try/except で防御**(`list_module.compose_contact` の action=generate)。`generate_personalized_email` が想定外の例外を投げると、compose の generate は例外を捕まえていなかったため『メール作成画面が真っ白=500』になっていた。例外を握って `result=None`→既存の『AI生成に失敗しました』フラッシュに集約し、トレースバックはサーバーログに出す(次に起きても原因が追える)。★compose の 500 はローカルで再現できず(GET/テスト送信/サンプル生成/実サイト生成すべて正常)、上記シーケンス修正で解消される可能性が高いが、防御も入れて二重に安全化。
v0.99.111 2026-07-16
✉️ **新規ユーザーの『成功の定義』の既定を `engaged` → `replied`(返信ファースト)に変更**。従来の新規既定 `engaged`(クリック or 返信)は AI に**メール本文へURL/リンクを書かせる方向**に振れるが、コールド1通目のリンクは迷惑メール判定を上げ到達性を下げる=v0.99.97 でオーナー自身が『返信ファースト』に舵を切った学びと逆方向だった。`replied` なら `email_module` が『URL・リンク・誘導文を一切書かない』CTAに自動で切り替え+`_strip_links_for_reply` の安全網も効く(v0.99.97の実装をそのまま活用)。変更箇所=`models.CompanyProfile.success_definition` の default/`onboarding.html` の hidden 値(**新規に実際に効くのはここ**)/`onboarding_module.save_company` のフォールバック。★**後方互換=既存ユーザーは影響なし**:行に保存済みの値がそのまま使われる。未設定(NULL)のレガシーユーザー向けの最終フォールバック(`learning_module.get_user_success_definition`)とメール設定画面の表示フォールバックは **`engaged` のまま据え置き**=表示と実挙動の一致を保ち、既存の挙動を1ミリも変えない。あわせて UI を実態に合わせて是正:メール設定の『推奨』バッジを engaged → **replied に移動**し『コールド営業はこれが基本(1通目にリンクがあると届きにくい)』と理由を明記。CTA説明にも『返信ならURL・リンクを一切書かず』を追記。🎨 **味付け欄(`ai_instruction_default`)のプレースホルダを汎用化**:従来は Nudge HQ 自身の例(『月98,000円で代替』『事前登録で200ユニット』『PR TIMES配信後23媒体に掲載』)がそのまま出ており、**別会社の新規ユーザーには無関係+『事前登録特典』はローンチ済みで陳腐化**していた。自社に依存しない汎用例(トーン/強み/特典/P.S.の信頼材料/禁止表現)に差し替え。★味付けは**テンプレのプリフィルではなくプレースホルダのまま**とした:業種・商材で中身が変わるため、的外れなテンプレを実保存すると AI がその指示に従って逆効果になる。CTA制御は上記の `replied` 既定がコード側で担保する。🧭 **同じ理由で、オンボーディングの営業ブリーフ(v0.99.109)もプリフィル→プレースホルダに変更**。ブリーフは『誰に・何を・どの切り口で売るか』=業種ごとに中身が変わる営業戦略そのものなので、汎用テンプレを実保存させると全ユーザーが同じ戦略で送ることになり、AIが自社に合わない指示に従う。`DEFAULT_BRIEF_INSTRUCTION`(プリフィル値)を廃止し `BRIEF_INSTRUCTION_PLACEHOLDER`(薄いグレーの例文)に置換=書き方は例で示しつつ、中身は本人に書いてもらう。**ブリーフ必須は維持**(=空のまま素通りはできない)。ブリーフ名だけは AI に渡らない単なるラベルなので `標準ブリーフ` のプリフィルを維持(無駄な摩擦を作らない)。⚠ トレードオフ=全員が自分で文章を書く必要があり、オンボーディングの摩擦は上がる(登録直後の離脱率は要観察)。🐛 ついでに**メール設定『成功の定義』のラジオの崩れを修正**:`style.css` の `.checkbox, .radio { display:inline-flex !important }` がテンプレのインライン `display:block` を !important で上書きしており、ラベル全体が横1列のflexに潰れて『推奨』バッジが縦積み・見出しが折り返していた。該当3ラジオを素の `label`(display:block)に変更し、`margin-left:24px` の説明文が下にぶら下がる本来の設計に是正(**CSSは触っていないので他画面への影響なし**)。
v0.99.110 2026-07-15
🔍 **リスト収集の役割分担を『発見=Gemini/メアド確定=HPクローラー』に変更**(リスト精度・件数の同時改善)。■背景1(取りこぼし):Gemini(Google検索)は検索インデックスのスニペットしか読めないため、『会社概要/お問い合わせページの奥』『JS描画』『画像で掲載』のメアドを構造的に取りこぼす。にもかかわらずプロンプトが『メアドが確認できない企業はリストに含めない』と命じていたため、**メアドが実在するのにGeminiから見えなかっただけの会社まで、黙って捨てていた**。■背景2(重大・v0.59.1の機能が死んでいた):Geminiのメアドを実HPで二次検証する `_verify_gemini_emails` は、**デッドコード `collect_company_list` の中にしか無く、本番経路 `_auto_list_worker` からは一度も呼ばれていなかった**(=共有DB読み出しが同じ場所で死んでいた v0.77 と同型の事故)。つまり本番では **Geminiのメアドは無検証のままリスト化**されており、実測バウンス率27%の有力な原因。■対応=`auto_list_module.resolve_emails_by_crawl` を新設し**本番経路に配線**。1回のクロールで2つを同時に解決:(1)メアド無しの社 → HPを読んで取得=**救済**(`crawl_recovered`)、(2)メアド有りの社 → HPに載っているか**検証**し違えば実在メアドに**差し替え**(`gemini_verified`/`crawl_replaced`)。取れなければ従来どおり除外(`none`=フォームのみ等)。既存の実績ある部品(`_fetch_html`/`_extract_emails`/`_find_contact_pages`/`_is_captcha_page`)を再利用=新規スクレイパは書いていない。■Gemini側:`_build_prompt`/`search_companies_with_gemini`/`_validate_and_filter` に `allow_no_email` を追加。**捏造禁止は厳守**(見つからなければ空文字を返させる=推測メアドは書かせない)。怪しいメアド(`_is_junk_email`)は『企業ごと捨てる』→『メアドだけ空にして企業は残す』に変更(クローラーが取り直すため)。⚠実装上の罠=空メアドを `seen_emails` に入れると2社目以降のメアド無し企業が全て『重複』扱いで消えるため、空のときは重複判定に使わないようガード(テスト済み)。■計測(ビフォーアフター):Renderログに `[効果測定]` 行を出力=発見N社/施策前(Geminiのメアドのみ)何社(何%)/施策後(HP直読み)何社(何%)/差分±N/内訳(確定・救済・差替・未検証・取得不可)/**★フォームのみ等で本当に取れない社数**(CAPTCHA・HP取得失敗の内訳つき)。収集完了メッセージにも『🔍HP直読みで N社を救済 ・ ✉️メアド誤りを N社 訂正』を表示。**この数字が『フォーム営業機能に投資すべきか』の判断材料になる**(本当に取れない社の実測比率が初めて分かる)。■副次効果:HPを読んで確定した社は `pages_crawled=1` で**検証済み扱い**=`verified_at` が入りリスト検証の再クロールをスキップ(API節約)。■安全性:CAPTCHA/Bot拒否は**突破しない**(絶対ルール順守・検出したら諦めて計上のみ)。`_add_items_to_succeeded` にメアド未確定は採用しない安全網を二重化。■後方互換・切り戻し:環境変数 `ALLOW_NO_EMAIL_DISCOVERY=false` で**旧挙動(Geminiがメアド確認できた社のみ)に即戻せる**。`CRAWL_WORKERS`(既定5)で同時接続数、`NO_EMAIL_OVERSAMPLE`(1.6)でGeminiへの要求増分を調整可。Brave/Anthropic経路(2〜4段目)は従来どおり `_process_one_site` でクロール済のため変更なし。
v0.99.109 2026-07-14
🧭 **オンボーディングに『営業ブリーフ』設定を必須ステップとして追加**(必須3→4項目)。従来、新規ユーザーはブリーフ未設定のまま使い始められ、その場合 AI分析(メモ生成)は汎用フォールバック=『Web導線・コンバージョン改善』寄りのメモになり、メール生成も自社情報そのままの売り込みになっていた(=v0.99.108 の業種チェックが『何屋か』を掴めず取りこぼす原因側でもあった)。対応=`onboarding_module.check_steps` の `all_required` に `brief` を追加し、オンボーディングのステップ5を『営業ブリーフ(必須)』に昇格+その場で入力できるインラインフォーム化。既定テンプレ(`DEFAULT_BRIEF_INSTRUCTION`=相手の事業/顧客/課題を実態から把握する中立指示・メモとメール両用 kind='both')をプリフィルしてあり、ユーザーは確認/編集して保存するだけ(`onboarding.save_brief` が is_default で登録)。★後方互換=`is_onboarding_completed` は `onboarding_completed_at` 済みの既存ユーザーを常にバイパスするため、**既存ユーザーが後付けでロックされることはない**(対象は onboarding 未完了の新規ユーザーのみ)。副次効果:全新規ユーザーに既定ブリーフが入るため、メモの『Web改善』偏りが解消され業種チェックの精度も上がる。オペレーター・紹介専用アカウント(特別代理店)は従来どおりオンボ自体をスキップ。
v0.99.108 2026-07-08
🔎 **業種チェック(的外れを外す)を『HP実読み』に強化**(精度向上)。従来は会社名+対象業種+**Web導線改善メモ**で判定していたが、導線メモは『Webの直し方』であって『何屋さんか』を書いていないため、『サンエイ企画(名前は広告っぽいが実態は施工業者)』のような紛らわしい会社を、安全設計の『迷ったら残す』で取りこぼしていた。対応=`relevance_scan` が判定前に**各社の公式サイトを並列取得**(`auto_list_module._fetch_html`/`_extract_page_summary`・最大8並列)し、サイトのタイトル+本文抜粋を『実態情報』として `judge_relevance_batch` に渡す(`evidence` フィールド追加・メモはフォールバック)。判定プロンプトも『公式サイト等の情報の実態を優先/名前だけの推測で残さない/サイトから明らかに別業種(施工・建設・製造・小売・飲食等)は false』に強化。HP取得が入り重くなるため**1回の上限を150→60件**に(多い時は絞って複数回)。ロード画面の文言も更新。★収集側の合わせ技:曖昧な業種語(例『マス広告』は広告が広く看板/サイン施工・印刷・Web広告まで拾う)は、収集の業種欄を具体化(対象媒体を明示+除外業種を書く)すると入り口で減る。
v0.99.107 2026-07-08
🎯 **リストの『業種チェック(的外れを外す)』機能を追加**(AI収集で混ざる『発注者側/比較まとめ記事/別業種』の一括除去)。全リスト/スマートリストのツールバーに **🎯業種チェック** ボタン。選択(または全選択)した**未送信**コンタクトについて、会社名・対象業種・AIメモから **その会社が対象業種を『提供している側』か** を Claude(Haiku) が一括判定(`list_quality_module.judge_relevance_batch`・25社/バッチ)。判定は**安全側**=『発注者側/比較・ランキング・まとめ記事/ポータル・求人媒体/明らかに別業種』だけを的外れ(false)にし、**情報不足・判断不能は必ず残す(true)**。API未設定/失敗時も全件残す。`POST /lists/relevance-scan`(同期・最大150件)→ 的外れ候補を確認画面 `relevance_review.html` に表示(各社チェック済み・判定理由つき・全選択/解除)→ `POST /lists/relevance-delete` で**人間が確認してからまとめて削除**(誤削除防止・送信済みは対象外・ユニット返却なし)。★これは既存リストの掃除用。今後の収集の質は v0.99.105 の収集厳格化が担当。
v0.99.106 2026-07-08
🔗 **AI分析でHPリンク切れを自動修正**(『送信画面の「開く」からHPに飛ぶとエラーなのに、会社名で検索し直すと会社が出てくる』現象への対処)。原因=`enrich_contact`(個別AI分析)と `_full_prep_worker`(一括🔍AI分析)は、保存 `website_url` の取得に失敗すると **メモだけ会社名でのGemini検索で救済し、壊れた website_url は直さないまま**にしていた(=メモは作れるのにHPリンクは切れたまま)。対応=URL取得失敗時に `gemini_search_module.lookup_url_by_company_name`(会社名→公式HP再検索・既存関数)で正しいURLを引き直し、HP取得に成功したら **`contact.website_url` を実在URLに上書き修正**(一括は結果に `website_url_fixed` を持たせ書き戻し時に反映)。修正後の実HPからメモも生成するため精度も向上。★該当コンタクトを**AI分析し直すと**リンクが直る(ユニット再消費なし・メモ再生成上限内)。v0.99.103 の収集救済(DNS落ち会社を会社名で救済)と同じ手法を、既存リストのAI分析にも適用。
v0.99.105 2026-07-08
🎯 **AI自動収集の業種マッチ精度を厳格化**(『営業代行を集めたのに営業代行でない会社が混ざる』への対処)。従来は「{業種} 会社」でGoogle検索してヒットした会社をそのまま入れており、その会社が本当にその業種を“提供している側”かを検証していなかった=(1)発注・利用する側の会社、(2)比較/ランキング/『おすすめ○選』等のまとめ記事・ポータル・求人媒体で紹介されているだけの会社、(3)その業種を数あるサービスの一つとして少し掲げているだけで本業は別の会社、が混入していた。`gemini_search_module._build_prompt` に**『対象企業の定義(最重要・厳守)』ブロック**を追加し、『{業種}を“主力事業(本業)として提供している側”の事業者だけ/上記(1)〜(3)は実在しても絶対に含めない/迷ったら含めない(数より質)/公式サイトのトップ・事業紹介から主力提供と明確に読み取れる会社だけ』を明示。重要ルールにも同趣旨の限定を追加。★プロンプトのみの変更=低リスク・追加API/コストなし・後方互換(既存の実在確認/メアド確認/捏造禁止ルールは維持)。厳格化で1回の収集数は減り得るが Refill ループが目標件数まで検索語を変えて探し続ける。既存リストの掃除は対象外(今後の収集の質を上げる変更)。
v0.99.104 2026-07-08
🎨 **パートナー(代理店募集)ページ `/site/partner` をマーケティング観点で全面リニューアル**。旧ページは78行の最小構成(ヒーロー+2カード+iframe+テキストのランク説明)だったのを、本家LP(site_top.html)で磨き込み済みのデザイン部品を全面展開して情報設計と導線を強化:★訴求は営業代理店の刺さる3点『①儲かる(高い報酬率+成果で伸びる料率)②売りやすい(既存顧客へのクロスセル・資料/実績提供)③手間ゼロ(商談同席・クロージング支援・導入後CSは当社担当)』を主役に。『積み上がる/資産のように』等の“不労所得=MLMっぽい”言い回しは排し、継続報酬は代理店に馴染む『継続手数料(ストック)』と表現。①ヒーロー刷新(『クロージングは、あなた。迷った案件は、私たちが引き取る。』=基本は代理店が売り切り/決めきれない案件は当社が引き取る保険付き+緑の主CTA+マイクロコピー)、②**ページ内アンカーナビ**(選ばれる理由/報酬の仕組み/シミュレーター/ランク制度/導入の流れ/FAQ・sticky+スクロールスパイ)、③『営業代理店に選ばれる3つの理由』の3本柱カード(WHY・番号付き=儲かる/売りやすい/手間ゼロ)、④報酬の仕組みを**シミュレーターと同じ色分け**(ショット=薄紫/ストック=濃紫)の2カード化、⑤報酬シミュレーターは従来どおり iframe で活用(枠を影付きで綺麗に見せる導入文を追加)、⑥**ランク制度を“上る階段”で可視化**(Copper→Diamond の6段・高さが段々上がる/Diamondは金+招待制バッジ)=要望の『もっと可視化』に対応、⑦導入までの流れ4STEP(話を聞く→自分で使う→申込→紹介開始)、⑧こんな企業におすすめ/向いていない の2カラム、⑨**FAQ**(ノルマ/条件/在庫/バッティング/報酬額/支払い=安心感)、⑩最終CTAを紫グラデ(site-cta-final)で締め。共通CSS(site-hero/anchornav/site-card/site-step/site-faq/site-cta-final 等)を再利用し、追加CSSはこのページ用の微調整のみ。プレビュー実機で反映・ランク階段の段階上昇・緑CTA・モバイル375pxで横はみ出しゼロ/カード1カラム化・コンソールエラー無しを検証済み。
v0.99.103 2026-07-08
🛟 **AI自動収集で『実在するのに落ちる会社』を救済**。Gemini(Google検索連動)は実在の会社を掴んで 会社名まで返しているのに、返した**URLの綴り違い・旧ドメイン・一時的なDNS不調**で名前解決に失敗すると、`_validate_urls_parallel`(`socket.gethostbyname`)で**会社ごと丸ごと破棄**していた(会社名でググると本物HPが出るのにエラー扱いになる現象)。オーナーが手作業でやる『会社名でググって本物のHPを探す』を自動化=`_recover_dropped_by_name`(`auto_list_module.py`)を新設し、DNSで落ちた会社を**会社名(+業種/エリアのヒント)で再検索**(既存の `gemini_search_module.lookup_url_by_company_name` を流用)→取り直したURLをDNS確認→**その本物HPをスクレイピングして実メアドを取得**して拾い上げる。★メアドは Gemini の推測値ではなく**実HPから取り直した値だけ**採用=バウンスは増やさない。HPに公開メアドが無い(フォームのみ等)会社は救済対象外。Gemini経路の1回目DNS検証の直後・Refillの前に実行(目標件数に届くまで=救済し過ぎない)。ドメイン重複は `already_domains` で防止。進捗は『会社名で再検索して救済中… n/N(救済 x社)』を表示。**Gemini経路のみ対象**(Brave/推測経路は会社名を持たないため)。
v0.99.102 2026-07-07
⭐ **特別代理店制度**(この時期限定・紹介だけする人向け)。admin『代理店管理』の「特別代理店を発行」で **メアド+代理店名だけ**で紹介専用アカウント+特別コードを作成(`create_special_agency`)。法人名・インボイス番号は不要。パスワードは設定リンク(reset再利用)を相手メールに送信+admin画面にも表示。`User.is_referral_partner`(新カラム)=オンボ/チュートリアル/導入サポート/クレカを全スキップ(各ゲートに分岐追加)=admin付与のスキップ設定も兼ねる(テスター管理にトグル)。`PromoCode.is_special`(新カラム)。集計に**見込み報酬額**(成約者のプラン月額×30%概算・手動支払いの目安)列を追加。**「正式に昇格」**=法人/インボイス番号を入れると is_special オフ=正規代理店へ(**同じコード・実績のまま引継ぎ**)。報酬の自動計上はしない(`record_reward_from_invoice` は従来どおり agency_user_id+契約中ユーザー前提=特別代理店は素通り=手動運用)。★招待リンク方式も追加:公開申込ページ `/referral/partner-apply`(ログイン不要・社名/氏名/メアド+規約同意→`SpecialAgencyApplication`)→ admin『特別代理店の申込』`/admin/special-agency-applications` で**承認(Diamond等のランク付与も同時に可=`set_rank_manual`)**→ 承認時に `create_special_agency` で発行+パスワード設定リンク送信。承認画面のランク選択でDiamondスタート可能。ハニーポットでボット対策。`admin_special_agency_apps.html`/`agency_partner_apply(_done).html`。★クリックラップ(電子契約)も正式版:申込ページで専用『Nudge HQ 紹介代理店規約』(agency_terms・12条)全文を提示して同意、同意記録(版/日時/IP)+**同意記録書PDF**(規約全文+同意記録・`generate_agreement_pdf` を両モデル対応に)を `SpecialAgencyApplication.pdf_blob` に保管。admin が `/admin/special-agency-applications/<id>/pdf` でDL可。
v0.99.101 2026-07-07
✅ **AI自動収集の完了画面を追加**。従来は完了すると1.2秒で全リストへ自動リダイレクトし『何も表示されずに終わった』ように見えていた。自動遷移をやめ、`#done-section`(✅リスト収集が完了しました/追加社数・除外件数のサマリー/内訳メッセージ/『追加されたリストを見る』『続けて収集する』ボタン)を表示する形に変更。`templates/auto_list.html` の done ハンドラを修正(`status.succeeded`/`failed`/`message`/`result_url` を表示)。最小化(右下ドック)経由の完了は従来どおり NudgeJobs 側で処理。
v0.99.100 2026-07-07
🧑 **アカウント登録フォームに『お名前』欄を追加(必須)**。`User.full_name`(新カラム・ALTER自動)に保存。従来はメアド+パスワードのみで氏名が無く、メアドから推測するしかなかった(例:tasuku.tominaga→富永)。登録者に正しく『◯◯様』と挨拶でき、CRM・導入サポート連絡にも使える。admin『テスター管理』の各行にも👤氏名を表示。既存ユーザーは full_name=NULL(管理画面では氏名行を出さないだけ)。register.html/auth.register/admin_beta_users.html。
v0.99.99 2026-07-07
📍 **新規登録者の流入元(経由)をユーザーに保存**。従来は直接登録だと経由が残らず『direct/不明』だった穴を解消。`before_request` の `_capture_inflow` がセッションに持っている `inflow_referrer`(外部リファラ)/`inflow_src`(utm_source)を、`auth.register` のユーザー作成時に `User.signup_referrer` / `User.signup_utm_source`(新カラム・ALTER自動)へコピー。紹介コード(referral_code)が無い直接登録でも経由が分かる。admin『テスター管理』の各行に『経由:』を表示(コード>utm>リファラ>直接/不明の優先)。⚠ この記録は本デプロイ以降の新規登録が対象(既存ユーザーは遡って分からないので『直接/不明』表示)。
v0.99.98 2026-07-01
🎓 **新規登録者に『導入サポートを受けてください』画面を追加**(TimeRex予約へ誘導)。メール認証リンクのクリック直後(`auth.verify_email`)に `/onboarding/support` へ誘導し、**予約を済ませて『予約しました。設定に進む』を押すまで他ページをブロック**(`_enforce_onboarding` に `needs_support` ゲートを追加=オンボーディングより手前)。予約カレンダーは既存の env `BOOKING_URL`(TimeRex等)を流用(`{{ booking_url }}`)。`User.support_booked_at`(新カラム・ALTER自動)で通過管理。**既存ユーザーは列追加時に `created_at` で一括バックフィル=この画面をスキップ**(新規登録者のみ対象)。オペレーター(親設定継承)・admin はバイパス。テンプレ `onboarding_support.html`。予約URLは `onboarding_module.ONBOARDING_SUPPORT_URL_DEFAULT`(TimeRex `https://timerex.net/s/yu06i19.a_0830/42422a03`)を既定で埋め込み=**env設定なしで即動作**。env `ONBOARDING_SUPPORT_URL` で上書き可。LPの『導入相談』ボタン(env `BOOKING_URL`)とは独立。⚠ TimeRexは外部のため“予約完了”は自動検知せず自己申告方式(『予約する』でTimeRexを開く→戻って『進む』)。真の完了検証はTimeRex Webhook連携が別途必要。
v0.99.97 2026-06-26
✉️ **成功の定義=返信(返信ファースト)のメール生成からリンク/URLを自動で排除**(コールド1通目はリンクが迷惑メール判定を上げるため)。(1)`email_module` のクロージング指示を修正:返信モードでは従来『自社URLを補足で1つ添える』としていたのを撤回し、**URL・ハイパーリンク・申込リンク・『下記のリンクから』等の誘導文を一切書かない**よう明示(`https://nudge-hq.co.jp/` 等が出ていた主因)。(2)安全網 `_strip_links_for_reply`:success=replied の生成本文から `http(s)://`/`www.`/`{{ }}プレースホルダ`(例 `{{招待リンク}}`)を最終的に除去。AIが“親切心”でURL/招待リンクを足しても確実に消える。clicked/engaged(リンク誘導が正解の)ブリーフは従来どおりURLを出す(影響なし)。★運用:返信ファーストのブリーフは『売る商材』欄から `{{招待リンク}}` の文字列も外すと、AIがリンク誘導文ごと書かなくなる(“象を想像するな”対策)。
v0.99.96 2026-06-25
🖼 **機能セクション(できること4つ)に実画面スクショ枠を追加**(BtoBの『Show, don\'t tell』=説明より実画面が説得力)。各カード上部に `.fc-shot` 枠を用意し、**`static/site/feature-1〜4.png` の4枚が揃ったときだけ**アイコン→実画面に自動切替(`app.py` index で `os.path.exists` 判定→`feature_shots_ready`)。中途半端な混在を避けるため**4枚揃って初めて**切替(all-or-nothing)。未配置時は従来のSVGアイコン表示のままで完全後方互換。対応=①リスト収集 ②メール作成 ③追客 ④承認送信 の実画面(オーナーが撮影して `static/site/` に置くだけ)。ダミー画像で表示・フォールバック双方を検証済み(ダミーは未コミット)。枠は `aspect-ratio:16/10`+`object-fit:cover`(上端基準)で固定=撮影サイズが違っても4枚が同じ形に揃う。
v0.99.95 2026-06-25
🧭 **サービスページ(`/`)にページ内アンカーナビを追加**(縦長ページの回遊性向上)。ヒーロー直後に目次バー(選ばれる理由/機能/比較/導入事例/料金/よくある質問)を配置し、**ヘッダー直下(`top:65px`)に sticky 追従**(`.site-anchornav`・z-40・ブラー背景)。クリックで該当セクションへ**スムーズスクロール**(対象6セクションに id+`scroll-margin-top:128px`=ヘッダー+ナビに隠れない)。**スクロールスパイ**で現在地チップを紫ハイライト(『ヘッダー+ナビのラインを通過した最後のセクション』方式=ビューポート高に依存せず堅牢)。モバイルは**横スクロールのチップ列**+現在地チップを自動で中央へ寄せる(ページ自体の横はみ出しは0)。
v0.99.94 2026-06-25
💅 料金カードで**箇条書き(`.pc-benefits`)とフッターの受け皿チップが詰まる**問題を解消。`margin-bottom:24px` を付与し両者の間隔を 0→24px に(上の『金額→箇条書き』の24pxと揃えて上下バランスを均一化)。フッターは `margin-top:auto` で下端固定のままなので左右の整列は維持。
v0.99.93 2026-06-25
💅 **料金カードの本文を『チェック付き箇条書き』に刷新**(`.pc-benefits`/左右とも2項目=高さが揃い金額・フッターも完全整列)。右カードのフッターを**お問い合わせへのリンク**に(`.pc-foot a`・紫リンク風)。旧 prose『規模に応じて…/中核機能はすべて…』は廃止。★コピーは事実ベースに調整:提案の『使い放題』はLightの月2,000ユニット上限と矛盾するため『中核のAI営業自動化機能をすべて利用可能』に、『専任担当による初期設定サポート』はLightで提供していない(専任サポートはEnterprise)ため不採用→『リスト収集・AIメール作成・追客まで一気通貫』に置換(誇大広告防止・§2/v0.42.1の方針)。左カードにも実情ベースの強み2点(クレカ登録なしで開始/アカウント発行・初期設定費用も0円)。
v0.99.92 2026-06-25
💅 **料金カード2枚のバランスを調整(4点)**。①説明文ブロック(`.pc-sub`)に `min-height:1.4em` を付与し**左右の金額の上下位置を完全一致**(実測 amtDiff 0)。②月額の補足(`.pc-desc`)の `margin-top` を 12→26px に広げて金額の数字を独立させる。③『〜/月』(`.pc-amount .per`)を 1.1rem→.95rem・色を `#666` に落として主役の数字を引き立てる。④フッター(`.pc-foot`)を**薄いグレーの受け皿チップ**(`background:#f5f4f8; border-radius:10px`)に統一=左右で『格』を揃える(旧 border-top 廃止・下端固定は維持)。
v0.99.91 2026-06-25
🧹 **料金カード『初期費用』の文言を整理**。紫の pill ボックス(`.pc-pill`)を廃止し、『人数が増えても追加料金なし(席課金なし)』をサブ行(`.pc-sub`)へ移動。意味が重複していた旧サブ『アカウント発行費・追加費用も』を削除。→ 2枚のカードが『ラベル/サブ/金額/…/脚注』の平行構造になり見た目がスッキリ(脚注の整列は v0.99.90 のまま維持)。
v0.99.90 2026-06-25
🐛 **料金カード2枚をPCで横並びにした際、下段(区切り線+脚注)の高さがズレる不具合を修正**。原因=フッターを下端固定する `margin-top:auto` が `.pc-foot:first-of-type` に書かれており、`:first-of-type` は『最初の<p>=pc-label』を指すため pc-foot に当たらず無効化していた(カードのmid要素 pill=54px/desc=47px の高さ差13pxがそのまま脚注のズレに)。`.price-card .pc-foot{margin-top:auto}` に直し両カードの脚注を下端固定=完全整列(実測 diff 13px→0px)。label/sub/amount は元から一致。
v0.99.89 2026-06-25
✨ **料金下・最終CTAを最終形にブラッシュアップ**(ヒーローと一貫したCTA設計を全面展開)。(1)**最終CTAをトップと同じ紫グラデ+ドット**の“締め”の特別エリアに(`.site-cta-final`・白見出し+STARTを白透かし+お問い合わせは白枠透明)=ページが紫で始まり紫で終わる一貫性+緑CTAが再び最も映える。(2)**両CTAにマイクロコピー追加**:料金下=『\ トライアル中の自動課金・違約金は一切なし /』(濃いグレー `on-light`)/最終CTA=『\ クレジットカード不要・14日間無料 /』(白)。(3)主CTA(緑)を**全体で太字+大サイズふっくら**(`.site-btn-cta`に`font-weight:800`、`.site-btn-cta.site-btn-lg`に`padding:19px 42px`)=料金・最終CTAにも自動適用。(4)**主CTAが画面内のとき右下の追従フロートを退避**(IntersectionObserver+`data-hide-float`+`.site-floats.is-hidden`)=CTAの二重表示を回避。マイクロコピーは flex→中央寄せテキスト化+狭幅で微縮小し、モバイルでの不自然な改行を解消(横はみ出しゼロを確認)。
v0.99.88 2026-06-25
✨ **ヒーローCTAをブラッシュアップ**(CTA改善案③=ハードルを下げる一言+主従コントラスト強化)。横並びボタン(左=緑トライアル/右=お問い合わせ)の**真下にマイクロコピー**を追加:『\ クレジットカード不要・1分で登録完了 /』(`.site-hero-micro`)。実態と一致(クレカなしトライアル v0.99.77)=『お金かかる?登録面倒?』の不安を解消。(1)マイクロコピーは**パキッとした白文字(#fff)**+ボタン群ラッパー(`.hero-cta-wrap`)で**2ボタン幅に中央揃え**(背景の紫に同化させない)。(2)セカンダリ『お問い合わせ』を**完全透明+細い白枠(1px solid #fff)**のスケルトンに=緑の主CTAを圧倒的な主役化。(3)主CTAを**横長+文字太め+上下padding拡張**(`padding:19px 42px; font-weight:800`)でふっくら・押しやすく。デスクトップ/モバイルとも横はみ出しなしを確認。
v0.99.87 2026-06-25
🟢 **主CTA(無料トライアル)を鮮やかなグリーンに**(CTA改善案①=紫の補色寄りで視認性を最大化)。site.css に色非依存の `.site-btn-cta` modifier を追加=エメラルドグリーン(`linear-gradient(135deg,#00c897→#02a37c)`・**白文字**)。ヒーロー(白上書き)・ナビ(白地紫枠上書き)でも緑が勝つよう専用上書き+ホバーを用意(specificity対策)。適用=最重要のトライアル誘導5箇所のみ(ナビ/ヒーロー主/『選ばれる理由』下/料金下/最終CTA主)。セカンダリ(お問い合わせ・資料DL・ゴースト)は据え置きで主従を明確化(改善案④)。フロートCTAは別コンポーネントのため対象外。
v0.99.86 2026-06-25
⭐ **『導入事例(CASE)』セクションを追加**(`/`=サービスページ・導入の流れの直後・料金の直前)。ベイジBtoBサイトチェックリストの最大の残ギャップ=事例の器を実装。1事例=『業種チップ+会社名→課題→Nudge HQで解決→数字タイル(最大3)→担当者コメント』。データは `site_module.py` の `CASE_STUDIES` リスト(NEWS同様、先頭に dict を足すだけで増える)+`get_case_studies()`。app.py の `/` が `case_studies` を供給。**捏造数字は禁止**=実掲載は自社運用事例1件のみ(株式会社Cynthia・開封率56.3%=『選ばれる理由』と同じ自社運用実測値)。残り2件は `is_published=False` の『事例準備中』プレースホルダ(破線枠+リボン+数字ダッシュ)=器だけ先に完成、オーナーは実数字を入れて公開フラグを立てるだけ。site_top.html に scoped CSS で自己完結(`.nhq-case*`)。レスポンシブ(820px以下で1カラム)。末尾に事例掲載協力の募集導線(お問い合わせへ)。
v0.99.85 2026-06-24
⭐ **『選ばれる理由(なぜNudge HQなのか)』セクションを追加**(`/`=サービスページ・お悩み→解決の直後・機能の前)。ベイジBtoBサイトチェックリストの『特長』要件に準拠:メリット視点の見出し(20〜40字)+簡潔本文+実証チップ+上下CTA。3つの理由カード=①カード不要・初期費用0で今日から ②1社ごとAIで開封率56.3%(自社運用) ③席課金なし・人数無制限で低コスト。site_top.html に scoped CSS で自己完結(`.nhq-reason*`)。事実ベース・誇大表現なし。レスポンシブ(820px以下で1カラム)。
v0.99.84 2026-06-24
🏠 **ルート(`/`)をサービスページのフル構成に統合**(旧LP landing.html を置き換え)。`/` が site_top.html(ヒーロー/65%痛み/お悩み/できること/学習/比較/流れ/料金/導入企業/FAQ/最終CTA/コラム/新着)を表示。**`/site`→`/` に301**(旧URL・SEO・ブックマークを / に集約。sitemapから /site を除去)。**会員入口(ログイン)を維持**:site_base.html ナビに『ログイン』(ログイン済みは『ダッシュボードへ』)を追加。無料トライアル系CTA(ヒーロー/料金/最終CTA/ナビ/フッター/フロート)を `auth.register` に向け替え(旧 `/` 依存を解消)。ナビ/フッターの『サービス』は `/` に。旧 landing.html は未使用化(ファイルは残置)。★主CTAの金色化は任意の次の一手。
v0.99.83 2026-06-23
🔥 **公開サイトに Microsoft Clarity(ヒートマップ+セッション録画)を導入**。タグは共通include `_clarity.html`(プロジェクトID xcci754a1n)。**本番ドメイン(nudge-hq.co.jp)でのみ読み込み**(ローカル/プレビューのノイズを送らない)。**ログイン後のアプリ画面では読み込まない**(base.html は `not current_user.is_authenticated` の時のみ=顧客の個人情報を録画しない/site_base.html は公開サイトなので無条件)。プライバシーポリシー第5条(業務委託先)に Microsoft Corporation を追記。導入対象=LP・/site・/corp・/column・法務/登録等の公開ページ。
v0.99.82 2026-06-23
🎨 **LP料金セクションのモバイル改行を調整**。(1)料金説明文を3行に(『…アプローチ権」。/HP補完…送信まで/全て込み。』)。(2)初期費用カードを『…初期費用は/一切なし。…』で改行。keep-all+<wbr>で語の途中割れも防止(ユーザー追加カードにもwbr追加してはみ出し回避)。320〜390pxではみ出しゼロを確認。
v0.99.81 2026-06-23
🎨 **LPモバイルの改行を実機指定どおりに調整**。(1)ヒーロー見出しを『営業の作業を手放して、/商談に集中する。』の2行に(モバイル font-size を clamp で自動縮小して1行に収める)。(2)ヒーローのサブコピーを文ごとに改行(…返信管理まで。/無駄な移動…お任せ。/あなたは価値ある仕事に集中できます。)。(3)(4)お悩みカード1・4を句点で改行(『毎日数時間。/本来…』『高すぎる。/でも社長…』)。(5)SOLUTIONサブを『…AIが最適な/アプローチを…』で改行。320〜390pxではみ出しゼロを確認。
v0.99.80 2026-06-23
🐛 **LP見出しの実機での横はみ出しを修正**。`word-break: keep-all` の『、』『・』での自動改行はブラウザ依存で、一部のスマホ実機では折り返さず最終CTAの見出し/サブコピーが横にはみ出していた。句読点位置に明示的な `<wbr>` を挿入して全ブラウザで確実に折り返すように(最終CTA見出し・サブコピー・PROBLEM見出し)。320px〜で全見出しはみ出しゼロを確認。
v0.99.79 2026-06-23
🎨 **LPのデザインを /site に寄せる**:(1)全セクション見出しに英字透かし(PROBLEM/SOLUTION/FLOW/PRICE/FAQ・`.lp-head-wm`)。(2)PROBLEMの4カードを /site と同じ手描きイラスト(worry-1〜4.png)+薄紫枠・ソフト影に。(3)最終CTAの背景を /site メインビジュアルと同じ紫グラデ+ドット模様+光のにじみに(ドットは左下濃→右上薄=見出しに被らせない)。(4)最終CTAの補足文字を白系にして紫背景でも視認可。(5)モバイルの見出し改行を keep-all+`<wbr>` で語の途中割れ解消(ヒーロー/全セクション/カードh3)。🔤 **全体フォントを Noto Sans JP に統一**:base.html で Noto Sans JP を読み込み、style.css の本文フォント順を `Inter,"Noto Sans JP",…`(/siteと同じ=OSフォントより優先)に。アプリ全体の日本語が細いOSフォント→Noto Sans JPになり /site と一貫。変更:landing.html / style.css / base.html。
v0.99.78 2026-06-23
💳 **クレカなしトライアルの文言を是正**。新規登録ページ・LPのFAQ/最終CTA・料金ページ・特定商取引法表記に残っていた『お申込みにはクレジットカードのご登録が必要です』を、新フロー(カード不要で開始・トライアル中は課金なし・終了後も続ける場合のみカード登録)に統一。register.html / landing.html / pricing.html / legal_tokushoho.html。トライアル終了後のカード必須文言(onboarding.html)は正しいので維持。
v0.99.77 2026-06-23
💳 **クレカなしトライアルに仕様変更**(登録→カード不要トライアル14日→終了→カード登録→課金)。Model A(カード必須)を巻き戻し。既存の comp(免除)ロジックを通常トライアルに一般化:`onboarding_module.trial_active`/`trial_expired_needs_card`/`free_period_active`/`card_required_now`。check_steps の card 判定を『無料期間中(comp or トライアル) or カード登録済』に。is_onboarding_completed は無料期間切れ(`card_required_now`)で再ゲート。onboarding.index はカード必須状態でダッシュボードに飛ばさない(リダイレクトループ防止)。billing.checkout の `trial_period_days` を『残りトライアル日数(終了済なら0=即課金)』に変更(再トライアル防止)。onboarding.html のカードステップにトライアル中(任意)/終了(必須)の分岐+ウェルカム注記を更新。トライアル終了3日前のカード登録リマインドメール(`send_trial_expiry_reminders`・日次)。後方互換:既存のカード登録済みトライアル・comp・ベータ(無期限)は影響なし。トライアル中は plan='trial' のまま=有料転換にも入らない(前回の修正と整合)。🎨 **LPの世界観を/siteに統一**:ヒーロー見出し『9割削減』→『営業の作業を手放して、商談に集中する』、メディア表記→『PR TIMES配信により計29媒体に掲載』(誇大表現の是正)。
v0.99.76 2026-06-23
🐛 **訪問アナリティクスの『有料転換』バグ修正**。Checkout完了(カード登録)の時点で `User.plan` が light 等になるが、Stripeは trial_period_days=14 のトライアル中=未課金。旧定義(plan∈有料)では**トライアル中の人まで有料転換に数えていた**(実際は0課金なのに2と表示)。→ 有料転換を『**trial_ends_at(無料期間の終了)が過ぎた有料プラン**かつ comp(billing_exempt)でない』に限定(`admin_module._paid_conditions`)。window/total/daily の3箇所に適用。無料期間が終わって実際に自動課金される人だけがカウントされる。
v0.99.75 2026-06-23
🧠 **サービスページ(/site)の特徴中盤に『学習機能』セクションを追加**(できること4機能→学習機能→比較表 の順)。全自動の『丸投げ型』AIに対する差別化=『使うほど返信率が上がる設計』を、事実の範囲で訴求(誇大表現なし)。①結果(開封/返信)を記録 ②返信につながった件名/文面を成功例として学習 ③次の生成に反映、の3ステップ+成長カーブの図+『丸投げ型(送りっぱなし)』vs『Nudge HQ(成果を学習して蓄積)』の対比カード。`site_top.html` に scoped CSS 付きで自己完結(`.nhq-learn*`)。成長カーブの図は **`static/site/learning-screen.png`(実際の学習画面スクショ)があればそれを表示、無ければSVGにフォールバック**(onerror)=差し替え口を用意。★スクショは個人情報を映さないこと。
v0.99.74 2026-06-23
📈 **訪問アナリティクス(`/admin/analytics`)を本番ファネルに作り替え**。事前登録はローンチで終了・登録ページも閉鎖したため、旧『LP→登録ページ(事前登録)→事前登録』を **『LP訪問→登録ページ到達→新規登録→トライアル(オンボ完了)→有料転換』** に変更。登録ページ到達は `auth.register` の GET で `record_visit('register')` を新規計測。新規登録以降は admin・オペレーター(サブ垢)を除いた実ユーザー数(`_real_users_query`=parent_account_id無し+ADMIN_EMAILS除外)。有料転換=plan∈light/standard/pro/enterprise。各段の歩留まり(登録率・トライアル率・有料転換率)+日次推移(LP/登録/有料)+流入元別。旧・事前登録の実績は下部に『ローンチ前実績(参考)』として畳んで保存。
v0.99.73 2026-06-23
📊 **コラム流入・送客の自前計測**(指示書ベース・ただしSupabase anonキー公開は採らず自前サーバー方式に適応)。コラム閲覧→CTAクリック→サービスページ到達→コンバージョン(問い合わせ)のファネルを `analytics_events` テーブル(models.py)に蓄積。計測JS `static/js/nhq-track.js`(visitor_id=localStorage / session_id=sessionStorage / 送客元slug=sessionStorageで引き継ぎ)が 公開エンドポイント `POST /a/e`(`column_analytics_module.track_bp`・ログイン不要・best-effort・ボットUA除外)へ送信。Supabaseのanonキーはブラウザに出さない(既存の施錠方針を維持)。site_base.html に `data-nhq-pv` で page_view 自動送信、コラム記事に `data-column-slug`+CTAに `data-nhq-cta`、問い合わせ完了で conversion。Admin『コラム分析』`/admin/column-analytics`(`column_analytics_bp`)=期間フィルタ/記事別 PV・UU・CTA・CTR・サービス到達・CV・CVR/送客ランキング/流入元内訳(検索/SNS/AI/直接)/日次PVトレンド。保持180日(日次ジョブ `analytics_purge` で自動削除)。プライバシーポリシーに匿名アクセス解析の一文を追加。個人情報は非保存。
v0.99.58 2026-06-17
🖥 TopのFV製品モックアップを **3デバイス浮遊(ノートPC+タブレット+スマホ)** に変更(参考LP風)。`mockup-laptop.png`(中央メイン)+`mockup-tablet.png`(左奥・傾け)+`mockup-phone.png`(右手前)を static/site/ に置くと表示、無ければ人物イラストにフォールバック。CSS `.dev-laptop/.dev-tablet/.dev-phone` で配置。背景透過PNG前提。
v0.99.57 2026-06-17
🖥 **TopのFVに製品モックアップの差し込み口**(参考LP風の複数デバイス浮遊)。`static/site/mockup-1.png`(メインの大きいノートPC)+`mockup-2.png`(左下に重なるサブ)を置くと表示、無ければ人物イラストにフォールバック(`onerror`)。`.hero-devices/.dev-main/.dev-sub` をCSS追加。★モックアップPNGは**背景透過**で `static/site/` に置くこと(紫グラデ上に浮かせるため)。mockup-3 は将来の機能セクション用に温存。
v0.99.56 2026-06-17
🖼 **生成AIイラストの差し込み口を用意**(プラグ&プレイ)。`_site_art.html` に `illus_img(file, svgkind)` マクロを追加=`static/site/<file>` の画像があればそれを表示し、無ければ自作SVGにフォールバック(`onerror` で切替)。お悩みカード3枚(illust-busy.png/illust-reply.png/illust-solo.png)とFV(illust-hero.png)に適用。★完成したPNGを `static/site/` に上記名で置くだけで自動反映(コード変更不要)。それまでは現行SVGが表示。
v0.99.55 2026-06-17
🧑💼 イラスト刷新:『棒人間の腕』『おにぎり髪』をやめ、**ジャケット(スーツ)姿のビジネスパーソン**に。上半身を**ジャケット+白シャツのV+ネクタイ(紫)+襟**で描き、髪は**横分け/ボブ**で自然に、棒線の腕は廃止(持ち物は手元に配置)。busy=書類を持つ困り顔/mailx=スマホ+『…』の無反応/solo=『?』で悩む/FV=営業と顧客の2人。ゆるい線・やわらかい紫系の配色は維持。`_site_art.html` illus 全面更新。
v0.99.54 2026-06-17
🧍 イラスト修正:頭と体の間に隙間があり『頭だけ浮いて見える(体がない)』状態だったのを、**頭が肩に乗るよう首〜肩〜上半身をつなげて描画**(busy/mailx/solo/FVの2人とも)。viewBoxを縦に延ばし体を収める。
v0.99.53 2026-06-17
🖼 **イラストの作り込み(shigureni風)**:お悩みカードとFVの挿絵を、粗い手描き線(#sketch)から**クリーンな細線+やわらかい紫系の塗り+シンプルで親しみのある人物**に刷新。busy=書類に追われる人/mailx=スマホを見て無反応に疲れる人(…吹き出し)/solo=ひとりで悩む人(?)/people(FV)=営業と顧客の2人+きらめき。`_site_art.html` の illus マクロを全面更新。📝 開封率56.3%に **『※自社運用実績』の小さい注記**を追加(お悩み解決ブロックの該当行=トップ/サービス、+パートナーの実績バー)。
v0.99.52 2026-06-17
🎨 **課題→解決セクションを『こんなお悩み、ありませんか?』型に刷新**(参考LPの構成を踏襲・配色は紫+手描き)。旧ビフォーアフター2枚パネル → **吹き出し付きお悩みカード3枚**(営業の3大悩み=準備に追われる/コールド反応薄い/属人化、各カードに手描き挿絵)→ **下向き矢印** → 『その悩み、Nudge HQ がすべて解決します』+解決ポイント4つ。薄紫の帯(.worry-band)に白カードを浮かせる。手描き挿絵に 'mailx'(反応薄)・'solo'(属人化) を追加。共用include `_site_worries.html`(トップ/サービス)。検証:表示・エラー確認。
v0.99.51 2026-06-17
🔠 ヒーロー透かしeyebrowの書体を **M PLUS Rounded 1c(weight 800・丸ゴシック)** に変更(指定の『Nudge HQ』風の太め丸みフォント)。英字・日本語とも同フォントで統一、中抜き(透ける)スタイル+nowrap/clampの1行維持。Google Fonts を M PLUS Rounded 1c に差し替え。
v0.99.50 2026-06-17
🔠 ヒーロー透かしeyebrow『BtoB営業支援AI / Nudge HQ』の**英字と日本語を同じ書体に統一**=`Dela Gothic One`(英字・日本語ともに対応するヘビーなdisplay体)に変更。従来は英字Anton+日本語Notoでちぐはぐ(漢字の雰囲気が浮いていた)→1フォントで揃えて『英語と同じ』見た目に。中抜き(透ける)スタイル+`white-space:nowrap`+`clamp(1rem,4.2vw,2rem)`の1行維持は継続。Google Fonts を Dela Gothic One に差し替え。
v0.99.46 2026-06-17
🪪 サイトの仕上げ3点。(1)**ヘッダー左上『Cynthia』の左にロゴマーク**を追加(桔梗=ひし形+2つの目をSVGで再現=`_site_logomark.html`、inline・fill=currentColorで背景色に追従=白ヘッダーは黒/黒フッターは白。フッターにも適用)。★アップロードされたPNGはファイル保存できないためSVG再現で実装、後日 正規ロゴに差し替え可。(2)**透かしeyebrowを拡大**(1.05→1.7rem・ストローク1px)して視認性UP(モバイルは1.25rem)。(3)**導入の流れをステップ別カードに刷新**(参考LP風:番号バッジ+手描きアイコン+見出し+説明の横並び3カード、`.site-stepcards`/`_site_steps.html`。トップ/サービス共用、見出しは中央寄せ)。検証:表示・エラー確認。
v0.99.45 2026-06-17
🎨 サイトのヒーロー/フッター微調整(CSSのみ)。(1)ヒーローのサブコピー(リスト集め…AIが自動化)を `.site-hero .site-lead` で実績テキスト相当の小サイズ(.92rem)に。(2)eyebrow『BtoB営業支援AI / Nudge HQ』を**背景が透けるアウトライン文字**(color:transparent+-webkit-text-stroke、CREATE FUTURE風の中抜き)に=紫グラデが文字から透ける。(3)フッター背景を**黒のグラデ**(linear-gradient 90deg #0a0a0a→#242424→#0a0a0a・Deep Space風)に。検証:表示・エラー確認。
v0.99.44 2026-06-17
🛠 トップページ(/site/)の調整4点。(1)`.site-eyebrow` の `text-transform:uppercase` を解除=『BtoB営業支援AI / Nudge HQ』等が大文字化されず正しく表示(全ページのeyebrowに適用)。(2)ヒーロー実績テキストの『 / 29媒体掲載』を削除し『コールドメール開封率 56.3%(自社運用実績)』のみに(媒体数はティッカーで表現)。(3)『数字で見る Nudge HQ』(実績数字リング)節をトップから一旦撤去(サービスページには残置)。(4)**課題→解決(ビフォーアフター)と導入の流れをトップに追加**(サービスと同じ手描き挿絵/ステップアイコン)。白/グレーのセクション交互を再調整。検証:表示・エラー確認。
v0.99.43 2026-06-17
✨ サイトの仕上げ2点。(1)**CTAボタンの影を強化**して浮遊感(通常ボタンは紫影 0 10/18px、ヒーロー白ボタンは濃い影+ホバーで更に浮く)。(2)**メディア掲載をLP風の『流れる媒体名ティッカー』に**(`_site_ticker.html`=媒体名が横スクロールで無限ループ・両端フェードmask・ホバーで一時停止・prefers-reduced-motionで停止)。トップ/パートナーの信頼バーをティッカーに置換、サービスはFV直後にティッカー節を追加。媒体名は `site_module` の context_processor(media_outlets=PRESS_OUTLETS)が全サイトページに供給。検証:全ページ目視(ティッカー流れる・ボタン浮遊)・エラーなし。
v0.99.42 2026-06-17
🟣 **ヒーロー(ファーストビュー)セクションのみ紫グラデ背景**(linear-gradient 135deg #8e2de2→#4a00e0)に変更(トップ/サービス/パートナー/会社の各 .site-hero)。グラデ上のコントラスト確保:見出し・本文・eyebrow・実績テキストを白系に、主CTA『無料トライアル』は**白地×紫文字(#4a00e0)**、副CTA『お問い合わせ』は**白枠線×白文字の透明**、製品写真カード(.site-photo)は**白〜薄グレーでグラデ上に浮かせる**(影強化)。ヒーロー以降のセクションは白基調+紫アクセントを維持(変更なし)。CSSは `.site-hero` 配下の上書きのみで実装。検証:全ページ目視・エラーなし。
v0.99.41 2026-06-17
🖍 **コーポレート/サービスサイトを就活キャリア風に改修**(写真ベースで明るく・手描き風イラストで親しみ・流れをアイコンで視覚化/配色はモノクロ+紫#7c3aedを維持)。**絵文字は全廃**し、線画SVGで統一。手描きの温かみは**単一の歪みフィルター `#sketch`(feTurbulence+feDisplacementMap)を全アイコン/挿絵に適用**=均一線でなく有機的な線で統一(site_base.html に defs を1つ定義)。(1)FVを2カラム化=コピー+**人物写真プレースホルダー枠**(中に手描きの『商談する2人』挿絵+紫スパーク)、(2)**課題→解決を手描き挿絵化**(before=時計+書類の山/グレー、after=チェック+上昇矢印/紫。絵文字😓を撤去、×/✓も手描きSVGマークに)、(3)**導入の流れに各ステップのアイコン**(STEP1 申込書/STEP2 アップロード/STEP3 再生、紫タイル)、(4)**CTAボタンを紫グラデ**(linear-gradient #7c3aed→#a05cf0+影)に、(5)仕組みフロー図のアイコンも #sketch 適用で手描き統一。手描きパーツは `_site_art.html`(Jinjaマクロ:mark/step_icon/illus)に集約=後日、作り込んだイラストに差し替え可。CSSに .site-photo/.art-step-ic/.art-mark/.ba-illus 追加。★後日差し込み:FV人物写真・製品スクショ・導入企業ロゴ(プレースホルダー実装済)。検証:全5ページ200・FV(挿絵+グラデCTA)/課題解決(手描き挿絵+マーク)/導入ステップ(アイコン)/フロー図 をデスクトップ・狭幅で目視・コンソール/サーバーエラーなし。
v0.99.40 2026-06-17
🎨 **コーポレート/サービスサイトの密度・作り込みを強化**(カオナビ系BtoB SaaS LPの情報量/配色はモノクロ基調+紫#7c3aedアクセントを維持)。サービスページを主戦場に全面拡充:(1)FVを2カラム化+**製品スクショのプレースホルダー枠**+実績数字をFV内に添える、(2)**実績数字セクション**(開封率56.3%を**SVGリングゲージ**/掲載29媒体/初期費用0円のカード)、(3)**仕組みフロー図**(リスト収集→メール生成→追客→人が最終承認、インラインSVGアイコン+矢印・`_site_flow.html`)、(4)**機能ジグザグ**(4機能を説明文+画面イメージ枠で左右交互)、(5)**課題→解決のビフォーアフター対比**(これまで×/Nudge HQなら✓)、(6)**FAQ**(details/summaryのアコーディオン)、(7)**導入企業ロゴ帯**(プレースホルダー)、(8)**CTAをFV/機能後/料金後/末尾に反復配置**。トップも FV2カラム+スクショ枠+実績数字セクション+フロー図に強化(3つの入り口カードは維持)。新CSSコンポーネント(site.css:.site-shot/.site-stats/.site-ring/.site-feature/.site-flow/.site-ba/.site-faq/.site-logos)+共用include(_site_flow.html/_site_stats.html)。★後日差し込み(プレースホルダー実装済):製品スクショ・機能別画面イメージ・導入企業ロゴ。検証:全5ページ200・デスクトップ目視(FV2カラム/リングゲージ/フロー図/ジグザグ/対比)・モバイル目視(フロー縦積み・カード単列)・コンソール/サーバーエラーなし。
v0.99.39 2026-06-17
🏛 **コーポレート/サービスサイトを新規構築**(株式会社Cynthia / Nudge HQ)。LPの『一歩手前』に置く公式サイトで、顧客・代理店候補・取引/採用の3者をトップから振り分ける。**4ページ+統合お問い合わせ**:トップ(/site/)/サービス(/site/service)/パートナー=代理店募集(/site/partner)/会社(/site/company)/お問い合わせ(/site/contact)。**デザイン=モノクロ基調(白・黒・薄グレー)+紫#7c3aedアクセント**、アプリ本体の紫chromeとは独立(`site_base.html`+`static/css/site.css`+`site_module.py`/Blueprint url_prefix=/site)。ヘッダーはCynthiaロゴ(ファイル未配置時はテキスト fallback)、レスポンシブ(ハンバーガー)。パートナーページに**報酬シミュレーターを iframe 埋め込み**(公開 `/partners` に `?embed=1` のchrome-lessモードを追加=`embed_mode` でアプリヘッダー抑止)。料金は『初期費用・追加費用0円』+『月額98,000円〜』を1ブロックで強調(上位金額は非公開)。問い合わせは用件種別セレクト付き統合フォーム→Resendで SITE_CONTACT_EMAIL(既定 info@nudge-hq.co.jp)へ通知+ハニーポット。現状は**別パス /site/* に仮置き**(/ は既存LPのまま・将来 / に昇格しやすいよう独立Blueprint)。/site をメンテ許可リストに追加。★未配置(別途共有):Cynthia/Nudge HQロゴ画像(static/site/)・メディア各記事URL(env PRESS_URL でまとめリンク)・iframe高さ自動調整。検証:全5ページ200・モノクロ+紫デザイン目視・パートナー埋め込みシミュレーター動作・問い合わせPOST(正常/bot/欠落)分岐・/partners正常/embed両方200 を確認。🐛 同時に `/partners` の500を修正(embed対応で足した `request` がapp.pyグローバル未importだったため `from flask import request as _req` に)。
v0.99.38 2026-06-17
🏆 **代理店レポート(/referral)に『代理店ランキング』を追加**(ゲーミフィケーション=もっと売る動機)。指標は**アクティブMRR**(継続課金中の顧客の定価月額合計・`agency_rank_module.active_mrr` 再利用)。〔**全体ランキング**〕と〔**自分のティア内ランキング**(同ランク同士=階級違いで萎えないため)〕の2表を表示、自分の行はハイライト+圏外なら末尾に自分の順位も補足表示。各行=順位/ランクバッジ/会社名(AgencyProfile.corporate_name)/MRR。新規 `agency_rank_module.leaderboard()`(全代理店をMRR降順・除名は除外)+`referral_module.index` で全体/ティアの行を組成。★顧客の個人情報は一切含まない(代理店の集計値のみ)。他代理店の報酬額(¥)は出さず MRR と順位のみ=競争は煽るが過剰露出は回避。検証:サーバーimportクリーン・/referral は500でなく認証リダイレクト・Jinja(format/ループ)レンダリング確認。★次の一手:半期表彰式=半期MRRランキング確定+MVPバッジ+admin受賞者CSV(未実装)。
v0.99.37 2026-06-17
🚀 **提案シミュレーター(/admin/simulator)に『成長シナリオ』トグルを追加**。**開始ランク→到達ランク**を選ぶと、その間を継続年数で等分して**ランクを駆け上がる**演出(1年目=開始/最終年=到達)。各年その年のランク料率で計算=**ランクが上がるほど(過去ブック含め)料率が上がり報酬が年々加速**する様子を可視化。(1)ランク昇格タイムライン(例:Copper→Bronze↑→Silver↑→Gold↑→Platinum↑→💎Diamondは招待制)、(2)『開始ランク固定なら累計¥X/到達ランクまで駆け上がると¥Y=+¥差分』の比較、(3)固定モードと1クリック切替。★当初は『累計MRRがしきい値超でランク自動昇格』にしたが、強い代理店(多社獲得)だと初年度で天井に張り付き駆け上がりが見えないため、**提案者が開始→到達を選べる手動モデルに変更**(獲得ペース非依存で必ず climb が見える=商談で物語を作れる)。料率は `AgencyRankConfig` と同一ソース。★公開ページ(/partners)と単体書き出しHTMLは『料率ラダーが漏れる』ため成長シナリオ未搭載(admin専用)=設計非漏洩を維持。検証:calc/buildClimbPath 数値が手計算一致(Copper→Platinum/50社/5年・年契約=駆け上がり¥697,200,000・開始固定¥498,000,000・差+¥199,200,000、パス Copper→Bronze→Silver→Gold→Platinum)、render両モード例外なし・3セレクト出し分け正常 を確認。
v0.99.36 2026-06-17
🌐 **代理店報酬シミュレーターの公開ページ(`/partners`)を新設**。コールド招待やLPからリンクし、相手が自分のPC/スマホでそのまま試算できる公開ページ(DL不要・URL共有)。★公開版の鉄則:(1)**維持MRR・降格条件・しきい値はクライアントに一切渡さない**(入口は広く=上り側だけ見せる方針)、(2)最上位 **Diamond は招待制**=料率を JSON から除外し『招待制(個別料率)』表示のみ。公開する料率ラダーは Copper〜Platinum のみ。app.py に公開ルート(メンテ中も常時公開・LP訪問計測 record_visit('partners'))+ `templates/partner_simulator.html`(紹介報酬のショット/ストック/累計+SVGグラフ+『1つ上のランク』比較+無料トライアル誘導CTA)。admin版 `/admin/simulator` は全情報を持つ内部用として温存。検証:GET 200・埋め込みJSONに diamond料率/thresholds 無し・Platinum選択時に次=『Diamond(招待制)』表示・計算/チャート/モバイル表示・コンソールエラー無し を確認。🔗 ついでに **admin提案シミュレーターへの導線追加**(v0.99.35でルート/テンプレは在ったがメニュー未掲載で辿り着けなかった)+公開ページへのadminリンク。🐛 **提案シミュレーターのスライダー固定**:コントロールを flex-wrap→grid 化。数値の文字幅変化で折り返しが動きスライダーが上の行へ飛ぶ挙動を解消。📊 **シミュレーターを『継続型(毎年N社獲得)』モデルに統一+累計バグ修正**(admin/公開/書き出しHTMLの3点)。旧版はグラフ(薄紫ショット一定+濃紫ストック増加)が『毎年N社獲得の年間受取額』の形なのに、ラベル/前提が『初年度に一度だけ獲得』とちぐはぐで、かつ累計(LTV)が『最終年の年間受取額』だけになっていた(全年合計でなかった)。オーナー判断で**継続型(毎年N社ずつ獲得し続ける)**に確定し統一:(1)累計=全年の年間受取額の合計に修正(例:上位/Gold/毎年50社/5年=¥759,450,000)、(2)指標を『毎年のショット報酬(N社分)/最終年の年間ストック/累計報酬(Y年・毎年N社)』に、(3)スライダーを『毎年の獲得社数』、凡例を『ショット(毎年の新規獲得分)/ストック(継続報酬・積み上がる)』、グラフ下に動的キャプション『各年の年間受取額/毎年N社ずつ獲得した場合』を明記。グラフの棒の計算式(recur=Y×ppy−1)は継続型の年間ストック発生回数と一致するため不変(年契約・月契約とも)。検証:公開ページで数値一致・エラー無しを確認。
v0.99.35 2026-06-17
🏅 代理店6段ランク制度 **Phase6=提案シミュレーター(商談資料)**で全6フェーズ完了。`/admin/simulator`(admin内):ランク(6段)・プラン(上位/中位/Light)・契約(年間/月額)・獲得社数(1-50)・継続年数(1-5)をスライダー/トグルで操作→ショット/満期年ストック/累計LTV+SVGグラフ(ストックの積み上がりが主役・#7c3aed/#a78bfa)がリアルタイム更新。料率は AgencyRankConfig と同一ソース(齟齬ゼロ)。ランク維持MRR表示+『1つ上との比較』。**単体HTML書き出し**(`/admin/simulator/export`)=表示中の条件(ランク/プラン/契約)だけで動く自己完結HTMLをDL(外部依存なし)。★書き出しHTMLには**全ランクの料率テーブル・維持条件・他ランクを一切含めない**(選択中の率のみ焼込=設計が第三者に漏れない)。検証:admin画面200・書き出し添付DL・焼込率(gold×上位=45%/8%/¥498,000)・漏洩なし(料率表/しきい値/他ランク名なし)・自己完結 を確認。
v0.99.34 2026-06-17
🏅 代理店6段ランク制度 **Phase5=admin UI**(`/admin/agency-ranks`・設定ドロップダウンに導線)。(1)代理店一覧:現在ランク・状態(稼働/警告/失効)・アクティブMRR・件数・連続未達/0件カウンタ・適用月。(2)手動操作:ランク変更(Diamond付与+tier別の個別料率%入力/手動降格=Platinum等/失効解除)。(3)四半期判定の手動実行:『試走(dry_run・変更なしで変動プレビュー)』『実行』。(4)料率テーブル/しきい値/判定パラメータ(降格連続・0件警告/失効・判定月)を画面から編集=`AgencyRankConfig` に保存(%↔小数変換)。(5)ランク変更履歴(監査)。admin_module に agency_ranks/set/release/config/evaluate ルート、agency_rank_module に set_rank_manual/release_eviction/admin_rank_overview/config_from_form を追加。検証:GET 200・dry-run実行・料率エディタ保存ラウンドトリップ(gold×上位45→46→戻し) を確認。
v0.99.33 2026-06-17
🏅 代理店6段ランク制度 **Phase4=報酬の戻入(§7・チャージバック対応)**。既存の『戻入なし』方針を転換。Stripe webhook の `charge.refunded`(返金)/`charge.dispute.created`・`charge.dispute.funds_withdrawn`(チャージバック/資金引上げ)を受け、`referral_module.reconcile_reversal(invoice_id, 無効化額, 理由)` が該当請求の報酬(acquisition/recurring・既払い含む)を**負の `kind='chargeback'` エントリ**で戻入=以後の報酬から相殺(未払い残高がマイナスになり次回以降の発生分と相殺)。適用率は計上時の applied_rate(旧データは amount/base から復元)。元入金額を上限に過剰戻入を防止。**冪等+partial比例**:累計返金額と既存戻入を突合し不足分だけ追加(複数回/部分返金でも二重戻入しない)。report計上の冪等判定は chargeback 行を除外するよう修正。★Stripe本番Webhookの対象イベントに `charge.refunded` / `charge.dispute.created` / `charge.dispute.funds_withdrawn` を追加すること(未追加だと戻入が走らない)。検証:全額返金で残高0・再実行冪等・partial(10万→5000/全額→残9900)を実データ経路で確認(DB汚染なし)。
v0.99.32 2026-06-17
🏅 代理店6段ランク制度 **Phase3=四半期判定**。`agency_rank_module.evaluate_agency/evaluate_all`:(1)昇格=即時(その判定でアクティブMRRが満たす最上位ランクへジャンプ・copper〜platinum)。(2)降格=現ランク維持MRRを**2四半期連続**で下回ったら1つ下へ(1回だけの未達は据え置き=consec_below)。(3)Copper除名・全ランク共通失効=アクティブ契約**0件が2四半期連続で警告通告→3連続で資格失効(evicted)**(consec_zero・warned_at/evicted_at)。(4)Diamondは自動対象外(last_eval/mrrのみ更新、降格は管理者手動)。判定タイミング=四半期の頭(1/4/7/10月1日)に全代理店一斉、`effective_ym=判定月`=その四半期初月の報酬から新料率(例:7月判定→7-9月Gold→7月分から・8月末払い)。結果は AgencyRankHistory に記録+本人へ通告メール(best-effort)。AgencyRank に status(active/warned/evicted)/evicted_at 追加(ALTER自動)。失効代理店は record_reward_from_invoice でも計上スキップ(停止方針)。スケジューラに日次cron(03:30 JST→is_eval_dayで判定日のみ実行、eval_monthsは設定値)。検証:昇格(copper→gold)・降格バッファ(2連続でgold→silver)・除名3段階(buffer→warn→evict)・qualified閾値・履歴記録 を固定MRRで決定論的に確認(DB汚染なし)。
v0.99.31 2026-06-17
🏅 代理店6段ランク制度 **Phase2=報酬計算のランク連動**。`record_reward_from_invoice` の料率を旧定数(30%/5%)から`agency_rank_module.get_rate('shot'|'stock', その請求月に有効なランク, 顧客プラン, ランク行)` 参照に変更。請求の発生月(`_invoice_month`=paid_at/created→JST の YYYY-MM)でランクを引き、`rank_effective_for_month` が履歴から『その月に適用するランクを1つだけ』返す=月中で料率混在しない/判定確定月の当月分から新料率。ReferralReward に `applied_rank`/`applied_rate` を追加(ALTER自動・監査/戻入/仕入明細の根拠)。**後方互換**:ランク未登録の代理店は copper にフォールバックし、copper料率は全プラン 30%/5% =従来と完全一致(既存代理店は挙動不変)。検証:使い捨ての代理店+紹介顧客で copper=30%/5%(89,400/14,900円)一致・gold昇格後の継続=8%(23,840円・中位)を実データ経路で確認(DB汚染なし)。★まだ四半期判定(Phase3)が無いので全代理店copperのまま=実質まだ料率は動かない。
v0.99.30 2026-06-17
🏅 代理店6段ランク制度(Copper/Bronze/Silver/Gold/Platinum/Diamond)の **Phase1=基盤**。新モデル:`AgencyRank`(現在ランク・連続未達/0件カウンタ・Diamond個別料率・effective_ym)/`AgencyRankHistory`(追記ログ=過去明細再計算・監査・その月のランク参照)/`AgencyRankConfig`(設定値JSON・admin編集可)。新モジュール `agency_rank_module.py`:料率テーブル既定値(§2のたたき台・ショット/ストック×ランク×プラン)・しきい値・評価指標を**すべて設定値化**(ハードコード禁止)。プラン対応(上位=Pro/中位=Standard/Light=Light)、**アクティブMRR算出**(紐付く課金継続中の有料顧客の定価月額合計/referral_code→PromoCode→agency、解約/停止/未課金除外)、`get_rate`(Diamondは手動個別料率優先)、`rank_effective_for_month`(その月に適用するランクを履歴から1つだけ引く)を実装。★まだ報酬計算(record_reward_from_invoice)には未配線=**ユーザー挙動の変化なし**(Phase2で配線)。新テーブルはcreate_allで自動作成。検証:3テーブル作成・料率が§2と完全一致・しきい値/プラン対応/MRR/設定読込 を確認。
v0.99.29 2026-06-15
🧾 料金プラン(billing_module.PLANS.features)の機能表記を実態に合わせて是正(誇大広告防止)。(1)Proの『業界別AI最適化』『データ分析レポート月1回』は**現状未実装なので削除**。(2)Few-shot学習は全プラン共通(Lightにもある)なので Light の機能に明記し、Standard の重複行は削除(Standardは『Lightの全機能』でカバー)。(3)請求書払い(Standard/Pro)・営業マンN人分の工数削減・優先サポート(Pro)は事実/提供予定なので維持。結果:プラン差はほぼ『アプローチ数(月次ユニット)』+工数削減目安+請求書払い(Std/Pro)+優先サポート(Pro)に整理。検証:料金ページで虚偽2項目が消え・Few-shotがLightに1回・優先サポート/請求書払い維持 を確認。
v0.99.28 2026-06-15
💳【課金フローを Model A に是正=重要】旧実装は `/billing/invoice-request` が『サブスク未保有者向けに no-card の send_invoice サブスクを新規作成』する仕様で、料金ページに非サブスク向けCTAを出していた=**オンボのカード必須を骨抜きにし、Lightファネルに摩擦**を生んでいた。Model A に是正:(1)新規は必ずオンボでカード登録→Lightトライアル(不変)。(2)請求書払いは『**ご契約後(カード登録済み)に Standard/Pro へ切替**』する導線に変更。`invoice_request` を反転:サブスク未保有はGET/POSTとも料金ページへリダイレクト/保有者は既存サブスクを `stripe.Subscription.modify`(price=Standard/Pro・`collection_method='send_invoice'`・`days_until_due=30`・`proration_behavior='none'`)で切替+Customer.modify で請求書送付先を反映。**カードはdetachせず残す**(→トップアップ等で使える=v0.99.27で気づいた『請求書払い顧客がトップアップ不可』も解消)。切替時アクセスは**継続**(前払いロックなし)、未入金で期日超過したら既存の webhook(past_due/payment_failed)→suspend_account→10日で自動BAN の通常ダニングに乗る。料金ページCTAを『請求書払いに切り替える』(has_subscription時のみ)に変更、invoice_request.html も『切替』文言に。★Stripe実APIはこの環境で検証不可=**本番で実サブスクを1件 Standard/Pro 請求書払いに切替→Stripeでcollection_method=send_invoice/プラン/請求書送付を要確認**。検証(自動):py_compile / Jinja parse / 非サブスクのGETが料金ページへ302 / 新規にCTA非表示 を確認。
v0.99.27 2026-06-15
⚡ ユニット買い切りトップアップ(/billing/topup)の発見性UP。(1)料金ページ(pricing.html)に『今月だけユニットが足りない方へ→ユニットを追加購入』リンクを追加(請求書払いカードの直後・ログイン中の全員に表示)。(2)ダッシュボードの『ユニットを追加購入』導線を **admin にも表示**(従来は `if not plan_info.is_admin` でオーナーには非表示だった=『どこで買うの?』と分からなくなる原因)。アップグレードボタンは従来どおり『非admin かつ 上限が近い/超過』時のみ。adminには『制限なしですが導線確認用に表示』の注記。検証:Jinja parse/ログイン済みadminで 料金ページ・ダッシュボードにtopupリンク有・/billing/topup 200 を確認。
v0.99.26 2026-06-15
⏱ 14日無料トライアルの起点を『登録時』→『オンボーディング完了時』に変更。従来は auth.register で trial_ends_at=登録+14日 を設定していたため、メール認証やセットアップ(クレカ/自社情報/SMTP)で手間取ると使い始める前にトライアルが消費されていた。`usage_module.restart_trial_clock(user)` を新設し、onboarding `_maybe_mark_completed`(必須3つ完了→onboarding_completed_at セットの単一ゲート)でトライアルを『今+14日』に測り直す+既存のトライアルUnitLot(period_key='trial')の expires_at も新起点に追従。対象は trial プランの実ユーザーのみ(admin/オペレーター/課金免除/有料/解約は対象外)。※Stripeの課金トライアル(trial_period_days=14)はカード登録時=オンボ中から起算で従来通り(ほぼ同時に揃う)。検証:使い捨てユーザーで trial→14日にリセット+ロット失効追従/light(有料)は不変 を確認(DB汚染なし)。
v0.99.25 2026-06-15
⚠ レンタルサーバーのメール接続に関する注意書きを強化。オンボーディングで必須のSMTP設定で、共有レンタルサーバー(Xserver・さくら等)は『クラウドからの送信がブロックされる場合があります』という控えめな muted small 表示だったのを、**目立つ警告ボックス(flash-warning)+『動作保証いたしかねます/ブロックされる可能性が非常に高い/Google Workspace(月¥1,000弱)または Microsoft 365 のご用意を強く推奨』**に変更(smtp.html+onboarding.html の両方)。バウンス事故・問い合わせを未然に減らす狙い。検証:Jinja parse/smtp に強文言・警告ボックス有・旧文言消去 を確認。
v0.99.24 2026-06-15
🔧 直前(v0.99.23)の調整2点。(1)AI分析の『全リスト(業種未絞り込み)』警告を、ブリーフが2個以上の時だけ表示に変更(条件に briefs|length > 1 を追加、const名も FULLPREP_UNSEGMENTED→FULLPREP_WARN)。ブリーフが1個以下=使い分けが無いユーザーに毎回警告が出てうざい問題を解消。(2)メール設定の追いメールシーケンス選択を、横並びチップ(btn)からプルダウン(select#seq-select・change で ?seq=ID へ遷移)に変更してわかりやすく。検証:Jinja parse/ブリーフ1個で警告OFF・stale const無し・seqドロップダウン描画 を確認。
v0.99.23 2026-06-15
🔍【AI分析(full_prep)の改善3点】(1)業種未絞り込みの『全リスト』表示中にAI分析を実行しようとすると『先にスマートリストで業種を絞り→ブリーフを選んで実行』を促す警告confirmを表示(list_detail.html、FULLPREP_UNSEGMENTED=saved_list無し かつ conditions空 で判定)。混在リストに1ブリーフ一括の事故を防止。(2)AI分析パネルに『使用するブリーフ』selectを追加(briefsは既に渡し済み・JSで brief_id を fd 送信。full_prep ルートは既に brief_id 受領済みでバックエンド変更不要)=**複数ブリーフを業種ごとに使い分け可能に**。(3)進捗モーダルに『右下に最小化して作業を続ける』ボタン=NudgeJobs(自動収集と同じ右下ドック)へ引き継ぎ。★AI分析はサーバー側のデーモンthread+BulkJobで動くため『画面を離れても分析は止まらない』(結果はDB保存・リストに反映)。止まるのは画面の進捗表示だけ。検証:Jinja parse/ログイン済みで未絞り込み=警告ON・絞り込み=OFF・ブリーフselect描画・最小化ボタン を確認。
v0.99.22 2026-06-15
⚙️【設定の整理・統合】散らかっていた設定ドロップダウンを見出し付き3グループに整理:✉️営業・メール設定(自社情報/メール設定/ブリーフ/予算判定の基準/再営業/送信メール設定SMTP/営業NGリスト)/👤アカウント(オペレーター管理/料金プラン/代理店プログラム/チュートリアル見直し/メールアドレス変更/パスワード変更)/🛠管理(admin)。`.nav-dropdown-label` を新設。再営業(reengagement.index)をメニューに追加し発見性UP。【物理統合】自社情報(company)に紛れていた『🎯成功の定義(success_definition)』『✉️メールの味付け(ai_instruction_default)』をメール設定(email_settings)へ移設=新ルート POST /email-settings/prefs(email_settings.save_prefs が CompanyProfile を保存)+email_settings.html 上部にカード追加(#success アンカー維持)。company.html から両fieldset削除、company.edit POST からも該当行を除去(フォームに無い項目で NULL 上書きしない=**自社情報保存で成功定義/味付けがリセットされない**ことを回帰テストで確認)。アンカー追従:compose_contact の『成功の定義を変更』→ email_settings.index#success、brief_form の文言を『メール設定の成功定義』に。再営業設定の本体は company に残置(reengagement.html の #reengagement-settings リンク維持)。検証:py_compile / Jinja parse / ログイン済みで email-settings に項目有・/prefs 保存・company から消去・非リセット回帰・メニュー3グループ表示 を確認。
v0.99.21 2026-06-15
🆘【サポート問い合わせをフォーム化】v0.99.20 のヘルプ内『サポートに連絡』は mailto だったが、エンタープライズ相談/不具合報告と同様に【フォーム→DB保存→admin画面で閲覧→support@へメール通知】に変更。新 SupportRequest モデル(support_requests・create_allで自動作成)/support_module.py(POST /support/contact=保存+SUPPORT_EMAIL へ Resend 通知、best-effort)/admin /admin/support-requests 一覧+対応済みトグル(admin_support_requests.html)+設定ドロップダウンにナビ追加。base.html のヘルプモーダルの支援フッターを textarea フォーム化(AJAX で送信、ページパス/ヘルプ見出しを自動付与、インライン成否表示)。SMTP設定ページのサポートカードは mailto→ヘルプ起動(data-open-help)に変更。お急ぎ用に support@ 直書きは残す。検証:py_compile / Jinja parse / ログイン済みで smtp にフォーム有・POST /support/contact 200+DB保存・/admin/support-requests に表示 を確認。
v0.99.20 2026-06-15
❓【ページ別ヘルプFAB】全画面の左下に『❓ヘルプ』ボタンを追加(不具合報告FABは右下=左右で分離)。押すと『そのページ専用のFAQ』モーダルが開き、末尾に『解決しませんでしたか?→サポートに連絡』(support_email への mailto・件名にページ名/本文にページパス自動付与)。自力解決→ダメならサポートの導線。実装:help_module.py にページ別ヘルプを**コードで**保持(DB不要)。キー=request.endpoint(smtp.settings/auto_list.index/list_bp.pool/list_bp.upload/email_settings.index/dashboard.index/send.work/inbox.index/company.edit/operators.index/billing.pricing/reengagement.index/onboarding.index 等)、未登録は DEFAULT にフォールバック。app.py context_processor inject_page_help が page_help を全テンプレに供給、base.html に FAB+モーダル(authenticated & not embed のみ・**admin にも表示**=普段チュートリアルをバイパスするオーナーも見られる)、style.css に .help-fab/.help-modal。検証:py_compile / Jinja parse / ログイン済み GET で /smtp・/dashboard・/auto-list が 200・helpFab表示・各ページ固有FAQ・サポートmailto を確認。文面修正は help_module.py を編集するだけ。
v0.99.19 2026-06-15
2件。(1)🔁【アップロードのやり直し】列マッピングを間違えた時にやり直せるよう、アップロード結果画面に『このアップロードを取り消してやり直す』ボタンを追加(list_bp.undo_upload)。session の recent_upload_batch のcontact_ids を使い、今回追加分のうち**まだ手をつけていない行(メモ/下書き無し・未送信)だけ**を一括削除し、アップロード画面へ戻す。AI分析/メール作成/送信済みの行は安全のため残す(件数を表示)。投入時のユニット消費は0なので返却不要。従来は『全リストで選択して削除』しかなく多数行のやり直しが面倒だった。(2)🆘【サポート連絡ボタン】SMTP設定ページ(smtp.html)に『設定でお困りですか?サポートにご連絡ください』カードを追加=support_email へのmailtoリンク(件名・本文テンプレ付き)+アドレス直記。新context_processor inject_support_email:環境変数 `SUPPORT_EMAIL`(未設定なら support@nudge-hq.co.jp)を全テンプレに供給。★本番で support@nudge-hq.co.jp の受信(Xserver MX のメールアカウント/エイリアス)を用意すること。検証:py_compile / Jinja parse / render(undoボタン+URL・urlencode・support_email注入)/ ログイン済み GET /smtp 200・カード表示。
v0.99.18 2026-06-15
📚【チュートリアルStep1の列マッピング画面に説明を追加】サンプルCSV取込後に出る『列マッピング』画面に何をすればいいか分からない問題に対処。RPG風introポップアップは action_endpoint(=upload画面)でしか出ず、マッピング画面(list_bp.upload_preview への入力画面)は無説明だった。mapping.html に `tutorial_current_step.num==1` のときだけ表示する紫グラデの『列マッピングの使い方』カードを追加:(1)列マッピングとは何か、(2)緑メッセージ=AI自動推測でそのままでOK、(3)メールアドレスのみ必須、(4)プレビューで中身確認、(5)『次へ』を押す、を番号付きで説明+『練習用なので自動マッピング済み・そのまま次へでOK』の一言。さらに『次へ:プレビューで確認』ボタンに tutorial-pulse で視線誘導。通常のCSV取込(非チュートリアル)では一切出ない。検証:render テストで ON=カード+パルス表示 / OFF=非表示 を確認。
v0.99.17 2026-06-15
2件。(1)📧【追いメール上限を撤廃=全プラン無制限】旧v0.35.1の上限(trial/light=2/standard=5/pro=10)は『SendGridの原価をNudge HQが吸収する』ための制限だったが、v0.47でSendGridを廃止し送信は各ユーザー自身のSMTP(自社負担)になったため根拠が消失。`PLAN_LIMITS[*].max_followup_count` を全て None=無制限に。1コンタクト=1ユニット=シーケンス権で通数に依存せず原価ゼロ、暴走は返信/配信停止/不達の自動停止で担保。email_settings.html は既に `max_followup is none`→『無制限』表示に対応済みでUI変更不要(アップグレード誘導も自動で非表示)。(2)🚪【オペレーター強制ログアウト】オーナーが `/operators` から各オペレーターを『ログアウトさせる』/『全員をログアウト』。方式=セッションepoch:`User.session_epoch`(ALTER自動マイグレーション・既定0)をログイン時に session['sess_epoch'] へ記録し、before_request `_enforce_session_epoch` で不一致なら強制ログアウト→ログイン画面。ボタンで対象の session_epoch を +1 し全端末セッションを無効化。再ログインは可能(恒久遮断は削除/PW再発行)。既存セッションは epoch 0 一致のためデプロイでの一斉ログアウトは起きない。スマホ対応済みの /operators から端末紛失・離任時に即遮断できる。検証:preview再起動でsession_epoch ALTER適用・起動エラー無し・LP200。
v0.99.16 2026-06-15
⏳【収集の待ちストレスを解消=進捗ドック】自動収集は件数が多いと数分かかり、進捗モーダルがページ離脱をロックして『ユーザーが待つしかない』のがストレスだった。収集ジョブ自体はサーバー側スレッドで完走し結果は全リストに入るため、待たせない設計に:(1)進捗モーダルに『右下に最小化して作業を続ける』ボタンを追加→押すと離脱ロック解除+右下の小さな進捗カードへ引き継ぎ、別画面で作業継続できる。(2)新 `window.NudgeJobs`(main.js)=localStorage にジョブを登録して右下ドックにカード描画+/jobs/<id>/status をポーリング。**ページ遷移しても復帰**して完了/エラーまで追従(完了時は『結果を見る→』リンク、連続失敗5回で停止)。(3)CSS `.job-dock/.job-card`(不具合報告FABの上に積む)。auto_list.html に最小化ボタン+『件数が多いと数分かかる場合があります。閉じても収集は続きます』の注記。検証:preview起動・LP200・main.js構文/NudgeJobsロード・コンソールエラー無し・ドックカード右下描画を実機確認。
v0.99.15 2026-06-15
🏢【gBizINFO『また0件問題』の構造的解決】キーワード『営業代行』で0件になる原因を実機API仕様で確定=gBizINFO の検索はテキストが name=商号 しか無く、業種キーワード(営業代行 等)では構造的にほぼ0件(business_item は行政調達の品目コードで自由文不可)。そこで役割分担を整理:**業種で“発見”=AI収集(Gemini)に一本化/会社規模の“確定”=gBizINFO** とし、(1)旧『gBizINFO専用収集(/auto-list/gbiz+_gbiz_collect_worker+専用フォーム)』を撤去、(2)AI収集(_auto_list_worker)に『🏢会社規模で絞る』フィルタ(size=micro/small/mid/large・複数可)を統合。指定時は収集後に各社の会社名→gBizINFOの公式従業員数を ThreadPool で照会し、規模不明・条件外を除外(規模はAI推測でなく公式値=捏造防止)。母集団が減るぶん発見をオーバーサンプル(SIZE_GATE_OVERSAMPLE=2、上限50)し、ユニット消費は requested_count で打ち切り(過剰消費なし)。(3)0件時は『無言の0件』をやめ『N社発見も規模不明X・条件外Y/規模を緩める・外すと追加できます』と具体提案。追加した企業には employee_count/capital_stock/hojin_number/gbiz_checked_at を付与(🏢従業員数バッジに反映)。検証:py_compile / Jinja parse OK。★大量収集は規模フィルタ無しのAI収集が引き続き本線。
v0.99.14 2026-06-15
🏢 gBizINFO収集を実用化(Phase2.1)+全選択バグ修正の2件。(1)【全選択バグ】list_detail.html のAI分析『表示中を全選択(最大100)』が、非表示のチェックボックスも拾って100件チェック→カウントだけ100・画面の行は未チェック、になっていたのを修正。boxes() を offsetParent で『表示中のみ』に限定+トグル化(全選択⇔解除)。(2)【Phase2.1】gBizINFO収集を『gBizINFOのHP登録(約5%)に依存』から『**会社名からAIがHP探索**(gemini_search.lookup_url_by_company_name)→クロールでメール取得』に変更。search_with_size に require_url=False を追加し、規模が合う実在企業を集めてからHPを別途特定。歩留まりが改善し実機で『規模確定+メアド付き』の追加に成功。★それでも volume は控えめ=(a)gBizINFOの従業員数データがそもそも疎、(b)中堅/大手はフォーム式でメアド非公開。→『規模を確定した質の高い少数リスト』の位置づけ。大量収集は通常のAI収集+Phase1の会社規模フィルタが現実的。
v0.99.13 2026-06-14
💼 エンタープライズお問い合わせ(=導入検討のお客様用)に営業ピッチが混ざる問題に対処。営業・協業・取引のご提案の方向けの別窓口ページ /enterprise/sales(enterprise.sales_proposal)を追加=件名ヒント付きメール窓口(VENDOR_CONTACT_EMAIL、既定 info@nudge-hq.co.jp)に誘導+返信非保証を明記。enterprise_contact.html 上部に『💼 営業・ご提案の方はこちら →』バナーを追加して誘導。検証:両ページ200・導線リンク・メール表示を確認。
v0.99.12 2026-06-14
🤖 Resend Webhook でメール不達を検知し、事前登録者(PreRegistration)を自動でボット/偽メアドフラグ。新 resend_webhook_module:POST /resend/webhook(email.bounced/failed/complained を受信→該当メアドの PreRegistration.bounced=True+bounced_at)。Svix署名検証(RESEND_WEBHOOK_SECRET=whsec_…があれば検証、無ければ素通し。検証はHMAC-SHA256で実装)。メンテ中も受信できるよう /resend/ を許可リストに追加。PreRegistration に bounced/bounced_at 追加(ALTER自動マイグレーション)。admin『事前登録管理』に『🚫不達』件数カード+各行に不達バッジ。用途=サービス開始メール一斉送信後、届かなかった=架空の登録者(ボット)を自動で炙り出す。検証:bounce→フラグ、delivered→無視、Svix正署名→通過・改竄→400 を test 確認。
v0.99.11 2026-06-14
✉️ 事前登録管理『サービス開始メール一斉送信』の送信元表示バグを修正。テンプレが config.get('SYSTEM_FROM_EMAIL', 'noreply@social-cynthia.com') と書かれており、Flask config に同変数は無いため**実値でなく固定の noreply@social-cynthia.com を表示していた**(実際の送信元は resend_module._from_address=環境変数 SYSTEM_FROM_EMAIL)。admin ルートから system_from_email(os.environ の実値・既定 noreply@nudge-hq.co.jp)を渡して表示するよう修正。あわせて admin 案内文と .env.example の例を noreply@nudge-hq.co.jp(Resend認証済みドメイン)に統一。★実送信元は Resend が認証済みの nudge-hq.co.jp 由来(social-cynthia.com 未認証なら送信自体が失敗するため)。
v0.99.10 2026-06-14
🔑 抜けていた『パスワードリセット』『メールアドレス変更』を追加(ローンチ前の必須機能)。(1)パスワードリセット:/auth/forgot(メアド入力→再設定リンクをメール送信、**存在は明かさない=列挙対策**)→/auth/reset/<token>(60分有効・新パス設定+ロックアウト解除)。ログイン画面に『パスワードをお忘れですか?』リンク。(2)メアド変更:/auth/change_email(ログイン+現パス確認→新メアドに確認リンク)→/auth/confirm_email_change/<token>(24時間有効・新メアド側のクリックで確定=乗っ取り防止。確定時 email_verified=True、重複は最終再チェック)。設定ドロップダウンに『メールアドレス変更』。Userに password_reset_token/sent_at・pending_email・email_change_token/sent_at 追加(ALTER自動マイグレーション)。メールは Resend(既存 send_email)。検証:リセット(有効/無効トークン・パス変更・ロック解除)・メアド変更確定・各画面200 を test 確認。
v0.99.9 2026-06-14
🖱️ ナビの設定ドロップダウン(.nav-dropdown-menu)が項目数の多いユーザー(admin=テスター管理/事前登録/資料請求/エンタープライズ/アナリティクス/不具合報告/代理店承認…)で縦に伸びすぎて画面外に見切れる問題を修正。desktop:max-height: calc(100vh - 80px)+overflow-y:auto+overscroll-behavior:contain でビューポート内に収めてスクロール。mobile:ナビ自体がスクロールするため二重スクロール防止で max-height:none/overflow:visible に解除。
v0.99.8 2026-06-14
⏰ LP(landing.html)の正式リリースカウントダウンの target を 2026-06-15 0:00 → **2026-06-15 09:00 JST** に変更。『0:00スタートのサービスはない』ため実サービス開始時刻に合わせた。あわせて `+09:00` を明示してタイムゾーン固定(旧:オフセット無し=閲覧者ローカル時刻基準 → 新:全閲覧者が同一の実開始瞬間=9:00JSTをカウント)。
v0.99.7 2026-06-14
🏢 gBizINFO Phase2(収集ソース化)。AI収集とは別に、経産省の公式法人データから『規模を確定した実在企業』を収集。フロー=gBizINFO検索(name=業種キーワード+prefecture)→法人番号→詳細で従業員数/HP→**会社規模で絞る**→HPを `_process_one_site` で巡回してメール取得→リスト追加(unitは実追加数のみ消費)。gbizinfo_module:prefecture_code(都道府県名→コード)+search_with_size(検索→詳細→規模フィルタ、HP保有企業のみ)。auto_list_module:_gbiz_collect_worker+POST /auto-list/gbiz(check_quota→BulkJob→スレッド→既存のジョブポーリングUI流用)。auto_list.html:『gBizINFOから収集(会社規模で絞る)』フォーム(業種キーワード/エリア/規模チェック/件数)+JSをwireCollectForm に共通化して両フォームで進捗ポーリング共有。GBIZINFO_API_TOKEN 未設定ならフォーム非表示。★実地の歩留まり=gBizINFOはHP登録が少なめ(サンプル約5%)=『少数精鋭・規模確定の質リスト』の位置づけ(UIに明記)。検証:実APIで E2E(リフォーム×東京→長谷工リフォーム644名をHP巡回でメール取得・追加・1unit消費)成功。
v0.99.6 2026-06-14
🏢 一覧の会社規模バッジ:従業員数が無い会社でも、**gBizINFO照会済み(gbiz_checked_at あり)なら『🏢規模不明』**を表示。未照会(AI分析していない)会社には出さない=『不明』と『未取得』を区別。list_detail.html の詳細列。
v0.99.5 2026-06-14
🏢 gBizINFO Phase1 実装(会社規模の付与+フィルタ)。(1)gbizinfo_module.enrich_contact_size:会社名+エリアで照会し従業員数/資本金/法人番号を Contact に付与、HP未設定なら company_url で補完。GBIZINFO_API_TOKEN 未設定なら no-op。(2)AI分析に配線:個別(enrich_contact)+一括(_full_prep_worker)の両方で、URL補完→メモ→予算判定の後に規模付与。(3)検索条件に『🏢会社規模(従業員数)』追加=〜10/11〜50/51〜300/301名〜/規模不明(list_module FILTER_KEYS+apply_filter_to_query、employee_count バケット)。フィルタフォーム+一覧の詳細列に 🏢従業員N名 バッジ。ライブ検証:トヨタ83,533名付与・micro/mid/large/unknown の絞り込みが正しく動作。★規模はgBizINFO公式値(捏造なし)。カバレッジ穴は『規模不明』として残す。次は Phase2=収集ソース化。
v0.99.4 2026-06-14
🏢 gBizINFO 連携をローカルで**ライブ検証**し、モジュールを実仕様に合わせて修正。実APIで判明=**検索(?name=)は最小項目のみ(従業員数なし)、詳細(/hojin/{法人番号})にフルデータ**。そこで lookup_company を**2段階フロー**化(名前検索→法人番号特定→詳細取得→従業員数/資本金/HP抽出)。名寄せは『正規化完全一致>都道府県一致>単独結果、曖昧は誤付与回避でNone』。実フィールド名 employee_number/capital_stock/company_url を確定。検証:トヨタ83,533・メルカリ2,101・ファストリテ1,801 を取得、ソフトバンクは従業員データ欠落=unknown(gBizのカバレッジ穴を実地確認)。★まだ未配線(土台のみ・ローンチ無影響)。次は Phase1=AI分析での規模付与+会社規模フィルタ。
v0.99.3 2026-06-14
🏢 gBizINFO(経産省の公式法人データ)連携の土台を追加。会社規模(従業員数)を検索条件にしたいニーズに対応。規模はAI推測だと捏造リスク(§2)なので gBizINFO の公式値を使う方針。(1)新モジュール gbizinfo_module(lookup_company:会社名→従業員数/資本金/法人番号/HP、認証ヘッダ X-hojinInfo-api-token、GET /hojin/v1/hojin?name=。**GBIZINFO_API_TOKEN 未設定なら全 no-op**=既存フロー無影響。レスポンスのフィールド名揺れに防御的な複数キー抽出。SIZE_BUCKETS で 〜10/11〜50/51〜300/301〜 に分類)。(2)Contact に employee_count/capital_stock/hojin_number/gbiz_checked_at を追加(ALTER自動マイグレーション)。★現状は土台のみ(どこからも呼んでいない=ローンチ無影響)。トークン発行後に『AI分析での規模付与+会社規模フィルタ』(Phase1)と『gBizINFO検索を収集ソース化=業種+エリア+規模で実在法人リスト→既存メール探索』(Phase2=目玉)を実装。検証:no-token時None、代表レスポンスの抽出/サイズ分類/数値パースを test 確認。★トークンは申請制(info.gbiz.go.jp/hojin/api_registration/form、無料)=即時とは限らないので先に申請が必要。
v0.99.2 2026-06-14
🎨 ダッシュボード『業種別 送信内訳』ドーナツの配色を修正。パレットの先頭2色が両方 #7c3aed(同じ紫)で、TOP2業種が同色になり見分けられなかった。色相を散らした10色(紫/シアン/アンバー/緑/ピンク/青/赤/ティール/藤/ライム)に差し替え。未使用だった brand.secondary もシアンに(dead value 整理)。データ・ロジックは変更なし。
v0.99.1 2026-06-14
🎟️ 解約後の扱いを『本人のユニットを期限内に消さない』方針へ調整。(1)データ削除を **30→60日** に(CANCEL_DATA_RETENTION_DAYS=60)。ユニット最長寿命=60日(繰り越し)に合わせる=最後の付与は必ず free 化以前なので、free から60日後には全ユニットが自然失効済み。(2)v0.99 で入れた『purge時にユニット強制削除』を撤回。**期限切れの空ロットだけ掃除**し、万一有効なユニットがあっても消さない(_purge_learning_data、有効ユニットは本人の権利)。(3)ダッシュボードの再契約カードを分離表示:『残りユニットN・あとX日(=各ロットの自然失効日)で失効』+『AI学習データは解約60日後に削除』。(4)解約中(free)はトップアップ購入をブロック(使えないユニットを買わせない=先に再開を案内、billing._is_free_user)。★背景:付与がカレンダー月基準で請求日と非連動なため、稀に繰り越しユニットが free+30 を超えて有効なケースがあり得た。保持を60日にして自然失効に任せることで、有効ユニットの強制削除を完全に回避。検証:有効購入ロット800が purge後も維持・期限切れ空ロットのみ削除・topupブロック・ダッシュボード2行表示 を test で確認。
v0.99.0 2026-06-14
🔒 解約後(Freeプラン)の扱いを整備。(1)Freeは**閲覧のみ**=状態変更(非GET)を全ロック(app.before_request _enforce_free_readonly、GET閲覧/billing・auth・account・legal・track・admin は许可。AJAXは403+メッセージ、フォームは /billing/pricing へ)。自動送信・追いメールもスケジューラでスキップ(予約は残し再開後に送信)。オンボーディング対象外。(2)バグ修正:get_plan が free を trial にフォールバックするため、解約ユーザーがダッシュボードを開くとトライアル枠(100/200)を新規付与されていた → usage_module で free を明示判定(ensure_grants/_period_grant/get_trial_remaining が free を除外、残ロットのみ表示)。(3)データ削除を **10日→解約30日後** に統一(CANCEL_DATA_RETENTION_DAYS=30)。30日経過時に AI学習データ(SentEmail/ReplyMessage)に加えて**残ユニット(UnitLot)も削除**=クリーンな区切り(_purge_learning_data)。(4)ダッシュボードに再契約フックカード:『解約中(閲覧のみ)/残りユニットN・あとX日で失効/プランを再開する』(dashboard_module free_state、cancel+30 を期限に)。検証:free=閲覧200・POST302ブロック・新規付与なし・trial_remaining None・purgeでロット0・再契約カード描画 を test で確認。
v0.98.0 2026-06-14
⚡ ユニットの買い切りトップアップを追加(『今月だけ巻き返したい』向け)。一時アップグレードや差額計算よりシンプルで、年間プランでもそのまま使える方式を採用。(1)固定3パック(+1,000=¥49,000 / +3,000=¥147,000 / +6,000=¥294,000、~¥49/ユニット=月額単価基準、billing_module.UNIT_PACKS)。(2)Stripe 一回払い Checkout(mode='payment'・price_data でその場価格)。/billing/topup(ページ)→ /billing/topup/checkout(POST)。(3)入金で UnitLot 付与=source='purchase'・有効30日(PURCHASE_EXPIRY_DAYS)。付与は success コールバックと checkout.session.completed webhook の両方から(usage_module.grant_purchase)。**冪等性は period_key='topup:<session_id>' の UNIQUE 制約**で担保=二重付与なし。(4)消費はFIFO(失効が近いものから)なので購入分・繰り越し分も自然に消化。(5)ダッシュボードの残高カードに『プランをアップグレード(恒久)/ ユニットを追加購入(今月だけ)』の2導線。検証:grant_purchase の付与・冪等(同keyで二重付与なし)・30日失効、topupページ/ダッシュボード描画、プレビュー実機でログイン→購入ページ表示まで確認。★Stripe 本番では checkout.session.completed を Webhook 送信対象に含めること。
v0.97.0 2026-06-14
🎟️ ユニットを『付与ロット台帳(UnitLot)』モデルに刷新=消費期限+繰り越し+FIFO消費。(1)有料プランは毎月 unit 数を付与し、付与から60日(ROLLOVER_DAYS)で失効=未使用は最大2ヶ月繰り越し。トライアルは累計上限を1ロットで付与し14日(TRIAL_DAYS)で失効。(2)消費は失効が近い(古い)ロットから=FIFO。(3)残高=未失効ロットの remaining 合計。usage_module を全面ロット化(ensure_grants/get_balance/_active_lots 追加、check_quota/consume_quota/refund_unit/get_remaining/get_trial_remaining/get_usage_summary/activate_contact_for_unit を関数シグネチャ維持のまま中身入れ替え=呼び出し側は無改修)。(4)refund_unit は返却ロットを作る方式に変更したため、v0.96.7 のバウンス返却の『送信と別月だと目減り』問題が解消(正確に1ユニット返る)。(5)新テーブル unit_lots は create_all で自動作成+既存ユーザーへ現残高を引き継ぐ初期ロットを app の移行で1回付与(旧 UsageCounter から算出・冪等)。(6)ダッシュボードを『ユニット残高』表示に更新(繰り越し説明+直近失効日を表示)。検証:付与/FIFO/失効除外/60日・14日/冪等/返却/消費/移行(残高引継ぎ)/ダッシュボード描画 を test で確認。
v0.96.7 2026-06-14
♻️ バウンス(不達)でユニット返却。IMAPのバウンス検知(imap_module、status='bounced'確定箇所)で unit_consumed のコンタクトに対し refund_unit で1ユニット返却(status遷移ガードにより1コンタクト1回)。送信時の mark_bounced(send_module・送信エラー全般=自分側不調も含む)では返却しない(確実な不達のみ対象)。全バウンス区分(not_found/rejected/other)を返却対象=『1送信1ユニット消費、届かなければ返す』方針。★制約:refund_unit は当月の UsageCounter を減算する設計のため、送信と別月にバウンス検知された分は当月カウンタが足りず返却が目減りし得る(バウンスは通常即時~同日なので大半は同月で返却される)。この月跨ぎの精度問題はユニットのロット化(消費期限)を入れる際に根本解決する想定。
v0.96.6 2026-06-14
📈 リスト自動収集(/auto-list)画面の冒頭に到達率Noticeを追加。前向きな見出し『より高い到達率をお求めのお客さまへ』で、(1)自動収集はあくまで新規開拓の補助機能で集めたてのメアドはバウンスが一定数含まれること、(2)最も到達率が高いのはお客さま自身がお持ちの営業リスト(CSV/Excel取込・手動追加)であること、(3)自動収集を使う場合も送信前に『🧹 リスト検証・クリーンアップ』で到達率を高められる(除外分はユニット返却)ことを案内。バウンス率15%の壁=自動収集リストの限界に対し『法人営業なら自前リストがあるはず』のスタンスをネガティブにならず前向きに提示。具体的なバウンス率の数値はUIに出さない(社内指標のため)。ブランド紫の情報カード。
v0.96.5 2026-06-14
📝 LP FAQ(メール送信)の再修正。v0.96.4で『どんな送受信できるメールでもOK(Xserver/さくら含む)』と薄めすぎたのを撤回。実態=Nudge HQ は中央サーバーから一斉送信せず『各ユーザー自身のビジネスメール(独自ドメイン)から1通ずつ送信』する(v0.47のSendGrid審査落ち→自前メール接続モデルの理由そのもの)。共用クラウド/レンタルサーバーメールや無料メールは営業送信がブロック・制限されやすいため、Google Workspace / Microsoft 365 など『自分のドメインで送信できるビジネスメール』を推奨、とFAQを修正。アプリパスワードで連携・暗号化保管の点は維持。★営業送信の前提=§5の自前ビジネスメールSMTP(Google Workspace/M365)。Xserver/さくらはIMAP受信対応だが送信主体としては非推奨。
v0.96.4 2026-06-14
📝 LP(landing.html)のFAQ『メール送信用のサーバーは自分で用意するんですか?』を実態に合わせて言い換え。『サーバー構築は不要、普段お使いのビジネスメール(メールアカウント)=送受信できるメールアドレスが1つあればOK』に。Google Workspace 必須という誤解を避けるため『Google Workspaceでなくても独自ドメインのメールボックスがあれば可』を明記+Microsoft 365 を例に追加。回答冒頭の『はい』(質問と噛み合わず誤解を招く)を『いいえ、構築は不要です』に修正。
v0.96.3 2026-06-14
✉️ 問い合わせメアドの整理+エンタープライズ問い合わせの受信改善。(1)サービス(Nudge HQ)向けの問い合わせ案内を info@social-cynthia.com → **info@nudge-hq.co.jp** に統一:お問い合わせページ/利用停止画面/メンテ画面+認証・請求・資料・オンボ・テスター作成の各メール文面。会社(株式会社Cynthia)の法的窓口は据え置き=**特定商取引法表記・利用規約(サービスクレジット請求窓口)は info@social-cynthia.com のまま**。(2)エンタープライズお問い合わせフォーム:従来は DB保存+print ログのみで**通知が飛ばず気づけなかった**問題を修正。送信時に通知先(`ENTERPRISE_INQUIRY_EMAIL` > ADMIN_EMAILS)へ Resend でメール通知(enterprise_module._notify_inquiry、保存は成功優先)+admin『エンタープライズ問い合わせ』一覧(/admin/enterprise-inquiries、新規/対応中/完了の状況をボタンで前進、未完了バッジ)。設定ドロップダウンに導線追加。検証:8ファイルの置換をgrepで分割確認、test_clientでフォーム送信→保存→admin表示→状況前進+通知先解決を確認。★info@nudge-hq.co.jp が実際に受信できる状態か(Xserver MX)を切替前にテスト受信で確認すること。
v0.96.2 2026-06-14
📥 LP資料請求で集めたメールアドレスをアプリ内でリスト化(案B)。従来は leads_module が Supabase の leads テーブルにのみ保存し、アプリから見られなかった。(1)新テーブル Lead(ローカルDB、create_allで自動作成)=email/source/utm_source/count/created_at/last_at、UNIQUE(email,source) で同一メアドは1行に集約(count+last_at更新)。資料請求は本人同意の first-party データ。(2)leads_module.save_lead_local を document() にフック(Supabase保存はそのまま併用)。流入元は session の inflow_src(v0.94)も記録。(3)admin『資料請求リスト』/admin/leads(一覧+ユニーク件数+『CSVをダウンロード』=BOM付きUTF-8でExcel文字化け無し)。設定ドロップダウンに導線追加。CSVはそのまま『リスト取込(CSVアップロード)』で営業リスト化できる。検証:test_client で資料請求2回(集約count=2)+別メアド→ローカル2行、admin一覧200、CSV出力200/ヘッダ/BOM を確認。★配布PDF /assets/nudge-hq-guide.pdf はまだプレースホルダ=launch前に static/assets/ へ実ファイル設置が必要。
v0.96.1 2026-06-14
💰 LP料金セクションの2枚目カードを『Light以外完全非表示』に。上位プラン名(Standard/Pro/Enterprise)やユニット数の言及を削除し、純粋な資料請求カード(『もっと詳しく知りたい方へ』→資料を無料DL)に変更。狙い=価格の比較検討で離脱させず、資料請求でメールアドレスを取得してリード化する。※資料DLのメアドは leads_module で Supabase の leads テーブル(source=document_download)に保存される(既存)。アプリ内で一覧・エクスポートする画面は未実装(必要なら /admin/leads を別途追加)。
v0.96.0 2026-06-14
💰 LP(landing.html)の料金セクションを刷新。(1)2大コスト優位を大きく訴求=『初期費用 0円』『ユーザー追加 0円』のバッジ(紫の特大0)。後者は席課金なし=1契約で人数無制限・追加料金0(v0.58オペレーター機能の差別化を明文化)。(2)価格表示はLightプランのみに集約(¥98,000/月+特典チェックリスト)。Standard/Pro/Enterpriseの価格は出さず、『もっと大規模に使う』カード→資料ダウンロード(data-doc-open)へ誘導=高単価帯はリード獲得&個別提案に回す。(3)FAQに『初期費用や人数による追加料金は?→どちらも0円』を追加。CSS:.lp-cost-badges/.lp-cost-zero/.lp-pricing-duo(2カード中央寄せ)/.lp-plan-points/.lp-plan-more を追加。★/pricing(特商法・購入フロー)の各プラン価格は法令順守のため従来どおり全表示で維持(LPはマーケ面のみ絞り込み)。検証:プレビューで desktop(1100px)=2バッジ+Light/資料カード等幅、mobile(375px)=縦積み・横溢れなし・¥298,000/¥498,000非表示を確認。
v0.95.1 2026-06-14
🐞 不具合報告の通知先を専用アドレスにできるように。環境変数 BUG_REPORT_EMAIL(カンマ区切り可)を設定するとそこへ送信、未設定なら従来どおり ADMIN_EMAILS へフォールバック(error_report_module._report_recipients)。Google Workspace のバグ対応エイリアス(例 bugs@social-cynthia.com)に振り分ける用途。★ADMIN_EMAILS は admin 権限判定に使うため、バグ送信先はそこに足さず BUG_REPORT_EMAIL を使う。
v0.95.0 2026-06-14
🐞 不具合報告機能(PSのクラッシュ報告風)。サービス開始当日のエラーを取りこぼさないため。(1)画面右下に常時『不具合を報告』フローティングボタン(ログイン中の全画面・embedとLPは除外、base.html)。(2)押すとモーダル=『エラーが出た経緯(任意・空欄OK)』のテキスト欄+『報告を送信』ワンクリック。ページURL・端末(UA)・JSエラー内容・アプリバージョンは自動添付(個人情報なし)。(3)JSエラー(window.onerror/unhandledrejection)を検知したら画面下にそっと通知が出て『報告する』で同モーダルへ(クラッシュ自動検知)。(4)エラー画面(error.html)にも『このエラーを報告する』ボタン(window.openErrorReport を公開)。バックエンド:新テーブル error_reports(create_allで自動作成・ALTER不要)+ error_report_module.py の POST /report-error(login必須・JSON)。保存と同時に ADMIN_EMAILS へ Resend でメール通知(失敗しても保存は成功)。admin『不具合報告』一覧(/admin/error-reports、設定ドロップダウン+未対応バッジ+対応済みトグル+JSエラー折りたたみ)。検証:test_client で POST→保存→admin表示→トグル、さらにプレビュー実機でログイン→FABクリック→モーダル→送信→完了表示→DB保存(url/version自動取得)まで一気通貫で確認。
v0.94.2 2026-06-14
🎨 LP(landing.html)ヒーローの可読性を3点修正。(1)見出し『営業の工数を、9割削減。』の読点を削除=2行(モバイル)でも1行でも自然に。(2)サブ文がモバイルで語句の途中(例『あなたは価値ある仕事に|集中できます。』)で折り返し可読性が低かったのを、`.lp-hero-sub` に word-break:keep-all+語句境界に <wbr> を置いて『折り返してよい位置でのみ改行』に。PC用の文区切り <br class=lp-br-pc> は ≤640px で display:none にして <wbr> に任せる(PCは従来の文単位2行を維持)。(3)セカンダリCTA『資料をダウンロード』(button)と『導入相談を予約』(a)のサイズ差を解消=`.lp-sub-col` を flex:1/max-width:240px で等幅列にし、`.lp-cta-sub` を display:block/width:100%/box-sizing:border-box/text-align:center/font-family:inherit/line-height:1.4 で button と a を同サイズに統一。検証:プレビューで mobile(375px)=サブ文が語句単位で改行・ボタン縦積み等幅、横並び(1000px)=両ボタン 240×50 で完全一致を確認。
v0.94.1 2026-06-14
🛡️ 事前登録フォームのスパム/ボット投稿対策。外部サービス(reCAPTCHA等)もキーも不要、人間には無摩擦。(1)ハニーポット:画面外に隠した囮の website 欄。人間は触らないが多くのボットは全欄を埋めるため、値が入っていたらボットと判定し、保存せず完了画面へ“静かに”流す(ボットに対策を学習させない)。(2)タイムトラップ:フォーム表示時刻をセッションに記録し、表示から MIN_FILL_SECONDS(2秒)未満での送信はボットとみなす。人間が万一誤爆しても困らないよう、静かな失敗にはせず『送信が早すぎました』で再入力を促す(再送に備えて測り直す)。クッキー無し(ts無し)の人間はハニーポットが空なら通す=誤ブロック回避。背景=プリローンチで15件の事前登録のうち海外フリーメール(qq.com等)が混じり、流入経路も全て『直接/不明』で自動投稿が疑われたため。検証:test_client でハニーポット→302未保存/即送信→400未保存/正常→保存/ts無し→保存 の4経路を確認。★スパムが続くなら次段で Cloudflare Turnstile(無料・キー必要)を検討。
v0.94.0 2026-06-14
🔎 事前登録者の流入経路(流入元)を admin で遡って確認できるように。背景=従来の PreRegistration.source は /pre-register の ?utm_source を送信時に読むだけだが、LP の CTA が utm を引き継がず遷移していたため、ほぼ全員 source='direct' になり流入元が分からなかった。(1)遡及表示:訪問計測ログ SiteVisit には utm だけでなく referrer(HTTP Referer=prtimes.jp 等の外部流入元)も記録済みなので、admin『事前登録管理』に〔リファラ別/utm_source別〕の実測内訳カードを追加(PR TIMES / X・Twitter /Google検索 等に自動ラベル化、analytics_module.classify_referrer)。utm 未タグでも外部ドメインから流入元を遡れる。(2)各登録者に『推定流入元』列:新カラムを持つ新規登録者は確実、既存登録者は pre_register 訪問ログを登録時刻でタイムスタンプ突合して推定(±30分。⚠registered_at=UTC と SiteVisit.created_at=JST の9時間差を+9hで補正)、推定にはその旨を明示。(3)今後の取得を改善:LP→登録ページ遷移で utm を引き継ぎ(landing.html CTA)+初回の外部リファラと utm をセッション保持(app.before_request _capture_inflow)し、送信時に新カラムPreRegistration.referrer と source へ記録(以後は遡及に頼らず確実に判定)。models 1カラム追加+ALTER 自動マイグレーション。検証:test_client で admin 画面が 200+リファラ実測(PR TIMES/X)+ログ突合推定が描画されることを確認。★宣伝リンクに ?utm_source=xxx を付けると最も確実(画面にも案内表示)。
v0.93.2 2026-06-13
📊 ダッシュボードの3グラフ(日別トレンド/ファネル/業種内訳)が空白になる不具合を修正。原因=dashboard.html の描画スクリプトを即時実行関数 (function(){...})() で囲っていたため、base.html の末尾で読み込まれる Chart.js 本体より先に実行され、new Chart の時点で Chart が未定義になっていた。対策=即時実行を document.addEventListener('DOMContentLoaded', function(){...}) に変更し、DOM+スクリプト(Chart.js含む)の読み込み完了後に描画するようにした。★教訓:外部ライブラリに依存する描画は DOMContentLoaded を待つ(スクリプトの記述順より後に本体が読み込まれる構成では IIFE 即時実行は早すぎる)。
v0.93.1 2026-06-12
📱 モバイルの設定ドロップダウンが展開時に消える不具合を修正。原因=ベース .nav の flex-wrap:wrap をモバイルの縦並び(flex-direction:column)で打ち消しておらず、設定展開で高さが max-height を超えると『2列目』に折り返し、設定とログアウトが画面右外(overflow-x:hidden の外)へ出てタップ不能になっていた。対策=モバイルの .nav に flex-wrap:nowrap を明示+各項目に flex-shrink:0(縦1列を維持し溢れはoverflow-y:auto でメニュー内スクロール)。検証:実機サイズ(375px)で全ナビ項目+設定メニュー全項目がx=14 の縦1列に揃い横はみ出しが無いことを確認。★教訓:flex-direction を切り替えるメディアクエリでは flex-wrap も必ずセットで上書きする。
v0.93.0 2026-06-12
↩️ 受信トレイから直接返信(一気通貫の完成)。各行の『↩ 返信』ボタン→ /inbox/<id>/respond で受信本文+過去の自分の返信を見ながら本文を書いて送信(確認モーダル=送信は必ず人間)。設計:(1)送信はユーザー自身のビジネスメールSMTP(送信窓口と同一。Google Workspace は送信済みフォルダにも自動保存)。(2)IMAP取込時に保存済みの Message-ID を In-Reply-To/References ヘッダに入れて相手側のスレッドに繋げる(smtp_module.send_via_smtp に extra_headers 引数を追加・後方互換)。件名は Re: 自動付与(二重付与なし)。(3)1対1の会話なのでトラッキング・配信停止リンクは付けない/ユニット消費なし/AI学習にも混ぜない=新テーブル sent_replies(SentReply)に記録(SentEmail と分離して統計を汚さない。create_all で自動作成)。(4)署名はSMTP設定から自動付与。送信後は対応済みに自動更新、トレイの『本文を見る(↩返信済みN件)』に会話履歴表示。(5)自動返信(送信専用)行には返信ボタンを出さない。検証:ローカル擬似SMTPで実送信E2E(Re:件名/In-Reply-To/署名/会話履歴/対応済み化を確認)。
v0.92.2 2026-06-12
📥 受信トレイの自動返信まわり2件。(1)自動返信(不在通知/受付確認/送信専用案内)は既定で非表示に。フィルタ行の『🤖自動返信も表示(N件)』チェックで表示切替(?auto=1)。0件表示時も非表示件数を案内。未対応カウントは元々自動返信除外(v0.68)なので変更なし。(2)自動返信行にも『配信停止』ボタンを表示(従来は非表示で打つ手がなかった)。オフィスステーションのような『送信専用メール・お問い合わせはフォームから』型=メールが人間に読まれない相手を、本文を読んだ人間の判断で1クリック除外(force_unsubscribe=以後の送信・追いメール・再営業から完全除外)するため。確認モーダルに用途説明を追記。★『送信専用』キーワードでの自動停止は不採用:受付確認メール(実はinfo@は読まれている)にも同じ文言があり、見込みのあるシーケンスを誤停止するリスクがあるため(v0.68の『自動返信は何にも影響させない』原則を維持、人間判断のみ)。
v0.92.1 2026-06-12
📨 配信停止希望の誤検知を修正。営業メール末尾の自動フッター『このメールの配信停止はこちら』が、相手の通常返信の引用部分に含まれてキーワード判定に誤反応し、丁寧なお断り返信が unsubscribed 扱いになる事故が実際に発生(ビズリーチからの返信で顕在化。前向きな返信でも引用があれば配信停止扱いになる構造的リスクだった)。対策=utils.strip_quoted_reply_text:引用の区切り(自社フッター/-----Original Message-----/On...wrote:/Gmail日本語引用ヘッダ/差出人: 等)以降と『>』行を除去し、相手自身が書いた部分だけで is_unsubscribe_request を判定。適用箇所=imap_module の受信検知+inbox_module の手動登録(件名判定は従来通り)。相手本人が本文に書いた『配信停止してください』『連絡不要』等は従来通り検知(検知力は不変・誤検知のみ削減)。なお返信はどのみち stop_sequence+再営業除外なので、見逃しても自動送信が続く事故にはならない設計。
v0.92.0 2026-06-12
🤝 企業間マッチング(将来機能)のDB土台+Coming Soon予告カード。本体(候補表示・突合・入力フォーム)は意図的に未実装。(1)新テーブル2つ(create_all で自動作成・ALTER不要):matching_profiles(uuid PK・company_id→users・selling/価格帯/課金形態/buying/予算帯/業種/相手業種/規模・visibility 既定False=非公開・created/updated_at。読み書きUIなし)、interest_flags(uuid PK・company_id→users・feature_name 既定'matching'・UNIQUE(company_id,feature_name) で二重登録防止)。業務データ(リスト/メール等)とは users へのFK以外で独立。SQLiteにRLSは無いため行分離はアプリ層で current_user.account_id スコープを強制(§10 #35 と同方式)。(2)matching_module.py:POST /matching/interest(login_required・冪等・has_interest ヘルパー)。(3)dashboard.html 最下部に控えめな予告カード(ブランド紫#7B2FBE 2px枠・白背景・角丸12px・セカンダリボタン『興味あり・通知を受け取る』→登録後『✓ご登録ありがとうございます』、登録済みユーザーは最初から登録済み表示、二重送信はボタン無効化+ユニーク制約の両面防止、スマホは余白調整のみで崩れない単純ブロック構造)。機能名 Nudging・リリース時期は表記しない(仕様)。
v0.91.1 2026-06-12
🚀 6/15ローンチ前点検で見つかった4件を修正。(1)資料PDFが assets/nudge-hq-guide.pdf.pdf(二重拡張子)で commit されており、LPの資料DLリンク(/assets/nudge-hq-guide.pdf)が本番404だったのをリネームで修正(Windowsの拡張子非表示による差し替えミス)。(2)pre_register_module.is_pre_launch_period/is_promo_period が date.today()(サーバーUTC)判定だったため、6/15 0:00〜9:00 JST にLPが事前登録モードのまま残る問題を now_jst() 化で修正。(3)ダッシュボード日別トレンドの『今日』とキャラクターの『今日の送信件数』『最終送信からの日数』が UTC 判定で、0:00〜9:00 JST に当日分が見えない問題を now_jst() 化で修正(sent_at は JST naive 保存のため)。(4)事前登録者への一斉送信ループに 0.6秒/件 のウェイトを追加(Resend レート制限 約2req/s 対策。失敗分は launch_notified_at が付かないのでボタン再実行で未通知分のみ再送可能)。
v0.91.0 2026-06-12
🖱 (#7)メール本文のリンク別クリック計測。従来は SentEmail.clicked(初回のみ・boolean)でしか分からなかったのを、新 LinkClick テーブル(user_id/sent_email_id/url/industry/clicked_at)にクリックのたび1行記録(tracking_module.track_click)。admin /admin/link-clicks でURL別に集計(クリック数・クリックされたメール数・最終クリック、期間7/30/90/全)。テスター管理ヘッダに導線。create_all で自動テーブル作成(ALTER不要)。検証:同一/別リンクのクリックが正しくURL別カウントされることを確認。★これで今回の要望9件(#1〜#9)すべて完了。
v0.90.0 2026-06-12
📊 表示系の改善2件。(#6 ダッシュボード)成功の定義が人により違う(返信/クリック)ため、返信率上位TOP10を廃し『返信率TOP3/開封率TOP3/クリック率TOP3』を指標別に並べて表示(is_initial=True=初回メールのみで集計しRe:ノイズ除外)。日別トレンドにクリックの線を追加(送信/開封/クリック/返信)、『日ごとの数値を表で見る』テーブル(日付・送信・開封・クリック・返信+各率、送信のある日のみ)を追加。dashboard_module+dashboard.html。(#5 送信ワークにスマートリスト)送信ワーク(send.work)にスマートリスト(ContactList)選択ドロップダウンを追加し、選んだ保存フィルタで一覧+タブ件数を絞る(apply_filter_to_query を流用、タブ/リセットでも list_id 維持)。★#2連携:list_id を compose(iframe)→送信/予約フォーム→next_contact/prev_contact まで引き継ぎ、『次/前の未送信コンタクト』も選択中のスマートリスト内で辿れるように(apply_smartlist_filter 追加)。検証:3テンプレートparse、スマートリストフィルタが業種で正しく絞れることを確認。
v0.89.0 2026-06-12
✉️ メール作成のUX改善2件。(#1 件名別案プルダウン)従来は別案をflashで一瞬表示して消えていた→Contact.draft_subject_alt に保存し、compose の件名欄下にプルダウン(案1=現在/案2=別案)を表示。選ぶと件名欄に反映+hidden(予約/送信フォームのミラー)も更新。生成時にdraft_subject_altへ保存。(#2 送信後に次コンタクトへ)即時送信(send_one)は全リスト(list_bp.pool)に、予約送信(schedule_send)は同じcompose画面に戻っていた→両方とも既存の next_contact ルート(次の未送信コンタクトのcompose・embed維持)へ遷移。compose の送信/予約フォームに embed フラグを引き継ぎ、スライドパネル(iframe)内でも連続作業できる。※next は『未送信』対象だがスマートリストのフィルタは未考慮(それは#5で対応予定)。新カラム draft_subject_alt は app.py で自動マイグレーション。
v0.88.0 2026-06-12
🧠 (#8)新規メールの件名に勝手に『Re:』が付く品質バグを修正。原因=追いメール(件名テンプレが『Re:{{初回件名}}』)が返信/開封の成功例として Few-shot・件名学習に混ざり、AIが新規初回メールでも Re: を真似ていた。対策:SentEmail に is_initial(初回=True/追い=False)を追加。send_followup=False、初回(send_draft_for_contact)・旧テンプレ(execute)=True。生成に効く学習を初回のみに限定:email_module._get_top_emails/learning_module.get_industry_examples_for_compose/get_top_subjects_by_open_rate に is_initial==True を追加。マイグレーション:ALTER sent_emails ADD is_initial DEFAULT 1+既存の Re:/RE:/re: 件名を is_initial=0 にバックフィル(初回コールドは Re: 始まりにならない前提)。検証:初回+追いRe:を両方『返信あり』で投入→Few-shotが初回のみ拾い Re: が混ざらないことを確認。
v0.87.1 2026-06-12
🧹 まとめ修正3件(9件の要望のうち回帰・バグ・整形を優先処理)。(#9 回帰)モバイルのナビ展開で横方向に膨張する問題=v0.87で .nav に overflow-y:auto を付けた副作用で overflow-x も auto になり横スクロールが出ていた。overflow-x:hidden を明示+box-sizing:border-box、ドロップダウン項目を white-space:normal/word-break:break-word/min-width:0 で折り返し。(#4 バグ)compose_contact の『内容を確認しました』(.checkbox.big=padding:12px)と『自動で追いメール送信』(.checkbox=padding:0)の左端ズレを、追いメール側に padding-left:12px を付けて揃えた(ついでに 📨 絵文字も除去)。(#3 整形)LP(landing.html)の絵文字を全廃。課題/機能アイコン(😩📝📉💸🔍✍️📨🧠🛡️📊)を Lucide SVG(34/40px・#7B2FBE)に置換、装飾絵文字(🚀📣🎁✨🧪)は削除。style.css の .lp-pain-icon/.lp-feature-icon を font-size→svgサイズ指定に変更。検証済(本文の絵文字0/SVG描画/横はみ出し無し)。★残り6件(#1件名別案プルダウン/#2送信後に次コンタクト遷移/#5送信ワークにスマートリスト選択/#6ダッシュボード日次+指標別TOP3/#7admin リンク別クリック計測/#8追い・自動返信を学習し件名にRe:)は次以降に順次。
v0.87.0 2026-06-12
📱 モバイルのナビ(ハンバーガー+設定ドロップダウン)のスクロール不具合を修正。原因:.topbar が position:sticky で、モバイルはナビをドキュメント内にインライン縦展開するため、メニューが長い(admin項目8個+設定)と『背後の本体が一番下までスクロールしてからメニューが動く』状態だった。修正:(1)展開中のナビ(.topbar-inner.nav-open .nav)を max-height:calc(100dvh-64px)+overflow-y:auto+overscroll-behavior:contain で『メニュー自体だけが内部スクロール』に。(2)main.js setOpen で body に nav-lock を付け、CSS body.nav-lock{overflow:hidden} で開いている間は背後の本体スクロールをロック(閉じると解除)。これでadmin項目はメニュー内スクロールで到達でき、背後は動かない。あわせてLPの新要素(金CTA/特典バッジ/カウントダウン/セカンダリCTA2つ/資料DLモーダル)のモバイル整形を検証:セカンダリCTAは縦積み・全幅、横スクロールなし、モーダルは画面内に収まる、入力欄16px(iOSズーム防止)を確認。
v0.86.0 2026-06-11
📄 LP(landing.html)に控えめな白セカンダリCTA2つを追加(メインの金CTAは変更なし)。ヒーロー・料金後・最下部に金CTAの下へ配置(スマホは縦積み)。サービス説明後は金CTAのみ。(1)資料DL:『資料をダウンロード』→モーダル(メアドのみ入力=離脱防止)→『資料を受け取る』(金#DEBD72/濃紫#4A1675)→その場でPDFダウンロードリンク表示+同リンクをメール送信(Resend)+完了メッセージ。(2)導入相談:『導入相談を予約』→環境変数 BOOKING_URL(TimeRex等・未設定は#)を新タブで開く。クリックをleadsに記録。新 leads_module.py=Blueprint /lead(document/consult-click)+Supabase leads テーブル保存(id/email/source/created_at・重複許容・best-effort)。PDFは /assets/nudge-hq-guide.pdf(app.pyに /assets/<file> 配信ルート+差し替え用プレースホルダPDFを reportlab で生成)。GA4イベント doc_modal_open / doc_download{method:email} / consult_click を送信(gtag未導入でも安全にno-op)。指定パレット厳守・新色なし。プレビューで色/エンドポイント(資料DL/PDF配信/クリック計測)/モーダル全状態/コンソール無エラーを検証済。★要オペ:Supabaseに leads テーブル作成+Renderに BOOKING_URL 設定+本物PDFを assets/nudge-hq-guide.pdf に差し替え。
v0.85.0 2026-06-11
🎯 LP(landing.html)の歩留まり改善。開封率が上がってきたので訴求とCTAを刷新。(1)ファーストビュー:見出しを『営業の工数を、9割削減。』に、サブを『無駄な移動・事務作業はAIにお任せ。あなたは価値ある仕事に集中』に変更(3秒で価値が伝わる)。(2)金グラデCTAボタン『14日間無料で試す』を新設(background #E3CE7F→#DDBF69/文字#4A1675/box-shadow/hover で#D4AF5A+translateY-2px)。ヒーロー・サービス説明後・料金後・最下部の4箇所に配置。(3)事前登録特典バッジ(金枠#DEBD72/淡金背景#FDF8EF):『🎁事前登録限定 無料トライアルのユニットが 通常100→200ユニット 2倍』。ヒーローと料金後のCTA上に表示(pre_launch_mode時)。200ユニットはブランド紫#7B2FBE・900。(4)バッジに『ライブカウントダウンタイマー(正式リリースまで あと N日 HH:MM:SS/2026-06-15目標・JSで毎秒更新・tabular-numsでジッター無し・0で本日リリース表示に切替)』と『メリット翻訳(=200社にアプローチできます・紫#7B2FBE)』を追加して限定感+価値訴求を強化。max-width 420px。Jinjaマクロ(gold_cta/bonus_badge)で再利用、CTAリンク先は pre_launch→事前登録/公開後→auth.register。指定パレット厳守・新色追加なし・スマホ中央寄せ可変。プレビューで計算済みスタイル・色・レスポンシブ・コンソール無エラーを検証済み。
v0.84.0 2026-06-09
🎟 相手ごとの使い捨て招待コード/URL(DB方式)。env共有コードは『相手ごと』に向かない(数増やせない)ため、DB の InviteCode テーブルで1件ずつ無限発行+使い捨て化。★コールドメール本文に {{招待リンク}}(/{{招待コード}})を入れると、送信時にその送信先専用のURLへ自動置換(invite_module.apply_invite_placeholders、contact紐付けで初回〜追いメールはURL一貫)。バラまかれても used_count>=max_uses(既定1) で無効=『渡した相手だけ』使える→承認の手間なし(DBコード登録は即利用可・承認スキップ)。env共有コード(PARTNER30等)は従来どおりv0.83の承認制のまま。登録:auth.register が lookup_valid_invite→consume_invite(DBコードは即active、envはpending)。送信置換:send_draft_for_contact / _personalize_followup / _personalize / test_send_draft の全送信経路。admin /admin/invites:一覧(コード/URL/対象/使用状況)+手動一括発行(Nudge送信以外で配る用)+無効化。InviteCode テーブルは create_all で自動作成(ALTER不要)。検証済(置換/初回追いURL一貫/使い捨て/無プレースホルダ時未発行/テンプレparse)。
v0.83.0 2026-06-09
🔐 特別招待(?comp= の30日無料)アカウントを『管理者の承認制』に変更=無差別バラまき対策。リンクは誰でも登録できるが、登録した瞬間は『管理者の承認待ち』でロック(ツール使用不可・ログインと案内は可)。admin が承認するまで使えない→承認でロック解除+本人に承認メール。実装:既存の account_status『suspended・suspended_at=None(自動BANなし)』を流用(set_pending_payment と同型の set_pending_approval)。auth.register=comp登録時に set_pending_approval。account.suspended ページは承認待ち専用コピーに分岐(pending_approval)。admin /beta_users 先頭に『承認待ち一覧』+[承認する]/[却下(BAN)]ボタン、account_action に action=approve(reactivate+承認メール+comp30日を承認時点から再起算=待ち時間で無料期間が削れない)。is_pending_approval/get_pending_approval_users 追加。対象は comp自己登録のみ(admin作成テスター・有料登録は従来どおり即利用可)。承認待ちは自動BAN対象外(放置されても消えない)。検証済(承認待ち化/一覧表示/承認→active/隔離ページ分岐/テンプレparse)。
v0.82.0 2026-06-09
🩹 AIメール生成が時々『AI生成に失敗しました』になる問題を根治。Renderログで真因判明=JSONDecodeError(line4=body。本文の未エスケープ引用符『"』や改行でJSONが壊れていた)。API過負荷ではなく出力フォーマットの脆弱性。本文は自由な日本語(「」改行 記号 コロン)が入るのでJSONは不向き。対策:(1)★出力を JSON→マーカー方式(===件名=== / ===件名2=== / ===本文===)に変更=本文に何が入っても壊れない。_parse_email_output がマーカー優先+旧JSONフォールバックで解析。(2)最大3回リトライ+バックオフ(一時的なAPI過負荷529/レート制限429も吸収。2s/4s)。(3)失敗理由を毎回ログ出力([compose_personal] …)。検証:引用符/改行/コロン入り本文がマーカーで正しく解析できることを確認(JSONなら壊れるケース)。max_tokensは2000据置。
v0.81.0 2026-06-09
🔀 追いメールシーケンスの複数対応(二足のわらじ=自社商材/Nudge代理店 等で追いメール群を売り分け)。従来は (user_id, step) 一意でアカウントに1シーケンスのみだった。新 FollowUpSequence(名前付き)+ FollowUpTemplate.sequence_id。★テーブル再作成を避けるため step は『ユーザー内で全シーケンス通し番号』にして UNIQUE(user_id,step) を温存(ローンチ直前にコア送信テーブルを作り直すリスク回避)。スケジューラは『同一 sequence_id 内で step 昇順』で次を引く。ブリーフ連動:PersonalizationBrief.followup_sequence_id を追加し brief_form で選択。メール生成時に Contact.followup_sequence_id へ固定(list_module、resolve_followup_sequence_id)→ 以降の追いはそのシーケンスで送信。send_module:get_user_followup_templates(sequence_id)/_compute_next_followup_at/send_followup を sequence で絞る(step未指定時は『現ステップより後の同シーケンス最初の有効テンプレ』を採用、scheduler の +1 前提を廃止)。email_settings:シーケンス選択タブ+新規作成/名前変更/削除(既定は削除不可・削除時は配下テンプレ削除&参照ブリーフを既定に戻す)。プラン別追いメール上限は『シーケンス単位』で判定(1コンタクト=1シーケンスなので原価はシーケンス長で決まる)。マイグレーション:3カラム自動ALTER+既存テンプレを各ユーザーの『標準シーケンス』へ backfill(挙動不変)。NULL は常に既定にフォールバック=後方互換。検証済(migration適用/ブリーフ連動解決/シーケンス別の追い解決/テンプレparse)。送信画面での明示上書きUIは未実装(連動で代替)。
v0.80.0 2026-06-09
🎁 セルフサービス『特別招待』導線を実装=コールド営業で30日Light無料(カード不要)をバラまく土台。背景:代理店リクルートで、原価が安い30日comp は気前よく配り(Hormozi リスクリバーサル)、価値ある代理店の椅子は絞る、という方針。従来 comp は admin が1件ずつ手動発行でスケールしなかったのを、登録リンクで自動付与に。実装:環境変数 COMP_INVITE_CODES(カンマ区切り)で招待コードを定義。登録リンク ?comp=CODE を app.before_request `_capture_comp_invite` がセッション捕捉→auth.register が有効コードなら plan=light+billing_exempt=True+billing_exempt_until=+COMP_FREE_DAYS(30日)+admin_note='特別招待comp:CODE' で作成。★ベータ中(BETA_MODE)でも有効コード付き登録は解禁=招待パートナーはローンチ前でも登録可。メール認証・オンボ(カードはbilling_exemptでスキップ・自社情報/SMTPは必要)・30日後の課金導線復帰(v0.69.3)・期限切れ3日前リマインド(v0.69.4)は既存のまま流用。register.html に特別招待バナー+hidden comp。コードを空/削除で即無効化。検証済(コード大小無視/ベータ中バイパス/バナー表示/hidden field)。
v0.79.0 2026-06-09
💳 解約まわりを整理+解約後のデータ削除ポリシーを実装。【A. 解約をポータルに一本化】従来 pricing.html の『😭解約』が `/billing/cancel`=即時 Subscription.delete+即 plan=free で、LP・特商法の『解約後も次回更新日まで利用可能』に反していた(バグ)。pricing.html を Stripeカスタマーポータル誘導に置換(期末解約=次回更新日まで利用可+解約の取り消し可)。`/billing/cancel` も互換で残すが cancel_at_period_end=True 化し即時失効を廃止。★Stripeダッシュボードでポータルの『期間終了時に解約』『解約の取り消しを許可』をONにする必要あり。【B. 解約後のデータ削除(AI学習データのみ)】従来は解約してもデータ削除は未実装(警告文だけのハッタリ)だった。webhook subscription.deleted で User.canceled_at を記録→日次ジョブ process_canceled_data_cleanup が CANCEL_DATA_RETENTION_DAYS=10日でAI学習データ(SentEmail送信履歴+ReplyMessage受信トレイ)を削除、その3日前に予告メール(Resend)を1回送信。削除対象はAI学習のみ=コンタクト/リスト/ブリーフ/自社情報は残す(再契約でリスト復活・学習はゼロから)。猶予中に再契約(plan が有料復帰)したら canceled_at をクリア=削除取消(誤解約の復帰救済、checkout成功でも即クリア)。一時停止/BAN経路は対象外(v0.41どおりデータ保持)。User.canceled_at/data_deletion_warned_at 追加(app.py自動マイグレーション)。APScheduler 日次ジョブ cancel_cleanup を追加。検証済(11日→削除/8日→予告/再契約→解除)。
v0.78.0 2026-06-09
🤝 代理店報酬の発生条件を厳格化=『代理店が契約中の有料Nudgeユーザーである期間の課金』に限定。背景:代理店=Nudge HQユーザー限定(PromoCode.agency_user_id がusersにFK=構造的に強制)という原則に合わせ、『使ってない/払ってない奴の言葉は信じられない』を報酬面でも担保。ルール:被紹介者の課金(invoice.paid)の“その時点”で代理店が契約中なら、成約30%/継続5%が発生。代理店が解約(plan=free/サブスク無)・停止/BANした後の課金分は成約・継続とも権利消滅。既に確定済みの未払い報酬は遡及して消さない(戻入なし原則と整合)=“以後の発生のみ止める”。実装:referral_module._agency_is_contracted(account_status=active+plan∈PLANS(light/std/pro)+stripe_subscription_id有)をrecord_reward_from_invoice の計上前ゲートに追加(成約・継続の両分岐をカバー)。comp(実サブスク無)・トライアルも対象外。規約:agency_terms 第4条に発生条件を明記+第10条(旧『別途定める』プレースホルダ)を正式定義に置換、版を 2026-06-09.v2 に。検証:契約中=True/解約free/trial/停止/compはFalse を確認済。
v0.77.0 2026-06-09
🔄 リスト自動収集のフライホイールを完成(共有DBの『読み出し』を本番フローに配線)。発覚した問題=共有DB(Supabase shared_companies)へは収集成功時/CSV取込時に『書き込み』していたが、実際の収集経路 _auto_list_worker は一度も『読み出し』ておらず(読む collect_company_list はデッドコード)、蓄積が増えても収集件数に反映されていなかった。対策:_lookup_shared_db を新設し worker の stage0(Gemini の前)に配線。①共有DBを業種+エリアで引く(bounced除外・自分のプール/NG重複除外)→②不足分だけ AI検索(v0.76拡張+Refill)で上乗せ。共有DBで充足すれば AI/Gemini を一切叩かない=API消費ゼロ・即時、ユーザー数が増えるほど充足率UP(ネットワーク効果=Nudgeのコア/堀)。共有DB由来は未検証扱い(verified_at=None)=リスト検証/バウンス検知v0.59が保険。0件/接続失敗時は従来どおりGeminiに進む安全設計(回帰なし)。★規約:プラポリ第5条に『共有データベース(重複収集の防止・効率化のための再利用)』を既に明記済みで追記不要。※Supabaseは service_role キー(本番Render)でRLSバイパス=読み書き可。anonキー(ローカル.env)ではRLSで全行不可視のためローカルE2E検証は不可。
v0.76.0 2026-06-09
🔎 リスト自動収集の取得件数を底上げ(『20件指示で14件しか取れない』対策)。原因=(1)Geminiプロンプトが業種を1語でしか検索せず網羅性が低い、(2)『件数未満でOK・質優先』で早期に切り上げ。対策:(a)expand_industry_terms=業種を Claude haiku で同義語・関連サービス名に展開(営業代行→セールスアウトソーシング/インサイドセールス代行/テレアポ代行/新規開拓代行/営業BPO 等、最大7語)。プロセス内キャッシュでRefill時も再展開しない。(b)_build_prompt に『検索のしかた(言い換え群で何度も検索語を変えて網羅的に)』ブロックを注入+『できる限り{count}社に到達するまで検索語・地名を変えて探し続ける(1回で止めない)』に指示を強化。★実在確認・メアド確認・捏造禁止のルールは厳守のまま(質は落とさず網羅性だけ上げる)。gemini_search_module のみの変更。search_companies_with_gemini 経由なので同期版・Refillループ両方に効く。
v0.75.1 2026-06-09
📝 リスト詳細のクイック表示切替に「メモ未生成のみ」(no_memo)を追加。各行の data-has-memo(0/1)で improvement_memo 未生成の行だけ表示=AI分析・メモ生成の対象を絞り込みやすく。ついでにクイックフィルタのアクティブボタンを btn-primary で強調表示するように改善(従来は選択状態が分からなかった)。list_detail.html のみ(ボタン1つ+applyQuickFilter に分岐追加)。
v0.75.0 2026-06-09
🎯 「成功の定義」(返信/クリック/どちらか)をブリーフ単位で設定可能に+送信時の定義を SentEmail に記録。目的:二足の草鞋(自社商材=返信ゴール/代理店紹介=クリックゴール等)で成功指標を売り分け、かつ途中で定義を切り替えても過去メールは送信時の定義で評価=AI学習が再解釈で濁らない。(a)PersonalizationBrief.success_definition(NULL=アカウント設定に従う)+brief_form に選択UI。(b)email_module=CTAクロージング分岐を learning_module.resolve_success_definition(ブリーフ優先→CompanyProfile)で解決し、解決した定義を戻り値に含める→list_module が下書き(Contact.draft_success_definition)に記録。(c)送信時=send_module の SentEmail 3箇所で success_definition_for_send(contact)(下書きの定義→無ければアカウント定義)を記録。(d)learning_module.success_filter を per-row 判定に変更(各メールの success_definition で成功判定、NULL旧データはアカウント現定義で fallback)。新カラム3つ(personalization_briefs/sent_emails/contacts)は app.py で自動マイグレーション。reengagement で下書きリセット時に定義もリセット。
v0.74.0 2026-06-09
🙅 代表者名(個人名)を既定で取得・使用しないように変更(個人情報の扱いを最小化=法的リスク回避)。ブリーフ/味付け/売る商材のテキストに『代表』『社長』等の明示指示がある時のみ取得・使用(brief_module.wants_rep_name で判定)。3箇所を改修:(1)research_memo_with_gemini=既定では代表者名を調べない・書かない、(2)analyze_page_with_brief=本文に代表者名があってもメモに含めない、(3)email_module の宛名=既定は『担当者名(ユーザー提供) or ご担当者様』でメモ内の代表者名は使わない。※CSV取込の列マッピング(代表者名→person_name)はユーザー自身がアップロードする自社データなので対象外(維持)。
v0.73.0 2026-06-09
🤝 代理店セルフ申込フロー(Uber方式の自己完結契約)。外部の電子契約サービス不要。(1)申込:/referral/apply で法人名+インボイス番号+法人チェック+代理店規約に『クリックラップ同意』。同意の規約バージョン・日時・IP を AgencyApplication に記録(電子契約の証跡)。法人+インボイスは申込時に検証。(2)承認:admin /admin/agency-applications で審査→承認。承認時に register_agency で紹介コード発行+AgencyProfileに法人名反映+『同意記録書PDF』(規約全文+同意記録、reportlab Platypus)を生成・DB保管・申込者へ承認通知メール。却下も可。(3)代理店規約:agency_terms.py(バージョン管理・全文12条のドラフト。成約30%/継続5%・単層・法人/インボイス必須・反社排除等)。代理店本人は /referral から同意記録書PDFをDL可、adminも /admin/agency-applications/<id>/pdf でDL(双方保管)。新テーブル AgencyApplication。設定ドロップダウンに『代理店プログラム(申込)』(代理店未登録の本垢ユーザーのみ)、admin に『代理店申込の承認』。商談→合意→この申込フローで契約締結、という導線。★自動生成コードはASCII英数字のみに修正(日本語社名はAGENCY+hexにフォールバック=URL安全)。E2E検証済み(申込→IP/同意記録→承認→コード発行→PDF生成→is_agency=True→本人PDF DL)。※規約文面の最終確認は弁護士へ。
v0.72.0 2026-06-09
📧 メールブリーフ=送信対象でメール戦略を切り替え可能に(二足の草鞋=自社商材とNudge代理店等を売り分け)。PersonalizationBrief に kind(memo/email/both)と offer_override(このブリーフで売る商材=自社情報の事業内容を上書き)を追加(app.pyマイグレーション)。brief_module:get_user_briefs/get_default_brief に use 引数(用途フィルタ。both/NULLは常に含む)。list_detail のメモ用ブリーフ選択は use='memo'、compose のメール用は use='email' で出し分け。★email_module.generate_personalized_email を改修:ブリーフを『味付け』に混ぜず、独立した『営業ブリーフ(戦略・切り口)』層として最優先で注入。offer_override があれば自社情報の事業内容より優先して“今回売る商材”にする(代理店としてNudgeを売るメール等が作れる)。custom_instruction は『味付け(トーン・禁止事項・P.S.素材)』に純化。brief_form に用途セレクト+売る商材欄、briefs一覧に用途バッジ、compose のブリーフ選択を『メール戦略ブリーフ』に明確化。E2E検証済み(用途フィルタ/デフォルトの用途整合/フォーム保存/offer_override保持)。
v0.71.0 2026-06-09
🧾 代理店報酬の仕入明細書を自動生成(PDF)=請求書チェックの工数ゼロ化。方式:買手(株式会社Cynthia)が作成し売手(代理店)が確認する『仕入明細書』(インボイス制度で仕入税額控除の要件を満たす想定)。報酬額はNudgeの報酬データから自動なので金額ミスが構造的に起きない。報酬は税込=消費税は税込から10%逆算(端数は明細書ごと1回・切り捨て)。新テーブル:AgencyProfile(代理店の法人名・住所・振込先=代理店本人が /referral で登録)、PurchaseStatement(明細書+PDFをDB保管)。ReferralReward に statement_id(精算した明細書)を追加。reportlab で日本語PDF生成(HeiseiKakuGo-W5 CIDフォント、requirements に reportlab==4.5.1)。フロー:admin /admin/payouts『支払いを確定』→ 支払い情報が揃った代理店ごとに仕入明細書PDFを自動発行+報酬paid化(未登録はスキップ&警告)。代理店は /referral で支払い情報を登録、発行された明細書PDFをDL+『確認する』(=相手方の確認)。admin/代理店双方がPDFをDL・保管可(保管義務対応)。PDFには買手/売手(登録番号)・期間・成約/継続の内訳・10%対象税込・消費税額・税抜・振込先・確認の注記を記載。E2E検証済み(税込34,300→税抜31,182/消税3,118、PDF生成、未登録スキップ、確認)。※様式・確認手続きの最終確認は税理士へ。
v0.70.1 2026-06-06
🧾 代理店の登録条件を『法人 かつ 適格請求書発行事業者(インボイス番号あり)』に限定。狙い:法人への紹介手数料は原則 源泉徴収不要+インボイス番号があれば消費税の仕入税額控除が取れる=面倒な税務処理を回避。PromoCode に is_corporation / invoice_number を追加(app.pyマイグレーション)。promo_module.validate_agency_eligibility(法人チェック必須+invoice番号 T+13桁を正規化検証:T無し/小文字/ハイフン入りも許容、桁不足は弾く)。register_agency と /admin/promo の単体発行の両方で必須化=条件を満たさないと登録不可。テスター管理の代理店登録フォーム+プロモ発行フォームに『法人である』チェックとインボイス番号欄を追加。プロモ一覧・支払い画面・支払いリストCSV に番号を表示(振込時の適格請求書照合用)。検証済み。※最終的な税務判断は税理士確認推奨。発行された適格請求書の保存も必要。
v0.70.0 2026-06-06
💰 代理店紹介報酬システム(現金・キャリア型)。報酬=成約報酬30%(初回課金時1回)+継続報酬5%(毎月)、いずれも『実入金額』ベース(割引クーポン併用でも入金の30%/5%=絶対に赤字にならない)。★戻入(クローバック)なし:報酬<初回入金なので即解約・自己紹介でも Nudge は黒字を維持する構造(キャリアは月額<<獲得報酬だから戻入が要る)。計上トリガーは Stripe の invoice.paid(実入金時)=トライアル中の¥0請求は対象外、初回有料課金で成約報酬が確定。新 ReferralReward テーブル(acquisition/recurring、stripe_invoice_id で冪等)。referral_module.record_reward_from_invoice をbilling webhook の invoice.paid にフック。支払いは月次バッチで最低支払額¥10,000以上の代理店に(未満は繰越)。admin /admin/payouts(未払い一覧+支払いリストCSV+『支払いを確定』で paid 化)。代理店本人は /referral(is_agency判定でナビに『代理店レポート』表示)で未払い/支払済/今月発生/紹介顧客数/明細/紹介リンクを確認。自己紹介ガード+¥0スキップ+冪等性を E2E検証済み(成約29,400/継続4,900、確定で支払済み化、ダッシュボード描画)。※Stripe側は既存の invoice.paid webhook をそのまま利用(追加設定不要)。報酬支払いの源泉徴収/インボイスは税理士確認推奨。
v0.69.5 2026-06-06
🎨 ファビコン(ブラウザタブのロゴ)を設定。これまで未設定で標準の地球儀アイコンだった。ブランドの紫グラデ(#7c3aed→#a855f7)角丸+白い『N』マークを作成:static/favicon.svg(ベクター・モダンブラウザ用)、Pillow で favicon.ico(16/32/48)/ favicon-16・32.png / apple-touch-icon.png(180、iOSホーム画面用)を生成。base.html の <head> に icon/apple-touch-icon の <link> を追加(app_version でキャッシュバスト)。※ロゴ画像を差し替えたい場合は static/ の各ファイルを置き換えるだけ。
v0.69.4 2026-06-06
📅 クレカ免除の期限を admin がカレンダーで自由設定できるように+⏰ 期限切れ前リマインドメール。(1)テスター管理の各ユーザー行に日付入力(<input type=date>)+『期限を設定』。作成フォームにも『無料期限(空欄なら30日後)』を追加。toggle_exempt に action=set_until(YYYY-MM-DD→その日23:59:59まで)。(2)期限切れ3日前(COMP_REMINDER_DAYS)にカード登録を促すリマインドメール。User.comp_reminder_sent_at 追加(app.pyマイグレーション)。onboarding_module.send_comp_expiry_reminders(免除ON・期限内・あと3日以内・カード未登録・未送信 を抽出して Resend 送信→送信済み記録)。APScheduler の日次ジョブ comp_reminder(24h) を追加。期限を変更(set_until/extend/免除ON)したら comp_reminder_sent_at を None にリセット=新期間で再送可能。E2E検証済み(候補選定の除外条件=早すぎ/カード有/送信済、カレンダー設定+フラグリセット)。※Resend未設定環境では送信スキップ。
v0.69.3 2026-06-06
⏳ クレカ免除(comp)に有効期限を導入=無限タダ乗り防止。User.billing_exempt_until 追加(app.pyマイグレーション)。免除=『発行から COMP_FREE_DAYS(30)日だけカード不要』に。onboarding_module: comp_deadline/comp_active/comp_expired_needs_card を新設し、check_steps の card は comp_active or _has_card に。★is_onboarding_completed は『免除期限切れ&カード未登録』なら onboarding_completed_at が立っていても False を返して /onboarding に再ゲート=使用停止+カード入力を促す(完了フラグの永久バイパス問題を解決)。オンボーディングのカードステップは免除中『〜MM/DDまで無料』、期限切れは『無料期間が終了しました。カード登録が必要』+Checkoutボタンを表示。admin:テスター作成の免除チェックで billing_exempt_until=now+30日、各ユーザー行に免除状態(〜期限/期限切れ)+『免除解除』『+30日延長』ボタン(toggle_exempt の action=extend)。3ケース(期間内/期限切れ無カード/期限切れ有カード)でE2E検証済み。
v0.69.2 2026-06-06
💳 課金免除(comp アカウント)。背景:admin がテスター/代理店にプランを付与しても、オンボーディングのゲートが stripe_subscription_id(カード有無)を見ているため、プラン付与とは無関係に『カード登録』が強制されていた(テスター/代理店を無料で使わせられない)。対応:User.billing_exempt を追加(app.pyマイグレーション)。check_steps で card = exempt or _has_card に。免除ユーザーはカード不要=自社情報+送信設定だけ揃えればオンボーディング完了(ツールが動くのに必要な2つは残す)。テスター作成フォームに『クレカ登録を免除する』チェック(既定ON)、各ユーザー行に免除状態+切替ボタン(/admin/users/<id>/toggle_exempt)。オンボーディング画面のカードステップは免除時『登録不要』表示。※あくまでオンボーディングのカードゲートを外すだけ。後から有料転換は通常の billing フローで可能。
v0.69.1 2026-06-06
🤝 代理店=Nudge HQユーザーであることを条件化。PromoCode に agency_user_id(FK→users)を追加(app.pyマイグレーション)。テスター管理画面(/admin/beta_users)の各ユーザー行に『代理店』列を追加し、『代理店にする』フォーム(代理店表示名/コード=空欄なら自動生成/StripeクーポンID/特典 任意)からそのユーザーにコードを発行(promo_module.register_agency、1ユーザー1コードの二重登録ガード付き)。リリース前でも admin がテスターアカウントを作って代理店登録できる。/admin/promo は紐付くユーザーのメールを表示+『ユーザー未紐付け』を警告表示し、単体フォームは社外パートナー用と明記。promo_module: agency_code_for_user / generate_code_for / register_agency 追加。E2E検証済み。
v0.69.0 2026-06-06
🤝 代理店プロモコード(紹介元アトリビューション)。admin が代理店ごとにコードを発行し、(1)入力経路=事前登録フォームの『紹介コード』欄 + 紹介URL(?ref=コード/?promo=も可)。URLで来た訪問者は app.py の before_request `_capture_referral` でセッションに保持し、登録時に紐付け。(2)アトリビューション=PreRegistration.referral_code / User.referral_code(models+app.pyマイグレーション)。本登録時は promo_module.resolve_ref がフォーム>セッション>既存事前登録の順で確定(auth.register)。(3)割引=PromoCode.stripe_coupon_id を紐付ければ billing のチェックアウトで discounts に自動適用(coupon_for_user)。クーポン未設定なら『記録のみ』のコードになる。(4)admin=/admin/promo でコード発行(コード空欄は代理店名ベースで自動生成)・有効無効切替・代理店ごとの『事前登録/本登録/成約(有料)』集計+紹介URL表示。新 PromoCode テーブル+promo_module.py。コードは大文字正規化+大小文字無視でマッチ。E2E検証済み(?ref捕捉→事前登録紐付け→クーポン解決→admin描画)。
v0.68.1 2026-06-06
🐛 トラッキング不達の根本原因=APP_BASE_URL が localhost だった件への防御。send_module._wrap_with_tracking の既定値を 'http://localhost:5000' → 'https://nudge-hq.co.jp' に変更(APP_BASE_URL 未設定でも開封ピクセル/クリックリンク/配信停止リンクが localhost に落ちないように)。さらに base_url が localhost/127.0.0.1 を含む場合は起動・送信時に log.warning で警告。★本番Renderの環境変数 APP_BASE_URL=https://nudge-hq.co.jp の設定が大前提(resend_module のシステムメール=認証/事前登録リンクも同じ変数を読むため、localhost だと認証メールのリンクも壊れる)。※既送信の77通はURL焼き込み済みで遡及修正不可(env修正後の新規送信から正常化)。
v0.68.0 2026-06-06
3点セット。(1)🤖 自動返信を受信トレイに表示(B案):不在通知/問い合わせ受付の自動応答を ReplyMessage.is_auto_reply で記録し『🤖自動返信』バッジ表示。差出人が送信先と違っても(contact+noreply@等)ドメイン一致でコンタクトに紐付け(imap_module._looks_automated / _find_contact_by_domain)。★本物の返信ではないので status変更・stop_sequence・返信率カウント・未対応カウントには一切影響させない(追いメールが自動返信で誤停止する事故を防止)。models+app.pyマイグレーション(reply_messages.is_auto_reply)。(2)📊 開封ピクセル改善:トラッキングピクセルの style から display:none を撤去(Gmail/Apple Mail が display:none 画像を読まず開封検知を取りこぼす問題)。1x1のほぼ不可視画像を block 配置に(send_module._wrap_with_tracking)。※クリック0は『メール本文にリンクが無ければ構造上0』が正常。開封0が続く場合は APP_BASE_URL とRenderログの /t/open ヒットを要確認。(3)📈 LP訪問の自前計測+歩留まり可視化:新 SiteVisit テーブル(Cookie不要・IP非保存=日次ソルト付きハッシュでユニーク推定・ボットUA除外・1日1訪問者1ページ1行)。landing と pre_register ルートで record_visit(analytics_module)。/admin/analytics(admin限定)に期間別サマリー・歩留まりファネル・日次推移14日・流入元(utm_source)別を表示。Render では訪問者数は分からない(生ログのみ)ため自前計測。utm_source=xxx をURLに付けると流入元別に集計可能。
v0.67.2 2026-06-05
📱 モバイル対応③(仕上げ):残り全画面をスマホ対応。(1)汎用 .responsive-cards を実用版に強化(data-labelで『見出し:値』、先頭セルはカード見出し、class=cell-action でボタン横並び、details/snippetの全幅化)。(2)高頻度のユーザー画面をカード化:受信トレイ(inbox)/再営業(reengagement)/ダッシュボードの統計表4つ(業種別・件名・CTA・TOP10)/営業NG(blocked_domains)/オペレーター(operators)/ブリーフ(briefs)/送信統計(send_index×2)/スマートリスト一覧(lists)。各テーブルに responsive-cards クラス+data-label を付与。(3)カード化しない管理系(admin各種/重複/CSV取込/送信プレビュー/sender_domain等)は CSS⑦の安全網で対応:.data-table を display:block+overflow-x:auto にしてラッパー無しでも横スクロール可能に(画面外への溢れを防止、テンプレ編集ゼロ)。table-scroll で囲み済みのものはラッパー側がスクロール。(4)Chart.jsグラフは maintainAspectRatio:false+幅100%+768pxで1列化で既にモバイル対応済み(変更なし)。★全画面 v0.67.0(土台+送信ワーク)→v0.67.1(リスト)→v0.67.2(残り)でスマホ完結フロー完成。
v0.67.1 2026-06-05
📱 モバイル対応②:リスト(コンタクト一覧 .contact-table)をテーブル→カード化(640px以下)。移動中に『リスト収集→AI分析』を回す本丸画面。横スクロールの広い表を1社=1カードに:会社名=見出し(HP🔗)、メール/業種・エリア=ラベル付きメタ行、詳細バッジ(📝💡📧💰)、状態バッジ、操作(送信画面で開く=全幅/AI分析=全幅/状態変更select+更新/🗑削除/🚫ブロック)。一括選択チェックボックスはカード右上に固定(thead非表示でも『表示中を全選択』ボタンで全選択可)。メモ・備考の詳細パネル(tr.contact-detail-row)はカード直下に薄い紫パネルで展開(row.hidden トグルは不変、[hidden]で display:none を再指定)。col-sticky-right の右固定はモバイルで解除。list_detail.html にcell-check/cell-company/cell-email/cell-ia/cell-detail/cell-status クラス+data-label を付与。CSS は style.css 末尾『モバイル土台』⑥セクション。
v0.67.0 2026-06-05
📱 モバイル対応の土台を構築(営業マンが移動中にスマホで新規営業を回せるように)。(1)ナビをハンバーガーメニュー化:860px以下で .nav-toggle 表示、.nav を縦展開(base.html+main.js+style.css)。設定ドロップダウンはモバイルでその場にインライン展開。メニュー外タップ/Esc/リンクタップで自動クローズ。(2)送信ワーク(最優先画面)をテーブル→カード化:640px以下で1社=1カード(会社名見出し+業種/エリアのメタ行+状態バッジ+全幅の操作ボタン)。横スクロール撲滅。send_work.html に cell-company/cell-meta/cell-status/cell-action クラス。(3)タップ最適化:入力欄を16pxに(iOSフォーカス時の自動ズーム防止)、ボタン min-height 44px、余白圧縮、ステータスタブを横スクロール1行化、バナーを縦積みに。(4)汎用 .responsive-cards クラス(data-label付きテーブルをカード化)を用意し他画面にも展開可能に。(5)アプリっぽい meta 群(theme-color/apple-mobile-web-app 等)。(6)スライドパネルはモバイルで全幅+セーフエリア対応。
v0.66.0 2026-06-05
🧹 リスト検証の統合&連打ガード。(1)『無効URL一掃』と『メアド検証』を1ボタン『リスト検証・クリーンアップ』に統合(verify_emails が HP取得1回で URL生存とメアド実在の両方を判定。無効URL一掃ボタンは撤去)。(2)Contact.verified_at を追加(app.py マイグレーション)。検証ツールは未送信かつ未検証(verified_at=None)のみ処理し、削除以外の処理済みコンタクトに verified_at をセット→再実行時はスキップ=HP取得/API/帯域の無駄打ちを防止。対象が全て検証済みなら『未送信N件はすべて検証済み(再検証はスキップ)』と表示して何もしない。(3)AI自動収集でHPからメアドを取得/確認できた分(pages_crawled>=1)は収集時点で verified_at をセット=『検証フィルタを通過してリスト追加されたばかり』のものは最初から検証済み扱い(再検証不要)。
v0.65.0 2026-06-05
⏳ 同期処理用のロードオーバーレイを追加。無効URL一掃 / メアド検証 はサーバー側で数十秒〜数分かかる同期POSTだが、実行中は白いブラウザ待ち画面で『動いてるか不安』だった。main.js に汎用 showLoadingOverlay を追加し、フォームに data-loading-overlay='メッセージ' を付けると本送信時にポップアップ(床屋クルクルの indeterminate バー+『ページを離れずに〜』注記)を表示。確認モーダルで横取りされた submit は e.defaultPrevented で除外し、実際に送信される時だけ表示。応答が返って画面遷移すると自動で消える。style.css に .loading-overlay。list_detail.html の無効URL一掃(『無効URLを一掃中…』)とメアド検証(『メアドを検証中…』)に適用。
v0.64.1 2026-06-05
🩹 ダッシュボード『開封率が高い件名パターン』に開封率0.0%の件名が並ぶ矛盾を修正。get_top_subjects_by_open_rate が開封0件の件名も開封率順に並べて表示していたため。開封が1件以上ある件名のみ対象にし、全件0なら結果空→テンプレ側 {% if learning.top_subjects %} でセクション自体を非表示に。※開封0が続く場合は『送信が最近・画像ブロックで開封は実態より低く出る・バウンスで未達』等が主因で、必ずしも計測バグではない(長期で0なら開封ピクセル要確認)。
v0.64.0 2026-06-05
📧 既存リストのメアド検証・一掃ツール(『無効URL一掃』のメアド版)。背景:v0.59.1(収集時のGeminiメアドHP検証)を入れても新規50件から40%バウンスが続いたため、収集経路に依存せず“既にリスト化済みのメアド”を後から一括検証したい要望。新規 /lists/verify-emails(list_id でスマートリスト限定可、未送信pendingが対象、最大300件、HP取得は5並列)。判定:(1)構文不正 or ドメインDNS消失→削除+unit_consumedなら usage_module.refund_unit で1ユニット返却、(2)HPに別の同一ドメインメアドあり→そのメアドに差し替え(より実在性の高いものへ)、(3)HPにそのメアドが載っている→確認済み維持、(4)HP取得不可/公開メアド無し→判定保留(維持)。★安全側:削除は『構文不正 or DNS消失』のみ(受信拒否は事前判定不可なので消さない)。list_detail.html の『無効URL一掃』隣に『📧 メアド検証・一掃』ボタン(確認モーダル付き)。usage_module.refund_unit 追加(当月カウンタ減算=trial累計も連動)。完了時に削除/返却/差し替え/確認/保留の件数を flash。※『受信拒否』バウンスはこの検証では消せない(v0.63.1の内訳で『アドレス不明』が多い時に効く)。
v0.63.1 2026-06-05
🔬 バウンス(不達)理由の記録・可視化。狙い:高バウンスの内訳が『リスト品質で減らせる不達』なのか『相手サーバーの受信拒否(事前に防げない)』なのか分からないと次の手の効果が読めないため、正体を見える化。実装:(1)Contact に bounce_category(not_found/rejected/other)と bounce_reason を追加(app.py マイグレーション)。(2)deliverability_module.classify_bounce_reason:SMTP拡張ステータス(5.1.x=アドレス不明 / 5.7.x・access denied・too many hops 等=受信拒否)+キーワードで分類し診断テキストも抽出。(3)imap_module のバウンス検知時に分類して記録。(4)get_bounce_stats に by_category 内訳と reducible(=アドレス不明件数)を追加。(5)ダッシュボードのバウンスカードに『アドレス不明N件/受信拒否N件/その他N件』+『アドレス不明は減らせる/受信拒否は構造的』の解説。(6)送信一覧の不達バッジに理由ツールチップ+分類ラベル。実バウンス4例(5.1.1/5.4.1 access denied/too many hops/user unknown)で分類テスト済み。※既存の8件は再検知されないため分類されない=今後の新規バウンスから内訳が貯まる。
v0.63.0 2026-06-05
🛡 バウンス率ガードレールを実装。背景:20件中8件(40%)バウンスなど高バウンスが続くと、新ドメイン(nudge-hq.co.jp)の送信評判が壊れ、正常なメールまでスパム判定・スロットリングされる重大リスク。実装:deliverability_module.get_bounce_stats(Contact.last_sent_at[JST]と status='bounced' から直近14日&当日のバウンス率を集計、account_idスコープ、最低サンプル10件ガード、warn=10%/critical=20%)。(1)app.py に context_processor inject_bounce_warning → 高バウンス時に全画面共通の警告バナー(base.html、critical は赤・warn は黄)。(2)ダッシュボードに『配信健全性(バウンス率)』カード(直近14日+当日、良好/注意/危険)。健全な目安5%以下を明示し、リスト品質見直し・送信ペース抑制を促す。※バウンス検知(v0.59)で status='bounced' が付くことが前提。IMAP連携が動いていることを要確認。
v0.62.0 2026-06-04
🧰 2つの操作性改善(既存ルートを流用、Python変更なし)。(1) メール作成画面(compose_contact)の送信先カードに『🔍 AI分析』ボタンを追加=list_bp.enrich_contact を return_to付きでPOST。リストに戻らず、その場で URL補完+パーソナライズメモ+予算判定💰 を実行・再生成できる(送信中の loading 表示付き、embed/iframeでもreturn_to維持)。(2) 送信一覧/送信ワーク(send_work)の操作列に『🗑 削除』ボタンを追加=list_bp.delete_contacts を return_to付きでPOST(確認モーダル付き、予約も取消)。行クリックでパネルが開く既存JSとは『ボタン上のクリックは open-compose 以外無視』の仕様により非干渉。操作列幅を110→150pxに。
v0.61.1 2026-06-04
🔢 まとめてAI分析の進捗『0/33(32選択なのに)』を解消。原因:_full_prep_worker が job.total を len(contacts)+1 としていた(+1=最後にまとめて1回行う業種分類ステップ分)ためバグではないが分母がズレて見えた。対策:job.total = len(contacts)(選択件数に一致)、最終 job.completed = len(work) に統一。業種分類は引き続き stage='業種分類中' のステージ表示で進行を示す(カウントには含めない)。
v0.61.0 2026-06-04
🎚 進捗バーの未完了トラックにも床屋クルクル(バーバーポール)を追加。背景:%が一時的に動かない時に『止まってる?』と不安になるため、塗り(.progress-bar)の右側=未完了部分にグレーの流れるストライプを表示。実装:style.css に .progress.is-loading(既存 progress-stripes アニメをトラックに適用)、main.js の NudgeProgress.start/end が section 内の全 .progress に is-loading を付け外し=**NudgeProgress を使う全ロードバー(自動収集・まとめAI分析 等)に一括適用**。ダッシュボードのトライアル/使用量バー等の静的バーは NudgeProgress を呼ばないので対象外(正しい挙動)。
v0.60.0 2026-06-04
🎖 AI学習レベルにプレステージ(Call of Duty 方式)を追加。学習は使うほど永続的に伸びるので、最高Lv.5(マスター/累計スコア5000)到達後も **5000スコアごとにプレステージ+1** で上がり続ける“やり込み要素”に。継続利用のモチベ&『他社へ移行不可の資産』の可視化を強化。実装:learning_module.get_learning_status に prestige / is_master / prestige_remaining / prestige_step を追加(prestige = score // 5000。マスター到達と同時にプレステージ1解放)。dashboard.html の学習セクションに金グラデのプレステージ・バッジ+『次のプレステージまで N』表示、style.css に .prestige-badge。データは消さず累積し続ける設計(プレステージしてもスコア・学習データはリセットされない)。境界値テスト済み。
v0.59.1 2026-06-04
🎯 リスト自動収集のメアド精度を向上(Gemini一括取得経路の弱点を補強)。背景:会社名・URLは Google Search Grounding で実在確認できるが、Gemini が返す“メアド”は grounding で検証しきれず、もっともらしい誤アドレス(例:hs-learning@science.co.jp=アドレス不明)を返してバウンスの一因になっていた。対策:auto_list_module._verify_gemini_emails を新設。0段目(Gemini一括)の各社について実際にHPをスクレイピングし、(1)HPにそのメアドが載っていれば確定、(2)載っていないが同一ドメインの実在メアドが取れれば**そちらに差し替え**、(3)HP取得不可/公開メアド無しは検証不能としてGeminiのメアドを維持(バウンス検知v0.59が保険)。ThreadPoolExecutor で5並列。HPスクレイピング経路(1段目以降)は元々実メアドのみ採用で高精度。これでGemini経路の誤アドレスを実HPと突合して補正できる。(trade-off:0段目に各社1回のHP取得が加わり少し遅くなるが精度優先。base_domain抽出の www. 除去も正しい接頭辞除去に修正)。
v0.59.0 2026-06-04
📭 バウンス(不達)自動検知&停止を実装。背景:コールド送信でアドレス不明・受信拒否のバウンスが一定割合発生するが、従来 IMAP は差出人をコンタクトと突合するだけで、mailer-daemon/postmaster から来るバウンスは“どのコンタクトにも一致せず無視”されていた=死にアドレスが sent のまま残り、追いメールが送られ続けて送信ドメインの評判を悪化させる恐れがあった。実装:imap_module に _is_bounce(差出人 mailer-daemon/postmaster、multipart/report=DSN、不達系の件名パターンで判定)と _find_bounced_contact(バウンス本文に引用された“元の宛先”からコンタクトを特定)を追加。バウンス検知時は該当コンタクトを status='bounced' にして stop_sequence(追いメール停止)+ supabase mark_bounced。返信としては記録しない。冪等(再取得しても二重処理しない)。実バウンス3例(旭化成 postmaster『too many hops』/ Google mailer-daemon『送信できませんでした』/ 通常返信)でテスト済み。※注意:高バウンス率(コールドでは20-30%も珍しくないが評判の観点では3-5%以下が理想)は本文品質ではなくリスト(アドレス実在性)の問題。次の改善余地:送信前のMX/構文検証、ダッシュボードにバウンス率表示。
v0.58.3 2026-06-04
🐛 ダッシュボードの500(TypeError: Object of type builtin_function_or_method is not JSON serializable)を修正。原因:dashboard.html の Chart.js データで `{{ chart_funnel.values }}` `{{ chart_industry.values }}` と書いていたが、Jinja の属性アクセス `dict.values` は辞書のキー'values'ではなく**辞書の組み込みメソッド `dict.values`** に解決され、そのメソッド参照を tojson しようとして失敗していた。**潜在バグで、初の実送信で metrics.sent>0 となりチャート節 `{% if metrics.sent > 0 %}` が初描画されて顕在化**(だから『送信できたがダッシュボードで500』)。修正:ブラケット記法 `chart_funnel['values']` / `chart_industry['values']` に変更(.labels 等は dict にメソッドが無いので無害)。教訓:Jinja で dict のキーが values/keys/items/get 等メソッド名と被る場合は必ず ['key'] で参照する。
v0.58.2 2026-06-03
👥 オペレーター(サブアカウント)機能を有効化(Phase3=機能ON)。(1) operators_module.py + /operators 管理画面:本垢がオペレーターを作成(メール+自動生成パスワード、1度だけ表示)/一覧/削除/パスワード再発行。operators.html。設定ドロップダウンに『オペレーター管理』追加(本垢のみ表示)。(2) 権限ガード _enforce_operator_limits(app.py before_request):オペレーターは /billing /smtp /operators /sender-domain に入れない(オーナー専用)。設定メニューでも該当リンクを非表示。(3) ステータス継承:オペレーターは親アカウントが suspended/banned なら同様に停止(_enforce_account_status で親を参照)。(4) オンボーディング/チュートリアルを操作者はスキップ(is_onboarding_completed / is_tutorial_completed / is_tutorial_active がis_operator を完了/非アクティブ扱い)。(5) 保留スコープ確定:app.py 再営業バナー件数と tutorial サンプルを account_id に。billing は操作者が入れないため変更不要。オペレーターは自分のメール/パスワードでログインし、親のデータ(リスト・コンタクト・SMTP・自社情報等)を共有してリスト編集・AI分析・メール作成・送信・受信トレイ等の実務を担当できる。追加は無料(席課金ではない差別化)。
v0.58.1 2026-06-03
👥 オペレーター機能 Phase2:データ・設定・ユニット・ジョブの所有スコープを current_user.id → current_user.account_id に切替。対象15モジュール(list/send/email_settings/reengagement/budget/brief/inbox/email/dashboard/sender_domain/smtp/auto_list/blocked_domains/company/jobs)=コンタクト・リスト・SMTP・自社情報・ブリーフ・NG・追いメール・返信・送信履歴・予算基準・ジョブ進捗など全ての“データ所有”を account(親)基準に。これでサブ垢が親のデータを共有し、ユニットも親に課金される土台が完成。★全員 parent_account_id=NULL のため account_id==id で挙動は完全に不変(ゼロリスク)。Phase3 保留:billing(課金は親・操作者は不可)/ onboarding(操作者は親設定を継承しスキップ)/ tutorial(操作者スキップ)/ admin(本人)/ app.py 再営業バナー。これらは『本人 vs アカウント』の意味づけと操作者ガードを Phase3 で個別対応。次:Phase3=オペレーター管理UI+サブ垢ログイン+権限ガード+上記保留分のスコープ確定。
v0.58.0 2026-06-03
👥 オペレーター(サブアカウント)機能の土台(Phase 1)。1契約で複数オペレーターが同じデータを分担編集でき、ユニットは本アカウントに課金する設計(アカウント数課金ではない差別化)。Phase1の内容:User に parent_account_id(NULL=本アカ / 値=その親に属するオペレーター)と operator_name を追加、User.account_id プロパティ(= parent_account_id or id=データ/ユニットの所有アカウント)と is_operator を追加、app.py に ALTER TABLE マイグレーション追加。★この段階ではサブ垢が存在しないため account_id==id で挙動は完全に不変(ゼロリスク)。次フェーズ:Phase2=データ/ユニットのスコープを current_user.id→current_user.account_id に段階切替、Phase3=オペレーター管理UI+サブ垢ログイン+権限ガード(課金/プランは本アカのみ)。送信設定は本アカ共有方針。
v0.57.11 2026-06-03
🛟 『今すぐ送信』でも下書きの最新編集を保存してから送るよう修正(v0.57.10の予約送信に続く対応)。本文を編集して『下書きを保存』を押さずに送信すると、保存前の古い内容が送られる罠だった。実装:下書きフォームの件名・本文を、予約送信/今すぐ送信フォームの hidden(data-mirror)に 入力イベントで常時ミラー(確認モーダル経由の requestSubmit/submit いずれでも確実に値が載る)。send_one でも subject/body 同梱時は送信前に draft 保存(drafted_at 更新)。予約フォームの hidden も同じ data-mirror 方式に統一(v0.57.10 の submit リスナー方式を置換)。今すぐ送信の確認モーダル文言も『下書きの最新の編集を含む内容を送信』に更新。
v0.57.10 2026-06-03
💾 予約送信時に下書きの編集が保存されない不便を解消。問題:メール作成画面は『下書き』フォームと『予約送信』フォームが別 form のため、本文を編集して『下書きを保存』を押さずに『予約する/予約を更新』を押すと、編集内容が保存されず最後に保存済みの下書きで予約されていた。対策:(1)予約フォームに hidden の subject/body を持たせ、送信直前に JS で下書きフォームの現在値をコピー。(2)schedule_send 側で subject/body が同梱されていれば予約処理の前に draft として保存(drafted_at も更新)。これで『予約する』ワンクリックで編集保存+予約が完了する。
v0.57.9 2026-06-03
🙅 AI分析で“無関係な人物が代表者名として出る”捏造を修正。原因:HP取得成功時の analyze_page_with_brief にはトップページの抜粋(title+snippet)しか渡らず、代表者名は通常そこに載っていない。にもかかわらずブリーフが『代表者名を書け』と指示するため、本文に無い氏名をモデルがでっち上げていた(出力ルールに捏造防止ガードが無かった)。対策:analyze_page_with_brief の出力ルールに『サイト本文に明記が無い情報(特に代表者名・役職者名・数値・実績)は創作しない。ブリーフで必須指定でも本文に無ければ代表者名:不明とし氏名を絶対に推測しない』を追加。(Geminiフォールバック側 research_memo_with_gemini は元々ガードあり)。※完全な代表者名取得には会社概要ページ取得 or Gemini検索の追加が要るが、まずは誤名出力の停止を優先。
v0.57.8 2026-06-03
🗓 予約送信が送信可能時間外でもドロップしないように。従来:予約発火時に時間帯チェックで弾かれると scheduled_at が既にクリアされた後で送信失敗→二度と送られない(サイレントドロップ)バグがあった。対策:(1)新ヘルパー _is_within_window / next_send_window_slot を追加(指定時刻が時間外なら次の送信可能枠=開始時刻へスライド。平日のみ設定なら土日も飛ばす)。(2)予約設定(schedule_send)で時間外を指定した場合、その場で次の枠へ自動調整しユーザーに通知(ゆらぎは維持)。(3)APScheduler の発火処理を『送信前に時間外なら send をドロップせず scheduled_at/next_followup_at を次の枠へリスケジュール(UPDATE)』に変更(初回・追いメール両方)。(4)あわせて停止/BAN中アカウントの予約は scheduled_at を消さず残し、復帰後に送信されるよう改善。既知の範囲外:日次上限到達での発火失敗時のドロップは別途(今回は時間帯のみ対応)。
v0.57.7 2026-06-03
🕘 タイムゾーンの重大バグを修正。症状:14:00 JST の手動送信が『送信可能時間外(現在5時)』で弾かれ、10:00 JST 予約が発火しない。原因:Render サーバが UTC のため datetime.now() が JST より9時間遅く、送信可能時間帯(9〜18時)判定・予約時刻比較・追いメール予定比較が全て UTC で行われていた。対策:utils.now_jst()(サーバTZに依存せず JST naive を返す)を新設し、(1)送信可能時間チェック _check_sending_window、(2)予約送信フォームの過去日時チェック、(3)送信ワーク画面の予約済み判定、(4)APScheduler の予約送信/追いメール due 判定(app.py)、(5)送信時刻の記録(last_sent_at/initial_sent_at/followup_sent_at)、(6)日次送信上限の『今日』判定 を全て JST に統一。予約時刻・追いメール予定・送信時刻は今後 JST naive で一貫保存。※デプロイ後、未発火だった本日の予約は JST 現在時刻が過ぎていれば次の1分tickで送信される。既存の進行中シーケンス(旧UTC保存)の次回追いメールは一度だけ最大9時間早く発火しうる(実害軽微)。
v0.57.6 2026-06-03
🎓 チュートリアル最終ステップ(テスト送信)後の導線を修正。問題:テスト送信後はメール作成画面に flash が出て戻るだけで、完了画面にも進捗ページにも飛ばず『終わった感』が無かった(オーナーが体験して気づいた)。対策:test_send_draft で is_tutorial_active なら tutorial_test_sent をセット後、完了メッセージとともに tutorial.index へリダイレクト(all_done なら『完了ボタン』が表示され仕上げに進める)。補足:素の admin は is_tutorial_active=False で全バイパスのため何も出ないのが正。チュートリアルの実体験は admin パネルの『シミュレーション開始』で行う。
v0.57.5 2026-06-03
🔚 クロージング(CTA)まわりの優先順位と導線を整備。(1) 味付け(ルール・素材)にCTA・結び方の明示指定がある場合、成功の定義ベースの既定クロージングより**味付けを最優先**で採用するよう構成⑥に明記+味付けセクション見出しも『原則は構成優先だがCTAだけ味付け優先』に。(従来は『矛盾時は構成優先』で味付けCTAが負けていた)(2) メール作成画面(compose_contact)に『メール末尾のCTAは成功の定義で切替。違和感があれば〈成功の定義を変更〉、または味付け欄でCTA直接指定が最優先』の注記+ company.edit#success へのアンカーリンクを追加。company.html の成功の定義 fieldset に id=success(scroll-margin付き)を付与。
v0.57.4 2026-06-03
🎯 初回メールのクロージング(CTA)を CompanyProfile.success_definition で分岐。背景:骨格に『ご返信はご無用』を固定していたが、これはクリック型成功(オーナー)には最適でも、返信型成功のユーザーには逆効果。万人向け骨格に固定値は不適切という指摘を反映。clicked→『ご返信はご無用』+自社URL誘導 / replied→返信を促す結び(候補日提示等、『ご返信はご無用』を書かない) / engaged→返信とURLを両方軽く提示。generate_personalized_email で closing_instruction を組み立てて構成⑥に注入。禁止事項は『要求を矛盾させない』に一般化。company.html の『成功の定義』に締め方が変わる旨の注記を追加。
v0.57.3 2026-06-03
✂ 初回メール骨格の P.S. をオプトイン化。問題:味付け(ルール)空でも P.S.(『このメールはAIが書きました』のネタバラシ)が自動生成されていた。原因は構成⑧の例示に『ネタバラシ』があり、モデルを誘導していたこと。P.S.のネタバラシは AI営業ツールを売る Nudge HQ 固有のギミックで、一般顧客には不適切(汎用骨格に入れるべきでない)。対策:構成⑧を『ルール欄に P.S. の明示指定がある場合のみ末尾に入れる。無ければ付けない&自分から創作しない』に厳格化し誘導ワードを削除。→ 味付けが空なら P.S. は出ず、オーナーのように味付けに P.S. 文面を入れた人だけ出る。
v0.57.2 2026-06-03
📐 予約送信フォームの「日付」と「時刻」が縦にズレる問題を修正。原因:input[type=date] だけ display 未指定(=inline)+width:auto で、ラベル文字の右隣に並んでいた一方、select は display:block で文字の下に来ていた。date/datetime-local を display:block・width:100% に統一して他の入力欄と揃えた。
v0.57.1 2026-06-03
🏆 初回メール骨格を、オーナーが実運用で高品質を出している“神メール指示文”に忠実化(v0.57.0の骨格を差し替え)。固定する普遍ルール:件名はシンプル・圧迫感なしで【2案】(subject/subject_alt)、宛名は代表者名/担当者名があれば必ず『○○様』、本題は『良い点を認めた上で気になる点を“1点だけ”指摘+的外れでしたら〜の逃げ道』、クロージングは自社URL1つ+返信不要、P.S.はルール欄の指定文を尊重、トーン(誇大語・絵文字禁止)、文章量(1分で読める)、禁止事項(返信不要なのに行動を求めるのNG 等)。自社固有の中身(サービス紹介・価格・特典・P.S.のPR実績)はハードコードせず味付け欄(ai_instruction_default)/自社情報に置く=全顧客が同一文面にならない。件名2案は draft_subject に主案を保存し、別案は生成完了 flash に提示(件名欄へ貼り替え可)。
v0.57.0 2026-06-03
🏆 初回メール生成の品質を構造から底上げ。背景:完成度の高いメールが書ける一方、自社情報の指示が雑だと出力が大きく崩れる=品質がユーザーの指示文に丸ごと依存していた。原因は generate_personalized_email のプロンプトが汎用ルール(件名20字/350-500字 等)のみで“勝ちパターンの構成”を固定していなかったこと。対策:構成(①件名ベネフィット②宛名③突然のご連絡+自己紹介④パーソナライズメモのシグナルを1点具体引用⑤課題提起+『的外れでしたら〜』クッション⑥解決提示⑦CTAは自社URL1つ⑧『ご返信はご無用』クロージング⑨署名なし⑩P.S.は素材があれば)と【ライティング指針】をプロンプトに固定。ユーザーのブリーフ/追加指示は構成を上書きしない『味付け(トーン・強調点・特典・P.S.素材・禁止事項)』として下層に配置(rules_block、このメール固有指示は後勝ち)。UI も compose_contact / company の該当欄を「味付け」表現+実例プレースホルダに刷新。※適用は初回メール(generate_personalized_email)のみ。追いメールは別ロジックのため今回は対象外。プロンプト内の『導線改善メモ』表記も『パーソナライズメモ』に統一。
v0.56.1 2026-06-03
✏ ユーザーに見える「コスト暴走防止」表記を削除(コスト管理は運営側の都合でユーザーには無関係なため)。compose_contact のAI生成ボタン下注記・メモ/メール再生成上限の flash・dashboard の説明を「回数上限」表現に変更。コード内コメント・CLAUDE.md の内部記述は残置。
v0.56.0 2026-06-03
✨ 2つの使い勝手改善。(1) 送信時刻のゆらぎ(分)をメール作成画面の予約送信フォームにも設置(従来はSMTP設定のみ)。compose_contact ルートが現在値を渡し、schedule_send が変更を SMTPSetting に保存してから今回のゆらぎ計算に反映(0〜60バリデーション)。(2) 個別AI分析・ステータス更新・メモ/備考保存の後の強制リロードで、ページ先頭に戻って触っていた企業を見失う問題を解消:各行に id=contact-row-<id> を付与し、これらの操作後のリダイレクト先URLに #contact-row-<id> アンカーを付加(新ヘルパー _back_to_contact_url)。ブラウザが自動でその行までスクロール+CSS :target で約2秒ハイライト。固定ナビに隠れないよう scroll-margin-top:90px。削除は行が消えるためアンカー無し。まとめAI分析(full-prep)はAJAX一括のため従来通り。
v0.55.1 2026-06-03
🔘 コンタクト一覧 操作列の「更新」ボタンだけ縦長で高さが揃わない問題を修正。原因:細い枠の中で「更新」が2行(更/新)に折り返していた。cell-action 内の小ボタン(btn-secondary/btn-danger .small)に white-space:nowrap + flex-shrink:0 を付与して1行固定。
v0.55.0 2026-06-03
🖼 コンタクト一覧テーブルの右側(操作列)見切れを根本修正。何度直しても再発していた問題の真因は2つ:(A) `main.container > *` の入場アニメ(fadeInUp)が `animation-fill-mode: both` で、完了後も `transform: translateY(0)` が全直下要素に残り続け、子孫の `position: sticky`(操作列の右端固定 col-sticky-right)を破壊していた→ fill-mode を both→backwards に変更(残留transform除去、見た目は不変)。(B) テーブルが横に長すぎて、固定が壊れた状態だと操作列がコンテナ右端の外へ流れて見切れていた。→ メール列を省略表示(cell-email:max-width 160px + ellipsis、全文は title ツールチップ)+ contact-table のセル余白を 12/14px→8/10px に圧縮し、7列が通常画面幅(container 1160px)に収まるように=そもそも横スクロール不要に。多重防御:万一狭い画面で横スクロールが出ても、修正後は操作列の右端固定が正しく効く。
v0.54.0 2026-06-03
🧹 リスト整備ツールの撤去+チュートリアル再構成。背景:URL補完・業種分類は v0.50 で「AI分析」に統合済みのため、リスト管理画面下部の『リスト整備ツール』(HP URL自動補完/業種カテゴリ自動分類)は冗長だった。(1) lists.html から『リスト整備ツール』セクション一式+autofill進捗スクリプトを削除(list_bp.autofill_urls / classify_industries ルートは残置・無害)。(2) これに伴いチュートリアルの独立『業種分類』ステップ(旧Step3)を廃止し7→6ステップに再構成:tutorial_module.check_step_status から旧Step3 dict削除+旧4〜7を3〜6にリナンバリング、テンプレ側の tutorial_current_step.num 参照を全更新(lists.html [3,4]/list_detail.html [3,4]/compose_contact.html 4・6/base.html '/ 6'/tutorial.html 6ステップ)。業種の大/中カテゴリは『AI分析(まとめて)』のfull-prepで引き続き付与される。(3) 手動追加(v0.53)を会社名も必須に変更=AI分析はメアドのドメインからHPを自動推測するためHPは任意のままだが、HP取得失敗時のGemini検索フォールバックとパーソナライズの拠り所として会社名は必須にした(manual_add.html+list_module.manual_add 両方でバリデーション)。
v0.53.0 2026-06-03
✍ 手動でリストに1社追加する機能。背景:これまで追加手段が CSV取込 と AI自動収集 の2つだけで、名刺交換した相手や単発で見つけた1社をサッと入れる手段が無かった。新規 /lists/manual-add(GET=フォーム / POST=登録)。メアドのみ必須、会社名/担当者/HP URL/業種/エリア/電話/パーソナライズメモは任意。CSV取込と共通ロジックでメアド重複チェック・営業NGドメイン除外・業種/エリア正規化を行い、unit_consumed=False のステージング状態で投入(AIアクション時に初めてユニット消費)。HP URL は http(s) 無しなら自動補完、共有DBにも best-effort で代表メアド送信。『追加して続けて入力』『追加してメール作成へ』の2ボタン。テンプレ manual_add.html、業種/エリアは既存値の datalist 補完。リスト管理(lists.html)と全リスト(list_detail.html)のヘッダーに『手動で追加』ボタンを追加。
v0.52.0 2026-06-03
🎲 送信時刻のランダムゆらぎ機能。背景:一括予約や追いメールが同一分(毎分起動のスケジューラ枠)に集中すると数十通が数秒で連続送信され『機械送信』に見える=コールド営業っぽさが出る。対策:予約送信・追いメールの送信予定時刻に+0〜N分のランダムオフセット(前方向のみ=指定時刻より前にはしない=過去化による送信スキップを防止)を加え、複数の処理枠に分散させて人が手で送ったような自然な間隔にする。実装:(1) SMTPSetting.send_jitter_minutes カラム追加(既定10、0=OFF、app.py で ALTER TABLE マイグレーション)、(2) send_module.apply_send_jitter(dt, user_id)=設定分数を読んで random.randint(0, N*60)秒 を加算(秒も散らして HH:MM:00 のきっかり感も回避)、(3) 初回予約は schedule_send で適用(flash は指定時刻+『ごろ』表示)、追いメールは _compute_next_followup_at で適用(各ステップ独立にゆらぎ)、(4) smtp.html に『送信時刻のゆらぎ(分)』入力欄+説明、smtp_module で 0〜60 バリデーション。毎分起動のスケジューラ仕様上、効くのは分単位のゆらぎ(同一分内の送信は1ループでまとめて処理されるため)。あわせて:予約送信の時刻選びを datetime-local(スクロールが飛ぶ問題)→『日付+30分刻みプルダウン』に分離(schedule_date/schedule_time、schedule_send は scheduled_at 後方互換あり)。compose_contact.html の表記整理(導線改善メモ→パーソナライズメモ、AI生成ボタンに残り回数 N/10)も同梱。
v0.51.2 2026-06-03
🏷 メール作成画面(compose_contact)まわりのUI表記を整理。(1) ユーザー向けラベル『導線改善メモ(パーソナライズ用)』を『パーソナライズメモ』に統一(compose_contact.html / auto_list_result.html / send_index.html、未生成警告文も)。DBカラム名 improvement_memo・AIプロンプト内の内部表現は変更なし。(2) 『AIでメールを生成する』ボタンを『AIでメール作成 N/10』表記に変更し、コンタクト単位の再生成残り回数(email_regen_count / EMAIL_REGEN_SOFT_LIMIT=10)を可視化。上限到達時は赤字で『上限に達しました』を表示。list_module.compose_contact が email_regen_limit をテンプレに渡す。(3) ボタン名変更に合わせ、チュートリアル誘導文(compose_contact.html Step5 / lists.html / list_detail.html / tutorial_module.py)の『AIでメールを生成する』参照を『AIでメール作成』に更新。
v0.51.1 2026-06-03
↩ v0.51.0 で入れた代表者名の Gemini ピンポイント取得(lookup_representative_name / ensure_representative_name)を撤去。オーナー確認の結果、代表者名が拾えなかったのは『メモ済みスキップ』が主因で、HP分析+Geminiフォールバックで実際は拾えていたため。余計な Gemini 消費を避けるため、まとめAI分析(_compute)・個別AI分析(enrich_contact) からの呼び出しと両ヘルパー関数を削除。v0.49 のフォールバック(HP取得失敗時に Gemini で代表者名込みメモ生成)はそのまま維持。v0.51.0 の進捗モーダル明るさ改善も維持。
v0.51.0 2026-06-03
🪪 代表者名の取得を確実化。原因:ブリーフに『代表者名を拾え』と書いても、HPの“トップページ”には代表者名が載ってないことが多く(会社概要ページにある)、まとめAI分析(HP取得成功時)では抽出できなかった。個別で拾えたのはHP取得が失敗→Geminiフォールバックが必ず代表者名を調べていたため。対策:brief_module.lookup_representative_name()(Geminiで氏名だけピンポイント検索)+ ensure_representative_name()(ブリーフが『代表』を含み、memoにまだ代表者名が無ければ取得して先頭に【代表者名:◯◯】付与)。まとめAI分析(_compute)・個別AI分析(enrich_contact)の両方に組み込み=どちらでも確実に拾う。(コスト注意:該当時1社あたりGemini1回。ブリーフが代表者名を求める場合のみ発動)。あわせて:進捗モーダルの背景を薄く(0.4)・ポップアップを純白+境界線+余白で『ポップアップだけ明るく』見やすく。完了/ステージ文言の『下準備』→『AI分析』統一。
v0.50.0 2026-06-03
🧹 コンタクト一覧のAI系ボタンを「AI分析」に統合してUIを整理(ボタンが散らかって邪魔、の解消)。(1) 旧『🚀まとめてAI下準備』→『🔍 AI分析(選択した会社をまとめて)』に改名(中身は URL補完→メモ→業種分類→予算判定 のまま)。(2) 別パネルの『🧠 AI パーソナライズ分析(bulk_enrich)』『💰 予算シグナル判定(budget bulk)』を撤去し AI分析ボタンに統合。(3) 各行は『AI分析』ボタンのみ残し、フル処理化=enrich_contact が URL補完+メモ(Gemini フォールバック込み)+予算判定💰 を一括実行。個別『💰判定』ボタンは廃止。AI分析ボタンは website_url 無しでも表示(URL補完+Gemini検索で対応)。(撤去したルート bulk_enrich / budget.bulk_judge / budget.judge_contact は残置・無害。判定基準ページ budget.settings はナビに継続)。送信/更新/削除など操作系ボタンは従来どおり。
v0.49.1 2026-06-03
🔄 「まとめてAI下準備」の進捗UX改善。(1) 進捗を window.NudgeProgress で画面中央モーダルに昇格(離脱警告付き)。(2) 開始直後や完了0件のうちは進捗バーを .indeterminate(床屋のクルクル=ストライプアニメ)にして「止まってる?」の不安を解消。実際に1件以上処理されたら通常の%バーに切替。done/error/送信失敗時は確実にモーダルを閉じる。
v0.49.0 2026-06-01
🧠 AI分析の Gemini ウェブ検索フォールバックを追加。背景:大手企業はサイトが Cloudflare/CAPTCHA でBot保護され HPスクレイピングが失敗→メモが空になる問題があった。brief_module.research_memo_with_gemini() を新設し、HP取得が失敗/空(captcha/403/dns/content_empty)の時に Gemini+Google検索で会社を調べてメモを生成。プロンプトに『1行目に【代表者名:◯◯】を必ず書く(捏造禁止)』を組み込み=**ゲートキーパー突破に効く代表者名を取得**(オーナーの知見:代表者名が本文にあるとゴミ箱直行率がほぼ0)。組み込み先:まとめてAI下準備(_full_prep_worker の _compute)+個別AI分析(enrich_contact)。代表者名をメール本文で使うには、ブリーフに抽出指示+メール生成指示を追加する運用と併用。(補足)v0.48.1:コンタクト一覧の詳細パネルを左固定+ビューポート幅(min(980px,100vw-40px))に収め、横長テーブルでの右見切れを解消。
v0.48.0 2026-06-01
⚡ 「まとめてAI下準備」(list_module._full_prep_worker) を並列化して大幅高速化。従来は各社を1件ずつ直列処理(HP取得+Claude分析+Gemini検索+Claude判定で1件30〜60秒→100件で30分超)。ネットワーク/AI処理を ThreadPoolExecutor で同時実行(既定5並列、env FULL_PREP_WORKERS で1〜10調整可)し、DB書き込みはメインスレッドに集約(SQLiteのロック競合を回避)。設計:Step A=ユニット消費+URL補完(直列DB)→ Step B=各社のHP取得/分析/予算判定を並列compute(DB書き込みなし)→ Step C=結果をまとめてDB反映 → Step D=業種分類1回。これで体感数倍速。※同時実行数を上げすぎると Anthropic/Gemini のレート制限に当たるため既定5。Gemini無料枠が細いので大量実行時は予算判定がunknown寄りになることあり。
v0.47.0 2026-06-01
📮 送信インフラの方針転換:SendGrid がコールドメール審査で落ちたため、「ユーザー自身のビジネスメール(Google Workspace / Microsoft 365)を接続して自社ドメインから送る」モデルへ正式移行。中央ESPを持たない=審査落ち・一斉停止リスクが消え、自社ドメイン送信で到達率も向上(コールド営業の業界標準=Lemlist/Instantly方式)。(1) 送信メール設定ページ(smtp.html)を刷新:Google Workspace/M365 のワンクリック・プリセット(smtp.gmail.com:587 等を自動入力)+アプリパスワードの取り方を手順付きで案内。(2) オンボーディングの送信ステップを『自社のビジネスメールを接続(Google Workspace/M365)』に文言変更+アプリパスワード案内。(3) SendGrid 専用の『送信ドメイン認証』ナビリンクを撤去(ページ/ルートは残置・無害)。エンジンは既存の `_send_email`(SendGrid優先→SMTPフォールバック)がそのまま機能:Render の環境変数 SENDGRID_API_KEY を削除すれば全体が自動的にユーザーSMTPモードに切替(コード変更不要)。★運用:オーナーは nudge-hq.co.jp を Google Workspace 化 → アプリパスワードでSMTP接続 → テスト送信OK後に SENDGRID_API_KEY を削除。
v0.46.0 2026-06-01
📣 LP(landing.html)のヒーロー直下に「掲載メディア」の流れるティッカー(回転寿司風の無限スクロール)を追加。PR TIMES 配信で転載された大手・経済メディア(朝日新聞デジタル/毎日/産経/時事/PRESIDENT Online/東洋経済/NewsPicks/JBpress/ライブドア/Infoseek/@DIME/ASCII/テレ東プラス/TBS NEWS DIG 等)を社会的証明として表示。CSS marquee(@keyframes media-scroll、リスト2重描画でシームレスループ、hoverで一時停止、両端フェードのmask、prefers-reduced-motion対応)。媒体名は media_list で編集可。誇大広告防止のため『※PR TIMES配信による各メディアへの掲載実績』の注記付き。
v0.45.1 2026-06-01
🎨 コンタクト一覧の「詳細」(メモ・備考)の表示を改善。従来は詳細セル内で <details> が右に伸び、sticky な操作列に被って見切れていた。バッジ部分をトグルボタン化し、クリックするとその行の下に colspan=7 の全幅パネルが開く方式に変更(メモ/備考を左右2カラムで広々表示、予算判定の根拠も表示)。行の左側のデッドスペースを活用でき、見切れも解消。
v0.45.0 2026-06-01
🚀 「まとめてAI下準備」ボタンを追加。バラバラだった URL補完・AI分析・業種分類・予算判定を依存関係順に1本のバックグラウンドジョブで一括実行(list_module._full_prep_worker / /lists/full-prep)。順序:① URL補完(メアド推測・無料でGeminiクォータ温存)→ ② AI分析メモ → ③ 業種分類(全体1回)→ ④ 予算判定💰。全リスト上部に🚀パネル(選択→1クリック、最大100件、1進捗バー、overwriteオプション、表示中全選択ヘルパー)。コンタクト単位で初回ユニット消費(既存と整合・チュートリアルのサンプルは消費せずスタブ)。個別ボタン(AI分析/業種分類/予算判定/URL補完)は従来どおり併存。チュートリアル中は業種分類をスタブ適用に切替。
v0.44.0 2026-06-01
💰 予算シグナル判定機能を追加(法人営業の『リストがすべて』という知見に基づくリスト優先順位づけ)。budget_module.py 新設:各社について Gemini+Google検索で根拠(採用・資金調達・広告・拡大等)を収集し、ユーザーが指定した基準で Claude が likely/unlikely/unknown を判定。詳細列に 💰(根拠ツールチップ付き)を表示。個別ボタン(💰判定)+一括(選択をバックグラウンドジョブで判定、最大100件、BulkJob+進捗ポーリング流用)。判定基準はユーザー自由記述(/budget/settings、CompanyProfile.budget_criteria、未設定時は営業ベテラン知見ベースのデフォルト)。全リストのフィルタに『💰予算: ありそう/なさそう/未判定』を追加。判定はコンタクト単位で初回ユニット消費(既存AIアクションと整合・idempotent)。Contact に budget_status/budget_reason/budget_checked_at、CompanyProfile に budget_criteria を追加。チュートリアルのサンプル企業はスタブ判定(API呼ばない)。★正直な制約:求人サイト(マイナビ等)の直接スクレイピングは不安定なため、Web全体/ニュースから基準合致シグナルを探す方式=あくまで推定。Gemini クォータを消費(枯渇時は根拠収集が空→unknown寄りになる)。
v0.43.0 2026-06-01
🛠️ 定期メンテナンスを実機能化(規約に書くだけでなく実際に停止)。utils.is_maintenance_window():毎週 土曜・日曜の21:00〜翌6:00(JST)を判定。環境変数 MAINTENANCE_MODE で上書き可(off=無効 / on=常時メンテ〔臨時メンテ用〕/ 既定auto=スケジュール)。(1) app.py before_request _enforce_maintenance:メンテ中は管理者以外に 503 + maintenance.html を返す。稼働継続するのは static / healthz / auth(admin ログイン用)/ legal / u(配信停止)/ track / billing(Stripe webhook・決済)/ pre-register / ランディング(/, /changelog)。それ以外のツール本体は停止。(2) /healthz 追加(メンテ中も常に200。監視・Render用にフラッピング防止)。(3) バックグラウンド送信も停止:_process_due_scheduled_sends と reengagement 自動処理の冒頭でメンテ判定して return。(4) templates/maintenance.html 新規(メンテ時間の案内付き)。admin は常にバイパスして作業・確認可能。
v0.42.2 2026-06-01
📜 利用規約に SLA 系の条項を追加(枝番で既存条番号を維持)。第6条の2(定期メンテナンス)=毎週土曜・日曜の21:00〜翌6:00(JST)は事前通知なく停止/制限する場合があり、稼働率算定から除外。第6条の3(稼働率)=月間稼働率の目標値99.0%。算定式と除外事由(メンテ・不可抗力・利用者起因・第三者サービス障害・未払い停止)を明記。第6条の4(稼働率未達時のサービスクレジット)=当社責で目標未達の月は、請求ベースで月額の10%/25%/50%(稼働率帯別)を翌月以降の利用料から減額する形で返金。上限は当月利用料、トライアル/無料は対象外、稼働率未達に関する唯一かつ排他的責任と明記。特商法ページの返品・キャンセル欄にもサービスクレジットへの参照を追記。最終更新日を2026年6月1日に更新。★稼働率99.0%・クレジット率はオーナー確認済みの値。文言は必要に応じ弁護士レビュー推奨。
v0.42.1 2026-06-01
⚖️ 優良誤認(誇大広告)の是正。料金ページ Enterprise カードに『Salesforce / Sansan / Musubu との連携』と 記載していたが、これらは未実装(API も Sansan/Musubu はパートナー契約が前提で自由に叩けない)。提供していない機能を提供機能として表示するのは景品表示法上アウトのため、『外部ツール連携のご相談(CRM・名刺管理ツール等、要件に応じて個別開発で検討)』に軽量化。重複する『カスタムインテグレーション開発』行は統合して削除、『SLA保証』も断定回避で『SLA保証のご相談』に。※CSVの列名自動マッピング(Musubu/Sansan のエクスポート列を認識)は事実なので変更なし。※お問い合わせフォームのツール名プレースホルダ(顧客への質問)も変更なし。
v0.42.0 2026-06-01
🧾 請求書払いをツール内で完結&自動化(メールお問い合わせを廃止)。`/billing/invoice-request` フォーム新設:プラン・サイクル・会社名・請求書送付先メールを入力して送信すると、Stripe で Customer + Subscription(collection_method='send_invoice', days_until_due=30) を自動作成し、Stripe が請求書をメールで自動送付。前払いモデルのため申請後は set_pending_payment で『入金待ち』(アクセス不可)になり、入金(invoice.paid webhook)で自動的に利用開始(reactivate)。オンボーディングの支払い判定 `_has_card` は stripe_subscription_id 有無で見るため、請求書サブスク作成で支払いステップも自動クリア。pricing.html の『請求書払い→お問い合わせ』を『請求書払いで申し込む』ボタン(→ invoice_request)に変更、onboarding のカードステップにも請求書払い導線を追加。Standard/Pro のみ対象。★Stripe側で1回だけ確認:請求書の自動メール送信設定(ダッシュボード → 設定 → Billing → 『確定した請求書を顧客にメール送信』をON)。
v0.41.3 2026-06-01
🩹 料金ページの『お支払い・プラン管理』ボタンの表示条件を修正。v0.41.2 では stripe_subscription_id だけで判定していたため、Stripe 決済を通していない (stripe_customer_id が無い)admin/手動 plan 設定アカウントにもボタンが出て、押すと 『お支払い情報がまだありません』になっていた。has_subscription 判定に stripe_customer_id 必須を追加し、Stripe 顧客が存在する人だけにポータル導線を表示。それ以外は通常どおり『申し込む』を表示。
v0.41.2 2026-06-01
💳 プランのアップ/ダウングレードを Stripe カスタマーポータル化(重要なバグ修正含む)。【バグ】従来は契約中ユーザーが料金ページで別プランを押すと checkout が毎回新規サブスクを作成し、二重課金+再トライアル付与になっていた(プリローンチで実顧客なしのため事故は未発生)。(1) サブスクを『カタログ価格(Stripe Price + lookup_key で冪等自動作成 `nudgehq_{plan}_{cycle}_{mode}`)』ベースに変更(従来の price_data 都度作成はポータルでプラン切替できないため)。`_get_or_create_price` 追加、checkout を price 指定に。(2) `/billing/portal` 追加:Stripe カスタマーポータルへ誘導(プラン変更・支払い方法変更・解約をユーザー自身が/差額は日割り自動精算)。(3) checkout は、既に有効サブスクがある人が押したら新規作成せず portal へリダイレクト(二重課金防止)。(4) pricing.html:契約者には『お支払い・プラン管理』バナー + 各カードを『現在のプラン/このプランに変更(ポータル)』表示。(5) webhook customer.subscription.updated で plan を Stripe 側の price から逆引きして同期(`_plan_from_subscription`)。(6) 請求書払いは self-serve チェックアウトには出せない(仕様+信用リスク)ため、料金ページに『請求書払い希望→お問い合わせ』導線を追加。★Stripe側で1回だけ必要:カスタマーポータルの有効化 + 切替対象プラン(3商品)の選択。
v0.41.1 2026-06-01
🔁 請求書払いを前払い(プリペイド)モデルに合わせて調整。設計:入金確認→その月の利用券を付与(先に使わせない)。未入金で期日超過→停止→10日で自動BAN。(1) account_module.set_pending_payment() 追加:請求書払い登録時の初期状態=『入金待ち』(account_status=suspended だが suspended_at=None =自動BANカウントは回さない)。請求書を出す前の新規顧客が10日で誤BANされるのを防ぐ。(2) suspend_account() を修正:suspended_at が None のとき(入金待ち含む)に now を打ってカウント開始。=Stripe past_due(期日超過)で初めて10日カウントが始まる。(3) admin『請求書払いで登録(入金まで停止)』ボタン:set_pending_payment を呼び、入金(invoice.paid)で自動復帰。(4) admin 一覧で『⏳ 入金待ち(請求書)』と『⏸ 一時停止(自動BANまであとN日)』を区別表示。(5) /account/suspended ページも入金待ち(自動で開く案内)と期日超過(自動解約warning)で文面を出し分け。
v0.41.0 2026-06-01
🔐 顧客管理(アカウントの生殺与奪)機能を追加。請求書払いの未入金対策。(1) User に account_status(active/suspended/banned)+ suspended_at/banned_at/suspend_reason/payment_method/invoice_due_date/admin_note を追加。新規 account_blacklist テーブル(BAN メアドの再登録防止)。(2) account_module.py 新設:suspend/reactivate/ban/unban + ブラックリスト + 自動BAN(process_suspension_auto_ban)+ /account/suspended 一時停止案内ページ。SUSPEND_TO_BAN_DAYS=10。(3) 一時停止=ログイン可だがツール停止:app.py before_request _enforce_account_status で /account/suspended に隔離。BAN=ログイン不可(auth.login で弾く + before_request で強制ログアウト)。register でブラックリスト拒否。(4) 停止/BAN 中はバックグラウンド送信(予約・追いメール・再営業)を全てスキップ。(5) 日次ジョブ auto_ban(24h):一時停止から10日経過で自動BAN+ブラックリスト(データは削除しない)。(6) Stripe webhook 連携:invoice.paid→復帰 / invoice.payment_failed・subscription past_due→一時停止。(7) admin パネル(/admin/beta_users)に顧客管理列:支払方法・状態・自動BANまでの残日数 + 一時停止/復帰/即BAN/解除/請求書払い設定ボタン(admin 自身は操作不可)。(8) 料金ページ(pricing)の Standard/Pro 特徴に「請求書払い(銀行振込)対応」を表示。
v0.40.2 2026-06-01
💬 LP・料金まわりの文言調整。(1) LP(landing.html)料金ミニセクションの「詳しい料金を見る」ボタンを削除(押すと billing.pricing → Stripe に飛んでしまうため)。(2) プラン訴求を「営業マンN人分の業務を削減」→「工数を削減」に変更(landing.html / billing_module.py / tutorial_module サンプルメール / CLAUDE.md)。日本は気軽に人員削減できないため『業務削減=人を切る』の連想を避け、『工数(手間・時間)を削減』とした方が刺さるという判断。
v0.40.1 2026-06-01
🎯 チュートリアルの最終ステップと追いメール設定を改善。(1) 【Step7】SMTP設定ページのテスト送信 → メール作成画面(compose)の「🧪 テスト送信」に変更。ステップ5で作った下書きを自分宛に送る、本番と同じ操作で締めくくる。action_endpoint を smtp.settings → list_bp.pool に、compose_contact.html に Step7 誘導カード(#test-send-draft-btn をパルス)追加。test_send_draft はプレビュー送信で SentEmail を記録しないため、完了判定は session['tutorial_test_sent'] フラグに変更(test_send_draft 成功時に is_tutorial_active ならセット、end_simulation でクリア)。チュートリアル中はテスト配信先未設定でもログイン中メアドにフォールバック(compose 表示・test_send_draft 両方)。(2) 【Step6】追いメール追加フォームに、そのまま本番でも使える文面({{会社名}}/{{担当者名}}/{{初回件名}}/{{初回送信日}} 入り)を初期入力。一から書く手間をなくす(自由に編集可)。
v0.40.0 2026-06-01
🎮 RPG風チュートリアル解説ポップアップを追加。「AIは使いこなせない」という先入観を崩すため、徹底的に親切な手取り足取りの体験を目指す。各ステップの操作画面に着くと「ステップN へようこそ / このステップでは○○することで○○できます」という 解説モーダルが自動で1回ポップ(sessionStorage でステップごと1回、しつこくなりすぎない)。CTAボタンを押すと閉じて、本物の操作ボタンが紫パルスで光る(既存 tutorialGuideTo を流用)。実装:tutorial_module.check_step_status の各ステップに intro={title, body[], cta, jump?, pulse?} を追加、base.html に #tutorial-intro-overlay モーダル(request.endpoint == action_endpoint の時のみ描画)、main.js に window.tutorialGuideTo() 抽出 + モーダル自動表示ロジック、style.css に .tutorial-intro-* スタイル。全7ステップ分の解説文を用意。pulse 対象ボタンに id 付与(#tutorial-step1-btn / #add-followup-section+submit / #test-send-submit 等)。
v0.39.3 2026-06-01
🧭 チュートリアルのステップ間ナビゲーション改善。(1) Step2 自動収集の完了後の遷移先を list_bp.pool(全リスト)→ list_bp.index(リスト管理)に変更。Step3(業種分類)の操作はリスト管理画面下部にあるため、従来は全リストに飛ばされ「進捗を確認」を経由しないと Step3 に辿り着けなかった。(2) base.html の全画面共通バナーに、現在ステップの操作画面へ直接ジャンプするボタンを追加(tutorial_current_step.action_endpoint へ url_for、操作画面に既に居る時=request.endpoint 一致時は非表示)。これでどのページに居ても1クリックで次の操作画面に行ける。(3) Step3 の desc/action_label の用語を実態に合わせて「リスト管理画面」に修正(旧「全リスト画面」は list_bp.pool と紛らわしかった。業種分類セクションは list_bp.index = リスト管理)。
v0.39.2 2026-06-01
🎯 チュートリアル Step1(CSV取込)を実画面型に。従来は tutorial.start で2社を即挿入して次ステップへ進むため 本番の核心である『列マッピング → プレビュー → 確定』をユーザーが一度も体験できなかった。新ルート list_bp.upload_tutorial_sample(POST)を追加:サンプルCSV(tutorial_module.sample_csv_bytes)を サーバー側で一時ファイル化し、本物の upload POST と同じく session に filepath/filename をセットして mapping.html を表示。以降は本物の upload_preview → upload_confirm をそのまま通る。upload.html のショートカットを『サンプルCSVを読み込んで列マッピングへ進む』誘導に変更(自分のCSVアップロードも併記)。OS のファイル選択ダイアログだけ省略し、Nudge 固有の操作(列対応付け・重複プレビュー・確定)は完全に体験させる。サンプルCSVの列(会社名/メールアドレス/業種/エリア/HP URL)は全て自動マッピング辞書にヒットするため確認するだけで進める。
v0.39.1 2026-06-01
🐛 v0.39.0 で実ボタン誘導に切替えた際の不具合2件を修正 + Step2 も同方式に統一。(1) 【500エラー修正】Step4 で本物の「AI分析」ボタン(list_bp.enrich_contact)をサンプル企業に押すと エラー500。原因:チュートリアル分岐で `brief` 変数が未定義のまま末尾の flash で `brief.name` を参照し NameError。しかも db.commit はその前に成功するためメモは保存され Step5 に進む→「Step5表示+500」状態だった。enrich_contact のチュートリアル分岐手前で `brief = None` を初期化。(2) 【Step2 実ボタン誘導化】auto_list.html のショートカット(tutorial.auto_collect)を廃止し、本物の入力フォーム + 「AIで自動収集を開始する」ボタン(#submit-btn)へパルス誘導。auto_list_module.index POST に is_tutorial_active 分岐を追加し、ユーザーが業種・地域に何を入力しても サンプル3社をスタブ追加(Gemini 不使用・ユニット消費なし)。AJAX は {tutorial:true, redirect} を返し JS が即遷移。tutorial_module に add_sample_contacts_for / add_auto_collect_samples を追加。
v0.39.0 2026-06-01
🎯 チュートリアル Step3-5 を「本物のボタンの場所を覚える」体験に再設計。背景:v0.38.3 で追加したヘッダー直下の1クリックショートカットは、本物のボタン(ページ下部の折りたたみ や 各コンタクト行)とは別の場所・別エンドポイントだったため、押しても本番でどこを操作するか身につかず 「何が起きたか分からない」状態だった(v0.38 の実画面型の狙いと矛盾)。(1) ショートカットを廃止し、誘導カードを「本物のボタンの場所へ移動・ハイライト」型に変更。Step3:lists.html 下部の「業種カテゴリ自動分類(AI)」セクション(#classify-section)を開いて 本物の「AI で業種カテゴリを分類」(#classify-submit) をパルスで指す。Step4:list_detail.html で各行の本物「AI分析」ボタンをパルス。Step5:list_detail の「送信画面で開く」→ compose_contact.html の本物「AIでメールを生成する」(#generate-btn) をパルス。(2) 共通ヘルパー:main.js の data-tutorial-jump / data-tutorial-pulse(<details> 自動展開 + スクロール + 紫パルス)、style.css に @keyframes tutorialPulse / .tutorial-pulse。(3) Step3 の本物エンドポイント list_bp.classify_industries にチュートリアル分岐を追加:is_tutorial_active 中は tutorial_module.apply_sample_industry_categories でサンプルを Claude 無し即時分類(コスト・待ち時間ゼロ)。Step4/5 の本物エンドポイントは既存のスタブ分岐(list_module enrich/compose)を流用。(4) tutorial.classify_industries ルートは共通ヘルパー呼び出しに整理(後方互換で残置)。
v0.38.3 2026-05-20
🎯 チュートリアル Step3-5 の「どこをクリックしていいか分からない」問題を解消。templates/lists.html のヘッダー直下に、チュートリアル中(Step3/4/5)専用の紫グラデショートカットカードを追加。Step3:「サンプル5社の業種を自動分類する」(tutorial.classify_industries)、Step4:「サンプル5社の AI分析を一括実行」(tutorial.generate_memos)、Step5:「サンプル1社の AIメールを生成」(tutorial.generate_email)。本番では既存の「業種カテゴリ自動分類」セクションや個別コンタクト画面の AI ボタンを使うが、チュートリアル中は1クリックで該当ステップを完了できる体験を提供。ユーザーは /lists/index に飛ぶだけで該当ステップの実行ボタンが目立つ位置に出る。
v0.38.2 2026-05-20
🐛 チュートリアル関連バグ2件修正。(1) /auto-list(自動収集画面)にチュートリアル中アクセスできず /tutorial にリダイレクトされる問題:原因は tutorial_bypass のコメントに「自動収集」と書いてあるのに実 URL prefix が /auto-list で /lists とは別だったため。tutorial_bypass に /auto-list を明示追加。(2) シミュ中の Step6(追いメール設定)/ Step7(テスト送信)が admin の既存データで最初から完了判定になる問題:admin.start_simulation で session['simulate_started_at'] に開始時刻を記録、tutorial_module.check_step_status でシミュ中は FollowUpTemplate.updated_at / SentEmail.sent_at が シミュ開始以降のもののみカウント。end_simulation で session キーもクリア。
v0.38.1 2026-05-20
🧹 シミュレーション終了時の進捗完全リセット + チュートリアル見直し導線追加。(1) admin.end_simulation でサンプル Contact(メアド *.tutorial.example.test)+ 関連 SentEmail を全削除。これでシミュ中の進捗が admin の本物データに混ざらず、毎回まっさらな状態でシミュ開始できる。(2) base.html ナビ設定ドロップダウンに「チュートリアルを見直す」追加(リンク先 /tutorial/?force=1)。完了済ユーザーでもいつでも7ステップの説明文と該当画面リンクを再確認できる。(force=1 で tutorial.index が dashboard リダイレクトをバイパスする既存ロジック流用)
v0.38.0 2026-05-20
🎓 チュートリアルを「実画面 × サンプルデータ」型に再構築。背景:v0.36 では /tutorial 画面内のボタンで完結する設計だったが、ユーザーが本物の UI を触らないため「本番でいざ使う時に画面の場所が分からない」状態になっていた。(1) tutorial.html を「進捗確認 + 該当画面リンク」に簡素化、実行ボタンを廃止して各実画面へ誘導。(2) tutorial_module.get_current_step_info() 新規ヘルパー:base.html バナーで現在ステップ取得。(3) app.py に inject_tutorial_step context_processor 追加。(4) base.html に全画面共通のチュートリアル誘導バナー(紫グラデ、現在ステップ + 説明 + 進捗確認リンク)。(5) templates/upload.html にチュートリアル中(Step1)専用ショートカット:「サンプル2社をワンクリック取込」。(6) templates/auto_list.html にチュートリアル中(Step2)専用ショートカット:「サンプル業種で実行」。(7) list_module.enrich_contact(AI分析):サンプル企業なら HP取得 + Claude呼出をスキップしてスタブメモを返す。(8) list_module.compose_contact AI生成:サンプル企業なら Claude呼出をスキップしてスタブメールを返す。効果:ユーザーは本物の画面・本物のボタンを操作するが、サンプル企業に対しては API コストゼロのスタブ応答が返るので体験が早い。
v0.37.7 2026-05-20
🐛 シミュレーション中のドメイン認証ステップで詰まる問題を修正。原因:admin が既に SendGrid に nudge-hq.co.jp を登録済のため、シミュ中に同じドメインを再登録できず 「既に登録されています」エラーで詰まっていた。(1) /admin/sim-set-domain エンドポイント新設:VerifiedDomain にダミー認証済みレコード(domain='sim-demo-xxxx.example.test', is_verified=True)を作成。(2) sender_domain.html 上部にシミュ中専用のスキップカード追加(黄色背景の警告風UI)。(3) /admin/end-simulation のクリーンアップに「sim-demo-」プレフィックスのダミー VerifiedDomain 削除を追加。これでシミュ中もオンボーディング Step4 → チュートリアルまでスムーズに進める。
v0.37.6 2026-05-20
🐛 シミュレーションモード関連バグ2件修正。(1) /admin/sim-set-card ボタンが反応しない問題:原因は _enforce_onboarding の bypass_prefixes に /admin/ が含まれていなかったため、シミュ中の admin が /admin/sim-set-card にPOSTすると /onboarding にリダイレクトされていた。bypass_prefixes に /admin/ を追加して解消。(2) シミュレーション中の途中脱出手段追加:base.html にシミュ中バナー(黄色)+「終了して admin に戻る」ボタンを全画面共通表示。どこからでも1クリックで admin 状態に復帰できる。
v0.37.5 2026-05-20
🛡 完全自動モード ON 時の二重確認モーダルを追加。背景:完全自動モードはユニットが勝手に消費されるリスクがあるが、説明文を読まずに ON にするユーザーがクレームの元になりやすい。(1) company.html の reengagement_auto_enabled チェックボックスに data-initial-value 追加。(2) OFF→ON にしようとした瞬間に専用モーダルを表示。(3) モーダル内:警告メッセージ(最大100ユニット/日が勝手に消費されるリスク)+ 「上記を理解したうえで有効化します」チェック必須。(4) 理解チェックを入れないと「有効化する」ボタンは disabled。(5) キャンセル / モーダル外クリック / Esc キーで OFF に戻す。(6) ON→OFF はモーダルなしで通常通り(解除は事故にならない)。
v0.37.4 2026-05-20
🔁 v0.37.3 をロールバック。execute_reengagement の実行時ユニット消費を復元。理由:v0.37.3 では「実行は無料、AI生成時に消費」としたが、execute_reengagement の中で既に HP再スクレイピング + Claude再分析という AIアクションを行っているため、CSV+一括AI分析モデル(=一括AI分析実行時にユニット消費)と一貫しない。ユーザー指摘で気づき、既存モデルとの整合性を優先して revert。(1) reengagement_module.execute_reengagement で activate_contact_for_unit を再び呼出。(2) unit_consumed を一旦 False に戻してから activate(idempotent な activate を通すため)。(3) reengagement.html / company.html の説明文を「実行時に1ユニット消費」に戻す。(4) 完全自動モードの警告を強化:1日100件 = 最大100ユニット/日が勝手に消費される可能性を明記。整合性:自動収集 = 投入時消費 / CSV = ステージング後の一括AI分析時消費 / 再営業 = 実行時消費。
v0.37.3 2026-05-20
💰 再営業のユニット消費タイミングを修正。背景:execute_reengagement 内で activate_contact_for_unit を呼んでいたため、「⚡実行」ボタン押下時点で勝手にユニット消費されていた。これだと「新規営業用の枠を再営業に勝手に奪われた」という不満になりクレームリスク大。(1) reengagement_module.execute_reengagement から activate_contact_for_unit 呼び出しを削除、代わりに unit_consumed=False をセット → 次の AI生成 で既存ロジック経由で再消費される。(2) reengagement.html / company.html の説明文を「AI生成時に消費」に修正。(3) bulk_execute の確認ダイアログも修正。効果:実行ボタンは無料(リセット + HP再分析のみ)、ユニット消費は AI生成ボタンを人間が押した瞬間のみ。勝手に消費されない透明性 + 新規営業枠を奪われる懸念ゼロ。
v0.37.2 2026-05-20
📣 再営業リスト新規追加リマインドバナー。(1) User.last_reengagement_viewed_at カラム追加。reengagement.index 開いた時に更新。(2) reengagement_module.count_new_candidates_since(user_id, since) 新規追加:next_reengagement_at が since より新しい & 現在以前 & 対象外ステータス以外、の件数。(3) app.py に inject_reengagement_notice context_processor 追加 → 全画面共通バナー判定。(4) base.html にリマインドバナー:「再営業リストに N 社追加されました。顧客になった会社があれば成約済みマークで除外を」+ 確認ボタン。目的:再営業の候補入りに気づかずに既存顧客に営業メールを送る事故を予防する親切心。
v0.37.1 2026-05-20
🎉 Contact.status='converted'(成約済み)を追加。背景:リンククリック型の成功定義の場合、システムは「興味を示した」までは検知できるが「商談→契約」までは知らないため、既存顧客に半年後にまた営業メールを送ってしまう重大な事故リスクがあった。(1) reengagement_module.get_candidate_query 候補判定で 'converted' を除外。(2) reengagement_module.schedule_reengagement_for_contact でも 'converted' を除外(新規シーケンス完走時に再営業セットしない)。(3) send_module.send_followup で converted は送信スキップ。send_draft_for_contact 冒頭でも converted を弾く。(4) reengagement_module に /<id>/mark-converted / unmark-converted エンドポイント追加(誤マーク救済可)。(5) reengagement.html の各候補行に「🎉 成約済み」ボタン追加、上部に注意バナー表示。(6) compose_contact.html の送信先ヘッダーに「成約済みにする」ボタン + 既に converted の場合は緑バッジ + 解除ボタン。これで「既存顧客に営業メール送ってトラブル」という最悪シナリオを構造的に防止。
v0.37.0 2026-05-20
🔄 再営業(リエンゲージメント)機能を追加(v0.37)。目的:日本の法人約300万社のリスト枯渇問題への対処。シーケンス完走(無反応で終わった)コンタクトを N ヶ月後に再分析+再メール+再シーケンスで「半永久ループ」を実現。プロプラン8年で用済みになる新規営業前提を覆し、解約理由を消す = LTV 最大化が狙い。(1) 新規 reengagement_module.py:候補判定、HP再分析、シーケンスリセット、自動/手動の両モード対応。(2) Contact に next_reengagement_at / reengagement_count / last_reengagement_at / reengagement_months(個別上書) 追加。(3) CompanyProfile に reengagement_months_default(既定6ヶ月)/ reengagement_auto_enabled(完全自動ON/OFF) 追加。(4) send_module.py:シーケンス完走時(next_followup_at が None になった時)に schedule_reengagement_for_contact() を自動呼出。(5) APScheduler に1日1回の再営業ジョブ追加。reengagement_auto_enabled=True のユーザーには自動再営業実行(1日100件まで暴走防止)。(6) 新規 /reengagement ルート群:候補一覧、個別実行、一括実行、延期、スキップ。(7) templates/reengagement.html 新規作成。base.html ナビに「再営業」追加。(8) company.html に「再営業設定」セクション追加(間隔・自動モード ON/OFF)、company_module.py 保存処理に対応。(9) 1再営業 = 1ユニット消費(新規と同じ、原価吸収)。(10) 対象外条件:返信あり / 配信停止 / 不達。
v0.36.1 2026-05-20
🧪 admin 新規ユーザー体験シミュレーション機能。目的:admin のままで本物のオンボーディング/チュートリアルフローを確認できるように。(1) usage_module.is_admin_effective(user):session['simulate_new_user'] が True のとき admin でも False を返す。プラン制限は is_admin() で判定するので admin 特権は維持される。(2) app.py の _enforce_onboarding と tutorial_module の admin バイパスを is_admin_effective に変更。(3) admin_module に /start-simulation /end-simulation /sim-set-card 追加。開始時に onboarding_completed_at / tutorial_completed_at / stripe_subscription_id を session に退避してリセット、終了時に復元(シミュレーション中のダミー sub は除外)。(4) admin_beta_users.html に「シミュレーション開始/終了」ボタン追加。シミュ中は警告バナー表示。(5) onboarding.html Step2 にシミュ中専用の「ダミー設定でスキップ」ボタン追加(本物の Stripe Checkout を回避)。
v0.36.0 2026-05-20
🎓 強制チュートリアル機能を追加(v0.36)。「AIわからんおじさんでもわかる」レベルの圧倒的な簡単さを目指して、オンボーディング完了後の必須7ステップ。(1)新規 tutorial_module.py:架空企業5社(メアド .tutorial.example.test)の定義 + 各社のスタブメモ・スタブメール、ステップ完了判定(DB状態から自動)、AI実行スタブ(コストゼロ・待ち時間ゼロで「本物っぽい」体験)、(2)新規 templates/tutorial.html:オンボーディングと同パターンの7ステップアコーディオン+進捗バー、(3)新規 templates/tutorial_completed.html:完了画面 + サンプルデータ削除選択、(4)7ステップ:①CSV取込②AI自動収集③業種分類④AIメモ⑤AIメール⑥追いメール設定⑦テスト送信、(5)User に tutorial_step / tutorial_completed_at カラム追加、既存ユーザーは completed_at で埋め戻し(影響ゼロ)、(6)app.py の _enforce_onboarding を拡張:オンボーディング完了 & チュートリアル未完了なら /tutorial に強制リダイレクト、tutorial 中は /lists /email-settings /smtp 等の操作ページにアクセス可、(7)onboarding.finish の遷移先を /tutorial に、(8)完了画面でサンプル削除オプション(メアドが .tutorial.example.test で一括削除)。目的:プラットフォーム命運を左右する初回体験の質を最大化、本物の機能を1クリックで体験させて離脱率最小化。
v0.35.7 2026-05-20
📅 ローンチキャンペーン期間を 6/15-7/31 → 6/15-8/31 に延長(trial 200ユニットの適用期間)。影響箇所:(1) usage_module.PROMO_END_DATE: _dt(2026, 8, 1) → _dt(2026, 9, 1)、(2) pre_register_module.PROMO_END_DATE: date(2026, 8, 1) → date(2026, 9, 1)、(3) 事前登録お礼メール(pre_register_thanks.html)と Resend 経由のテキスト「2026年7月31日まで」→「2026年8月31日まで」、(4) CLAUDE.md のサービス段階表「2026-06-15〜2026-07-31」→「2026-06-15〜2026-08-31」、「2026-08-01〜通常運用」→「2026-09-01〜通常運用」。判定ロジック:user.created_at < PROMO_END_DATE (= 9/1) なら 200U、それ以降は 100U。
v0.35.6 2026-05-20
📅 サービス正式開始日を 2026-06-01 → 2026-06-15 に変更。影響箇所:(1) pre_register_module.py の LAUNCH_DATE 定数(pre_launch_mode 判定用)、(2) LP(landing.html)のヒーロー・最終CTA、(3) 事前登録ページ(pre_register.html / pre_register_done.html)、(4) 事前登録お礼メール(emails/pre_register_thanks.html)、(5) CLAUDE.md の内部ドキュメント全箇所。なお、ローンチキャンペーン期間(usage_module の trial 200ユニット上限)は 2026-09-01 まで据え置き。BETA_MODE 環境変数の解除日も Render 側で 6/15 に変更必要。
v0.35.5 2026-05-20
🧭 メール作成画面のナビ改善 3 件。(1) list_module.prev_contact を新規追加(ID 昇順で「前」= 視覚的に上のコンタクト)、「先頭まで到達」flash で末尾到達時と同じ UX。(2) next_contact / prev_contact の両方で `?embed=1` クエリを引き継いで、スライドパネル内(iframe)で開いた場合に embed モードを維持。従来は次のコンタクトに進むと iframe 内でフルナビ付き画面が表示される問題を解消。(3) compose_contact ルートで has_prev_contact / has_next_contact を判定してテンプレに渡す。compose_contact.html では、(a) 「前のコンタクト」ボタンを新規追加、(b) 両ボタンとも前後がない場合は span 要素で disabled 表示(opacity:0.4 + cursor:not-allowed)、(c) embed_mode 時は「全リストへ戻る」リンクに target=_top を付けて親フレームを遷移(スライドパネルを抜けて /lists/pool に遷移する自然な挙動)。
v0.35.4 2026-05-20
🎯 送信ワーク画面の UX 改善 2 件。(1) list_module.next_contact:「次のコンタクト」の進行方向を ID 昇順→ID 降順に変更。リスト表示が ID 降順(新しい順)なのに「次」が ID 昇順だったため、リスト一番上で「次」を押すと「末尾まで到達」と出る違和感を解消。flash メッセージも「ID順で末尾」→「リストの最後」に。(2) send_work.html のスライドパネル:iframe 内でアクション(送信・予約・編集等)が発生した場合、閉じる時に自動的に親画面をリロードしてステータス更新を反映。iframe の load 回数で検知(初回 about:blank と openPanel 直後の初回ロードはスキップ、2回目以降のロード = アクション完了とみなす)。アクション無しで閉じた場合はリロードしない(従来通り)。
v0.35.3 2026-05-20
🐛 オンボーディング未完了ユーザーが /sender-domain にアクセスできないバグ修正。原因:app.py の _enforce_onboarding フックの bypass_prefixes に /sender-domain が未登録で、ドメイン認証ページへのアクセスが /onboarding にリダイレクトされていた(admin はバイパスされるので気づかなかった)。対処:(1)bypass_prefixes に /sender-domain 追加、(2)onboarding.html Step4 のリンクを別タブから同タブに変更、(3)sender_domain_module.verify で認証完了時にオンボーディング未完了なら /onboarding に自動リダイレクト。これで「オンボーディング → ドメイン認証 → 完了 → ダッシュボード」の強制フローが完成。
v0.35.2 2026-05-20
🏷 商標対応:プロダクト名を「Nudge」→「Nudge HQ」に統一。対象70ファイル:(1)ロゴ・ページタイトル・LP全セクション、(2)法務ページ全4本(特商法・利用規約・プラポリ・お問い合わせ)、(3)メールテンプレ全種(認証・事前登録お礼・サービス開始・テスト・共通レイアウト)、(4)オンボーディング・送信ドメイン認証・SMTP設定・料金ページ等の全画面、(5)AI メール生成プロンプト内のブランド名表記、(6)CLAUDE.md / version.py 等の内部ドキュメント。影響なし:ドメイン名 nudge-hq.co.jp、メアド、Python モジュール名、JS 変数名(NudgeProgress 等は元のまま復元済)。⚠ 残作業:DB 内のユーザー入力データ(CompanyProfile.business_description, FollowUpTemplate.subject/body, SystemEmailTemplate 等)に 「Nudge」が含まれていれば手動で「Nudge HQ」に更新する必要あり。
v0.35.1 2026-05-20
💰 プラン別追いメール段数の上限を導入:(1)PLAN_LIMITS の各プランに max_followup_count 追加:trial=2 / light=2 / standard=5 / pro=10 / enterprise=None(無制限)、(2)新規 usage_module.get_max_followup_count(user) / get_current_followup_count(user_id) / can_add_followup(user)、(3)email_settings.save の新規追加分岐に上限チェック追加(上限到達なら error flash でブロック)、(4)email_settings.html 上部に「{plan}プランの追いメール上限:N/M 通」表示 + 上限到達時にアップグレード CTA、(5)新規追加フォーム自体も上限到達時には「上限到達」バッジ + 追加ボタン disabled、(6)send_module.send_followup に step > max_followup_count の保険スキップ追加(プランダウングレード後の既存テンプレ救済)、(7)enterprise プランを PLAN_LIMITS に正式追加(Stripe Checkout 対象外、admin 手動設定用)。目的:SendGrid を Nudge HQ 原価として吸収(v0.35)した結果、1コンタクトあたりの送信通数を制限する必要が生じたため。
v0.35.0 2026-05-20
🚀 SendGrid プラットフォーム統合(v0.35):Nudge HQ が SendGrid を契約・原価吸収し、ユーザーは追加契約不要に。(1)requirements.txt に sendgrid==6.11.0 追加、(2)新規 sendgrid_sender_module.py(SendGrid API 経由送信、smtp_module と互換インターフェース)、(3)send_module.py に統一送信関数 _send_email() を追加:SENDGRID_API_KEY 設定済みなら SendGrid 経由、未設定なら SMTP 直接接続にフォールバック(後方互換維持)、(4)送信4箇所(初回送信・追いメール・テスト送信・旧テンプレ送信)を全て _send_email() 経由に統一、(5)新規 VerifiedDomain モデル:ユーザーごとの送信ドメイン認証状態を保存、SendGrid Domain Authentication と連動、(6)新規 sender_domain_module.py + /sender-domain ルート群(一覧・登録・検証・削除)、SendGrid Whitelabel Domains API を直接叩く、(7)新規 templates/sender_domain.html:DNS CNAME 3つの表示 + Verify ボタン + Xserver 向けヒント、(8)base.html のナビに『送信ドメイン認証』を追加、SMTP設定は『SMTP/IMAP設定』にリネーム、(9)オンボーディング Step4 を SendGrid 環境ではドメイン認証ページへのリンクに自動切替(未環境では従来通り SMTP フォーム)、(10)onboarding_module の完了判定を _has_sender_setup() に変更:SendGrid 環境では VerifiedDomain.is_verified=True が必要、(11)ユーザー側のメリット:Render などクラウドからの送信が可能、SMTP リレー個別契約不要、DNS CNAME 追加だけで本番運用開始。Nudge HQ側のコスト:SendGrid Essentials $19.95/月で月50,000通まで、Pro $89.95/月で月700,000通まで(原価率1〜2%)。
v0.34.3 2026-05-19
📤 SMTP認証ユーザー名フィールド追加(SMTP リレーサービス対応)。背景:Render など クラウドサーバーの IP は Xserver 等の SMTP プロバイダから拒否される(554 5.7.1 Access denied)。本番から営業メール・追いメール自動送信を可能にするには SMTP リレーサービス(Resend/SendGrid/SES/Mailgun等)が必要だが、これらのサービスは認証ユーザー名がメアドではなく固定値('resend' / 'apikey' 等)。対処:(1)SMTPSetting に smtp_username カラム追加(nullable、空欄なら from_email を使う=後方互換維持)、(2)smtp_module.send_via_smtp の server.login で smtp.smtp_username or smtp.from_email を使うように変更、(3)smtp_module.settings と onboarding_module.save_smtp の両方で smtp_username を form から保存、(4)templates/smtp.html と templates/onboarding.html に「SMTP認証ユーザー名(任意)」フィールド追加 + 各リレーサービスのヒント記載、(5)app.py の _migrate_legacy_db に ALTER TABLE smtp_settings ADD COLUMN smtp_username VARCHAR(255) 追加。
v0.34.2 2026-05-19
🐛 /email-settings で追いメール新規追加時に Internal Server Error が出る問題を修正。原因:FollowUpTemplate.kind カラムは v0.25 で NOT NULL 制約付きで作成されたが、v0.30 で step 列に置き換えた際、SQLite は ALTER TABLE で nullable 変更できないため 旧 NOT NULL 制約がDBに残ったまま。models.py 側を nullable=True に変えても効かない。対処:email_settings_module.save() で INSERT 時に step 値から導出した kind 値(step=2 → 'followup1' / step=3 → 'followup2' / それ以外 → 'stepN')を必ず入れて 制約を満たすように修正。models.py にも注意コメント追記。
v0.34.1 2026-05-19
🐛 進捗モーダルの backdrop-filter:blur(4px) を削除。Chromium系ブラウザで backdrop-filter がスタッキングコンテキストの上下関係を無視し、z-index で上にあるモーダル本体までボケる副作用があり、進捗バー内の文字が読めなくなる事象を解消。背景クリック防止の暗幕(rgba alpha 0.55)だけ残し、blur 効果は廃止。
v0.34.0 2026-05-19
🚧 BulkJob 進捗UIをモーダル化:(1)main.js に共通ヘルパー window.NudgeProgress(start/end)追加、(2)CSS に .progress-modal-active + .progress-modal-backdrop(半透明オーバーレイ + 中央モーダル)追加、(3)auto_list.html / list_detail.html / lists.html の3つのBulkJob進捗UIで start/end を呼ぶ修正、(4)実行中は背景クリックブロック + beforeunload で離脱警告(モーダル内に常時警告バナーも表示)、(5)完了/エラー/例外いずれの分岐でも確実に end が呼ばれるよう全リターンパスをカバー。目的:『リスト収集中に別ページに行くと結果が見えなくなる』事故防止。なお実際のジョブは daemon=True のスレッドで継続するので、データ自体は失われない設計。
v0.33.0 2026-05-19
🚀 オンボーディング画面:(1)新規 onboarding_module.py + /onboarding ルートで7ステップのアコーディオン式UI、(2)ステップ構成:①ようこそ(トライアル特典 14日/100U/全機能)②クレカ登録(必須・Stripe Checkout 経由・Light¥98K/月でトライアル開始)③自社情報(必須)④SMTP設定(必須・IMAPは任意)⑤メール設定(任意)⑥ブリーフ(任意)⑦最初のリスト作成(任意)、(3)User.onboarding_completed_at カラム追加 → before_request フックで未完了ユーザーを強制リダイレクト、(4)必須3つ(クレカ/自社情報/SMTP)が揃った時点で自動的に onboarding_completed_at をセット、(5)既存ユーザーはマイグレーション時に completed_at を埋め戻し(影響ゼロ)、(6)bypass 対象:/auth /static /u/ /legal /billing /track /pre-register /changelog + admin、(7)Stripe Checkout success → onboarding 未完了なら #step-3(自社情報)に戻す、(8)verify_email 後の遷移先を dashboard → onboarding に変更、(9)CSS:紫グラデのトライアル特典カード・プログレスバー・完了済みカードは緑系の hover に。目的:「課金しないと使えない」誤解の解消+必須セットアップの離脱率低減。
v0.30.0 2026-05-17
📨 カスタムシーケンス(N通対応):(1)FollowUpTemplate を kind 列 → step 整数列に変更し、1ユーザーが任意の数の追いメールを保有可能に、(2)Contact に sequence_step / next_followup_at / initial_sent_at の3カラム追加、旧 sequence_status / followup1/2_* は互換のため残存、(3)スケジューラを next_followup_at ベースに一本化、N通対応で次のステップを自動計算、(4)email_settings 画面を 動的リスト + 追加/編集/削除/ON-OFF UI にリニューアル、(5)既存データを kind→step / status→step に自動マイグレーション、(6)LP/料金ページのコピーを「3通シーケンス」→「カスタムシーケンス(何通でも)」に変更。
v0.28.0 2026-05-17
💰 プラン全面改定:(1)Light ¥9,800/200U → ¥98,000/2000U(中小企業向け・営業マン1人分削減)、(2)Standard ¥98,000/2000U → ¥298,000/6000U(営業マン3人分削減)、(3)Pro ¥398,000/10000U → ¥498,000/20000U(営業マン10人分削減)、(4)Enterprise プラン追加(要相談・専任サポート + Salesforce/Sansan/Musubu連携)、(5)アップグレード通知の閾値を残り200ユニットに拡大(旧50)、(6)無料トライアル累計100ユニットは維持。billing_module.PLANS と usage_module.PLAN_LIMITS、LP、特商法、CLAUDE.md を全て同期更新。
v0.26.0 2026-05-17
🚫 営業NGリスト(ブロックリスト)機能:(1)新規 BlockedDomain モデル(user_id × domain で UNIQUE)、(2)/blocked-domains に管理画面(一覧 + 手動追加 + 解除)、ドメイン/URL/メアド どの形式でも自動正規化、(3)プールビューの一括削除フォームに「ブロックリストにも追加」チェック追加、(4)自動収集の Gemini プロンプト除外ドメインにブロックリストを合算(API消費削減)、(5)Contact 保存直前にもブロックリスト最終チェック(Gemini が指示無視したケースの防御)、(6)CSV/Excel アップロード時もブロックリストとマッチしたら自動スキップ、(7)ナビに「🚫NG」リンク追加。用途:取引拒否済み・競合・訴訟リスク企業・配信停止依頼を受けた会社等の永続的な除外管理。シンプル単位はドメイン(BtoB営業に妥当、メアド単位は運用負荷大)。解除も可能(誤登録のリカバリ)。
v0.25.0 2026-05-16
📨 3通シーケンス送信機能:(1)1ユニット = 1コンタクトに最大3通の送信権利込み(API追加コストゼロ)、(2)初回はパーソナライズメール(Claude生成)、2通目は追いメール(3日後、テンプレ置換のみ)、3通目は撤退予告メール(10日後、テンプレ置換のみ)、(3)新規 FollowUpTemplate モデルで ユーザーごとに followup1/followup2 のテンプレ保存、is_enabled で各段ON/OFF(シーケンス短縮可)、(4)Contact に sequence_enabled / sequence_status / followup1_2_scheduled_sent_at カラム追加、(5)APScheduler に followup チェックを追加(1分間隔で予約到達したものを自動送信)、(6)プレースホルダ {{初回件名}}/{{初回送信日}} 等で過去の文脈を引用可能、(7)返信あり/配信停止/不達 を検知した瞬間にシーケンス自動停止(inbox/unsubscribe/手動更新 全箇所で stop_sequence 呼び出し)。🛠 新規「メール設定」タブ:(8)/email-settings で追いメールテンプレを編集(件名/本文/経過日数/ON-OFF)、(9)各段ON/OFFで 1通/2通/3通 シーケンスを切替可能、(10)デフォルトに戻すボタン、(11)ナビに「メール設定」追加(旧 followup_module は削除し email_settings_module に統合)。🎨 UI 更新:(12)compose 画面に「自動追い送信」チェックボックス(即時送信・予約送信ともに、デフォルト ON)、(13)プールビューの 📧 バッジを段階表示(📧✓ 初回 / 📧✓→ 予約あり / 📧✓✓ 追い1済 / 📧✓✓✓ 完走 / 📧🛑 停止)
v0.24.0 2026-05-16
🎯 ユニット消費モデルを「アクション起点」に変更:(1)Contact に unit_consumed フラグ追加、(2)CSV アップロード = ユニット消費 0(ステージング状態で投入、重複チェックや整理に使える)、(3)自動収集 = 投入時にアクティブ化(API コスト発生済みのため)、(4)usage_module.activate_contact_for_unit() で初回 AI アクション時に idempotent でユニット +1、(5)enrich/bulk_enrich/compose generate/HP補完Step2/send_draft_for_contact のすべてで activate 呼び出し、(6)同一コンタクトへの 2回目以降のアクションは追加消費なし(1:1:1:1 維持)。📊 CSV アップロード「確定前プレビュー」:(7)mapping → preview → confirm の3段階、(8)新規 / メアド重複 / ドメイン重複(同社の別担当者候補)/ 不正メール を集計表示、(9)サンプル5行 + ステータス分布表示、(10)「ドメイン重複もスキップ」オプションで投入時に除外可能。📥 CSV ステータス列マッピング:(11)CSV の「送信済み」「返信あり」等の値を内部ステータスに自動変換、(12)送信済み等で取り込まれたコンタクトは初期から unit_consumed=True、再送信ロジックでスキップされる、(13)スプシ既存リスト → CSV → このツール の移行で、過去の送信履歴を保ったまま統合可能。🎨 UI 表示:(14)プールビューの各行に「⚡ アクティブ / ⏸ ステージング」バッジ、(15)ダッシュボードの使用状況カードに アクティブ/ステージング 件数を内訳表示。🔧 既存データ:マイグレーションで unit_consumed=True を初期値にセット(v0.22 で消費済みのため)
v0.23.0 2026-05-16
🚮 ミスリカバリ機能:(1)CSV アップロード完了後に専用結果画面表示、「このアップロードを取り消す」ボタンで 追加された Contact 一括削除 + 消費ユニット返却、(2)自動収集完了時の進捗バーに「この収集を取り消す」ボタンを並列表示(自動遷移せず、ユーザー判断を待つ)、(3)プールビューにチェックボックス一括選択 + 「🗑 選択した N 件をプールから削除」ボタン(削除はユニット返却なし、悪用防止)、(4)選択チェックボックスを AI 分析 / 削除の両フォームで共用(HP 無しでもチェック可、AI 分析側は URL ありのみ対象)、(5)BulkJob に result_meta JSON カラム追加(追加した Contact IDs を保存、取り消し機能で参照)、(6)to_dict() に undoable フラグを返して JS から取り消しボタン表示を判定、(7)二重取り消し防止:取り消し済みフラグでバッチ無効化。「削除」と「取り消し」の意味的区別:取り消しは直近1回のミスリカバリ(返却あり)、削除は意図的な後始末(返却なし)
v0.22.0 2026-05-16
🎯 課金モデルを「1ユニット = 1コンタクト権」に再設計:(1)PLAN_LIMITS を 4種類(list_collect/memo/email/send)から 'unit' 単一カウンタに統合、(2)ユニット消費は **リスト追加(CSV/自動収集)時のみ**、HP補完・メモ・メール・送信は権利込みで追加カウントなし、(3)1:1:1:1 モデルが Contact ID 軸で自動成立、(4)Contact に memo_regen_count / email_regen_count カラム追加(再生成 soft limit)、メモ5回 / メール10回 を超えたら「コスト暴走防止のため上限」エラーで再生成不可、(5)CSV インポートでもユニット消費(partial 追加:上限超過分はスキップ + 警告)、(6)UsageCounter v0.22 マイグレーション:既存 list_collect → unit にリネーム、memo/email/send 行を削除、(7)ダッシュボード使用状況を1行に統合、トライアル表記を「件」→「ユニット」に、(8)グローバル通知バナー・キャラクターメッセージも unit ベースに統一、(9)旧テンプレ送信 execute フローの quota 消費を削除
v0.21.0 2026-05-16
🗂 業種3層カテゴリ化:(1)Contact に industry_l1(大)/industry_l2(中)追加、原文 industry は小として保持、(2)新規 industry_classifier_module で Claude に distinct industry を投げて 大/中 カテゴリ辞書を自動生成、(3)辞書は instance/industry_categories_<user_id>.json に保存、ユーザーが手動編集可、(4)/lists/classify-industries エンドポイント + リスト管理画面に「🤖 AI で業種カテゴリを分類」ボタン、(5)プールフィルタを 大→中→小 の3層カスケード(大選ぶと中が JS で絞られる)、(6)未分類は「その他」へフォールバック、CSV 追加後の差分分類モードも対応。🔍 重複チェック:ドメイン単位(メアドドメイン + URL ドメイン)で Union-Find グルーピング、ラジオで残すものを選んで一括削除する確認 UI、認可は user_id 直接チェック。🔧 業種・エリア正規化:normalize_industry(区切り文字で先頭採用 + 末尾「会社/業/業界/業者」除去)、normalize_area(47都道府県マスタ + 別名 + 部分一致、「愛知県名古屋市」→「愛知県」)、起動時に既存データを idempotent backfill、Gemini プロンプトに prefecture 必須化で会社住所ベース判定。📥 CSV マッピング強化:HP / URL / ホームページ / 公式サイト 等の列を自動検出して website_url に取り込み、マッピング画面に「HP URL」列追加、HP 無しコンタクトは AI 分析で disabled チェックボックス + 理由ツールチップ表示。🐛 旧テンプレ送信 execute フローの _wrap_with_tracking アンパック数を修正
v0.20.0 2026-05-16
🗃 プール + スマートリスト方式に再設計:(1)すべての Contact を user_id 直下の単一プールに統合、(2)ContactList を「保存済みフィルタ条件(filter_conditions JSON)」に再定義、(3)プールに対する動的フィルタ:業種/エリア/ステータス/メモ有無/下書き有無/分析結果/自由検索の7軸、(4)アップロード・自動収集は常にプール直行(追加先選択 UI を撤廃、重複はプール全体でチェック)、(5)リスト一覧ページにプール統計を追加、削除はリスト(フィルタ)のみでコンタクトは残る、(6)新エンドポイント:/lists/pool(プール本体)、/lists/save-filter(フィルタ保存)、/lists/<id>/update(フィルタ条件・名前更新)、(7)DB マイグレーション:contacts テーブルを再作成して list_id → user_id 直下に移行、contact_lists.filter_conditions カラム追加、(8)スマートリストを開くと 保存済みフィルタ適用ビュー、URL クエリでフィルタ変更可能、明示チェックでフィルタ上書き保存。🐛 旧テンプレ送信 execute フローの _wrap_with_tracking アンパック数を修正(配信停止リンク・トラッキング正常化)
v0.19.0 2026-05-13
🎁 トライアル累計100件制限(残数50/10件で警告色+バナー)。📊 業種別AI学習度メーター(送信件数×返信率で0-100%)。🤖 キャラクター機能:送信状況・返信率・離脱日数等に応じて喜怒哀楽メッセージ。📣 グローバル・アップグレードバナー(残50/10件で全画面表示)。🏢 エンタープライズお問い合わせフォーム(料金ページからアクセス、3営業日連絡)。🗄 共有Supabase DB:自動収集前に検索→ヒットしたらAPI消費ゼロ、収集成功後は代表メアド(info@等)のみ保存、送信失敗でバウンスマーク、180日経過で要確認フラグ。📥 Musubu/Sansan CSV列名を自動マッピング(会社名/担当者/メール/業種/エリア/電話)。😭 解約警告:『今まで育てたAI学習データがリセットされます』を強調
v0.18.2 2026-05-13
🧪 テスト送信を本番と同じ見た目に:(1)配信停止リンク・List-Unsubscribeヘッダー・トラッキングピクセル全て含めて送信、(2)tokenに 'preview_' プレフィックスを付けてクリックしても本物のコンタクトには影響しない設計、(3)preview_ token で /u/ を開くと『🧪 テスト送信のプレビュー』専用画面表示、(4)tracking_module の open/click も SentEmail 不在時は静かに通過するので preview token でも問題なし
v0.18.1 2026-05-13
🧪 テスト送信機能追加:(1)SMTP設定に「テスト配信先メールアドレス」フィールド追加、(2)メール作成画面に「テスト送信」ボタン → 現在の下書き+署名をそのアドレスに送信、(3)件名に「[テスト送信]」プレフィックス付与、(4)プランの月次送信枠は消費しない(SMTP日次上限のみカウント)、(5)トラッキング・配信停止リンクは含めずプレーン送信
v0.18.0 2026-05-13
📭 ワンクリック配信停止:(1)送信メールに /u/<token> へのリンクを自動追加、(2)受信者がクリック→確認画面→「配信停止を実行」で即unsubscribed設定、(3)受信トレイにも配信停止リクエストを記録(送信者が確認可能)、(4)List-Unsubscribe / List-Unsubscribe-Post ヘッダー追加でGmail/Outlookネイティブ配信停止UIにも対応。⏰ 予約送信:(5)Contactにscheduled_at追加、(6)compose画面で日時指定して予約、(7)APScheduler が1分間隔で到達した予約を自動送信、(8)複数worker環境でも原子的claim(UPDATE WHERE)で重複送信防止、(9)リスト詳細に「⏰ 予約」バッジ表示、(10)予約キャンセル可能。send_module を共通関数 send_draft_for_contact に整理し、即時送信と予約送信で共有
v0.17.1 2026-05-13
メール作成画面(compose_contact)に「AIへの追加指示」テキストボックスを追加。このメール固有のトーン・禁止事項・ルール(例:「『お忙しいところ』禁止」「件名20文字以内」)をAI生成プロンプトに『最優先』として注入。自社情報ページに『ai_instruction_default』カラム追加:よく使う指示文をデフォルトとして保存可能、compose 画面で自動入力される。個別メールで上書き編集も可能。戦略的(ブリーフ・サービス全体)vs 戦術的(追加指示・このメール固有)の2階層構造
v0.17.0 2026-05-13
自社情報(送信者側プロファイル)機能を追加:(1)新規 CompanyProfile モデルで会社名/担当者/役職/事業内容/USP/自社URL/電話番号を保存、(2)新規 /company ページで CRUD、(3)ナビに「自社情報」追加、(4)AIメール生成のプロンプトに『自社情報セクション+捏造禁止指示』を必須注入。未設定時は『弊社』『私』など主語をぼかすよう指示することで架空の会社名・実績の生成を防止。(5)compose 画面に自社情報の設定状態を表示して未設定時に警告
v0.16.0 2026-05-13
完全パーソナライズ送信への大型リファクタ:(1)Contactにdraft_subject/draft_body/drafted_at追加、(2)SMTPSettingにsignature追加、(3)新エンドポイント compose_contact:個別ページで「AI生成」ボタン→memo+業種+ブリーフ+学習データを使ってコンタクト固有のメール生成、(4)新エンドポイントsend.send_one:下書き+署名を組み立てて1コンタクトに送信、(5)送信管理画面を再設計:リスト一覧+ドラフト/送信可能/送信済の統計表示、(6)リスト詳細に「ドラフト」列+「📧メール作成/編集」ボタン、(7)SMTP設定に署名textarea追加、(8)ナビから「メール作成」を除去(個別ページに移行)、(9)DB自動マイグレーション(ALTER TABLE)
v0.15.1 2026-05-13
一括AI分析の「全選択メモ未生成」が、DNS失敗・Bot拒否・404・CAPTCHA・コンテンツ不足のコンタクトを自動除外するように変更(再試行しても無駄なため)。AI失敗・例外・未分析のものは引き続き対象。「失敗済みも対象に含める」チェックボックスで強制リトライも可能。サーバー側の未生成全件モードも同じフィルタを適用
v0.15.0 2026-05-13
リスト自動収集に Refill ループを追加。1回目の取得 → DNS検証 → 目標未達なら自動的にGeminiを再呼出(最大2回追加)して不足を補充。再呼出時は既に取得済みのドメインをexclude_domainsに加えて重複防止。不足分の2.5倍を多めに要求してDNS失敗バッファを確保。例:『40件目標、1回目で9件→Refillで+22件→2回目で+9件=合計40件達成』のように動く。進捗バーには『再収集中(試行 X/3・あと Y件)』とステージ表示
v0.14.2 2026-05-13
🐛 重大バグ修正:auto_list ワーカー内で url_for を呼ぶと「Unable to build URLs outside an active request」例外でジョブが永久停止していた。ワーカースレッドにはリクエストコンテキストが無いため、result_url は直書きパス(/lists/<id>)に変更。🎨 進捗バーUX改善:completed=0 かつ running の間はストライプアニメーション(API呼出中のGemini等で『止まってる』と誤解されない)
v0.14.1 2026-05-13
URL保存前のDNS並列検証を追加:(1)Gemini結果を 50URL/5秒で並列DNS解決、(2)Brave/Anthropic結果も同様にスクレイピング前に検証して無駄なリクエストを削減、(3)Geminiプロンプトに『推測・捏造禁止、Google検索で実在確認したURLのみ』を強調、(4)進捗表示に「URLの有効性を検証中」ステージ追加。これにより無効URLが最初からDB保存されないため、後の無効URL一掃も最小化
v0.14.0 2026-05-13
Contact に analysis_status/analysis_note カラム追加。AI分析失敗時に「失敗理由+推奨アプローチ」(DNS失敗→削除推奨、Bot拒否→手動アプローチ推奨、CAPTCHA→目視確認、コンテンツ不足→JSレンダリング判別等)を自動で備考欄に記入。リスト詳細に「備考」列追加、目視確認結果やメモを手動編集可能。起動時の軽量DBマイグレーション(ALTER TABLE)で既存DBにも自動適用
v0.13.4 2026-05-13
一括AI分析の失敗カテゴリを細分化:(1)HTTP 403を「Bot拒否(403)」として分離、(2)HTTP 404を「ページなし(404)」として分離、(3)HTML取得は成功したがコンテンツが100字未満の場合「コンテンツ不足」として分離(JSレンダリング型サイト判別)、(4)コンテンツ不足は無駄なClaude呼び出しを省略してAPI節約
v0.13.3 2026-05-13
CAPTCHA/Bot保護ページを自動検出(Cloudflare/reCAPTCHA/hCaptcha/Akamai/Imperva 等10種類以上のパターン)。検出時は無駄なClaude API呼び出しを回避してコスト節約。失敗内訳に「CAPTCHA保護 N件」として分類表示。「無効URL一掃」では CAPTCHA 保護サイトは削除せず保持(実在企業のため手動アプローチ可)。AI による突破は不実装(法的・倫理・コスト・ROI 全ての観点から非推奨のため)
v0.13.2 2026-05-13
ボタン名・確認文・フラッシュメッセージを「死URL一掃」→「無効URL一掃」へ変更(縁起担ぎ)
v0.13.1 2026-05-13
一括AI分析の透明性向上:(1)1件ごとに [bulk_enrich] (N/M) OK/NG: URL → 理由 をターミナル出力、(2)ジョブ完了時に失敗カテゴリ内訳(DNS失敗N件、HTTP失敗N件、AI分析失敗N件、例外N件)を表示、(3)DNS失敗が過半数なら「AI推測モード時代の古いリスト?」とサジェスト、(4)「🧹 無効URL一掃」ボタン追加:DNS解決失敗・接続不可なURLを持つ未送信コンタクトを一括削除
v0.13.0 2026-05-13
リアルタイム進捗バー実装:(1)BulkJob モデルでジョブ進捗を DB 管理、(2)新規 jobs_module.py で /jobs/<id>/status エンドポイント、(3)bulk_enrich と auto_list 収集をバックグラウンドスレッド化(即JSON返却)、(4)フロントは fetch でジョブ起動→1.5秒ごとにポーリング→進捗バー・件数・成功失敗を更新→完了で自動遷移、(5)auto_list は段階表示(Gemini検索中→Brave検索中→スクレイピング中→DB登録中→完了)、(6)bulk_enrich は1件処理ごとに進捗・直近処理URLをライブ表示
v0.12.1 2026-05-13
一括AI分析を大幅強化:(1)各行にチェックボックス+全選択UI、(2)処理上限を 20→100 件に拡大、(3)既存メモ上書きオプション、(4)「メモ未生成を全選択」ボタンで未処理だけ一発選択、(5)選択件数を動的表示、(6)10件ごとにこまめにcommitで途中エラー耐性、(7)推定所要時間を確認ダイアログ表示、(8)Procfile/start.sh の gunicorn timeout を 120→600秒に延長
v0.12.0 2026-05-13
新規 learning_module.py:(1)学習レベル算出(送信×返信×業種数の合成スコア)、(2)件名別の開封率・返信率スコアリング、(3)業種別パフォーマンス分析、(4)業種×CTAの効果分析、(5)過去30日 vs それ以前の改善メトリクス、(6)A/Bテスト勝者判定。ダッシュボードに「🧠 AI 学習ステータス」セクション追加(紫グラデのカード、AIレベル星表示、業種別ベスト、件名トップ、CTA最強表)。メール作成画面に過去実績ベースのサジェスト表示。メール生成プロンプトに学習ヒント(業種実績・件名スタイル・最強CTA・A/B勝者)を自動注入
v0.11.1 2026-05-13
ADMIN_EMAILS 環境変数(カンマ区切り)を追加。該当ユーザーはリスト/メモ/メール/送信の月次クォータを完全に無視(実質無制限)。ダッシュボードには「🛡 Admin(制限なし)」バッジ表示、使用量は実数表示・上限欄は「∞」、アップグレード誘導CTAも非表示。DBスキーマ変更不要
v0.11.0 2026-05-13
完全パーソナライズ商品設計:リスト/メモ/メール/送信を同量提供する1:1:1:1モデル。UsageCounter による月次クォータ管理、4機能(自動収集/メモ生成/メール生成/送信)に上限チェック・成功時の消費・上限到達時のアップグレード誘導を実装。ダッシュボードに使用状況ウィジェット(進捗バー、残り日数、80%超でWarning、上限到達で赤)。プラン価格を Light ¥9,800 / Standard ¥98,000 / Pro ¥398,000 に改定
v0.10.1 2026-05-13
既存リスト追加モード時、登録済みのドメイン一覧を Gemini/Brave に渡して事前除外。AIが「これら以外の企業を探す」よう指示されるため、無駄な重複取得が消えてAPI効率がほぼ100%に。200ドメインまでプロンプトに含める(多すぎる場合は最近の200件で打ち切り)。Geminiの応答後にも安全策として再度除外フィルタを適用
v0.10.0 2026-05-13
自動収集・CSV/Excelアップロード両方で「新規 or 既存リストへの追加」を選択可能に。既存リスト内でメアド完全一致のものは自動スキップ(重複チェック)。結果画面に「追加先・追加件数・重複スキップ件数」を明示。重複でスキップされた企業の一覧も折りたたみで確認可能。これにより同じ業種で複数回実行 → 同一リストに積み上げ → 重複なく送信管理ができる
v0.9.1 2026-05-13
Gemini モデル候補を 2.5-flash / 2.5-pro / flash-latest / pro-latest に更新(2.0系は新規アカウント404対策)。503は5/10/15秒の指数バックオフで最大3回リトライ。mailto: 抽出に EMAIL_REGEX.fullmatch を強制してCSS由来の偽メアド除去。ドメインのハイフン位置(先頭/末尾/連続)も検証。Brave のポータル除外を強化:my-best.com/rehome-navi等を明示追加+「-navi/matome/ranking/-guide/-portal/review-」等のヒューリスティック検出
v0.9.0 2026-05-13
Brave Search API(月$5無料枠、超過$5/1K)を2段目フォールバックに統合。1段Gemini→2段Brave→3段Anthropic→4段AI推測 の堅牢構成。Brave は SNS・ポータル・検索エンジン・求人・ECサイト等を自動除外し、営業対象として価値のある企業サイトのみ抽出。結果画面に取得モード別のフィードバック表示を追加
v0.8.2 2026-05-13
スクレイピングを5スレッド並列化(25URLが2分→30秒目安)。タイムアウト 10秒→5秒、巡回ページ数 3→2、メアド発見次第以降スキップ。メアド正規表現を厳格化(ドメインラベルの先頭/末尾は英数字必須)でCSSクラス由来の偽メアド排除。DNS失敗のサイトは www. 再試行を省略(時間節約)
v0.8.1 2026-05-13
Anthropic Web 検索のプロンプトを大幅緩和:URLだけ集めて貰い、メアド有無は scraping 側で判定。Gemini 503(一時混雑)は同モデルで自動リトライ、429(クォータ枯渇)は次モデルへ。DuckDuckGo HTML 版は CAPTCHA(202) で実質使えないためフォールバック段階から除外
v0.8.0 2026-05-13
パーソナライズ・ブリーフ機能を追加:(1)ユーザーごとに「HPの何を見るか」をテンプレ保存(CRUD)、(2)リスト詳細でブリーフを選んで一括AI分析(メモ未生成のみ対象・既存メモ保護)、(3)個別AI分析もブリーフ対応、(4)返信実績のあるメモを次回プロンプトの例示に使うFew-shot学習、(5)メモを手書きで編集できるインライン編集UI、(6)ブリーフ未選択時の警告表示
v0.7.0 2026-05-13
リスト取得は company+URL+email の3項目のみ必須化(高速化)。導線改善メモは「リスト詳細→AI分析ボタン」でコンタクト個別に遅延生成。Gemini 1.5系(廃止404)を候補から除外、モデルフォールバック間に2秒ウェイト追加。「成功」の判定をメアド取得のみに変更(除外件数を減らす)
v0.6.1 2026-05-12
Gemini SDK を廃止予定の google-generativeai から新版 google-genai に移行。モデル名を 2.5/2.0/1.5 から自動試行(404対策)。Gemini 2.x は GoogleSearch ツール、1.5 は GoogleSearchRetrieval を自動切替。BeautifulSoup の XMLParsedAsHTMLWarning を抑制
v0.6.0 2026-05-12
Gemini API + Google Search Grounding を自動収集の0段目(最優先)に統合。スクレイピング不要で実在企業の会社名・URL・メアド・導線メモを一括取得。失敗時は従来の Anthropic→DDG→推測 のフォールバックに自動切替
v0.5.1 2026-05-12
プレースホルダのメアド(xxx@xxx.xx.xx, sample@yamadahp.jp など)を除外。AI分析の memo が空・短すぎる場合に強めの指示で1回リトライして除外件数を削減
v0.5.0 2026-05-12
DuckDuckGo HTML検索を2段目のフォールバックに追加。Web検索→DDG→AI推測の3段構え。fetch を非streaming化してRuntimeErrorを解消、DNS解決失敗を明示。オーバーサンプリングを3倍→5倍に拡大。anthropic SDK を 0.40 以降に引き上げ
v0.4.1 2026-05-12
HTML取得失敗の原因対策:ブラウザ風 User-Agent に変更、SSL エラーは検証なしで再試行、www. の付け外しで再試行、失敗理由を具体的に表示、URL一覧をターミナルに表示
v0.4.0 2026-05-12
自動収集を必須項目フィルタ方式に変更:メアドと導線メモが両方そろった企業のみ登録。URL を目標の3倍取得して試行、失敗理由を画面とログに表示
v0.3.0 2026-05-12
リスト自動収集を改善:Anthropic Web 検索 / 問合せページ巡回 / mailto・難読化メアド対応
v0.2.0 2026-05-12
リスト自動作成機能を追加(業種・地域からHP→メアド・導線改善メモ生成)
v0.1.0 2026-05-12
初期リリース(認証・SMTP・リスト・AIメール生成・送信・受信・ダッシュボード・Stripe)
バージョン番号は version.py で管理しています。