LINE セルフ登録フロー設計
既存「受付登録 + 本人確認」モデル → 「LINE 直接セルフ登録」への移行設計 — 視覚要素 + 詳細仕様併存版
TL;DR
- 受付経由の事前登録を廃止し、患者は LINE でセルフ登録 する形に変更
- 突合ロジック(氏名・電話・生年月日の 3 要素マッチ)を 完全撤廃。常に新規 User を作成
- Google ログイン廃止 → LINE 一本化。既存 manual User は「孤立カルテ」として残置、将来手動マージ
📍 全体フロー一望
LINE ログイン
OAuth 認可
→
/onboarding
情報入力
→
User 作成
常に新規
→
予約可能
登録完了
1. 背景・現状の課題
現在の受付業務では、手作業での情報確認や対応時間の長さがボトルネックになっています。本章では、解決すべき現場のリアルな課題を整理します。
現行システムでは患者の利用開始までに以下のフローが必要で、受付スタッフの業務負荷と新規患者の取りこぼしが恒常化している。
現状フロー
- 来院 → 受付スタッフが紙カルテをシステムに手動入力(数分〜十数分)
- 患者は自身の LINE / Google アカウントでログイン
- 本人確認画面で 氏名・電話番号・生年月日の 3 要素突合 を実施
- 突合成功 → カルテと予約アカウントが紐付き、予約可能
- 突合失敗 → 来院時に受付スタッフが手動修正
定量的な課題(運用観測値)
15〜20%
3 要素突合の失敗率
入力ゆれ・改姓・転居が要因
初回利用の離脱に直結
初回利用の離脱に直結
5〜10分
受付の初期登録作業時間
1 患者あたり、ピーク時の待ち時間増
9-17時
受付対応可能時間
平日のみ、夜間・休日の
新規登録は不可
新規登録は不可
<5%
Google ログイン経由の登録
2 系統維持の保守コスト負担、
廃止候補
廃止候補
本設計のゴール
- 受付の初期登録業務を 廃止 し、患者がいつでもセルフで登録できる状態にする
- 突合の失敗を構造的に発生させない(突合自体を行わない)
- 認証経路を LINE 一本に集約し、保守対象を削減
2. Before / After 比較
新たな LINE セルフ登録フローを導入することで、患者の体験とスタッフの業務負荷がどのように改善されるかを具体的に比較します。
❌ Before(現行)
- 受付スタッフが紙カルテをシステムに登録
- 患者は本人確認画面で 3 要素突合
- 突合失敗 → 来院時に手作業修正
- Google ログイン + LINE の二択
- 受付負荷 高、新規患者の取りこぼし
✅ After(新設計)
- 患者が LINE 認証後、セルフで登録
- 突合ロジック完全撤廃
- Google ログイン廃止 → LINE 一本化
- 既存 manual User は孤立カルテとして残置
- 受付業務削減、24h 登録可能
💡 ここがポイント: 一番のキモは「突合ロジックを撤廃する」という割り切り。現状の失敗率 15〜20% を構造的にゼロにできます。
変更の詳細
| 項目 | 現行 | 新設計 | 変更の理由 |
|---|---|---|---|
| 登録経路 | 受付スタッフによる事前登録 | 患者の LINE セルフ登録 | 受付業務の負荷削減 + 24h 受付の実現 |
| カルテとの紐付け | 3 要素突合(氏名・電話・生年月日) | 紐付けしない(常に新規 User) | 突合失敗の構造的排除 |
| 認証経路 | LINE OR Google | LINE のみ | Google 利用率 5% 未満、保守コスト削減 |
| 既存 manual User | 突合成功時に統合 | 残置(孤立カルテ) | データ消失防止、将来手動マージで対応 |
| 本人確認画面 | あり(突合 UI) | 廃止 | 不要になるため削除 |
3. 設計方針(振る舞い・割り切り)
開発期間と運用効果のバランスを最適に保つため、今回実装する機能とあえて見送る(割り切る)スコープの基準を明確にします。
シナリオ別の振る舞い
新規患者の初回利用
現行受付登録 → 突合
新設計LINE OAuth → セルフ登録
影響受付業務削減
既存患者(manual 登録済み)の再ログイン
現行3 要素突合で復帰
新設計新 User として作成、旧カルテは残置
影響履歴の参照経路が分離
突合失敗時
現行来院時に受付修正
新設計発生しない(突合しない)
影響受付対応削減
Google ログイン中のユーザー
現行そのまま利用可
新設計LINE への切替を促す案内表示
影響移行期間中の併存運用
割り切り(採否と理由)
突合ロジック完全撤廃
採用
受付業務削減を最優先。突合失敗 15〜20% の解消効果が大きい
既存 manual User の維持
採用
データ消失リスクを回避。過去の予約・カルテ参照に必要
自動マージ
棄却
誤マージの個人情報リスク。人の目を介した手動運用で安全に処理
過去予約データの移行
棄却
整合性検証コスト過大。既存 User の予約はそのまま参照、新 User では新規予約のみ
Google ログインの即時停止
段階的
既存利用者保護のため 90 日の猶予期間を設け、案内バナー表示
4. 認証シーケンス
LINE アカウントと患者情報を安全かつ確実に紐付けるための、システム間の連携手順と通信の流れを解説します。
図1: LINE OAuth 認可 → セルフ登録 → 予約可能までの API シーケンス
各メッセージの詳細仕様
| # | From → To | 内容 | 失敗時 |
|---|---|---|---|
| ① | Client → LINE | LINE LIFF SDK 経由で OAuth 認可(scope: profile, openid) | ユーザーキャンセル → エラー画面、再認可ボタン表示 |
| ② | LINE → Client | authorization_code を redirect_uri で受領 | state パラメータ検証失敗 → CSRF 検出ログ、再認可へ |
| ③ | Client → API | POST /api/v1/auth/oauth/register、Header に LINE access_token、Body に name/kana/phone/dob | 後述のエラー分岐参照 |
| ④ | API → DB | User テーブルに INSERT、line_user_id を UNIQUE 制約で保護 | UNIQUE 違反 → 409 Conflict、再ログインを促す |
| ⑤ | DB → API | 新規 user_id を返却 | DB エラー → 500、Sentry 通知 |
| ⑥ | API → Client | JWT(24h 有効)+ user_id を 201 で返却 | — |
| ⑦ | Client → API | JWT を Authorization Header に乗せて以降の予約 API へ | JWT 期限切れ → リフレッシュフロー(既存) |
5. API 仕様(完全版)
アプリケーションとサーバ間で正確に情報をやり取りするための、エンドポイントや通信フォーマットの詳細を定義します。
エンドポイント
POST /api/v1/auth/oauth/register — 新設
Request
POST /api/v1/auth/oauth/register HTTP/1.1
Host: api.example-clinic.jp
Authorization: Bearer <LINE access_token>
Content-Type: application/json
X-Request-Id: <uuid>
{
"name": "山田 太郎",
"kana": "ヤマダ タロウ",
"phone": "090-1234-5678",
"dob": "1990-01-01"
}
Request フィールド制約
| フィールド | 型 | 必須 | 制約 | 備考 |
|---|---|---|---|---|
name | string | ✓ | 1〜50 文字、全角/半角混在可、前後空白は trim | 表示用 |
kana | string | ✓ | 1〜50 文字、全角カタカナと半角スペースのみ | 検索キー、ふりがな正規化対象 |
phone | string | ✓ | E.164 形式 (+819012345678) または 0X0-XXXX-XXXX | サーバ側で E.164 に正規化 |
dob | string | ✓ | ISO 8601 YYYY-MM-DD、1900-01-01 以降、未来日不可 | UTC 基準 |
Response 201 Created
HTTP/1.1 201 Created
Content-Type: application/json
{
"user_id": "usr_01HXY3K9P5R2J7Q1",
"jwt": "eyJhbGciOiJSUzI1NiIs...",
"expires_at": "2026-05-18T03:00:00Z",
"registration_type": "line_self_registered"
}
非機能要件
| 項目 | 値 | 備考 |
|---|---|---|
| Rate Limit | 10 req / min / IP | 既存 middleware(Redis 利用)を再利用 |
| 監査ログ | 有効 | audit_logs テーブルに request_id, line_user_id, result_code を記録 |
| タイムアウト | 5 秒 | DB 書き込み 1 回 + LINE Verify 1 回 |
| 冪等性 | X-Request-Id ベース | 同一 X-Request-Id の再送は同じ response を返す(24h 保持) |
6. データモデル
新しい予約フローを実現するために必要となる、情報の保存形式や各データの関連性を設計図として示します。
User テーブル拡張
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
id | uuid | PK | 既存 |
line_user_id | varchar(64) | UNIQUE, NULL 可 | LINE 連携時のみセット |
name | varchar(50) | NOT NULL | 既存 |
kana | varchar(50) | NOT NULL | 既存 |
phone | varchar(20) | NOT NULL, AES 暗号化 | E.164 形式で保存 |
dob | date | NOT NULL | 既存 |
registration_type | enum | NOT NULL | 新設(下記 enum 参照) |
created_at | timestamptz | NOT NULL | 既存 |
registration_type enum
| 値 | 説明 | 該当ユーザー |
|---|---|---|
line_self_registered | 新設計の LINE セルフ登録 | 本設計以降の新規登録 |
manual_registered | 受付スタッフによる旧登録 | 本設計より前の既存ユーザー(孤立カルテ) |
google_legacy | 旧 Google ログイン経由 | 移行期間中の既存ユーザー、90 日後に廃止予定 |
マイグレーション順序
registration_typeカラムを追加(defaultmanual_registered)- 既存全レコードをバックフィル(Google ログイン者は
google_legacy) - NOT NULL 制約を付与
line_user_idに UNIQUE インデックス追加
7. UI フロー・バリデーション
患者が迷わず操作できる画面遷移と、誤入力を未然に防ぐためのシステム的なチェック機構について説明します。
患者目線で見るとシンプル: LINE 上で 4 フィールド入力 → 完了画面 → 即予約可能。
所要時間およそ 30〜60 秒。受付不要、24h いつでも。
所要時間およそ 30〜60 秒。受付不要、24h いつでも。
9:41📶 100%
本人確認
氏名例: 山田 太郎
電話番号090-XXXX-XXXX
生年月日YYYY-MM-DD
⚠ 受付登録済みの方のみ
突合する
Before
3 要素突合・失敗多発
LINE 公式アカウント
ご利用登録
お名前山田 太郎
フリガナヤマダ タロウ
電話番号090-XXXX-XXXX
生年月日1990-01-01
登録する
After
セルフ登録・24h 受付
LINE 公式アカウント
登録完了 🎉
ご登録ありがとうございます
診療予約のご利用が可能になりました。
下のボタンから予約画面へお進みください。
下のボタンから予約画面へお進みください。
予約を開始
マイページ
After: 完了
即日予約可能
バリデーションルール
name
空 or 51 文字以上
クライアント / サーバ 両方で検証
kana
非カタカナ含む
クライアント / サーバ 両方で検証
phone
フォーマット不正
クライアント / サーバ 両方で検証
dob
未来日 or 1900 年以前
クライアント / サーバ 両方で検証
(全体)
LINE token 失効
サーバ側のみで検出
画面遷移条件
- 登録ボタン押下 → クライアントバリデーション通過 → API 呼び出し
- API 201 → 完了画面(自動遷移、戻る不可)
- API 400 → フィールド下にエラー表示、入力値は保持
- API 401 → ログイン画面に戻し、トーストで通知
- API 429 → 「混み合っています、しばらくお待ちください」表示、60 秒後に再送可能
- API 500 → エラー画面、リトライボタン + サポート問い合わせ案内
8. エラー分岐とレスポンス
通信障害や予期せぬ操作が行われた際に、ユーザーへどのようなメッセージを返し、どう解決へ導くかを定義します。
図2: 登録 API のレスポンス分岐(5 パターン)
レスポンス body の完全スキーマ
400 Bad Request — validation_error
{
"error": "validation_error",
"request_id": "req_01HXY...",
"details": [
{ "field": "kana", "code": "non_katakana", "message": "フリガナはカタカナで入力してください" },
{ "field": "phone", "code": "invalid_format", "message": "電話番号の形式が正しくありません" }
]
}
401 Unauthorized — invalid_token
{
"error": "invalid_token",
"request_id": "req_01HXY...",
"message": "LINE アクセストークンが無効または期限切れです"
}
429 Too Many Requests — rate_limited
{
"error": "rate_limited",
"request_id": "req_01HXY...",
"retry_after": 60,
"message": "リクエストが多すぎます。60 秒後に再試行してください"
}
500 Internal Server Error
{
"error": "server_error",
"request_id": "req_01HXY...",
"message": "サーバエラーが発生しました。サポートまでご連絡ください"
}
ハンドリングポリシー
400 Bad Request
401 Unauthorized
429 Too Many
500 Internal
9. 実装スコープ
プロジェクトを計画通りに進めるため、初期フェーズで確実に対応する機能と、次期開発へ回す機能の境界線を整理します。
IN 今回実装
- POST /oauth/register エンドポイント
- LINE token 検証
- セルフ登録 UI 画面
- Google ログイン UI の削除
- 本人確認画面の廃止
OUT 今回スコープ外
- 孤立カルテのマージ機能
- 過去予約データの移行
- 受付スタッフ向け管理画面の改修
- 電子カルテ連携
REUSE 既存活用
- レート制限ミドルウェア
- audit_logs テーブル
- JWT 発行ロジック
- LINE OAuth 認可フロー
スコープ外項目の理由と将来対応
| 項目 | スコープ外の理由 | 将来対応のタイミング |
|---|---|---|
| 孤立カルテマージ機能 | 誤マージの個人情報リスクが高く、自動化に慎重を要する | 運用 3 ヶ月後、手動マージ件数を踏まえて UI 自動化を検討 |
| 過去予約データの移行 | 整合性検証コスト過大、既存ユーザーは旧 User で参照可能 | マージ機能と併せて検討(運用 6 ヶ月後想定) |
| 受付スタッフ向け管理画面 | 受付業務削減により利用頻度が下がる見込み | 必要が顕在化した段階で対応 |
| 電子カルテ連携 | 本設計の範囲を逸脱、別プロジェクトとして扱う | 別途プロジェクト化 |
10. セキュリティ・テスト
医療データを扱う上で必須となるセキュリティ対策と、リリース前の品質を担保するための具体的なテスト手法について説明します。
脅威モデル
| 脅威 | 対策 | 監視 |
|---|---|---|
| LINE access_token のなりすまし | LINE Verify API でトークンを毎回サーバ検証 | audit_logs に検証結果を記録、失敗増加でアラート |
| レート濫用(bot による大量登録) | 10 req/min/IP、ハーフ通過時 reCAPTCHA | Prometheus メトリクス、Grafana アラート |
| 個人情報漏洩 | phone は AES-GCM 暗号化、dob は同テーブル別カラムで分離 | DB アクセスログを 90 日保持 |
| SQL Injection | ORM パラメータバインド、生 SQL 禁止(lint で検知) | 静的解析を CI に組込 |
| CSRF(state 改竄) | OAuth state を nonce + HMAC で署名、サーバ側で検証 | 検証失敗ログを SIEM に転送 |
テスト戦略
| レベル | 対象 | ツール | カバレッジ目標 |
|---|---|---|---|
| 単体 | 各バリデーター、ふりがな正規化、phone E.164 正規化 | RSpec / Jest | 95% |
| 統合 | POST /oauth/register の全分岐、LINE Verify モック化 | RSpec request spec | 分岐 100% |
| E2E | LINE OAuth → 登録 → 予約画面までのハッピーパス、エラーパス | Playwright | 主要 2 シナリオ |
| 負荷 | 10 req/sec × 1 分、レート制限の挙動 | k6 | p95 < 500ms |
移行時の注意: Google ログインの 90 日廃止期間中、既存ユーザーへのリマインドメール送信を 30 日前・7 日前・当日に送る。LINE への切替手順を明記したヘルプページを別途用意すること。