金色の配線パターンが広がる基板の接写
設計と運用

個人開発PWAをそのまま本番導入する前に確認すべき5つの非機能要件

目次を見る

個人のHackathon提出物や週末プロジェクトのPWA(Progressive Web App、オフラインでも動くインストール可能なWebアプリ)を、社内ツールや小規模サービスに転用しようとする場面があります。React 19やTypeScriptで書かれたコードは一見すると本格的で、機能一覧も充実しています。こうした「個人開発品質」のコードを業務利用に流用する際に見落としがちな非機能要件を整理します。

オフライン学習アプリ「Cogniva」は、PomodoroタイマーやSM-2間隔反復アルゴリズム(忘却曲線に基づいてカードの復習タイミングを最適化する手法)を使ったフラッシュカード、AIコパイロットによる学習計画生成などを1つのワークスペースに統合したPWAです。Service Worker登録とWeb App Manifestでオフライン利用を実現し、Zustand(軽量な状態管理ライブラリ)でユーザー情報や学習セッションを管理しています。こうした構成は個人の学習ツールとしては十分魅力的ですが、組織で使うツールとして流用する場合は話が変わってきます。

何が起きるか:機能の豊富さと非機能要件の手薄さのギャップ

個人開発のPWAは、機能要件(何ができるか)には力が入っていても、非機能要件(どう動くべきか)の設計が省略されている場合があります。

たとえばCoginvaのデモは「Alex Morgan」という単一の事前投入ユーザーで動作する前提になっています。複数ユーザーが同時に使う状況、認証が破られた場合の権限制御、データのバックアップや復旧といった観点は、個人向けツールの性質上、最初から要件に含まれていないことがほとんどです。

この状態のまま「便利そうだから社内で使おう」と判断すると、ユーザーが増えた途端にデータ競合が起きたり、オフラインキャッシュが古い情報を表示し続けたりする問題が表面化します。機能デモが動くことと、複数人・長期運用に耐えることは別の基準だという点を見落としやすいのが落とし穴です。

なぜ起きるか:設計判断の前提がそもそも異なる

原因を段階的に分解すると、個人開発と業務システムでは設計の出発点が違うことが見えてきます。

第一に、想定ユーザー数の違いです。 個人開発では「自分と友人1人」が使う前提でZustandのようなクライアント側の状態管理だけで十分です。サーバー側でのデータ整合性管理や排他制御は設計対象に入りません。複数人が同時にアクセスする業務利用では、この前提が崩れます。

第二に、オフラインファーストの設計がもたらすデータ鮮度の問題です。 Service Workerによるキャッシュは、ネットワークが切れても動く利便性と引き換えに、「どのデータが最新か」という整合性の管理を複雑にします。個人用途ならキャッシュが多少古くても実害は小さいですが、業務データでは古い情報に基づく判断ミスにつながります。

第三に、セキュリティ設計の不在です。 デモ環境が単一の事前投入ユーザーで動く構成は、認証・認可の仕組みを本格的に組み込んでいない可能性を示しています。src/store/useAppStore.tsがクライアント側で完結する状態管理であれば、サーバー側での権限チェックが存在しない設計かもしれません。

自分のプロジェクトが該当するか確認する方法

手元で流用を検討しているPWAが同じ落とし穴を抱えていないか、次の観点で確認できます。

# Service Workerのキャッシュ戦略を確認する
cat public/sw.js | grep -i "cache"

# 認証・認可に関する処理がどこにあるか探す
grep -r "auth" src/ --include="*.ts" --include="*.tsx"

# 状態管理がクライアント完結かサーバー連携ありかを確認する
cat src/store/useAppStore.ts | head -50

sw.jsの中身を見て、キャッシュ戦略が「Cache First(まずキャッシュを返す)」なのか「Network First(まずネットワークを試す)」なのかを確認してください。業務データを扱うなら、鮮度が重要な画面ではNetwork Firstを選ぶべき場面が多いはずです。

package.jsonのdependenciesに認証ライブラリ(Firebase Auth、Auth0、NextAuthなど)が含まれていなければ、認証機構が未実装である可能性が高いと判断できます。

またmanifest.jsonとsw.jsが存在するかどうかは、PWAとしての最低限の体裁を確認する手がかりになります。存在しても、キャッシュ対象ファイルのバージョン管理(キャッシュ名にハッシュ値を含めるなど)がされていなければ、更新時に古いキャッシュが残り続けるリスクがあります。

対策の手順

流用を決めた場合、次の順序で非機能要件を補強することをおすすめします。

1. 想定ユーザー数を明文化する - 何人が同時に使うか、1人用設計のままでよいかをまず決めます。2人以上が同時に書き込むなら、サーバー側のデータストアとAPIを用意する設計変更が必要です。

2. 認証・認可を後付けで組み込む - Firebase AuthenticationやAuth0のような認証基盤(アプリ側で認証ロジックを自前実装しなくて済むサービス)を導入し、ユーザーごとのデータ分離を実装します。クライアント側の状態管理だけに頼らず、APIサーバー側でも権限チェックを行う二重構成にします。

3. キャッシュ戦略を業務データ向けに見直す - sw.jsのキャッシュ対象を精査し、頻繁に更新されるデータ(学習進捗や通知など)はNetwork Firstに、静的アセット(画像やフォント)はCache Firstに分けます。

4. バックアップとデータ復旧の仕組みを用意する - クライアント側の状態(ブラウザのlocalStorageやIndexedDB)だけに依存していると、端末故障やブラウザのデータ削除で全履歴が消えます。サーバー側への定期同期を追加します。

5. 技術的負債として記録する - 流用した時点で「これは個人開発由来のコードである」という出自をREADMEやADR(Architecture Decision Record、設計判断を記録する文書)に残し、後から見た人が前提を誤解しないようにします。

まとめ

個人開発のPWAは、機能のデモとしては十分に魅力的でも、複数ユーザー・長期運用・セキュリティという観点では別物として扱う必要があります。

流用を検討する際は、まずsw.jsのキャッシュ戦略とpackage.jsonの依存関係を確認し、認証機構の有無を判断材料にしてください。

対策としては、想定ユーザー数の明文化、認証・認可の後付け、キャッシュ戦略の見直し、バックアップ体制の整備、そして出自を記録に残すことの5点が土台になります。

これらを飛ばして「動くから」という理由だけで本番導入すると、後から非機能要件の不足が技術的負債として重くのしかかってきます。

参考

Cogniva — AI-Powered Adaptive Learning Workspace Built for a Friend

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。