更新履歴|Nudge HQ

更新履歴

現在のバージョン:v0.99.68(2026-06-17)
🟣 FV:タブレットをもう少し上に(左上の飛び出しを強調)

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 で管理しています。