自作アプリ開発の要件メモ

この開発で大切にすべきこと
- 「大きく考えても小さく作る」を忘れずに
- Next.jsとReactの理解を優先する
- 学習の過程で学んだことはしっかり記事にも残しておく
- 拘り過ぎず、悩み過ぎず、あとからアップデートするつもりで作る
実装優先度

ライブラリの依存関係
"dependencies": {
"@hello-pangea/dnd": "^16.3.0",
"@supabase/auth-helpers-nextjs": "^0.8.1",
"@supabase/supabase-js": "^2.38.0",
"next": "^14.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.47.0",
"react-syntax-highlighter": "^15.5.0",
"swr": "^2.2.4",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/node": "^20.8.2",
"@types/react": "^18.2.25",
"@types/react-dom": "^18.2.10",
"autoprefixer": "^10.4.16",
"eslint": "^8.50.0",
"eslint-config-next": "^14.0.3",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.3",
"typescript": "^5.2.2"
}
ライブラリ選択理由
- @hello-pangea/dnd:
メモの並び替えをドラッグ&ドロップで行うため。React 18との相性、元のreact-beautiful-dndより開発が活発なことから選択。 - Supabase関連:
認証とかデータベース操作が比較的簡単であるため。オープンソースで、カスタマイズもしやすいことから選択。 - Next.js, React:
安定版のNext.js14
と最新版のReact18
を使用しApp Router
やサーバーコンポーネントや新機能を使うため。パフォーマンスが良い点も選択理由の一つ。 - react-hook-form:
フォーム管理を比較的簡単にできることから選択。バリデーションも充実していて、パフォーマンスもいい点がうれしい。 - react-syntax-highlighter:
コードブロック機能に使用する。エンジニア向けアプリならではの機能を実装するために欠かせない。 - swr:
データフェッチングをCSRとSWRで効率的に行うために選択。キャッシュや再検証の機能が便利。このアプリ開発では複数の機能を組み合わせて使用する予定。 - zod:
型安全なスキーマ検証をするため。TypeScriptと相性抜群なことから選択。 - 開発ツール系:
型安全に書くためのTypeScript、手動では把握しきれない癖を統一するためのESLint、.tsx
に直接書き込めるTailwindCSSなどは開発効率を向上させるため。コードの品質、安全性、可読性、スタイリングのしやすさから選択。

LogicLoom: エンジニア向けメモアプリケーション開発計画
1. プロジェクト概要
1.1 目的
- Next.js、TypeScript、TailwindCSS、Vercel、Supabaseの実践的な使用方法を学習する
- エンジニア向けの高機能メモアプリケーション "LogicLoom" を開発する
1.2 技術スタック
- フロントエンド: Next.js (App Router), TypeScript, TailwindCSS
- バックエンド: Supabase
- デプロイメント: Vercel
- その他: zod, react-hook-form
2. 機能要件
2.1 高優先度
-
メモ管理 (CRUD操作)
- フロントエンド: メモ作成・編集フォーム、メモ一覧表示UI
- バックエンド: メモデータのCRUD操作API
-
Supabase Authentication
- フロントエンド: ログインUI、認証状態管理
- バックエンド: Supabase Auth設定、ユーザー情報の保存
-
ドラッグ&ドロップによるメモの並び替え
- フロントエンド: ドラッグ&ドロップUI、状態管理(React Hooks使用)
- バックエンド: メモの順序情報の保存API
-
ダッシュボード(Parallel Routes活用)
- メインビュー:メモ一覧表示
- サイドビュー:最近のメモ、メモ統計(総数、作成日別数など)
2.2 中優先度
-
コードブロック機能
- フロントエンド: コードブロック入力UI、シンタックスハイライト表示
- バックエンド: コードブロックのデータ構造設計
-
検索機能
- フロントエンド: 検索UI、検索結果表示
- バックエンド: 全文検索API
2.3 低優先度
-
タグ機能
- フロントエンド: タグ入力・表示UI、タグベースの絞り込み機能
- バックエンド: タグデータの管理API
-
外部メモアプリAPI連携
- フロントエンド: データインポートUI
- バックエンド: 外部APIとの連携処理、データ変換ロジック
3. 非機能要件
3.1 パフォーマンス
-
フロントエンド:
- ISR(Incremental Static Regeneration)の活用
- Parallel Routesの最適化
- 効率的な状態管理(React Hooks使用)
- アセットの最適化(画像最適化、コード分割)
- クライアントサイドのパフォーマンス最適化
-
バックエンド:
- データベースクエリの最適化
- 効果的なキャッシュ戦略の実装
- 効率的なAPI設計
3.2 セキュリティ
-
フロントエンド:
- クロスサイトスクリプティング(XSS)対策
- 適切なCSRF対策
- zodを使用したクライアントサイドでのデータバリデーション
- react-hook-formを活用したフォームの状態管理とバリデーション
-
バックエンド:
- Supabase Authenticationの適切な実装と設定
- SupabaseのRow Level Security (RLS)の設定
- APIエンドポイントの適切な保護
- JWTトークンによる安全なセッション管理
- SQLインジェクション対策(パラメータ化クエリの使用)
-
共通:
- すべての通信でのHTTPS/TLS使用
- ユーザーフレンドリーなエラーメッセージの表示
- 重要な操作(ログイン、データ変更など)のログ記録
3.3 ユーザビリティ
-
フロントエンド:
- レスポンシブデザイン(モバイル対応)
- 直感的なUI/UX設計
- アクセシビリティへの配慮
-
バックエンド:
- 一貫性のあるAPIレスポンス設計
3.4 拡張性・保守性
-
フロントエンド:
- コンポーネントベースの設計
- 適切なコード分割
-
バックエンド:
- モジュラーな設計
- 適切なログ記録
4. データベース設計
4.1 テーブル構造
- ユーザーテーブル
- メモテーブル
- コードブロックテーブル
- タグテーブル
- メモタグ中間テーブル
4.2 セキュリティ設定
- Row Level Security (RLS)ポリシーの適用
- 最小権限の原則に基づいたデータベースロールの作成
- 機密情報のフィールドレベル暗号化(必要に応じて)
4.3 パフォーマンス最適化
- 適切なインデックス設計
- 効率的なクエリ構築
- 必要に応じたJSONカラムの活用
5. 認証システム
5.1 Supabase Authentication
- 新規登録、ログイン、ログアウト機能の実装
- JWTトークンによるセッション管理
- メール確認プロセスの実装
5.2 セキュリティ強化
- 多要素認証(MFA)の検討
- パスワードポリシーの設定
- アカウントロックアウトポリシーの実装
6. 開発アプローチ
- 最初は高優先度の機能に焦点を当て、MVPを早期に完成させる
- ISRとParallel Routesを活用したダッシュボード実装を優先
- Supabase Authenticationの基本実装から開始し、段階的に機能を拡張
- 段階的に中優先度、低優先度の機能を実装
- 各機能実装後、非機能要件の観点からの最適化を行う
- セキュリティ要件を各開発フェーズに組み込む
- 定期的なセキュリティ監査とペネトレーションテストの実施
- ユーザーフィードバックを基に継続的に改善を行う
7. 技術選定の理由と組み合わせの意図
-
Next.js + TypeScript + React:
- パフォーマンスと開発効率の両立
- ISRとParallel Routesによる最適化されたダッシュボード実装
- 型安全性による堅牢なコード開発
-
TailwindCSS:
- Reactコンポーネントとの高い親和性
- 迅速なUI開発とカスタマイズの容易さ
-
Supabase:
- バックエンド開発の負荷軽減
- リアルタイム機能とNext.jsのISRの相性の良さ
- 認証、データベース、ストレージの統合提供
- Supabase Authenticationによる簡単で安全な認証実装
-
Vercel:
- Next.jsとの完璧な互換性
- CI/CDパイプラインの簡素化
- エッジネットワークによるグローバルな高速配信
-
zod + react-hook-form:
- 型安全性とランタイムバリデーションの両立
- フロントエンドとバックエンドで一貫したバリデーションルールの適用
8. 将来的な拡張性
- リアルタイム共同編集機能
- AIを活用したメモ分析・推奨機能
- モバイルアプリ版の開発
- OAuth認証への移行(必要に応じて)
9. Supabase利用における注意点
- 開発環境と本番環境の分離
- テストアカウントの適切な管理
- セキュリティ設定の徹底(特にRLSポリシー)
- 定期的なデータクリーンアップ
- 認証周りの学習記録の作成と共有
- Supabaseおよび依存ライブラリの定期的な更新
- ログ分析と異常検知の仕組みの構築
10. セキュリティ監査とモニタリング
- 定期的なセキュリティ監査の実施
- ログ管理と分析
- 異常検知システムの導入検討
- セキュリティインシデント対応計画の策定

データベース要件
LogicLoom: Supabase無料枠ではどこまで実現可能か
1. Supabase無料枠の制限
- データベース容量: 500MB
- ストレージ容量: 1GB
- 月間データ転送量: 2GB
2. 想定データベース構造
- ユーザーテーブル
- メモテーブル
- コードブロックテーブル
- タグテーブル
- メモタグ中間テーブル
3. 実現可能性の分析
3.1 データ容量
- 主にテキストデータを扱うため、500MBの制限内で十分実現可能。
- JSON列の活用により、柔軟なデータ構造を維持しつつ容量を抑制可能。
3.2 パフォーマンス考慮点
-
インデックス設計
- 検索機能向上のためのインデックス設計が必要。
- ただし、過剰なインデックスは容量を圧迫する可能性あり。
-
関連テーブルの最適化
- 多対多関係(メモとタグなど)の効率的な設計が重要。
-
メモの順序管理
- ドラッグ&ドロップ機能による頻繁な更新に注意。
3.3 データ管理戦略
-
削除済みデータの扱い
- 完全削除 vs 論理削除(削除フラグ)のトレードオフを検討。
-
データアーカイブ
- 長期未使用データの圧縮や外部ストレージへの移動を検討。
4. スケーラビリティの考慮
- 将来的な有料プランへのアップグレードパスは検討しているが、現状は個人学習及び利用の範囲に収めるため最小限で済むように考えている。
5. 結論
現状の要件と想定されるデータ構造を考慮すると、LogicLoomプロジェクトはSupabaseの無料枠内で十分に実現可能であると判断できる。ただし、以下の点に注意が必要:
- 効率的なデータ構造設計
- インデックスの適切な使用
- 将来的なデータ増加への対策
適切な設計と最適化により、無料枠の制限内で高機能なメモアプリケーションを実現できる見込みが高い。また、自身の学習に使うという用途であれば、ユーザー数やデータ量の増加によるスケーリング計画は検討を保留にしておける。

セキュリティ要件
LogicLoom: データベースセキュリティ要件
1. Supabase認証の活用
1.1 ユーザー管理
- Supabase Authenticationを使用した堅牢な認証システムの実装
- 新規登録、ログイン、ログアウト機能の適切な実装
1.2 セッション管理
- JWTトークンによる安全なセッション管理
-
getSession
を使用したログイン状態の確認
2. データベースアクセス制御
2.1 Row Level Security (RLS)
- テーブルごとに適切なアクセス制御ポリシーを設定
- ユーザーが自分のデータのみにアクセスできるよう制限
2.2 ロール管理
- 最小権限の原則に基づいたデータベースロールの作成と管理
3. データバリデーションとサニタイズ
3.1 zodによるバリデーション
- フロントエンド:ユーザー入力の検証
- バックエンド:APIリクエストの検証
- カスタムバリデーションルールの実装
3.2 react-hook-formの活用
- フォームの状態管理とバリデーションの統合
3.3 SQLインジェクション対策
- パラメータ化クエリの使用
- ユーザー入力のエスケープ処理
4. エラーハンドリング
4.1 バリデーションエラー
- ユーザーフレンドリーなエラーメッセージの表示
- クライアントサイドでのリアルタイムバリデーション
4.2 認証エラー
- メール未確認やユーザー不在の適切な処理
- セキュリティを損なわない程度の詳細なエラーメッセージ
5. データ暗号化
5.1 転送時の暗号化
- すべての通信でのHTTPS/TLS使用
5.2 保存時の暗号化
- パスワードのハッシュ化
- 必要に応じた機密情報のフィールドレベル暗号化
6. 監査とモニタリング
6.1 ログ管理
- 重要な操作(ログイン、データ変更など)のログ記録
- 定期的なログ分析と異常検知
6.2 セキュリティ更新
- Supabaseおよび依存ライブラリの定期的な更新
- セキュリティパッチの迅速な適用
7. 追加のベストプラクティス
7.1 CORS設定
- 許可されたオリジンからのリクエストのみを受け付ける
7.2 API設計
- 認証済みユーザーのみがアクセス可能なエンドポイントの設定
- 必要最小限の権限でのAPI設計
7.3 フロントエンドセキュリティ
- クロスサイトスクリプティング(XSS)対策
- クリックジャッキング対策

12. デザインとUIUX要件
12.1 デザイン方針
- コンセプト: シンプルかつ直感的な操作感で使いやすいメモアプリ
- アプローチ: 「大きく考えて小さく作る」
12.2 デザインリソース
-
Udemyの教材で学んだデザインを土台として活用
- メリット: 既存のベストプラクティスを学べる
- 注意点: 著作権に配慮し、そのまま使用せず独自にアレンジする
-
Photoshopで作成した簡易的なカンプを基にコーディング
- メリット: 迅速な視覚化と柔軟な修正が可能
- 注意点: 詳細なデザイン決定は実装段階で行う
12.3 UIUXガイドライン
-
シンプルさの追求
- 不必要な装飾を避け、機能性を重視
- 直感的な操作感を大切にする
-
一貫性のあるデザイン
- 色使い、フォント、アイコンなどの統一感を保つ
- TailwindCSSのユーティリティクラスを活用し、一貫性を維持
-
レスポンシブデザイン
- モバイルファーストの設計
- 異なるデバイスサイズに対応したレイアウト調整
-
アクセシビリティへの配慮
- 適切なコントラスト比の確保
- スクリーンリーダーへの対応
-
フィードバックの視覚化
- ローディング状態の表示
- エラーメッセージの明確な提示
- 操作成功時の視覚的フィードバック
12.4 実装アプローチ
-
コンポーネントベースの設計
- 再利用可能なUIコンポーネントの作成
- Storybookなどのツールでコンポーネントを管理・テスト(オプション)
-
プロトタイピング
- 初期段階でのモックアップ作成
- ユーザーフィードバックを早期に取り入れる
-
イテレーティブな改善
- MVP(最小限の機能を持つ製品)を早期にリリース
- ユーザーフィードバックを基に段階的に改善
12.5 デザインシステム(簡易版)
-
カラーパレット
- プライマリカラー: [例: #3B82F6 (青)]
- セカンダリカラー: [例: #10B981 (緑)]
- アクセントカラー: [例: #F59E0B (オレンジ)]
- 背景色: [例: #F3F4F6 (薄いグレー)]
- テキスト色: [例: #1F2937 (濃いグレー)]
-
タイポグラフィ
- 見出し: [例: Inter, sans-serif]
- 本文: [例: Roboto, sans-serif]
- フォントサイズ: TailwindCSSのデフォルト設定を基本とする
-
アイコン
- 使用するアイコンライブラリの選定 [例: Heroicons]
-
スペーシング
- TailwindCSSのデフォルト設定を基本とする
12.6 注意点
- デザインよりも機能性と使いやすさを優先する
- 過度な装飾や複雑なアニメーションは避ける
- ユーザーフィードバックを積極的に取り入れ、継続的に改善する
- 技術的な制約とデザインのバランスを常に意識する

後で考えるポイント
- モバイルファーストなデザインか
- パソコン使用前提か

ISRとParallel RoutesのSupabase無料枠での使用に関する考慮点
Supabase無料枠の主な制限
- データベース容量: 500 MB
- 月間のデータベースエグレス(転送量): 2 GB
- ストレージ容量: 1 GB
- 月間のストレージエグレス: 2 GB
- 同時接続数: 10
- サーバーレス関数の実行時間: 500,000 実行/月
ISRとParallel Routesを使用する際の潜在的な問題
- 頻繁なデータベースクエリ: ISRは設定した間隔でページを再生成するため、定期的なデータベースクエリが発生する。
- 並行データ取得: Parallel Routesでは、複数のコンポーネントが同時にデータを取得するため、1回のページ表示で複数のクエリが発生する可能性がある。
- データベースエグレス: 頻繁なデータ取得により、月間のデータベースエグレス制限に達する可能性がある。
- 同時接続数: 並行データ取得により、同時接続数の制限に達する可能性がある。
対策と最適化方法
-
ISRの間隔調整
- 再生成の間隔を長くすることで、クエリの回数を減らす。
- 例: 1分間隔 → 5分または10分間隔
-
キャッシュの活用
- Edge CacheやNext.jsのクライアントサイドキャッシュを効果的に使用し、データベースアクセスを減らす。
-
データ取得の最適化
- 必要最小限のデータのみを取得するようクエリを最適化する。
- 不要なフィールドや関連データの取得を避ける。
-
バッチ処理の利用
- 複数のクエリをまとめて1回で処理し、接続回数を減らします。
-
静的生成(SSG)の活用
- 更新頻度の低いコンテンツにはISRではなく完全な静的生成を使用。
-
クライアントサイドでのデータ取得
- 適切な場合、一部のデータをクライアントサイドで取得し、サーバーサイドのクエリ回数を減らす。
-
データベース設計の最適化
- インデックスを適切に設定し、クエリのパフォーマンスを向上。
- 必要に応じてデノーマライゼーションを検討し、クエリの複雑さを軽減。
-
モニタリングと分析
- Supabaseのダッシュボードを活用し、リソース使用状況を定期的に確認。
- パフォーマンスのボトルネックを特定し、適切に対処。
結論
ISRとParallel RoutesはSupabaseの無料枠内で使用可能だが、慎重な設計と最適化が必要。上記の対策を実装し、リソース使用状況を常にモニタリングすることで、無料枠の制限内でアプリケーションを効果的に運用できる可能性が高まる。
ただし、アプリケーションの規模や要件によっては、将来的に有料プランへのアップグレードを検討する必要があるかもしれない。実際の使用状況を見ながら、必要に応じて調整を行っていくことが重要だろう。

メモ
- 外部メモアプリのAPI使用には認証方法をソーシャルに変更することがセットになりそう

ディレクトリとコンポーネント構成
logicloom/
├── .github/ # GitHub Actions用の設定ファイル
├── public/ # 静的ファイル(favicon.icoなど)
├── src/
│ ├── app/
│ │ ├── api/ # APIルート
│ │ ├── auth/ # 認証関連のページ
│ │ │ ├── login/
│ │ │ └── signup/
│ │ ├── dashboard/ # ダッシュボード(メインページ)
│ │ │ └── page.tsx # ダッシュボードのメイン内容
│ │ ├── memos/ # メモ関連のページ
│ │ │ ├── [id]/ # 個別メモページ
│ │ │ └── new/ # 新規メモ作成ページ
│ │ ├── settings/ # 設定ページ
│ │ ├── layout.tsx # ルートレイアウト
│ │ └── page.tsx # ルートページ(リダイレクト処理)
│ ├── components/ # 再利用可能なコンポーネント
│ │ ├── ui/ # 汎用UIコンポーネント
│ │ ├── layout/ # レイアウト関連コンポーネント
│ │ └── dashboard/ # ダッシュボード関連コンポーネント
│ ├── hooks/ # カスタムReact Hooks
│ ├── lib/ # ユーティリティ関数やヘルパー
│ │ └── supabase/ # Supabase関連の設定や関数
│ ├── styles/ # グローバルスタイル
│ └── types/ # TypeScript型定義
├── .env.local # 環境変数(gitignore対象)
├── .eslintrc.js # ESLint設定
├── .gitignore
├── next.config.js # Next.js設定
├── package.json
├── postcss.config.js # PostCSS設定(TailwindCSS用)
├── README.md
├── tailwind.config.js # TailwindCSS設定
└── tsconfig.json # TypeScript設定
ページ遷移図

- 404ページは必要か?
- メモアプリにSEO対策は必要か?

404ページ入れた場合のディレクトリ構成図
logicloom/
├── .github/ # GitHub Actions用の設定ファイル
├── public/ # 静的ファイル(favicon.icoなど)
├── src/
│ ├── app/
│ │ ├── api/ # APIルート
│ │ ├── auth/ # 認証関連のページ
│ │ │ ├── login/
│ │ │ └── signup/
│ │ ├── dashboard/ # ダッシュボード(メインページ)
│ │ │ └── page.tsx # ダッシュボードのメイン内容
│ │ ├── memos/ # メモ関連のページ
│ │ │ ├── [id]/ # 個別メモページ
│ │ │ └── new/ # 新規メモ作成ページ
│ │ ├── settings/ # 設定ページ
│ │ ├── layout.tsx # ルートレイアウト
│ │ ├── page.tsx # ルートページ(リダイレクト処理)
│ │ └── not-found.tsx # 404ページ
│ ├── components/ # 再利用可能なコンポーネント
│ │ ├── ui/ # 汎用UIコンポーネント
│ │ ├── layout/ # レイアウト関連コンポーネント
│ │ └── dashboard/ # ダッシュボード関連コンポーネント
│ ├── hooks/ # カスタムReact Hooks
│ ├── lib/ # ユーティリティ関数やヘルパー
│ │ └── supabase/ # Supabase関連の設定や関数
│ ├── styles/ # グローバルスタイル
│ └── types/ # TypeScript型定義
├── .env.local # 環境変数(gitignore対象)
├── .eslintrc.js # ESLint設定
├── .gitignore
├── next.config.js # Next.js設定
├── package.json
├── postcss.config.js # PostCSS設定(TailwindCSS用)
├── README.md
├── tailwind.config.js # TailwindCSS設定
└── tsconfig.json # TypeScript設定
