中規模の整形外科クリニックが私たちのところにやってきました。ヘルスケア業界でよくある問題を抱えていました。WordPress サイトが遅く、患者の初診時受付プロセスは PDF ダウンロードとファックス送信の悪夢で、IT コンプライアンス責任者は HIPAA リスクで眠れない状況でした。6ヶ月後、彼らは Next.js フロントエンド、Payload CMS バックエンド、HIPAA 対応の患者初診時受付フォーム、競合他社のサイトをダイアルアップのように見せてしまう Lighthouse スコアを手に入れました。以下は、私たちがどのようにしてこれを実現したかの詳細です。

目次

Healthcare Practice: WordPress to Next.js + Payload CMS Migration

スタート地点:私たちが何を扱っていたのか

このクリニック—Southeastern Ortho と呼びましょう(NDA があるのでご承知ください)—は 2017 年から WordPress を実行していました。それらの設定は、技術的な監督なしに有機的に成長してきたヘルスケア クリニックの典型的でした:

  • WordPress 6.2 34 個のプラグイン付き(そのうち 11 個は 1 年以上更新されていない)
  • 共有ホスティング 月額 $29 のプランで
  • Contact Form 7 が患者の問い合わせを処理—暗号化なし、ホスティング プロバイダーとの BAA なし
  • PDF 初診時受付フォーム 患者がダウンロード、印刷、手書き記入してファックスするか、予約時に持参する必要がある
  • ページ読み込み時間 モバイルで平均 6.8 秒
  • Lighthouse モバイル スコア:38

その Lighthouse スコアは誤植ではありません。38 です。サイトには最適化されていないヒーロー画像(1 つは 4.2MB の PNG)、5 つの異なるプラグインからのレンダリング ブロック CSS、プラグインの競合により 3 回読み込まれる jQuery がありました。

しかし、本当の問題はパフォーマンスではありませんでした。それはリスクです。

彼らの連絡先フォームは患者の名前、電話番号、時には医学的訴状説明を収集していました。そのデータは暗号化されていないフォーム プラグインを通じて流れ、共有ホスティング上の WordPress データベースに保存され、事業提携契約(BAA)のないサービスにバックアップされていました。彼らのコンプライアンス担当者がこのフラグを立てていて、彼らの医療過誤保険キャリアは質問をしていました。

要件

このクリニックが必要としていたもの:

  1. 彼らのケアの質を反映した、高速でモダンな Web サイト
  2. HIPAA 対応の患者初診時受付フォームで、紙のプロセスに置き換わるもの
  3. CMS:彼らのオフィス マネージャーが開発者に電話をかけることなく更新できるもの
  4. より良い SEO パフォーマンス(彼らは新しいクリニックへのローカル検索ランキングで負けていた)
  5. これらすべてが予算内で—彼らはテック スタートアップではなく医療クリニックです

Next.js と Payload CMS を選んだ理由

私たちはいくつかのアーキテクチャ オプションを評価しました。クライアントに提示した正直な比較は以下の通りです:

オプション 利点 欠点 推定コスト
WordPress リビルド(新しいテーマ + プラグイン) スタッフに馴染みがある、初期コストが低い HIPAA リスクと同じ、パフォーマンス上限、プラグインの依存性 $15-25K
Webflow + サードパーティ フォーム ビルドが高速、パフォーマンスが良い HIPAA コンプライアンス オプションが限定的、継続的な座席あたりのコスト、ベンダー ロック イン $20-30K
Next.js + Payload CMS 完全なコントロール、HIPAA 対応アーキテクチャ、最高のパフォーマンス より高い初期投資、ホスティング管理が必要 $35-50K
Next.js + Sanity 優れた編集エクスペリエンス、良いエコシステム Sanity の価格は使用量に応じてスケーリング、PHI 処理に関する懸念(クラウドホスト CMS) $30-45K

私たちは Next.js と Payload CMS を推奨しました。以下がその理由です。

Next.js が適切なフロントエンドでした

Next.js 14(このプロジェクトは 2024 年後半に開始され、その後 15 で実行されています)は、ヘルスケア サイトが必要とするもの全てを提供しました:

  • コンテンツ ページの静的生成 — 医師の経歴、サービス説明、場所情報。これらのページはめったに変わらないため、ビルド時に事前にレンダリングします。リクエスト時にサーバー計算がゼロになるため、高速な TTFB が実現します。
  • 動的コンテンツのサーバー コンポーネント — 予約可能性、ブログ投稿、初診時受付フォーム ロジックはすべて、クライアントに不要な JavaScript を送信せずにサーバーサイド レンダリングの恩恵を受けます。
  • すぐに使える画像最適化next/image 自動 WebP/AVIF 変換は、それらの 4MB PNG を適切にサイズされた遅延読み込み画像に置き換えました。
  • セキュリティ ヘッダー用ミドルウェア — 私たちは Next.js ミドルウェアを使用して、厳密な CSP ヘッダー、HSTS、および HIPAA 監査役が見たいその他のセキュリティ ヘッダーを設定します。

アプローチについて知りたい場合は、Next.js 開発機能についてさらに詳しく記録しました。

Payload CMS が適切なバックエンドでした

ヘルスケアに固有の理由から、私たちは他のヘッドレス オプションよりも Payload CMS 3.0 を選びました:

設計上、自己ホストされた。 Payload は独自のインフラストラクチャで実行されます。これは HIPAA にとって非交渉可能です。保護された健康情報(PHI)を扱う場合、データが正確にどこに存在するか、誰がアクセスできるか、インフラストラクチャ プロバイダーと BAA に署名できるかを知る必要があります。Contentful や Sanity などのクラウド ホストの CMS プラットフォームは、彼らのサーバーにデータを保存します—一部はエンタープライズ レベルで HIPAA コンプライアンスを提供しますが、コストは通常、Payload を HIPAA 対応プロバイダーで自己ホストするコストの 3~5 倍です。

TypeScript ネイティブ。 Payload の設定は単なる TypeScript です。これは、コンテンツ モデル、API レスポンス、フロントエンド型が同じ真実の唯一のソースを共有することを意味します。オフィス マネージャーが初診時受付フォームに「保険事前承認番号」の新しいフィールドを追加すると、生成される型を通じてフロントエンドがそれをすぐに認識します。

組み込みアクセス制御。 Payload のフィールドレベルのアクセス制御では、マーケティング担当者がブログ投稿とサービス ページを編集できるロールを作成できましたが、患者初診時受付データには触れられません。オフィス マネージャーは初診時受付提出物を表示できますが、フォーム構造を変更することはできません。コンプライアンスのためのアクセス制御を文書化する場合、この粒度は重要です。

リッチ テキスト が正しく行われた。 Payload は Lexical(以前の Slate)をリッチ テキストに使用しており、編集エクスペリエンスは本当に優れています。何年も WordPress を使用してきたクライアントのオフィス マネージャーは、1 回の 45 分のトレーニング セッション内で Payload の管理パネルで快適でした。

私たちは定期的に Payload およびその他のヘッドレス CMS プラットフォームで作業しています—ヘッドレス CMS 開発アプローチについてさらに詳しく見ることができます。

ヘッドレスアーキテクチャにおける HIPAA 考慮事項

何かをはっきりさせておきましょう:技術スタック自体は「HIPAA 対応」ではありません。 HIPAA コンプライアンスは組織的な慣行であり、ソフトウェア機能ではありません。技術スタックが「HIPAA 対応」できるのは、それが不要なリスクを導入せず、HIPAA が必要とする行政的、物理的、技術的なセーフガードをサポートすることを意味します。

ここが私たちが実装したものです:

インフラストラクチャ

  • ホスティング: AWS と署名済み BAA。ECS Fargate で Payload CMS コンテナを使用し、Next.js フロントエンドを Vercel にデプロイしました(PHI を処理しないことが重要な違い)。
  • データベース: 保存時暗号化(AES-256)と転送時暗号化(TLS 1.2+)を備えた Amazon RDS PostgreSQL。Payload 3.0 は Postgres をネイティブにサポートしており、v3 を待つ大きな理由でした。
  • ファイル ストレージ: サーバーサイド暗号化、アクセスを制限するバケット ポリシー、監査証跡の有効化を備えた S3。

患者初診時受付用データ フロー

ここが構造が興味深くなるところです。患者初診時受付フォームは Next.js フロントエンドに存在しますが、決して PHI を Vercel のインフラストラクチャを通じて送信しません。

Patient Browser → HTTPS → API Route (Next.js on Vercel) → No PHI stored here
                                    ↓
                           AWS API Gateway (with WAF)
                                    ↓
                           Lambda function (validates, encrypts)
                                    ↓
                           Payload CMS API (on ECS Fargate)
                                    ↓
                           RDS PostgreSQL (encrypted at rest)

Next.js API ルートは薄いプロキシとして機能します。リクエスト構造を検証しますが(CSRF トークン、レート制限、基本的なフィールド検証)、PHI をログまたは保存しません。実際のデータ処理は AWS の HIPAA 対応サービス内で完全に発生します。

暗号化の詳細

最も機密性の高いデータに対してフィールドレベルの暗号化を実装しました。患者 SSN フラグメント(最後の 4 桁)、保険 ID、医学的訴状説明は、データベースに入る前に AES-256-GCM を使用してアプリケーション層で暗号化されます。つまり、データベース アクセスを取得した場合でも、機密フィールドについては暗号化されたブロブが表示されます。

// Payload でのフィールドレベルの暗号化フックの簡略版
import { encrypt } from '../lib/crypto';

const PatientIntake: CollectionConfig = {
  slug: 'patient-intake',
  hooks: {
    beforeChange: [
      async ({ data }) => {
        if (data.ssnLastFour) {
          data.ssnLastFour = await encrypt(data.ssnLastFour);
        }
        if (data.medicalComplaint) {
          data.medicalComplaint = await encrypt(data.medicalComplaint);
        }
        return data;
      },
    ],
  },
  access: {
    read: ({ req: { user } }) => {
      return user?.role === 'office-admin' || user?.role === 'provider';
    },
    create: () => true, // Public form submission
    update: ({ req: { user } }) => user?.role === 'office-admin',
    delete: () => false, // Retention policy - no deletions through CMS
  },
  fields: [
    // ... field definitions
  ],
};

監査ログ

患者初診時受付データへのすべてのアクセスがログに記録されます—誰が表示したか、いつ、どの IP からのか。私たちは、別の監査ログ テーブルに書き込む Payload プラグインをカスタムビルドしました。このテーブルは追加のみです。管理者ユーザーでもエントリを変更または削除することはできません。クリニックの年次 HIPAA リスク評価の間に、この監査証跡は特に強みとして指摘されました。

Healthcare Practice: WordPress to Next.js + Payload CMS Migration - architecture

患者初診時受付の再設計

古いプロセス:患者が 6 ページの PDF をダウンロードし、印刷し、ペンで記入し(半分の時間は判読不可能)、オフィスに持参し、スタッフ メンバーがそれを彼らの EHR システムに手動で入力します。ダウンロードから EHR 入力までの平均時間:3~5 営業日。

新しいプロセス:患者は予約の 48 時間前にテキスト メッセージまたはメール リンクを受け取り、電話で複数ステップのフォームを約 8 分で完了し、データは彼らが玄関を通る前にクリニックのシステムで利用可能になります。

フォーム UX の決定

初診時受付フォームを 7 つのステップに分割しました:

  1. 本人確認(名前、生年月日、連絡先情報)
  2. 保険情報(保険会社、ID、グループ番号、カード写真アップロード)
  3. 医療履歴(状態チェックリスト、外科的履歴)
  4. 現在の薬剤(オープン処方箋データベースからのオートコンプリート付き)
  5. 来院理由(自由記述 + 痛みの位置を示す身体図)
  6. 同意と契約(電子署名キャプチャ)
  7. 確認と送信

本当に差を作ったいくつかの UX の詳細:

  • プログレス インジケーター「ステップ 3/7」を表示すると、すべてのフィールドを一度に表示した最初のプロトタイプと比較して、放棄を約 40% 削減しました。私たちはソフト ローンチ中にこれを A/B テストしました。
  • 保険カード写真アップロード 自動トリミングとプレビュー付き。患者はカードの表と裏を写真撮影します。これだけで、フロント デスク データ入力の約 60% を排除しました。
  • 薬剤オートコンプリート RxNorm API を使用。患者が「hydroxychloroquine」を綴ろうとするのではなく、「hydro」を入力してフィルタされたリストから選択します。これは薬剤入力エラーを大幅に削減しました。
  • セッション永続化 — 患者がフォームを開始して中断されても、彼らの進捗は保存されます(sessionStorage に暗号化、localStorage には決してしない)30 分間。彼らはどこから始めたかを再開できます。
// RxNorm API を使用した薬剤オートコンプリート
const useMedicationSearch = (query: string) => {
  return useQuery({
    queryKey: ['medications', query],
    queryFn: async () => {
      if (query.length < 3) return [];
      const res = await fetch(
        `/api/medications/search?q=${encodeURIComponent(query)}`
      );
      return res.json();
    },
    staleTime: 1000 * 60 * 5, // Cache for 5 minutes
    enabled: query.length >= 3,
  });
};

サーバー側の薬剤検索エンドポイントは AWS バックエンドを通じて RxNorm をクエリし、外部 API 呼び出しをクライアントから遠ざけ、結果をキャッシュできるようにします。

パフォーマンス結果と Lighthouse スコア

ビフォーアフターは以下の通りです:

メトリック WordPress(変更前) Next.js + Payload(変更後) 改善
Lighthouse モバイル 38 94 +147%
Lighthouse デスクトップ 61 99 +62%
First Contentful Paint(モバイル) 4.2s 0.8s -81%
Largest Contentful Paint(モバイル) 8.1s 1.4s -83%
Total Blocking Time 1,840ms 45ms -98%
Cumulative Layout Shift 0.34 0.01 -97%
Time to Interactive 9.3s 1.2s -87%
Page Weight(ホームページ) 4.8MB 340KB -93%
Core Web Vitals Pass いいえ はい(すべて緑)

モバイルの Lighthouse スコア 94(100 ではなく、その理由については説明します)は、患者初診時受付ページで測定されました。これはサイトで最も JavaScript が多いページです。ホームページやサービス ページなどのコンテンツ ページは、モバイルとデスクトップの両方で一貫して 98~100 のスコアを獲得しています。

なぜモバイル上で完璧な 100 ではないのか。2 つの理由:

  1. 薬剤オートコンプリート ウィジェットは、初診時受付フォーム ページに約 12KB gzip を追加するクライアント側 JavaScript を必要とします。
  2. 初診時受付フォーム上で reCAPTCHA v3 を使用してボット防止レイヤーとしていますが、Google の reCAPTCHA スクリプトは非常に軽いわけではありません。遅延読み込みしますが、それでも数ポイントを消費します。

100 に達するために reCAPTCHA を削除することを考慮しましたが、セキュリティ メリットは虚栄心メトリックを上回ります。ボット保護のない医療初診時受付フォームは、実際の患者データと混ざった迷惑メール送信を求めています。

移行戦略:ゼロダウンタイム、ランキング喪失なし

医療クリニックの Web サイトを移行することはストレスが多いです。ダウンタイムは文字通り失われた患者の予約を意味するからです。以下が私たちがそれを処理する方法です:

コンテンツ移行

WordPress REST API からコンテンツを取得し、Payload CMS ドキュメントに変換するスクリプトを作成しました。スクリプトは以下を処理しました:

  • 47 のサービス ページ
  • 12 の医師/プロバイダー プロフィール
  • 89 のブログ投稿(画像の再ホスティング付き)
  • 6 つの場所ページ
  • すべての SEO メタデータ(タイトル、説明、正規 URL)

URL マッピング

すべての WordPress URL は同等の Next.js にマッピングされました。可能な限り同じ URL 構造を維持し、変更された少数の URL に対して next.config.js に 301 リダイレクトを設定しました:

// next.config.js
const redirects = async () => [
  {
    source: '/services/:slug',
    destination: '/orthopedic-services/:slug',
    permanent: true,
  },
  {
    source: '/team/:slug',
    destination: '/providers/:slug',
    permanent: true,
  },
  // ... 23 more redirects
];

DNS カットオーバー

私たちはブルー グリーン デプロイ戦略を使用しました。新しいサイトは 2 週間並行して実行され、テストしました。カットオーバーの日、日曜日の夜のメンテナンス ウィンドウ中に DNS レコードを更新しました。表示されたダウンタイム:約 3 分(DNS の伝播は迅速でした。カットオーバーの 1 週間前に TTL を 60 秒に事前に削減していたため)。

SEO 結果

ローンチ後 3 ヶ月:

  • オーガニック トラフィックが 34% 増加
  • 「近所の整形外科医」の平均位置が位置 14 から位置 5 に改善
  • Google からのクリック率が 28% 増加(Core Web Vitals の向上 = より良いモバイル SERP エクスペリエンス)
  • 以前にインデックスされていた URL について Search Console で 404 エラーがゼロ

技術アーキテクチャの詳細解析

完全なピクチャーが必要な方向け:

┌─────────────────────────────────────────────┐
│                  Vercel                       │
│  ┌─────────────────────────────────────────┐ │
│  │  Next.js 15 App Router                  │ │
│  │  - Static pages (ISR, 60s revalidation) │ │
│  │  - Server Components                    │ │
│  │  - API routes (proxy only, no PHI)      │ │
│  └─────────────────────────────────────────┘ │
└──────────────────┬──────────────────────────┘
                   │ HTTPS
┌──────────────────▼──────────────────────────┐
│              AWS (HIPAA BAA)                 │
│  ┌──────────────┐  ┌─────────────────────┐  │
│  │  API Gateway  │  │  CloudFront (assets)│  │
│  │  + WAF        │  └─────────────────────┘  │
│  └──────┬───────┘                            │
│         │                                    │
│  ┌──────▼───────┐  ┌─────────────────────┐  │
│  │  ECS Fargate  │──│  RDS PostgreSQL     │  │
│  │  (Payload 3)  │  │  (encrypted)        │  │
│  └──────┬───────┘  └─────────────────────┘  │
│         │                                    │
│  ┌──────▼───────┐  ┌─────────────────────┐  │
│  │  S3 (uploads) │  │  CloudWatch (logs)  │  │
│  │  (encrypted)  │  │  (audit trail)      │  │
│  └──────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────┘

月間インフラストラクチャ コスト:AWS で約 $180~220/月(この規模では ECS Fargate は意外と手頃です)、Vercel Pro で $20/月を追加。彼らが以前にいた月額 $29 の共有ホスティングと比較してください。はい、より高価ですが、HIPAA 対応のインフラストラクチャ、自動スケーリング、本物のセキュリティが得られます。

学んだ教訓

1. HIPAA の会話を早期に開始します。 私たちはコードの 1 行を書く前に、アーキテクチャ計画に 3 週間を費やしました。これにより、少なくとも 2 つの潜在的なリデザインを回避しました。

2. Payload CMS v3 は待つ価値がありました。 このプロジェクトは Payload 3.0 がベータ版の時に開始されました。粗いエッジがありました—移行ドキュメントは不完全で、一部のプラグインはまだ更新されていませんでした。しかし、ネイティブ Postgres サポートと改善された管理 UI はそれを正しい選択にしました。

3. 初診時受付フォームを過度に設計しないでください。 最初のプロトタイプには、6 レベル深い条件付きロジックがありました。オフィス マネージャーが見て、「質問を順番に尋ねることはできませんか?」と言いました。彼女は正しかった。簡素化すると、完了率が上がりました。

4. ヘルスケア クライアントは CMS トレーニングに手をかける必要があります。 私たちは通常の 1 つではなく 3 つのトレーニング セッションを提供しました。さらに、一般的なタスク用の記録された Loom ビデオ。トレーニングへの投資は初月中にそれ自体を支払いました。オフィス マネージャーが新しいプロバイダー ページを追加できた時点で、サポート チケットを申請しなかった場合です。

5. パフォーマンス予算は交渉不可能です。 プロジェクトの開始時にパフォーマンス予算を <400KB ページ重量および <100ms Total Blocking Time に設定しました。すべての PR は CI のこの予算に対してチェックされました。アニメーション イラスト レーション ライブラリを追加しようとしたときだけ、予算を爆破し、配送前に捕捉しました。

規制対象のサイトに対するヘルスケアまたは同様の移行を検討している場合は、詳細について話し合わせてください。直接連絡するか、プロジェクト範囲に関する価格ページをご確認ください。

FAQ

Next.js と Payload CMS を使用すれば、自動的にサイトが HIPAA 対応になりますか?

いいえ。技術スタック自体は本質的に HIPAA 対応ではありません。HIPAA コンプライアンスには、行政的なセーフガード(ポリシー、トレーニング、リスク評価)、物理的なセーフガード(施設のアクセス制御)、技術的なセーフガード(暗号化、アクセス制御、監査ログ)が必要です。Next.js と Payload CMS が提供するのは、柔軟なアーキテクチャです。ここで技術的なセーフガードを適切に実装できます。特に Payload の自己ホスト性質により、PHI がどこに存在するかを制御できます。

Jotform や FormStack などの HIPAA 対応フォーム サービスを使用しない理由は?

絶対に、そしてシンプルなユース ケースではそれは合理的な選択です。Jotform の HIPAA プラン($99/月)と FormStack($83/月)を評価しました。この クライアントの問題は統合の深さでした。初診時受付データが、保険適格性をリアルタイムで確認し、EHR システムを事前に設定するカスタム ワークフローに流れることを望んでいました。既成のフォーム ツールはその深いレベルの統合をサポートできず、重要な同期なしに実現できません。この時点で、とにかくカスタム インフラストラクチャを構築しています。

プロジェクトの総コストとタイムラインはいくらでしたか?

プロジェクトは 14 週間で約 $42,000 でした。これには、発見とアーキテクチャ計画(3 週間)、設計(2 週間)、開発(7 週間)、テスト/移行(2 週間)が含まれました。継続中のホスティング とメンテナンスは月額約 $250 で、インフラストラクチャ コストと小さなサポート retainer が含まれます。

Payload CMS はヘルスケア グループの複数の場所を処理できますか?

はい。Payload で「Locations」コレクションをアドレス、時間、プロバイダー、受け入れられた保険、場所固有のコンテンツのフィールドで構築しました。各ロケーションは、ローカル SEO 用の構造化データ マークアップ(LocalBusiness スキーマ)を備えた Next.js で生成される独自のページを取得します。新しい場所を追加することは、Payload の管理パネルで新しいエントリを作成するのと同じくらい簡単です。

患者データの保持と削除要件をどのように処理しますか?

自動化されたデータ ライフサイクル ポリシーを実装しました。初診時受付フォーム送信は 7 年間保持されます(クリニックの州医療記録保持要件に一致)。その後、S3 Glacier に自動的にアーカイブされ、最終的に削除されます。患者は州のプライバシー法の下でデータ アクセスまたは削除をリクエストすることもできます。スタッフが完全な監査証跡を持つこれらのリクエストを処理できる Payload で管理ワークフローを構築しました。

Payload CMS サーバーがダウンした場合はどうなりますか?

Next.js フロントエンドは Vercel の CDN から静的に生成されたページを提供するため、メイン Web サイトは Payload バックエンドが完全にオフラインの場合でも稼働し続けます。患者初診時受付フォームはバックエンド停止中は利用不可になりますが、ECS を自動再開ポリシー、30 秒ごとのヘルス チェック、当社チームとクリニックの IT 担当者の両方に警告する CloudWatch アラームで設定しました。本番環境の 6 ヶ月で、計画外のダウンタイムはゼロでした。

単一の場所を持つ小さなクリニックの場合、このアーキテクチャは過度ですか?

患者データで何をしているかによって異なります。ブロシュア サイトが必要で、電話番号とアドレスだけが必要な場合、良いテーマを持つ WordPress は問題ありません。このすべてが必要ありません。しかし、Web サイトを通じて PHI を収集するのであれば(初診時受付フォーム、医療質問票、医療詳細のある予約リクエスト)、適切なセキュリティ制御をサポートするインフラストラクチャが必要です。私たちが構築したアーキテクチャは、より低いトラフィック のため、単一の場所のクリニックではスケールダウンするとコストがかかります。

移行は Google ランキングにどのように影響しましたか?

移行直後、約 10 日間のランキング変動が見られました。これは正常です。3 週間までに、ランキングは安定し、上昇傾向を示していました。3 ヶ月までに、オーガニック トラフィックは 34% 増加し、クリニックの主要キーワードは平均 4 位置改善されていました。Core Web Vitals の改善が最大の要因でした。Google は検索結果で古いサイトのパフォーマンス不振にペナルティを与えていました。