CancelNavi の開発記 — サブスク解約ガイドを1ヶ月で作ってリリースした話

2026.02.13
Share:

はじめに — 「解約の仕方が分からない」という身近な課題

サブスクリプションサービスを解約したいのに、解約方法が見つからない。設定画面の深い階層に「解約」ボタンが隠されていたり、アプリ内からは解約できずWebブラウザでの操作が必要だったり。この経験は多くの人に心当たりがあるのではないでしょうか。

CancelNavi は、サブスクリプションの解約手順をサービスごとにガイドするWebアプリです。Web、iOS、Google Play、キャリア決済など、プラットフォームごとの解約パスを整理して案内します。

この記事では、2025年12月から2026年1月にかけてCancelNaviを企画・開発・リリースした1ヶ月間の舞台裏を、開発日記から振り返ります。

リリースの決断 — 完璧主義を捨てた日

2025年12月18日、CancelNavi の最初のバージョンをリリースしました。

「完璧を目指して永遠にリリースしない」より「最低限で出して改善し続ける」を選んだ。情報の正確性は last_verified と sources フィールドで担保する

PMとして最も悩んだのは「情報の正確性をどこまで担保してからリリースするか」でした。サブスクの解約手順はサービス側のUI変更で古くなる可能性があります。全サービスの解約手順を完璧に検証してからリリースしようとすると、永遠にリリースできません。

そこで last_verified(最終確認日)と sources(情報源URL)というフィールドを設け、「いつ時点の情報か」を明示する方針にしました。完璧な情報よりも、「最終確認日が分かる情報」の方がユーザーにとって誠実だと判断しました。

情報サービスの「鮮度」問題

リリース後に直面したのが、情報系サービス特有の課題です。

サービス側のUI変更への追従

サブスクの解約手順は、サービス側がUIを変更すると古くなります。たとえば「設定 → アカウント → サブスクリプション → 解約」という手順が、「設定 → プランと請求 → 解約」に変わることがあります。

情報の「鮮度」問題: 全サービスの解約手順を常に最新に保つのは不可能。ユーザーが「この情報は古いかも」と判断できる仕組み(最終確認日の表示)を優先した

PMとして考えたのは、「鮮度を保つ努力」と「鮮度が分かる透明性」のどちらを優先するかでした。個人開発の規模では全サービスを常時監視できません。だから「いつ確認した情報か」を明示することで、ユーザー自身が判断できる設計にしました。

ダークパターンの扱い方

2025年12月27日、解約を意図的に分かりにくくしている「ダークパターン」について記事を公開しました。

ダークパターンの記事: 事実を説明するが、特定サービスを批判しない。「こういう仕組みがある」と中立的に伝える

特定サービスを名指しで批判するのは簡単ですが、それはCancelNaviの目的ではありません。「こういうパターンがある」「対処するにはこうする」と中立的に伝える方針にしました。

ユーザーレビュー機能の追加

12月21日、解約体験のレビュー機能をClaude Codeで実装しました。

ユーザーレビュー: 解約の難易度評価(5段階)+ かかった時間 + コメント。ニックネーム制(Googleログイン必須)でスパム防止と投稿ハードルのバランスを取った

PM-AI 対話: 匿名投稿 vs ログイン必須

レビュー機能の設計で、匿名性とスパム防止のバランスについて Claude Code と議論しました。

ZeronovaZeronova
レビューは完全匿名にしたい。でもスパムが心配だ。
Claude Code
完全匿名だと、ボットによるスパムや虚偽レビューを防ぎにくくなります。Google OAuth でのログインを必須にしつつ、表示名はニックネーム(匿名OK)にする方式が、スパム防止と投稿ハードルのバランスが取れます。
ZeronovaZeronova
なるほど。「Googleアカウントで投稿するが、公開されるのはニックネームだけ」という方式か。投稿ハードルは少し上がるが、レビューの信頼性は確保できる。
Claude Code
Supabase Auth の Google OAuth を使えば実装は比較的シンプルです。RLSで「自分のレビューだけ編集・削除可能」とすれば、データ保護も担保できます。

この方式で実装し、スパム問題は発生しませんでした。

PWAとリマインダー — 「忘れない」仕組み

12月25日、PWA対応とリマインダー機能をClaude Codeで実装しました。

PWA + メール通知 + Webプッシュ通知: 無料トライアル終了日と更新日のリマインダーを実装。デフォルトは1日前通知

「解約したいのに忘れていた」は、サブスク管理で最もよくある失敗です。次の更新日を登録しておけば、前日にリマインダーが届く仕組みを入れました。

更新日の自動計算

12月26日には、月額・年額サブスクの更新日自動計算をClaude Codeで実装しました。

月額課金の更新日計算: 月末エッジケースへの対応が必要。1月31日契約の場合、次の更新日は2月28日(うるう年は29日)

一見単純に見える「1ヶ月後の日付」計算には、月末のエッジケースがあります。1月31日の1ヶ月後は2月28日(または29日)です。JavaScript の Date オブジェクトは月末を超えると翌月に繰り越してしまうため、明示的なバリデーションが必要でした。

iOS PWAの罠

12月25日と翌年1月19日には、iOS PWA特有の問題に直面しました。

iOS PWA: Webプッシュ通知はiOS 16.4以降でのみ対応。apple-touch-iconのキャッシュが頑固で、manifestだけでは更新されない

iOSのPWAサポートはAndroidに比べて制限が多く、特にプッシュ通知はiOS 16.4以降でないと使えません。さらにアイコンのキャッシュが非常に頑固で、manifest.json でアイコンを指定しても更新されず、HTMLの <link rel="apple-touch-icon"> を明示的に設定する必要がありました。

セキュリティ監査 — 50件の問題

2026年1月8日、CancelNaviのフルコードレビューをClaude Codeに依頼しました。

セキュリティ監査で50件以上の問題を発見。Critical/High を優先修正。最も深刻だったのは、クライアント側Supabaseの使用とデフォルトシークレット

Critical の修正内容は BandBridge と共通するパターンが多く、Server Component では createServerSupabaseClient() を使う、シークレットをハードコードしない、CRONエンドポイントに認証を追加する、といった基本を徹底しました。

特に学びがあったのは、Webhook検証のタイミング攻撃対策です。

Webhook検証: 文字列の単純比較ではタイミング攻撃に脆弱。crypto.timingSafeEqual() を使って定数時間比較にすることで防御

通常の文字列比較(===)は、先頭から文字を比較して不一致を見つけた時点で false を返します。この応答時間の差から正しいトークンを1文字ずつ推測する「タイミング攻撃」に対して、crypto.timingSafeEqual() は常に一定時間で比較を完了するため安全です。

LINE内ブラウザの問題

1月6日、ユーザーから「LINEから開くとログインできない」という報告を受けました。

LINE内ブラウザでOAuth認証が動かない。User-Agentを見て、LINE/Facebook/InstagramのWebViewを検出し、外部ブラウザでの起動を案内する警告を表示

LINEやFacebookのアプリ内ブラウザ(WebView)は、OAuth認証のリダイレクトを正しく処理できないことがあります。サードパーティCookieの制限やポップアップブロックが原因です。

User-Agent文字列に含まれる LineFBANFBAVInstagram を検出し、外部ブラウザ(Safari/Chrome)で開き直すよう案内する警告を表示することで対処しました。

機能削除の判断 — IdeaSpool への移行

1月24日、CancelNaviに組み込んでいたバグ報告機能を削除する決断をしました。

バグ報告機能を廃止し、IdeaSpool に統合。「機能を減らす勇気」。CancelNavi独自のバグ報告フォームを維持するより、IdeaSpoolのフィードバック機能に一本化した方が運用コストが下がる

個人開発で複数プロダクトを運営していると、同じ機能が各プロダクトに分散してしまうことがあります。CancelNaviのバグ報告、BandBridgeのバグ報告、Wakulierのバグ報告…。これらを IdeaSpool のフィードバック機能に一本化すれば、1箇所で全プロダクトのフィードバックを管理できます。

「機能を追加する」のは簡単ですが、「機能を削除する」には勇気が要ります。しかし、使われていない機能を維持するコスト(メンテナンス、セキュリティ対応、UIの複雑化)は無視できません。

まとめ — 情報サービスを個人開発する際の学び

CancelNaviの1ヶ月間の開発を通じて得た学びをまとめます。

  1. 「完璧」を待たずにリリースする: 情報の鮮度が命のサービスは、完璧を目指すと永遠にリリースできない。「いつ時点の情報か」を明示する透明性で補う
  2. 情報の「鮮度」は仕組みで担保する: last_verifiedsources のようなメタデータで、情報の鮮度を構造的に管理する
  3. セキュリティ監査はMVP直後に: 1ヶ月かけて作ったサービスでも50件以上の問題が潜む。早期発見・早期修正が重要
  4. プロダクト間の機能共通化を意識する: バグ報告のような汎用機能は、専用プロダクト(IdeaSpool)に集約した方が運用コストが下がる
  5. ブランディングは早めに固める: 活動名、Xアカウント、運営者情報は後から変更すると影響範囲が広い

CancelNaviは ZERONOVA LAB の最初のプロダクトでした。完璧主義を捨ててリリースする決断、情報鮮度との向き合い方、セキュリティ意識の芽生え。ここでの学びは、その後の5つのプロダクト開発すべてに活かされています。

関連記事:

Zeronova avatar

Zeronovaゼロノバ

Product Manager / AI-Native Builder

Web/IT業界19年以上・20以上のWebサービスを担当したPdM。東証プライム上場企業の子会社代表として事業経営を経験。現在はAIを駆使して企画から実装まで完結させる個人開発を実践中。

関連プロダクト

CancelNavi(キャンセルナビ)

サブスク解約の最短ルート