LINE セルフ登録フロー設計

既存「受付登録 + 本人確認」モデル → 「LINE 直接セルフ登録」への移行設計 — 視覚要素 + 詳細仕様併存版

TL;DR
  • 受付経由の事前登録を廃止し、患者は LINE でセルフ登録 する形に変更
  • 突合ロジック(氏名・電話・生年月日の 3 要素マッチ)を 完全撤廃。常に新規 User を作成
  • Google ログイン廃止 → LINE 一本化。既存 manual User は「孤立カルテ」として残置、将来手動マージ

📍 全体フロー一望

📱
LINE ログイン
OAuth 認可
✍️
/onboarding
情報入力
👤
User 作成
常に新規
📅
予約可能
登録完了

1. 背景・現状の課題

現在の受付業務では、手作業での情報確認や対応時間の長さがボトルネックになっています。本章では、解決すべき現場のリアルな課題を整理します。

現行システムでは患者の利用開始までに以下のフローが必要で、受付スタッフの業務負荷と新規患者の取りこぼしが恒常化している。

現状フロー

  1. 来院 → 受付スタッフが紙カルテをシステムに手動入力(数分〜十数分)
  2. 患者は自身の LINE / Google アカウントでログイン
  3. 本人確認画面で 氏名・電話番号・生年月日の 3 要素突合 を実施
  4. 突合成功 → カルテと予約アカウントが紐付き、予約可能
  5. 突合失敗 → 来院時に受付スタッフが手動修正

定量的な課題(運用観測値)

15〜20%
3 要素突合の失敗率
入力ゆれ・改姓・転居が要因
初回利用の離脱に直結
5〜10
受付の初期登録作業時間
1 患者あたり、ピーク時の待ち時間増
9-17
受付対応可能時間
平日のみ、夜間・休日の
新規登録は不可
<5%
Google ログイン経由の登録
2 系統維持の保守コスト負担、
廃止候補

本設計のゴール

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 アカウントと患者情報を安全かつ確実に紐付けるための、システム間の連携手順と通信の流れを解説します。

📱 Client ⚙️ API 🟢 LINE 💾 DB ① LINE 認可リクエスト ② 認可コード返却 ③ POST /oauth/register ④ User 新規作成 ⑤ user_id 返却 ⑥ JWT + 完了レスポンス ⑦ 以降は予約 API 利用可
図1: LINE OAuth 認可 → セルフ登録 → 予約可能までの API シーケンス

各メッセージの詳細仕様

#From → To内容失敗時
Client → LINELINE LIFF SDK 経由で OAuth 認可(scope: profile, openid)ユーザーキャンセル → エラー画面、再認可ボタン表示
LINE → Clientauthorization_code を redirect_uri で受領state パラメータ検証失敗 → CSRF 検出ログ、再認可へ
Client → APIPOST /api/v1/auth/oauth/register、Header に LINE access_token、Body に name/kana/phone/dob後述のエラー分岐参照
API → DBUser テーブルに INSERT、line_user_id を UNIQUE 制約で保護UNIQUE 違反 → 409 Conflict、再ログインを促す
DB → API新規 user_id を返却DB エラー → 500、Sentry 通知
API → ClientJWT(24h 有効)+ user_id を 201 で返却
Client → APIJWT を 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 フィールド制約

フィールド必須制約備考
namestring1〜50 文字、全角/半角混在可、前後空白は trim表示用
kanastring1〜50 文字、全角カタカナと半角スペースのみ検索キー、ふりがな正規化対象
phonestringE.164 形式 (+819012345678) または 0X0-XXXX-XXXXサーバ側で E.164 に正規化
dobstringISO 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 Limit10 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 テーブル拡張

カラム制約備考
iduuidPK既存
line_user_idvarchar(64)UNIQUE, NULL 可LINE 連携時のみセット
namevarchar(50)NOT NULL既存
kanavarchar(50)NOT NULL既存
phonevarchar(20)NOT NULL, AES 暗号化E.164 形式で保存
dobdateNOT NULL既存
registration_typeenumNOT NULL新設(下記 enum 参照)
created_attimestamptzNOT NULL既存

registration_type enum

説明該当ユーザー
line_self_registered新設計の LINE セルフ登録本設計以降の新規登録
manual_registered受付スタッフによる旧登録本設計より前の既存ユーザー(孤立カルテ)
google_legacy旧 Google ログイン経由移行期間中の既存ユーザー、90 日後に廃止予定

マイグレーション順序

  1. registration_type カラムを追加(default manual_registered
  2. 既存全レコードをバックフィル(Google ログイン者は google_legacy
  3. NOT NULL 制約を付与
  4. line_user_id に UNIQUE インデックス追加

7. UI フロー・バリデーション

患者が迷わず操作できる画面遷移と、誤入力を未然に防ぐためのシステム的なチェック機構について説明します。

患者目線で見るとシンプル: LINE 上で 4 フィールド入力 → 完了画面 → 即予約可能。
所要時間およそ 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 文字以上
お名前を入力してください(50 文字以内)
クライアント / サーバ 両方で検証
kana
非カタカナ含む
フリガナはカタカナでご入力ください
クライアント / サーバ 両方で検証
phone
フォーマット不正
電話番号の形式が正しくありません
クライアント / サーバ 両方で検証
dob
未来日 or 1900 年以前
生年月日が正しくありません
クライアント / サーバ 両方で検証
(全体)
LINE token 失効
セッションが切れました。再度ログインしてください
サーバ側のみで検出

画面遷移条件

  • 登録ボタン押下 → クライアントバリデーション通過 → API 呼び出し
  • API 201 → 完了画面(自動遷移、戻る不可)
  • API 400 → フィールド下にエラー表示、入力値は保持
  • API 401 → ログイン画面に戻し、トーストで通知
  • API 429 → 「混み合っています、しばらくお待ちください」表示、60 秒後に再送可能
  • API 500 → エラー画面、リトライボタン + サポート問い合わせ案内

8. エラー分岐とレスポンス

通信障害や予期せぬ操作が行われた際に、ユーザーへどのようなメッセージを返し、どう解決へ導くかを定義します。

POST /oauth/register 入力検証 VALIDATION OK 201 Created JWT + user_id 入力不正 400 Bad Request validation_error LINE token 無効 401 Unauthorized invalid_token 過剰呼出 429 Too Many rate_limited 500 Internal server_error
図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
ログINFO Sentry フロントフィールド下にエラー表示 リトライ—(修正後再送)
401 Unauthorized
ログWARN Sentry フロントログイン画面へリダイレクト リトライ
429 Too Many
ログWARN Sentry フロント「混み合っています」トースト リトライ60 秒後に許可
500 Internal
ログERROR Sentry✓ 通知 フロントエラー画面 + リトライボタン リトライ指数バックオフ 3 回

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、ハーフ通過時 reCAPTCHAPrometheus メトリクス、Grafana アラート
個人情報漏洩phone は AES-GCM 暗号化、dob は同テーブル別カラムで分離DB アクセスログを 90 日保持
SQL InjectionORM パラメータバインド、生 SQL 禁止(lint で検知)静的解析を CI に組込
CSRF(state 改竄)OAuth state を nonce + HMAC で署名、サーバ側で検証検証失敗ログを SIEM に転送

テスト戦略

レベル対象ツールカバレッジ目標
単体各バリデーター、ふりがな正規化、phone E.164 正規化RSpec / Jest95%
統合POST /oauth/register の全分岐、LINE Verify モック化RSpec request spec分岐 100%
E2ELINE OAuth → 登録 → 予約画面までのハッピーパス、エラーパスPlaywright主要 2 シナリオ
負荷10 req/sec × 1 分、レート制限の挙動k6p95 < 500ms
移行時の注意: Google ログインの 90 日廃止期間中、既存ユーザーへのリマインドメール送信を 30 日前・7 日前・当日に送る。LINE への切替手順を明記したヘルプページを別途用意すること。