SAC Private Club · Final Design v5

予約特典 — 確定デザイン(入会日自動連携対応版)

個別コンサルティング予約を「予約特典」として整備。新規入会・コミュニティからのアップグレード両方に対応した入会日自動セット + ダッシュボード通知 + 利用履歴の日時記録 + リセット時期の非開示設計

User Side · Normal

お客様サイト「特典状況」ページ

予約URLが設定された特典は最上部にヒーローカードとして表示。「予約する」ボタンタップでGoogleカレンダーの予約フォームを別タブで開きます。下に通常の特典が続く構成。

sac-private-club.vercel.app / benefits

特典状況

プライベートクラブ会員の特典と利用状況をご確認いただけます

Private Reservation

紗希との 30 分のひととき

あなたのために設けられた、年2回の特別なお時間
資産設計、ビジネス、これからの人生について。
15:00 〜 19:00 のあいだでご都合のよい時間をお選びください。

1 残り / 年2回まで
予約する
所要時間 30 分 / オンライン
ご予約後、確認メールが届きます

VIPイベント優先招待

月例イベントの先行案内・抽選優遇

無制限

提携施設ご利用優待

提携ホテル・レストランでの優待価格でのご利用

5

残り / 上限10

9:41● ● ●

特典状況

PC会員の特典と利用状況

Private Reservation

紗希との 30 分のひととき

年2回の特別なお時間。
資産設計、ビジネス、これからの人生について。

1残り / 年2回まで
予約する
所要時間 30 分 / オンライン

VIPイベント優先招待

先行案内・抽選優遇

無制限

提携施設優待

5

残り / 10

User Side · Edge case

残り回数が 0 になった本年度の表示

CTAをグレーアウトし、丁寧なメッセージを表示します。具体的なリセット日は表示しません(運用の柔軟性を保つため、お客様には「年2回」という上限のみが伝わる設計)。

Private Reservation

紗希との 30 分のひととき

本年度分はすべてご利用いただきました。
またお目にかかれることを楽しみにしております。

0 残り / 年2回まで
Admin · Benefits Master

管理サイト:特典マスタ編集フォーム(変更)

既存の特典編集モーダルに「予約URL」「ボタンラベル」の2項目を追加。URLが入っていれば、お客様サイトでヒーローカードに昇格表示されます。

面談特典は「加入記念日」を選択 → お客様ごとの入会日(最初のログイン情報送付日)から1年ごとに自動リセット。手動操作は一切不要です。
URLを設定すると、お客様画面でこの特典が予約特典カードとして強調表示されます。空欄なら通常の特典として表示します。
空欄なら「予約する」が使われます。「面談を申し込む」など特典に合わせて変更可能。
Admin · Manual Count

管理サイト:顧客別状況での「+1 利用として記録」

面談を実施し終えたら、紗希さんもしくは管理者が顧客別状況タブで「+1」ボタンを1クリック。確認ダイアログを挟み、利用履歴に1件追加されます。

Selected Benefit
紗希との 30 分のひととき
2026年 上限2回 · 予約URLあり
お客様 本年利用 直近の利用 操作
山田 太郎
member1@example.com
1 / 2 2026/04/18 16:00
田中 花子
member2@example.com
0 / 2 未利用
佐藤 一郎
member3@example.com
2 / 2 2026/03/29 16:30
「+ 利用を記録」をクリックすると
Record Usage

山田 太郎 様 の利用を記録

紗希との 30 分のひととき

お客様画面の利用履歴にも表示されます。空欄でも構いません。
ⓘ 記録すると、お客様の本年利用回数が 1 → 2 になります(上限到達)。
山田 太郎 様の「紗希との 30 分のひととき」を 2026/05/03 16:00 として記録しました
Admin Dashboard · Renewal Notice

管理ダッシュボード:更新時期のお客様ウィジェット NEW

入会1周年(2周年・3周年…)まで 30日以内 のお客様を一覧表示。情報のみで操作ボタンは置かず、残り日数や具体的な周年日付も表示しません(運用の柔軟性を保つ設計)。CRMでティアが外れている方は警告アイコン付き。

🎉
Renewal Approaching
まもなく更新時期を迎えるお客様 ・ 3 名
CRM継続状況のご確認をおすすめします
お客様
入会日 / 周年
現在のステータス
山田 太郎
member1@example.com
2025-06-10
更新時期が近づいています
✓ 継続中(PC会員・アクティブ)
田中 花子
member2@example.com
2025-05-25
更新時期が近づいています
✓ 継続中(PC会員・アクティブ)
佐藤 一郎
member3@example.com
2024-05-13
更新時期が近づいています
⚠ ティア降格の可能性(CRM要確認)
このリストは情報表示のみ。リセット作業は不要です(自動的に切り替わります)。 顧客一覧で詳しく見る →

※ 該当者 0 名のときは、このウィジェット自体をダッシュボードに表示しません(雑音にならないよう)

Admin · Customer Detail

顧客一覧 / 詳細:入会日と本年度の利用状況 NEW

既存の顧客編集モーダルに「入会日」と「予約特典の本年度状況」を追加。入会日は CRM webhook(PCティアになった瞬間)または初回ログイン情報送信時 に自動セット。管理者は必要に応じて手動修正も可能(既存ユーザーのバックフィル誤差等の救済用)。

Membership
入会日
2025-06-10
CRM連携で自動セット(PCティア取得日)
現在の本年度
1 年目
入会日基準で自動カウント
本年度の予約特典 利用状況
紗希との 30 分のひととき: 1 / 2 直近: 2026/04/18 16:00
通常は CRM webhook(PCティアになった瞬間) または 初回ログイン情報送信時 に自動セット。 管理者ロールのみ手動編集が可能。
※ システム移行前から在籍されている方など、自動取得が不正確な場合の修正用。
Architecture · Enrollment Date

入会日(pcEnrolledAt)の決定ロジック NEW

3つのアプリ(PCサイト・PC管理サイト・コミュニティサイト)は同じ users テーブルを共有しているため、コミュニティ会員からのアップグレードでも漏れなく入会日が記録されるよう、複数のトリガーから設定します。

Trigger Priority (上から順に判定)
1
CRM webhook(PCティアになった瞬間)
tier-changed webhook で memberTier === 'private_club' & 既存の pcEnrolledAt が空のとき自動セット。
CRMの tierChangedAt を優先採用、なければ webhook 受信時刻。
2
初回ログイン情報送信(フェイルセーフ)
webhook が届かなかった等の理由で pcEnrolledAt がまだ空なら、初回送信時にセット。
再送ではセットされない(既に値がある場合は無視)。
3
管理者による手動修正
既存ユーザーのバックフィル誤差や、特殊事情への対応用。
管理者ロール(role === 'admin')のお持ちの方のみ顧客編集モーダルから変更可能。
Scenario Coverage
シナリオ 入会日のセット元 結果
① 完全新規でPC入会
コミュニティ会員ですらない方
トリガー1(CRM webhook) ✓ 正しく記録
② コミュニティ→PCアップグレード
既にコミュニティでログイン済み
トリガー1(CRM webhook) ✓ アップグレード日が入会日として正しく記録
③ コミュニティ→PCアップグレード
webhookが何らかで失敗
トリガー2(初回ログイン情報送信) ✓ フェイルセーフで記録
④ PC会員のティア継続更新
同じPCティアで契約更新
—(既に値があるので変更なし) ✓ 元の入会日を保持
⑤ ログイン情報の再送(パスワード再発行) —(既に値があるので変更なし) ✓ 元の入会日を保持
⑥ 既存PC会員(マイグレーション時)
v5 リリース前から在籍
マイグレーション時に loginInfoSentAt を暫定採用 △ 不正確の可能性 → 必要なら手動修正
⑦ 降格→再アップグレード
PC→general→PC のような変動
—(元の値を保持する設計) ⚠ 元の入会日を保持(要件次第で変更可)

本デザインの判断(変更可)

  • シナリオ⑦の扱い: 「一度PC会員になったらお客様」として元の入会日を保持する設計。再アップグレード時に新しい入会日として上書きしたい場合は、webhook ロジックを微調整します。
  • CRMの tierChangedAt: webhook payload に含まれる場合は採用、なければ webhook 受信時刻。両方とも実時刻として実用上の差はほぼなし。
Workflow

運用の流れ(紗希さん視点)

面談予約から記録までの一連のフローです。Googleカレンダー側はそのまま現状維持で、サイトの世界観だけきれいに整えます。

0a
【新規入会】CRMでPCティアに設定 → webhook PC users テーブルに pending で作成、その時点で入会日も自動記録 (CRMの tierChangedAt を採用、なければwebhook受信時刻)
0b
【コミュニティ→PCアップグレード】CRMでティア変更 → webhook 既存 user の memberTier を更新、同時に pcEnrolledAt が空なら自動セット (コミュニティ会員でも入会日が漏れない)
0c
管理者がログイン情報を送信 pending → active に昇格。もし pcEnrolledAt がまだ空ならここでもセット(フェイルセーフ) (以降、再送しても入会日は変わらない)
1
お客様が「特典状況」ページを開く 最上部のヒーローカードで予約特典を確認 (本年度の残り回数を表示)
2
「予約する」ボタンをタップ 別タブでGoogleカレンダーの予約フォームが開く (モバイルはGoogle側がレスポンシブ対応)
3
お客様が日時を選んで予約完了 Googleからお客様と紗希さんに自動で確認メール
4
面談を実施 ZoomまたはGoogle Meetで30分
5
面談後、管理サイトで「+ 利用を記録」をクリック 日時とメモを入力 → 利用履歴に1件追加 (実際の面談開始時刻を残せる)
6
入会記念日が近づくと、ダッシュボードに通知表示 お祝いメッセージ送付やCRMでのティア状況確認のチャンス (残り日数や具体的な日付は表示しない/ボタン操作なし)
7
記念日を経過すると、利用枠が自動でリセット 本年度の集計がゼロに戻り、お客様画面の残り回数も「2 / 年2回」に (cron不要、毎回SQL集計でその年度分のみカウント)
Implementation

必要な実装の総量

小さくまとめれば、データベース1マイグレーション・お客様サイト2ファイル・管理サイト1ファイルの修正で完了する想定です。

DB
  • users.pc_enrolled_at (timestamp, nullable)— 入会日
  • pc_benefits.booking_url (text)
  • pc_benefits.booking_button_label (varchar(50))
  • pc_benefits.usage_period (varchar(20), default 'lifetime')
  • マイグレーション 1 本(既存ユーザーは loginInfoSentAt から backfill)
User Side
  • benefits-list-view.tsx にヒーロー分岐追加
  • data/benefits.ts で記念日基準の本年度集計を実装
  • 残り0時のグレーアウト+次回リセット日表示
Admin Side
  • CRM webhook に「PCティアになった瞬間に pcEnrolledAt 自動セット」処理を追加
  • send-login-info に「初回時のみ pcEnrolledAt セット」処理を追加(フェイルセーフ)
  • 特典マスタ編集に 3フィールド追加
  • 顧客編集モーダルに入会日 & 本年度状況を表示(管理者のみ手動編集可)
  • 顧客別状況タブに「+ 利用を記録」ボタン+日時入力モーダル
  • ダッシュボードに「更新時期通知」ウィジェット追加
Manual
  • 5-1 ダッシュボードに「更新時期のお客様」ウィジェットの説明を追記
  • 5-2 顧客一覧に「入会日」表示と本年度状況を追記
  • 5-6 特典状況に予約特典 & 加入記念日リセットの概念を追記
  • 夕方チェックに「面談実施後、日時を入力して記録」を追加