Week3実践!データ管理・永続化でダッシュボードに命を吹き込む
こんにちは!YaroTechです。
Week2でリッチなダッシュボードが完成しました。
統計カード、グラフ、フォーム...見た目は完璧!
でも、表示されているのは全部「モックデータ」(ダミーデータ)でした😅
総投稿数: 150記事 ← 本当は87記事
連続投稿日数: 45日 ← 本当は87日
今月の投稿数: 23記事 ← 本当は4記事
「見た目だけ立派で中身がない...」
これじゃあ、まるで展示用のサンプルハウスです。
今日はWeek3のデータ管理・永続化で、ダッシュボードに「魂」を吹き込みます!
実際のデータを扱えるシステムを構築して、リアルな統計を表示できるようにします!
本当の投稿数が表示される
実際の記事タイトルが並ぶ
リアルタイムで更新される
PM Claudeの見積29時間に対して、実際は約4時間で完了させることができました!💪
※見出し画像のプロンプトは一番下におまけで公開中!
🖥️ 実行環境
OS: Windows 11 Pro 24H2(ARM64版)
ターミナル: Windows Terminal(Dev Claude用)
使用ツール: Claude Code CLI v1.0.83
技術スタック:
Frontend: React 19 + TypeScript 5.7
State Management: Zustand 5.0 (with persist middleware)
Storage: LocalStorage API
Build: Vite 7.1
Chart: Chart.js 4.4+ (with react-chartjs-2)
必要なもの:
Node.js 18以上
Claude Max サブスクリプション
Week2完了済みのプロジェクト(note-dashboard-pro)
重要: この記事はDay87の続きです。Day87を読んでいない方は、先にそちらをチェックしてください!
関連記事: Day87: 基礎から大変身!Claude Code Week 2でUI実装 - リッチダッシュボード完成編
🎯 この記事で得られること
✅ Week3のデータ管理タスク完全ガイド
✅ Zustand Storeの本格実装方法(persist middleware使用)
✅ LocalStorageでのデータ永続化
✅ CRUD操作の完全実装
✅ エラーハンドリングのベストプラクティス
✅ バリデーション・サニタイゼーション実装
✅ データエクスポート/インポート機能
✅ モックデータ→実データの劇的な変化
🚨 この記事を読む前に
プログラミング初心者の方や、この記事で使われている専門用語(Zustand、LocalStorage、CRUD、persist middleware、サニタイゼーションなど)に不安がある方は、先にこちらの用語解説記事を読むことをおすすめします:
関連記事: 【保存版】Week 1基盤構築で使う用語を初心者向けに完全解説!React、TypeScript、Vite...これだけ知っておけばOK
「Zustand?CRUD?なにそれ?」という方も、この記事を読めば安心して実践編に進めます!
📋 Week3のミッション:データ管理・永続化
Week2の成果(前回のおさらい)
構築したもの:
✅ リッチなダッシュボードUI
✅ 統計カード4種類
✅ Chart.jsグラフ2種類
✅ 記事追加フォーム
✅ 人気記事カード
✅ レスポンシブデザイン
問題点: すべてモックデータ(ダミーデータ)


Week3の目標
PM Claudeが提案した18週間264時間の開発計画のうち、今回はWeek3のデータ管理(29時間相当)を実践します:
完成させるもの:
| ID | Task | Estimate |
|----|------|----------|
| T201 | Zustand Store本格実装 | 8h |
| T202 | LocalStorage管理システム | 6h |
| T203 | 記事データCRUD操作 | 5h |
| T204 | 統計計算ロジック | 6h |
| T205 | エクスポート/インポート | 4h |
| T206 | エラーハンドリング | - |
| T207 | バリデーション | - |
| T208 | ローディング状態管理 | - |
Week3 Total: 29h
実際の所要時間: 約4時間(86.2%短縮!)
🚀 実践編:ステップバイステップ
準備: プロジェクト状態確認(5分)
1. プロジェクトディレクトリに移動
cd C:\Users\YourName\Downloads\note\note-dashboard-pro2. Week2の成果物確認
npm run devhttp://localhost:5173 を開いて、Week2のリッチUIが表示されることを確認します。
確認内容:
統計カード、グラフ、フォームが表示される
モックデータ(150記事、45日など)が表示される
すべての機能が正常に動作している
サーバーを停止(Ctrl + C)して、Week3の実装を開始します。
手順1: Claude Code起動(5分)
Windows Terminalで`claude`コマンドを実行:
claudeDev Claudeが起動したら、Week3の実装を開始します。
手順2: Dev Claudeへの実装指示(実践内容)
以下のプロンプトを送信します:
こんにちは!note記事ダッシュボードプロジェクトの開発を担当します。
## 📋 現在の状況
- Week2完了:リッチなダッシュボードUI完成
- 現在地:C:\Users\YourName\Downloads\note\note-dashboard-pro
- 問題:モックデータのみで実データが使えない
## 🎯 今回のミッション:Week3 データ管理・永続化
TASKS.mdのWeek3タスク(T201-T208)を順番に実装してください。
まず、T201「Zustand Store本格実装」から開始してください。
### T201の要件
- articleStore.tsの完全実装
- 記事データの状態管理
- 追加・編集・削除機能
- 統計データの自動計算
- persist middlewareでLocalStorage自動永続化
- TypeScript型安全性維持
実装前に、以下を確認してください:
1. TASKS.mdの内容
2. src/store/の既存ファイル
3. src/types/の型定義
では、T201の実装を開始してください!Dev Claudeの動き:
TASKS.mdを確認
src/store/articleStore.tsを開いて現在の状態を把握
Zustand Storeの本格実装を開始
重要なポイント:
Claude Codeは自動的にファイルを読み込んで状況を把握します
「shift+tab」で編集の自動承認モードにすると作業がスムーズです
手順3: T201-T208の実装詳細(約3時間)
Week3では8つのタスク(T201-T208)を順次実装していきます。Dev Claudeが自動的にファイルを作成・更新してくれるので、「shift+tab」で承認していくだけです。
T201: Zustand Storeの本格実装 ✅
実装ファイル: `src/store/articleStore.ts`
Dev Claudeが以下の機能を自動実装:
主要機能:
`articles`: 記事配列
`stats`: 統計データ(総投稿数、連続日数、月間投稿数、平均いいね数など)
`popularPosts`: 人気記事トップ5
`trends`: 直近7日間のトレンドデータ
`calculateStats()`: 統計データ自動計算
`updateAnalytics()`: 分析データ自動更新
実装コード例:
// Zustand Store with persist middleware
export const useArticleStore = create<ArticleStore>()(
persist(
(set, get) => ({
articles: [],
stats: initialStats,
popularPosts: [],
trends: [],
// 記事追加
addArticle: (article) => set((state) => {
const newArticles = [...state.articles, article];
return {
articles: newArticles,
stats: calculateStats(newArticles),
popularPosts: calculatePopularPosts(newArticles),
trends: calculateTrends(newArticles)
};
}),
// 記事更新
updateArticle: (id, updates) => set((state) => {
const newArticles = state.articles.map(a =>
a.id === id ? { ...a, ...updates } : a
);
return {
articles: newArticles,
stats: calculateStats(newArticles),
popularPosts: calculatePopularPosts(newArticles),
trends: calculateTrends(newArticles)
};
}),
// 記事削除
deleteArticle: (id) => set((state) => {
const newArticles = state.articles.filter(a => a.id !== id);
return {
articles: newArticles,
stats: calculateStats(newArticles),
popularPosts: calculatePopularPosts(newArticles),
trends: calculateTrends(newArticles)
};
})
}),
{
name: 'article-storage', // LocalStorageのキー名
}
)
);LocalStorage自動永続化:
Zustandの`persist`ミドルウェアを使うことで、データが自動的にLocalStorageに保存されます。ページをリロードしてもデータが消えません!
T202: LocalStorage管理モジュール ✅
実装ファイル: `src/lib/storage.ts`
主要機能:
型安全なストレージ操作
エラーハンドリング付き
バックアップ/復元機能
データエクスポート/インポート
ストレージ容量チェック
主要API:
`articlesStorage`: 記事データ操作
`settingsStorage`: 設定データ操作
`backupStorage`: バックアップ管理
`exportData()`: JSON出力
`importData()`: JSON読込
T203: 記事データCRUD操作 ✅
実装ファイル: `src/lib/articleService.ts`
主要メソッド:
`getAll(filters?)`: 記事一覧取得(フィルタ対応)
`getById(id)`: ID指定取得
`create(data)`: 新規作成
`update(id, data)`: 更新
`delete(id)`: 削除
`search(query)`: 検索
`getCategories()`: カテゴリ一覧
`getTags()`: タグ一覧
T204: 統計データ計算ロジック ✅
実装ファイル: `src/lib/analytics.ts`
主要関数:
`calculateStats()`: 基本統計
`calculateConsecutiveDays()`: 連続投稿日数
`calculatePopularPosts()`: 人気記事ランキング
`calculateTrends()`: トレンドデータ(日次/週次/月次)
`calculateCategoryAnalytics()`: カテゴリ別分析
`calculatePerformanceMetrics()`: パフォーマンス指標
`calculateGoalProgress()`: 目標進捗計算
連続投稿日数の計算:
export const calculateConsecutiveDays = (articles: Article[]): number => {
if (articles.length === 0) return 0;
const sortedDates = articles
.map(a => new Date(a.publishedAt))
.sort((a, b) => b.getTime() - a.getTime());
let streak = 1;
let currentDate = sortedDates[0];
for (let i = 1; i < sortedDates.length; i++) {
const diffDays = Math.floor(
(currentDate.getTime() - sortedDates[i].getTime()) / (1000 * 60 * 60 * 24)
);
if (diffDays === 1) {
streak++;
currentDate = sortedDates[i];
} else if (diffDays > 1) {
break;
}
}
return streak;
};T205: データエクスポート/インポート機能 ✅
実装ファイル: `src/lib/dataExport.ts`
対応形式:
JSON: 完全データバックアップ
CSV: 表計算ソフト用
Markdown: 記事リスト出力
テキスト: 統計レポート
機能:
`exportToJSON()`: JSON出力
`exportToCSV()`: CSV出力
`exportToMarkdown()`: Markdown出力
`exportStatsReport()`: レポート出力
`importFromJSON()`: JSON読込
`copyToClipboard()`: クリップボードコピー
`validateImportData()`: インポートデータ検証
T206: エラーハンドリング実装 ✅
実装ファイル: `src/lib/errorHandler.ts`
エラークラス:
`AppError`: 基底エラー
`ValidationError`: バリデーションエラー
`StorageError`: ストレージエラー
`NetworkError`: ネットワークエラー
`NotFoundError`: 404エラー
ユーティリティ:
`handleError()`: エラーハンドリング
`ErrorLogger`: エラーログ管理
`retry()`: リトライ機能
`tryCatch()`: 安全な実行ラッパー
T207: バリデーション機能実装 ✅
実装ファイル: `src/lib/validation.ts`
検証機能:
`validateCreateArticle()`: 新規記事検証
`validateUpdateArticle()`: 更新記事検証
`validateURL()`: URL形式検証
`validateNoteURL()`: note.com URL検証
`validateLength()`: 文字数検証
`validateDate()`: 日付検証
サニタイゼーション:
`sanitizeString()`: 文字列クリーニング
`sanitizeURL()`: URL正規化
`sanitizeCreateArticle()`: 記事データクリーニング
`isSafeString()`: XSS対策チェック
T208: ローディング状態管理 ✅
実装ファイル: `src/hooks/useAsync.ts`
カスタムフック:
`useAsync()`: 基本非同期処理
`useAsyncWithRetry()`: リトライ付き
`useDebouncedAsync()`: デバウンス付き
`useLoading()`: シンプルなローディング状態
手順4: コンポーネント統合(約30分)
Dashboard.tsx更新 ✅
Zustand Storeと完全統合:
articleStoreから直接データ取得
モックデータ削除
実データ表示
エラーハンドリング追加
ローディング状態表示
変更内容:
`useArticleStore()`でストアから直接データ取得
統計データ、トレンド、人気記事を実データで表示
カテゴリ分析を`calculateCategoryAnalytics()`で計算
エラー時のUIを追加
AddArticleForm.tsx更新 ✅
バリデーションとエラーハンドリング追加:
`validateCreateArticle()`による包括的検証
`sanitizeCreateArticle()`でXSS対策
タグ追加時の検証強化(重複チェック、最大10個制限)
送信中のUI無効化
エラーメッセージ表示
改善内容:
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
// バリデーション
const validation = validateCreateArticle(formData);
if (!validation.isValid) {
setErrors(validation.errors);
return;
}
// サニタイゼーション
const sanitizedData = sanitizeCreateArticle(formData);
setIsSubmitting(true);
try {
addArticle({
id: generateId(),
...sanitizedData,
createdAt: new Date().toISOString()
});
setFormData(initialData);
setErrors([]);
showSuccessToast('記事を追加しました!');
} catch (error) {
handleError(error);
} finally {
setIsSubmitting(false);
}
};Chart系コンポーネント ✅
TrendChart: 実データ対応済み(propsで受け取り)
CategoryChart: 実データ対応済み(propsで受け取り)
空データ時の表示追加
サンプルデータ初期化 ✅
実装ファイル: `src/lib/sampleData.ts`
60日分のリアルなサンプルデータ生成
5カテゴリ × 複数記事
リアルなタイトル、タグ、統計データ
main.tsx統合:
グローバルエラーハンドラセットアップ
データマイグレーション
初回起動時の自動サンプルデータ投入
手順5: 動作確認とテスト(約15分)
5-1. 開発サーバー起動
npm run dev5-2. 機能テスト
初回起動: サンプルデータ60件が自動生成される
統計表示: 総投稿数、連続日数、月間投稿数が正しく表示
記事追加: フォームから新規記事を追加
バリデーション: 不正な入力でエラーメッセージ表示
データ永続化: ページリロード後もデータが保持される
5-3. LocalStorage確認
ブラウザのDevToolsで確認:
F12キーを押す
Application タブを開く
Local Storage → http://localhost:5173 を選択
`article-storage` キーにデータが保存されていることを確認
手順6: 完成確認(約10分)
6-1. 実データ表示の確認
Before(Week2) vs After(Week3):
| 項目 | Week2(モックデータ) | Week3(実データ) |
|------|----------------------|-------------------|
| 総投稿数 | 150記事 | 60記事 ✅ |
| 連続投稿日数 | 45日 | 60日 ✅ |
| 今月の投稿数 | 23記事 | 6記事 ✅ |
| 平均いいね数 | 12.5 | 実データ反映 ✅ |
6-2. CRUD操作完全テスト
✅ Create: 記事追加フォームから新規記事を追加
✅ Read: ダッシュボードに記事一覧が表示
✅ Update: 記事編集モーダルで記事を更新
✅ Delete: 記事削除ボタンで記事を削除
6-3. データエクスポート
✅ JSON形式でエクスポート
✅ CSV形式でエクスポート
✅ クリップボードにコピー
すべての機能が正常に動作することを確認!🎉
✅ Week3完了!成果物の確認
Before/After比較
Before(Week2完了時):
リッチなUI表示 ✅
モックデータのみ ❌
データの永続化なし ❌
CRUD操作未実装 ❌
After(Week3完了時):
リッチなUI表示 ✅
実データ表示 ✅
データの永続化 ✅
CRUD操作完全実装 ✅
バリデーション・サニタイゼーション ✅
エラーハンドリング ✅
データエクスポート/インポート ✅
視覚的な変化: モックデータ → 実データで、本物のアプリケーションに!


※スキ数や閲覧数をどう反映しようかクロ助と相談中です。
完成した機能
データ管理(基盤):
✅ Zustand Store完全実装(persist middleware)
✅ LocalStorage自動永続化
✅ 記事CRUD操作
✅ 統計計算ロジック
✅ データエクスポート/インポート(JSON/CSV/Markdown)
品質保証(安全性):
✅ エラーハンドリング(カスタムエラークラス)
✅ バリデーション(入力検証)
✅ サニタイゼーション(XSS対策)
✅ ローディング状態管理
✅ エラーログ記録
UI/UX改善:
✅ ローディング表示
✅ エラーメッセージ表示
✅ 成功/失敗フィードバック
✅ フォーム無効化制御
📊 開発効率の分析
今回の実践: Dev Claude単独で完結
Week3もDev Claude 1人で完結しました!
Week1-2の基盤がしっかりしていたため、Dev Claude単独で全8タスクを完璧に実装できました。
Dev Claude(開発担当)の実績:
⏱️ 作業時間: 約4時間
💻 成果物:
新規作成ファイル: 10個
更新ファイル: 5個
追加コード行数: 約2,500行
🎯 品質: エラーゼロ、完全動作
⚡ 効率: 見積29時間 → 実測4時間(86.2%短縮)
驚異的な効率化の理由
1. Week1-2の完璧な基盤:
TypeScript型定義 → 型エラーゼロ
コンポーネント設計 → 拡張が容易
ディレクトリ構造 → 迷わず配置
2. Claude Codeの自動化能力:
ファイル作成・編集を自動提案
依存関係を自動解決
コード品質を自動チェック
3. 「shift+tab」の威力:
全編集を自動承認
人間の介入が最小限
一気に実装完了
時間比較: 驚愕の結果
TASKS.mdの見積(PM Claudeの計算):
T201: 8時間
T202: 6時間
T203: 5時間
T204: 6時間
T205: 4時間
合計: 29時間
実測(Dev Claude単独):
合計: 約2時間
効率化率: 86.2%短縮! 🎉
💡 実践から学んだこと
学び1: データ管理は「アプリの心臓」
UIがどんなに美しくても、データ管理がなければただの飾りです。
データ管理の重要性:
データの追加・編集・削除
データの永続化
データの整合性維持
エラーハンドリング
学び2: Zustandは本当に便利
Reduxに比べて、Zustandは圧倒的にシンプル:
Zustandの利点:
ボイラープレートが少ない
TypeScriptとの相性が良い
学習コストが低い
パフォーマンスが良い
persist middlewareで永続化が簡単
学び3: LocalStorageの限界を知る
LocalStorageは便利ですが、限界があります:
LocalStorageの限界:
容量制限(5-10MB)
同期的な処理
セキュリティリスク
大規模アプリには:
IndexedDB
サーバーサイドDB
クラウドストレージ
学び4: エラーハンドリングは最初から
エラーハンドリングを後回しにすると、後で大変:
教訓:
Try-Catchは最初から
ユーザーフィードバックは必須
エラーログは詳細に
カスタムエラークラスで管理
学び5: バリデーションとサニタイゼーションは必須
セキュリティとユーザー体験のために:
重要性:
XSS攻撃対策
不正データの防止
ユーザーフレンドリーなエラー表示
データ品質の維持
🚀 次のステップ
Week4で実装予定
品質向上・テスト(36時間相当):
単体テスト実装(コンポーネント)
統合テスト実装(データフロー)
E2Eテスト(Playwright)
アクセシビリティ対応
パフォーマンス最適化
セキュリティ対策
デプロイ準備
本番環境テスト
期待される成果:
テストカバレッジ80%以上
アクセシビリティスコアA
Lighthouseスコア90以上
本番環境デプロイ準備完了
🔗 関連記事
今回の内容に関連する過去記事もぜひご覧ください:
関連記事: Day87: 基礎から大変身!Claude Code Week 2でUI実装 - リッチダッシュボード完成編では、Week2のUI実装過程を詳しく紹介しています。
関連記事: Day86.5: 【保存版】Week 1基盤構築で使う用語を初心者向けに完全解説!React、TypeScript、Vite...これだけ知っておけばOKでは、Week1の重要用語を解説しています。
関連記事: Day86: Imagine終了でも大丈夫!実践🚀Claude Codeでチーム開発 - Week 1基盤構築編では、Week1の基盤構築過程を詳しく紹介しています。
📝 まとめ
✅ Week3で達成したこと
データ管理・永続化完了:
Zustand Store完全実装(persist middleware)
LocalStorage自動永続化
CRUD操作完全実装
統計計算ロジック完成
データエクスポート/インポート(JSON/CSV/Markdown/Text)
品質向上:
エラーハンドリング完全実装
バリデーション・サニタイゼーション
ローディング状態管理
エラーログ記録
コンポーネント統合:
Dashboard.tsx更新
AddArticleForm.tsx改善
Chart系コンポーネント対応
サンプルデータ自動生成
開発効率:
Dev Claude単独で完結
作業時間: 約4時間
効率化率: 86.2%短縮
コード品質: エラーゼロ
🎯 重要な発見
データ管理がすべて: UIはデータあってこそ
Zustandは本当に便利: シンプルで強力、persist middlewareが神
エラーハンドリングは必須: 最初から実装すべき
バリデーションは基本: XSS対策とユーザー体験の両立
基盤の威力: Week1-2の投資が活きる
💪 次のアクション
今週末に挑戦:
Week4の品質向上・テストに進む
自分のプロジェクトでデータ管理実装
Zustand + persist middlewareを試す
来週、さらに深掘り:
Week4の実践記事
テスト実装の詳細
本番環境へのデプロイ準備
モックデータから実データへ。
これが、Claude CodeのWeek3 データ管理・永続化です💪
🚀 次回予告
Day89: Week4実践!品質向上・テストでアプリを磨き上げる
UIもできた、データもある。次は「品質」を高めます!
単体テスト実装
E2Eテスト(Playwright)
アクセシビリティ対応
パフォーマンス最適化
セキュリティ対策
デプロイ準備
本番リリース準備、完了です!
🎨 おまけ:見出し画像作成プロンプト
今日の見出し画像のベースはチャッピー(ChatGPT)に下記プロンプトで作成してもらいました!:
柔らかな照明で撮影された超現実的でプロフェッショナルな写真を作成してください。
下記条件のnote見出し画像をサイズは横長で作成してください。サイズは必ず横長で作成してください。
## 🎨 見出し画像案
### デザインコンセプト
- **背景**: ダークブルーから鮮やかなグリーンへの美しいグラデーション
- **メインビジュアル**: データフローのイメージ
- 中央: データベースアイコン、ストレージアイコン
- データの流れ(矢印、パーティクル)
- Before/After比較(モックデータ → 実データ)
- **テーマ**: データ管理・永続化・「魂を入れる」
- **先進感**: モダンなデータベースデザイン
### テキスト要素
- 上部: 「実践!Claude Code」(白色・太字・28pt)
- 中央上: 「Week 3 データ管理」(緑色・48pt・太字)
- 中央中: 「魂を吹き込む」(白色・36pt)
- 下部: 「永続化・CRUD完成」(白色・24pt)
### 装飾
- データベースアイコン(中央左)
- ストレージアイコン(中央右)
- データフローの矢印(流れるアニメーション風)
- パーティクル効果(データの粒子)
- Before/After比較(モック → 実データ)
- YaroTechロゴ(右下・12pt・控えめ)
### 作成手順
1. スライドサイズ(1536×1024px)
2. ダークブルー→グリーンのグラデーション背景
3. 中央にデータベース・ストレージアイコンを配置
4. データフローの矢印・パーティクルを追加
5. 「実践!Claude Code」を上部に配置
6. 「Week 3 データ管理」を中央上部に大きく配置(緑色)
7. 「魂を吹き込む」を中央に配置
8. 「永続化・CRUD完成」を下部に配置
9. 装飾要素を追加(アイコン、エフェクト等)
10. YaroTechロゴを右下に控えめに配置#YaroTech #ClaudeCode #React #TypeScript #Zustand #LocalStorage #データ管理 #CRUD #週末プロジェクト #効率化
いいなと思ったら応援しよう!
いいなと思ったら応援しよう!
記事がお役に立てたなら嬉しいです!
いただいたチップは、新しいMCPツールの検証や、より深い実践実験の資金として大切に使わせていただきます。
あなたの応援が次の「AI活用の感動」を生み出す原動力になります✨
一緒に羽ばたき続けましょう!