こんにちは。エンジニアのaraoです。
このブログはギークフィードアドベントカレンダー2025の9日目の記事です。
他の記事もぜひチェックしてみてください!
目次
自己紹介
クラウド開発事業部所属のaraoです。
普段は複数案件のAWS設計構築や運用保守、クラウドPBXのXCALLYの運用保守を担当しています。
エンジニア歴は10年くらいで、主にインフラを担当しているのでCDKやLambdaを書いたり、案件のPLをしてます。
日々やることがいっぱいあるので、業務を楽にすることが出来ないかずっと考えてます。
なので、n8nによる作業の自動化・省力化やAmazon Bedrock Knowledge baseやBedrock Agentsを活用できないか試すのが最近の楽しみです。
普段使ってるAIツール
日常的に以下のAIツールを活用しています。
- Claude Code: もはや親友。毎日何かしら依頼してます。cdkのデプロイから切り分け調査もやってもらったり。n8nのワークフローのベースも作ってます。
- Codex: Claude Codeの結果をダブルチェックやコード調査やドキュメント作成はCodexに依頼することが多い。
- Cursor: 修正内容が明確なときや軽微な修正(インデント揃えるなど)に使ってます。
企画概要とゴール
今回、「フルAI開発バトル」という企画に参加しました。
ルールはシンプルかつ過酷です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 禁止事項:エディタで直接コードを書く・修正すること - 許されるのは「AIへの指示」のみ。人間の役割は「Architect/Reviewer」、つまりAIをマネジメントして成果物を判断することです。 # お題 社員の生産性を上げる日々の業務管理ツールを作ってください。 ## 必須要件: - KiroとPlaywright MCPを使うこと - スペック駆動開発を行うこと(vibe codingはNG) - Todoを追加・編集・削除できること - 追加は画面上部のフォームから可能 - 編集・削除は各行の操作ボタンで行う - 一覧でTodoを確認できること - 一覧にはタイトル、担当者、期限を表示 - サクサク軽く操作できること - 画面は1ページで完結 - PlaywrightでCRUD周りのテストをすること |
詳しいルールや目的はアドベントカレンダー1日目の記事で紹介しております。
作業プロセス
要件の理解と整理
今回は要件がふわっとしているので、自分だったらどんな機能があったら嬉しいなであったり、
個人的に利用しているGoogleの「ToDoリスト」アプリを触ってみました。
運営への質問事項
Specs定義
指示に至るまでの思考プロセス
Kiroへの指示
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 目的 Webで動作するTodoアプリを作成したい。 # 実行環境 動作環境はAWSを利用するため、リソース作成はCDKを利用する。 # 機能要件 - タスクの追加(画面上部のフォームからテキスト入力)、編集、削除、一覧表示(タイトル、 担当者、期限を表示) - ログイン機能は不要 # 操作性 - 画面は1ページで完結。サクサク軽く動いて、直感的に操作できること - 編集・削除は各行のボタンで可能 # データ保持 - ブラウザを閉じてもデータが消えないこと # 品質保証 - Playwright MCPを活用し、E2Eテストが通っていること |
Kiroの出力
- requirements.md
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# Requirements Document ## Introduction 本ドキュメントは、Webブラウザで動作するTodoアプリケーションの要件を定義します。このアプリケーションは、ユーザーがタスクを追加、編集、削除、一覧表示できる単一ページアプリケーション(SPA)です。データはブラウザを閉じても永続化され、AWS上でホスティングされます。インフラストラクチャはAWS CDKで管理されます。 ## Glossary - **Todo App**: タスク管理を行うWebアプリケーション - **Task**: ユーザーが管理する個別のタスク項目。タイトル、担当者、期限を含む - **Browser Storage**: ブラウザのローカルストレージ機能 - **AWS CDK**: AWS Cloud Development Kit。インフラストラクチャをコードで定義するツール - **SPA**: Single Page Application。ページ遷移なしで動作するWebアプリケーション ## Requirements ### Requirement 1 **User Story:** As a user, I want to add new tasks to my todo list, so that I can capture and organize things I need to accomplish. #### Acceptance Criteria 1. WHEN a user enters a task title, description, assignee, and due date in the input form and clicks the add button, THEN THE Todo App SHALL create a new task and add it to the task list 2. WHEN a user attempts to add a task with an empty title, THEN THE Todo App SHALL prevent the addition and display a validation message 3. WHEN a new task is added, THEN THE Todo App SHALL clear the input form and display the new task in the list immediately 4. WHEN a task is added, THEN THE Todo App SHALL persist the task to Browser Storage immediately 5. THE Todo App SHALL display the input form at the top of the page with fields for title, description, assignee, and due date ### Requirement 2 **User Story:** As a user, I want to edit existing tasks, so that I can update task information as circumstances change. #### Acceptance Criteria 1. WHEN a user clicks the edit button on a task row, THEN THE Todo App SHALL enable inline editing for that task's fields 2. WHEN a user modifies task fields and confirms the changes, THEN THE Todo App SHALL update the task with the new values 3. WHEN a task is edited, THEN THE Todo App SHALL persist the updated task to Browser Storage immediately 4. WHEN a user cancels editing, THEN THE Todo App SHALL restore the original task values without saving changes ### Requirement 3 **User Story:** As a user, I want to delete tasks, so that I can remove completed or unnecessary items from my list. #### Acceptance Criteria 1. WHEN a user clicks the delete button on a task row, THEN THE Todo App SHALL remove the task from the list immediately 2. WHEN a task is deleted, THEN THE Todo App SHALL remove the task from Browser Storage immediately 3. WHEN a task is deleted, THEN THE Todo App SHALL update the displayed task list without page reload ### Requirement 4 **User Story:** As a user, I want to view all my tasks in a list, so that I can see what needs to be done. #### Acceptance Criteria 1. WHEN the page loads, THEN THE Todo App SHALL display all tasks from Browser Storage in a list format 2. WHEN displaying tasks, THEN THE Todo App SHALL show the title, description, assignee, and due date for each task 3. WHEN the task list is empty, THEN THE Todo App SHALL display a message indicating no tasks exist 4. THE Todo App SHALL display each task with edit and delete buttons in the same row ### Requirement 5 **User Story:** As a user, I want my tasks to persist across browser sessions, so that I don't lose my data when I close the browser. #### Acceptance Criteria 1. WHEN a user closes the browser and reopens the application, THEN THE Todo App SHALL load and display all previously saved tasks from Browser Storage 2. WHEN tasks are modified (added, edited, or deleted), THEN THE Todo App SHALL synchronize changes to Browser Storage within 100 milliseconds 3. WHEN Browser Storage contains task data, THEN THE Todo App SHALL parse and validate the data before displaying it ### Requirement 6 **User Story:** As a user, I want the application to be fast and responsive, so that I can work efficiently without delays. #### Acceptance Criteria 1. WHEN a user performs any action (add, edit, delete), THEN THE Todo App SHALL complete the operation and update the UI within 200 milliseconds 2. THE Todo App SHALL operate as a single page application without full page reloads 3. WHEN the application loads, THEN THE Todo App SHALL display the initial interface within 1 second ### Requirement 7 **User Story:** As a developer, I want the application infrastructure defined with AWS CDK, so that I can deploy and manage AWS resources consistently. #### Acceptance Criteria 1. THE Todo App SHALL include CDK code that defines all required AWS resources for hosting the application 2. WHEN the CDK stack is deployed, THEN THE system SHALL provision all necessary AWS resources (S3, CloudFront, etc.) 3. THE CDK code SHALL follow AWS best practices for static website hosting ### Requirement 8 **User Story:** As a user, I want input suggestions based on my previous entries, so that I can quickly fill in common values without retyping. #### Acceptance Criteria 1. WHEN a user types in the title field, THEN THE Todo App SHALL display suggestions from previously used titles 2. WHEN a user types in the description field, THEN THE Todo App SHALL display suggestions from previously used descriptions 3. WHEN a user types in the assignee field, THEN THE Todo App SHALL display suggestions from previously used assignee names 4. WHEN a user selects a suggestion, THEN THE Todo App SHALL populate the field with the selected value 5. WHEN the suggestion list is displayed, THEN THE Todo App SHALL show up to 5 most relevant matches 6. THE Todo App SHALL store input history in Browser Storage for future suggestions ### Requirement 9 **User Story:** As a developer, I want comprehensive E2E tests using Playwright, so that I can verify the application works correctly from a user perspective. #### Acceptance Criteria 1. THE Todo App SHALL include Playwright E2E tests that verify task addition functionality 2. THE Todo App SHALL include Playwright E2E tests that verify task editing functionality 3. THE Todo App SHALL include Playwright E2E tests that verify task deletion functionality 4. THE Todo App SHALL include Playwright E2E tests that verify task persistence across page reloads 5. WHEN all E2E tests are executed, THEN THE system SHALL report pass or fail status for each test scenario |
- design.md
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 |
# Design Document ## Overview 本Todoアプリケーションは、React + TypeScriptで構築されるシングルページアプリケーション(SPA)です。データの永続化にはブラウザのLocalStorageを使用し、AWS CDKを用いてS3 + CloudFrontでホスティングします。シンプルで直感的なUIを提供し、高速な操作性を実現します。 技術スタック: - フロントエンド: React 18 + TypeScript + Vite - スタイリング: CSS Modules(軽量でシンプル) - データ永続化: LocalStorage API - インフラ: AWS CDK (TypeScript) - テスト: Playwright (E2E), Vitest (Unit), fast-check (Property-based) - ホスティング: S3 + CloudFront ## Architecture ```mermaid graph TB User[ユーザー] Browser[Webブラウザ] CloudFront[CloudFront CDN] S3[S3 Bucket] LocalStorage[LocalStorage] User -->|アクセス| Browser Browser -->|HTTPSリクエスト| CloudFront CloudFront -->|静的ファイル取得| S3 Browser -->|データ読み書き| LocalStorage subgraph "React Application" UI[UI Components] State[State Management] Storage[Storage Service] Validation[Validation Logic] UI -->|ユーザー操作| State State -->|データ永続化| Storage Storage -->|読み書き| LocalStorage State -->|検証| Validation end ``` アーキテクチャの特徴: - **クライアントサイド完結**: すべてのロジックがブラウザ内で動作 - **ステートレス**: サーバーサイドの状態管理不要 - **高速配信**: CloudFront CDNによるグローバル配信 - **シンプルな構成**: 認証不要、APIサーバー不要 ## Components and Interfaces ### 1. Data Model ```typescript interface Task { id: string; // UUID v4 title: string; // タスクのタイトル(必須) description: string; // タスクの詳細説明(任意) assignee: string; // 担当者名(任意) dueDate: string; // 期限(ISO 8601形式、任意) createdAt: string; // 作成日時(ISO 8601形式) updatedAt: string; // 更新日時(ISO 8601形式) } interface InputHistory { titles: string[]; // 過去に使用されたタイトルのリスト descriptions: string[]; // 過去に使用された詳細説明のリスト assignees: string[]; // 過去に使用された担当者名のリスト } ``` ### 2. Storage Service LocalStorageとのやり取りを抽象化するサービス層。 ```typescript interface StorageService { // すべてのタスクを取得 loadTasks(): Task[]; // すべてのタスクを保存 saveTasks(tasks: Task[]): void; // ストレージをクリア clearTasks(): void; // 入力履歴を取得 loadInputHistory(): InputHistory; // 入力履歴を保存 saveInputHistory(history: InputHistory): void; } ``` 実装の詳細: - キー名: `todo-app-tasks`, `todo-app-input-history` - データ形式: JSON配列、JSONオブジェクト - エラーハンドリング: LocalStorage容量超過、パース失敗時の処理 **入力履歴の保持ロジック**: - タスク追加時、空でないフィールド(title、description、assignee)の値を履歴に追加 - 各フィールドの履歴は配列として保存され、重複は除外される - 履歴の最大保持件数は各フィールドあたり50件 - 50件を超えた場合、最も古いエントリから削除される(FIFO方式) - 履歴はLocalStorageに即座に保存され、ブラウザを閉じても永続化される ### 3. Task Manager タスクのCRUD操作を管理するビジネスロジック層。 ```typescript interface TaskManager { // タスクを追加 addTask(title: string, description?: string, assignee?: string, dueDate?: string): Task; // タスクを更新 updateTask(id: string, updates: Partial<Omit>): Task; // タスクを削除 deleteTask(id: string): void; // すべてのタスクを取得 getTasks(): Task[]; // タスクを検証 validateTask(task: Partial): ValidationResult; // 入力履歴を更新 updateInputHistory(title: string, description: string, assignee: string): void; // サジェストを取得 getSuggestions(field: 'title' | 'description' | 'assignee', query: string): string[]; } interface ValidationResult { valid: boolean; errors: string[]; } ``` ### 4. UI Components #### App Component - アプリケーション全体のルートコンポーネント - タスクの状態管理(useState) - StorageServiceとの連携 #### TaskForm Component ```typescript interface TaskFormProps { onAddTask: (title: string, description: string, assignee: string, dueDate: string) => void; inputHistory: InputHistory; } ``` - タスク追加フォーム - バリデーション表示 - フォームのクリア処理 - 入力サジェスト機能 #### AutocompleteInput Component ```typescript interface AutocompleteInputProps { value: string; onChange: (value: string) => void; suggestions: string[]; placeholder?: string; maxSuggestions?: number; } ``` - 入力フィールドとサジェストリストを統合したコンポーネント - キーボードナビゲーション対応(↑↓キーで選択、Enterで確定) - 入力値に基づくフィルタリング(部分一致) - 最大表示件数の制限(デフォルト5件) #### TaskList Component ```typescript interface TaskListProps { tasks: Task[]; onEditTask: (id: string, updates: Partial) => void; onDeleteTask: (id: string) => void; } ``` - タスク一覧の表示 - 空状態の表示 #### TaskItem Component ```typescript interface TaskItemProps { task: Task; onEdit: (updates: Partial) => void; onDelete: () => void; } ``` - 個別タスクの表示 - インライン編集機能 - 編集/削除ボタン ## Data Models ### Task Entity ```typescript interface Task { id: string; // UUID v4形式の一意識別子 title: string; // 1-200文字のタスクタイトル description: string; // 0-1000文字のタスク詳細説明 assignee: string; // 0-100文字の担当者名 dueDate: string; // ISO 8601形式の日付文字列(YYYY-MM-DD) createdAt: string; // ISO 8601形式のタイムスタンプ updatedAt: string; // ISO 8601形式のタイムスタンプ } ``` バリデーションルール: - `id`: UUID v4形式 - `title`: 必須、1-200文字、空白のみは不可 - `description`: 任意、0-1000文字 - `assignee`: 任意、0-100文字 - `dueDate`: 任意、有効なISO 8601日付形式 - `createdAt`, `updatedAt`: ISO 8601形式のタイムスタンプ ### LocalStorage Schema ```json { "todo-app-tasks": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "title": "サンプルタスク", "description": "これはサンプルタスクの詳細説明です", "assignee": "山田太郎", "dueDate": "2025-12-31", "createdAt": "2025-11-27T10:00:00.000Z", "updatedAt": "2025-11-27T10:00:00.000Z" } ], "todo-app-input-history": { "titles": ["サンプルタスク", "会議の準備", "レポート作成"], "descriptions": ["これはサンプルタスクの詳細説明です", "会議資料を準備する", "月次レポートを作成する"], "assignees": ["山田太郎", "佐藤花子", "鈴木一郎"] } } ``` ## Correctness Properties *A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.* ### Property 1: タスク追加でリストが成長する *For any* タスクリストと有効なタスクデータ(空でないタイトル)、タスクを追加すると、タスクリストの長さが1増加する **Validates: Requirements 1.1** ### Property 2: 空白タイトルは無効 *For any* 空白文字のみで構成された文字列、それをタイトルとしてタスクを追加しようとすると、追加が拒否され、タスクリストは変更されない **Validates: Requirements 1.2** ### Property 3: タスク追加後にフォームがクリアされる *For any* 入力フォームの状態、タスクを追加すると、フォームのすべてのフィールドが空になる **Validates: Requirements 1.3** ### Property 4: ストレージのラウンドトリップ *For any* タスクのリスト、それをLocalStorageに保存してから読み込むと、元のリストと同等のリストが得られる **Validates: Requirements 1.4, 4.1, 5.1** ### Property 5: タスク編集で値が更新される *For any* タスクと更新データ、タスクを編集すると、指定されたフィールドが新しい値で更新され、他のフィールドは変更されない **Validates: Requirements 2.2** ### Property 6: 編集後のストレージ同期 *For any* タスク、それを編集すると、LocalStorageに保存されているタスクも同じ値で更新される **Validates: Requirements 2.3** ### Property 7: 編集キャンセルで元の値に戻る *For any* タスク、編集モードに入って変更を加えた後、キャンセルすると、タスクは元の値のままで変更されない **Validates: Requirements 2.4** ### Property 8: タスク削除でリストから除外される *For any* タスクリストと削除対象のタスク、そのタスクを削除すると、タスクリストにそのタスクが含まれなくなり、リストの長さが1減少する **Validates: Requirements 3.1, 3.3** ### Property 9: 削除後のストレージ同期 *For any* タスク、それを削除すると、LocalStorageからもそのタスクが削除される **Validates: Requirements 3.2** ### Property 10: タスク表示に必須情報が含まれる *For any* タスク、それをレンダリングすると、結果にタイトル、詳細、担当者、期限の情報が含まれる **Validates: Requirements 4.2** ### Property 11: 各タスク行に操作ボタンが存在する *For any* タスク、それをレンダリングすると、編集ボタンと削除ボタンが同じ行に表示される **Validates: Requirements 4.4** ### Property 12: サジェストが入力履歴から生成される *For any* 入力履歴とクエリ文字列、サジェスト結果はすべて履歴に含まれる値であり、クエリ文字列に部分一致する **Validates: Requirements 8.1, 8.2, 8.3** ### Property 13: サジェスト結果の件数制限 *For any* 入力履歴とクエリ文字列、サジェスト結果の件数は最大5件を超えない **Validates: Requirements 8.5** ### Property 14: 入力履歴の永続化 *For any* タスク追加操作、使用されたタイトル、詳細説明、担当者名が入力履歴に追加され、LocalStorageに保存される **Validates: Requirements 8.6** ## Error Handling ### 1. LocalStorage エラー **容量超過** - 検出: `QuotaExceededError` の捕捉 - 対応: ユーザーに警告メッセージを表示し、古いデータの削除を促す - フォールバック: メモリ内でのみ動作(セッション中のみ有効) **アクセス不可** - 検出: プライベートモードやブラウザ設定による制限 - 対応: ユーザーに通知し、メモリ内モードで動作 - 制限: データは永続化されない旨を明示 ### 2. データ検証エラー **不正なJSON** - 検出: `JSON.parse()` の例外 - 対応: LocalStorageをクリアし、空のタスクリストで開始 - ログ: コンソールにエラーを記録 **スキーマ不一致** - 検出: Taskインターフェースとの型チェック - 対応: 不正なタスクをスキップし、有効なタスクのみ読み込む - 通知: ユーザーに一部データが読み込めなかった旨を通知 ### 3. バリデーションエラー **タイトル未入力** - 検出: 空文字列または空白のみの文字列 - 対応: フォーム送信を防止し、エラーメッセージを表示 - メッセージ: "タイトルを入力してください" **日付形式エラー** - 検出: 無効な日付文字列 - 対応: エラーメッセージを表示し、入力を促す - メッセージ: "有効な日付を入力してください" ### 4. UI操作エラー **存在しないタスクの編集/削除** - 検出: タスクIDがリストに存在しない - 対応: 操作を無視し、エラーログを記録 - UI更新: リストを再レンダリングして最新状態を表示 ## Testing Strategy 本アプリケーションでは、3層のテスト戦略を採用します: ### 1. Unit Tests (Vitest) ビジネスロジックとユーティリティ関数の単体テストを実施します。 **対象**: - StorageService: LocalStorageの読み書き操作 - TaskManager: CRUD操作のロジック - Validation: 入力検証ロジック - ユーティリティ関数: UUID生成、日付フォーマットなど **テストケース例**: - 空のタイトルでタスク追加を試みると失敗する - 有効なタスクデータでタスクが正しく作成される - タスク削除後、そのIDのタスクが存在しない - LocalStorageが利用不可の場合、適切にフォールバックする ### 2. Property-Based Tests (fast-check) 普遍的な特性を検証するプロパティベーステストを実施します。 **使用ライブラリ**: fast-check (TypeScript/JavaScript用のプロパティベーステストライブラリ) **設定**: - 各プロパティテストは最低100回の反復実行を行う - ランダムなタスクデータを生成してテスト **テスト対象プロパティ**: 各プロパティテストは、設計書の「Correctness Properties」セクションで定義された特性を実装します。 **タグ付けルール**: 各プロパティベーステストには、以下の形式でコメントを付与します: ```typescript // Feature: web-todo-app, Property 1: タスク追加でリストが成長する ``` **実装要件**: - 各Correctness Propertyに対して1つのプロパティベーステストを実装 - テストは対応するプロパティ番号を明示的に参照 - ランダムデータ生成には fast-check のジェネレータを使用 ### 3. E2E Tests (Playwright) ユーザー視点での統合テストを実施します。 **対象シナリオ**: - タスクの追加フロー(フォーム入力→送信→リスト表示) - タスクの編集フロー(編集ボタン→フィールド変更→保存) - タスクの削除フロー(削除ボタン→確認→リストから削除) - データ永続化(タスク追加→ページリロード→データ保持確認) - 空状態の表示(タスク0個の場合のメッセージ表示) - バリデーションエラー(空タイトルでの送信→エラーメッセージ表示) **実行環境**: - ブラウザ: Chromium, Firefox, WebKit - ローカル開発サーバーに対して実行 **テストデータ**: - 各テスト実行前にLocalStorageをクリア - テストごとに独立したデータセットを使用 ### テスト実行順序 1. Unit Tests: 開発中に継続的に実行 2. Property-Based Tests: 実装完了後、各機能に対して実行 3. E2E Tests: すべての機能実装完了後に実行 ### カバレッジ目標 - Unit Tests: ビジネスロジックの90%以上 - Property-Based Tests: すべてのCorrectness Propertiesをカバー - E2E Tests: 主要なユーザーフローをすべてカバー ## Infrastructure Design (AWS CDK) ### CDK Stack構成 ```typescript class TodoAppStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); // S3 Bucket for static hosting const websiteBucket = new s3.Bucket(this, 'TodoAppBucket', { websiteIndexDocument: 'index.html', websiteErrorDocument: 'index.html', publicReadAccess: true, blockPublicAccess: s3.BlockPublicAccess.BLOCK_ACLS, removalPolicy: RemovalPolicy.DESTROY, autoDeleteObjects: true, }); // CloudFront Distribution const distribution = new cloudfront.Distribution(this, 'TodoAppDistribution', { defaultBehavior: { origin: new origins.S3Origin(websiteBucket), viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED, }, defaultRootObject: 'index.html', errorResponses: [ { httpStatus: 404, responseHttpStatus: 200, responsePagePath: '/index.html', }, ], }); // Outputs new CfnOutput(this, 'DistributionDomainName', { value: distribution.distributionDomainName, }); } } ``` ### リソース構成 **S3 Bucket**: - 静的ウェブサイトホスティング有効化 - パブリック読み取りアクセス許可 - index.htmlをデフォルトドキュメントとして設定 **CloudFront Distribution**: - S3をオリジンとして設定 - HTTPS強制(HTTP→HTTPSリダイレクト) - キャッシュ最適化ポリシー適用 - SPA対応(404エラーをindex.htmlにリダイレクト) **セキュリティ**: - HTTPS通信の強制 - S3バケットへの直接アクセス制限(CloudFront経由のみ) - CORS設定(必要に応じて) ### デプロイメントフロー ```mermaid graph LR Build[npm run build] --> Upload[S3へアップロード] Upload --> Invalidate[CloudFrontキャッシュ無効化] Invalidate --> Complete[デプロイ完了] ``` 1. `npm run build`: Viteでプロダクションビルド 2. `cdk deploy`: CDKスタックをデプロイ(初回のみ) 3. `aws s3 sync`: ビルド成果物をS3にアップロード 4. `aws cloudfront create-invalidation`: キャッシュ無効化 ### コスト最適化 - S3: 標準ストレージクラス(数MB程度の小規模アプリ) - CloudFront: 無料枠内で収まる想定(月間50GB転送まで無料) - 推定月額コスト: $1未満(低トラフィック想定) ## Performance Considerations ### 初期ロード最適化 - Viteによるコード分割とTree Shaking - 最小限の依存関係(React + 必要最小限のライブラリ) - CloudFront CDNによるグローバル配信 - 目標: 初期ロード1秒以内 ### ランタイムパフォーマンス - React.memoによる不要な再レンダリング防止 - LocalStorage操作の最適化(バッチ更新) - 仮想スクロール(タスク数が多い場合) - 目標: 操作レスポンス200ms以内 ### LocalStorage最適化 - JSON.stringify/parseの最小化 - デバウンス処理(連続操作時) - データサイズ監視(5MB制限に注意) ## Security Considerations ### クライアントサイドセキュリティ - XSS対策: Reactのデフォルトエスケープ機能を活用 - 入力サニタイゼーション: タイトル、担当者名の検証 - LocalStorage: 機密情報は保存しない(認証情報なし) ### インフラセキュリティ - HTTPS通信の強制 - S3バケットポリシーの適切な設定 - CloudFrontのセキュリティヘッダー設定 - X-Content-Type-Options: nosniff - X-Frame-Options: DENY - Content-Security-Policy ### データプライバシー - すべてのデータはクライアント側に保存 - サーバーへのデータ送信なし - ユーザーのプライバシー保護 ## Deployment and Operations ### CI/CD Pipeline ```mermaid graph LR Commit[Git Push] --> Test[テスト実行] Test --> Build[ビルド] Build --> Deploy[CDK Deploy] Deploy --> Verify[動作確認] ``` **推奨ツール**: GitHub Actions **パイプラインステップ**: 1. コードチェックアウト 2. 依存関係インストール 3. Lintとフォーマットチェック 4. Unit Tests実行 5. Property-Based Tests実行 6. ビルド実行 7. CDKスタックデプロイ 8. E2E Tests実行 9. デプロイ完了通知 ### モニタリング - CloudFront アクセスログ - S3 バケットメトリクス - ブラウザコンソールエラー監視(開発時) ### ロールバック戦略 - S3バージョニング有効化 - CloudFrontキャッシュ無効化による即時反映 - 前バージョンへの迅速な切り戻し ## Future Enhancements 本設計では実装しないが、将来的に検討可能な機能: - タスクの完了状態管理(チェックボックス) - タスクの優先度設定 - タスクのフィルタリング・ソート機能 - タスクの検索機能 - 複数ユーザー対応(認証・バックエンド追加) - タスクのカテゴリ/タグ機能 - リマインダー通知 - データのエクスポート/インポート機能 |
- tasks.md
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# Implementation Plan - [x] 1. プロジェクトのセットアップと基本構造の構築 - React + TypeScript + Viteプロジェクトを初期化 - 必要な依存関係をインストール(fast-check、Vitest、Playwright) - ディレクトリ構造を作成(src/components、src/services、src/types、src/utils) - TypeScript設定ファイルを構成 - _Requirements: 7.1_ - [x] 2. データモデルとユーティリティの実装 - [x] 2.1 型定義とインターフェースの作成 - Task、InputHistory、ValidationResultの型定義を作成 - StorageService、TaskManagerのインターフェースを定義 - _Requirements: 1.1, 4.2, 8.6_ - [x] 2.2 ユーティリティ関数の実装 - UUID v4生成関数を実装 - ISO 8601日付フォーマット関数を実装 - バリデーション関数を実装(タイトル、日付) - _Requirements: 1.2_ - [x] 2.3 ユーティリティ関数のユニットテスト - UUID生成のテスト - 日付フォーマットのテスト - バリデーション関数のテスト - _Requirements: 1.2_ - [x] 3. StorageServiceの実装 - [x] 3.1 LocalStorage操作の実装 - loadTasks、saveTasks、clearTasksメソッドを実装 - loadInputHistory、saveInputHistoryメソッドを実装 - エラーハンドリング(QuotaExceededError、JSON.parse失敗)を実装 - _Requirements: 1.4, 4.1, 5.1, 5.3, 8.6_ - [x] 3.2 StorageServiceのプロパティテスト - **Property 4: ストレージのラウンドトリップ** - **Validates: Requirements 1.4, 4.1, 5.1** - [x] 3.3 StorageServiceのユニットテスト - LocalStorage読み書きのテスト - エラーハンドリングのテスト - 入力履歴の保存・読み込みのテスト - _Requirements: 1.4, 5.3_ - [x] 4. TaskManagerの実装 - [x] 4.1 CRUD操作の実装 - addTaskメソッドを実装(タスク作成、タイムスタンプ設定) - updateTaskメソッドを実装(部分更新、updatedAt更新) - deleteTaskメソッドを実装 - getTasksメソッドを実装 - validateTaskメソッドを実装 - _Requirements: 1.1, 1.2, 2.2, 3.1_ - [x] 4.2 TaskManagerのプロパティテスト(追加) - **Property 1: タスク追加でリストが成長する** - **Validates: Requirements 1.1** - [x] 4.3 TaskManagerのプロパティテスト(バリデーション) - **Property 2: 空白タイトルは無効** - **Validates: Requirements 1.2** - [x] 4.4 TaskManagerのプロパティテスト(編集) - **Property 5: タスク編集で値が更新される** - **Validates: Requirements 2.2** - [x] 4.5 TaskManagerのプロパティテスト(削除) - **Property 8: タスク削除でリストから除外される** - **Validates: Requirements 3.1, 3.3** - [x] 4.6 入力履歴管理の実装 - updateInputHistoryメソッドを実装(重複除外、FIFO、最大50件) - getSuggestionsメソッドを実装(部分一致フィルタリング、最大5件) - _Requirements: 8.1, 8.2, 8.3, 8.4, 8.5, 8.6_ - [x] 4.7 入力履歴のプロパティテスト(サジェスト生成) - **Property 12: サジェストが入力履歴から生成される** - **Validates: Requirements 8.1, 8.2, 8.3** - [x] 4.8 入力履歴のプロパティテスト(件数制限) - **Property 13: サジェスト結果の件数制限** - **Validates: Requirements 8.5** - [x] 4.9 入力履歴のプロパティテスト(永続化) - **Property 14: 入力履歴の永続化** - **Validates: Requirements 8.6** - [x] 5. StorageServiceとTaskManagerの統合 - [x] 5.1 TaskManagerとStorageServiceの連携実装 - TaskManager内でStorageServiceを使用してデータ永続化 - タスク追加・編集・削除時にLocalStorageへ即座に保存 - _Requirements: 1.4, 2.3, 3.2_ - [x] 5.2 統合のプロパティテスト(編集後の同期) - **Property 6: 編集後のストレージ同期** - **Validates: Requirements 2.3** - [x] 5.3 統合のプロパティテスト(削除後の同期) - **Property 9: 削除後のストレージ同期** - **Validates: Requirements 3.2** - [x] 6. AutocompleteInputコンポーネントの実装 - [x] 6.1 基本的な入力フィールドとサジェストリストの実装 - 入力フィールドのレンダリング - サジェストリストの表示・非表示制御 - 入力値に基づくフィルタリング - サジェスト選択時のコールバック - _Requirements: 8.1, 8.2, 8.3, 8.4_ - [x] 6.2 キーボードナビゲーションの実装 - ↑↓キーでサジェスト選択 - Enterキーで確定 - Escapeキーでサジェストを閉じる - _Requirements: 8.4_ - [x] 6.3 スタイリングの実装 - CSS Modulesでスタイルを作成 - サジェストリストのホバー効果 - 選択中のアイテムのハイライト - _Requirements: 8.4_ - [x] 7. TaskFormコンポーネントの実装 - [x] 7.1 フォームUIの実装 - title、description、assignee、dueDateの入力フィールドを配置 - AutocompleteInputコンポーネントを統合(title、description、assignee) - 追加ボタンの実装 - _Requirements: 1.1, 1.5, 8.1, 8.2, 8.3_ - [x] 7.2 フォームバリデーションの実装 - タイトル必須チェック - エラーメッセージの表示 - 送信ボタンの無効化制御 - _Requirements: 1.2_ - [x] 7.3 フォーム送信とクリア処理の実装 - onAddTaskコールバックの呼び出し - 送信後のフォームクリア - _Requirements: 1.1, 1.3_ - [x] 7.4 TaskFormのプロパティテスト - **Property 3: タスク追加後にフォームがクリアされる** - **Validates: Requirements 1.3** - [x] 8. TaskItemコンポーネントの実装 - [x] 8.1 タスク表示の実装 - タイトル、詳細、担当者、期限の表示 - 編集・削除ボタンの配置 - _Requirements: 4.2, 4.4_ - [x] 8.2 TaskItemのプロパティテスト(表示内容) - **Property 10: タスク表示に必須情報が含まれる** - **Validates: Requirements 4.2** - [x] 8.3 TaskItemのプロパティテスト(ボタン存在) - **Property 11: 各タスク行に操作ボタンが存在する** - **Validates: Requirements 4.4** - [x] 8.4 インライン編集機能の実装 - 編集ボタンクリックで編集モードに切り替え - 各フィールドを入力可能に変更 - 保存・キャンセルボタンの表示 - _Requirements: 2.1_ - [x] 8.5 編集の保存とキャンセル処理 - 保存時にonEditコールバックを呼び出し - キャンセル時に元の値に戻す - _Requirements: 2.2, 2.4_ - [x] 8.6 編集キャンセルのプロパティテスト - **Property 7: 編集キャンセルで元の値に戻る** - **Validates: Requirements 2.4** - [x] 8.7 削除機能の実装 - 削除ボタンクリックでonDeleteコールバックを呼び出し - _Requirements: 3.1_ - [x] 8.8 スタイリングの実装 - CSS Modulesでタスク行のスタイルを作成 - 編集モードと表示モードの切り替えスタイル - ボタンのスタイリング - _Requirements: 4.4_ - [x] 9. TaskListコンポーネントの実装 - [x] 9.1 タスク一覧の表示 - TaskItemコンポーネントをマッピングして表示 - 空状態のメッセージ表示 - _Requirements: 4.1, 4.3_ - [x] 9.2 編集・削除のイベントハンドリング - onEditTaskコールバックの実装 - onDeleteTaskコールバックの実装 - _Requirements: 2.2, 3.1_ - [x] 9.3 スタイリングの実装 - CSS Modulesでリストのスタイルを作成 - 空状態のスタイリング - _Requirements: 4.3_ - [x] 10. Appコンポーネントの実装 - [x] 10.1 状態管理の実装 - useStateでタスクリストと入力履歴を管理 - TaskManagerとStorageServiceのインスタンス化 - _Requirements: 1.1, 2.2, 3.1_ - [x] 10.2 初期データロードの実装 - useEffectでLocalStorageからタスクと入力履歴を読み込み - _Requirements: 4.1, 5.1_ - [x] 10.3 タスク操作ハンドラの実装 - handleAddTask: タスク追加、入力履歴更新、状態更新 - handleEditTask: タスク編集、状態更新 - handleDeleteTask: タスク削除、状態更新 - _Requirements: 1.1, 2.2, 3.1, 8.6_ - [x] 10.4 コンポーネントの統合 - TaskFormとTaskListをレンダリング - propsを適切に渡す - _Requirements: 1.5, 4.1_ - [x] 10.5 エラーハンドリングの実装 - LocalStorageエラーのキャッチと通知 - バリデーションエラーの表示 - _Requirements: 5.3_ - [x] 10.6 スタイリングの実装 - CSS Modulesでアプリ全体のレイアウトを作成 - レスポンシブデザインの実装 - _Requirements: 1.5_ - [x] 11. チェックポイント - すべてのテストが通ることを確認 - すべてのテストが通ることを確認し、質問があればユーザーに尋ねる - [x] 12. AWS CDKインフラストラクチャの実装 - [x] 12.1 CDKプロジェクトの初期化 - CDKプロジェクトを作成 - 必要な依存関係をインストール(@aws-cdk/aws-s3、@aws-cdk/aws-cloudfront) - _Requirements: 7.1_ - [x] 12.2 S3バケットの定義 - 静的ウェブサイトホスティング設定 - パブリック読み取りアクセス設定 - _Requirements: 7.1, 7.2_ - [x] 12.3 CloudFront Distributionの定義 - S3オリジンの設定 - HTTPS強制の設定 - SPA対応のエラーレスポンス設定 - _Requirements: 7.1, 7.2_ - [x] 12.4 CDKスタックの出力設定 - CloudFrontドメイン名の出力 - _Requirements: 7.1_ - [x] 13. Playwright E2Eテストの実装 - [x] 13.1 Playwrightのセットアップ - Playwright設定ファイルを作成 - テスト用のヘルパー関数を作成(LocalStorageクリアなど) - _Requirements: 9.1, 9.2, 9.3, 9.4_ - [x] 13.2 タスク追加のE2Eテスト - フォーム入力→送信→リスト表示の確認 - _Requirements: 9.1_ - [x] 13.3 タスク編集のE2Eテスト - 編集ボタン→フィールド変更→保存の確認 - _Requirements: 9.2_ - [x] 13.4 タスク削除のE2Eテスト - 削除ボタン→リストから削除の確認 - _Requirements: 9.3_ - [x] 13.5 データ永続化のE2Eテスト - タスク追加→ページリロード→データ保持の確認 - _Requirements: 9.4_ - [x] 13.6 バリデーションエラーのE2Eテスト - 空タイトルでの送信→エラーメッセージ表示の確認 - _Requirements: 9.1_ - [x] 13.7 サジェスト機能のE2Eテスト - 入力→サジェスト表示→選択の確認 - _Requirements: 9.1_ - [x] 14. 最終チェックポイント - すべてのテストが通ることを確認 - すべてのテストが通ることを確認し、質問があればユーザーに尋ねる |
出力の判定と修正
判定結果
期待通り(実装後に修正が必要だと気づきました)
良かった点
問題点
Kiroとの対話
最初に定義されたタスクの項目が以下です。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
### Task Entity ```typescript interface Task { id: string; // UUID v4形式の一意識別子 title: string; // 1-200文字のタスクタイトル assignee: string; // 0-100文字の担当者名 dueDate: string; // ISO 8601形式の日付文字列(YYYY-MM-DD) createdAt: string; // ISO 8601形式のタイムスタンプ updatedAt: string; // ISO 8601形式のタイムスタンプ } ``` |
このままでもいいのですが、タスクの詳細を記載できるほうが便利と思い追加しました。
また、titleやassignee、descriptionは過去に入力した内容からサジェストする機能を追加するよう指示を行いました。
サジェスト機能で利用する入力履歴はどのように保持されるのか気になったので、Kiroに確認しました。
SDDのメリットでもありますが、想定されている仕様を整理してドキュメントに記載されるため、後から仕様を確認することが楽ですね。
テスト実装
以下はKiroにPlaywrightを利用したE2Eテストの実行内容を聞いた内容です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
## タスク追加機能 (task-add.spec.ts) - フォーム入力→送信→リスト表示の確認 - 複数のタスクを追加できる - 必須フィールド(タイトル)のみでタスクを追加できる - タスク追加後に空状態メッセージが非表示になる - タスク数のカウントが正しく更新される ## タスク削除機能 (task-delete.spec.ts) - 削除ボタン→リストから削除の確認 - 複数タスクから特定のタスクを削除できる - すべてのタスクを削除すると空状態になる - 削除後にタスク数が正しく更新される ## タスク編集機能 (task-edit.spec.ts) - 編集ボタン→フィールド変更→保存の確認 - 編集モードと表示モードの切り替え - 編集をキャンセルすると元の値に戻る - 一部のフィールドのみ編集できる - 編集後に変更が正しく反映される ## データ永続化機能 (task-persistence.spec.ts) - タスク追加→ページリロード→データ保持の確認 - 複数タスクの永続化 - タスク編集後の永続化 - タスク削除後の永続化 - 空状態の永続化 - LocalStorageへのデータ保存・読み込みの確認 ## サジェスト機能 (task-suggestions.spec.ts) - 入力→サジェスト表示→選択の確認 - 部分一致でサジェストがフィルタリングされる - サジェストの最大表示件数が5件 - キーボードでサジェストを選択できる(↓キー、Enter) - Escapeキーでサジェストを閉じる - 説明フィールドでもサジェストが機能する - 担当者フィールドでもサジェストが機能する - マッチするサジェストがない場合、リストが表示されない ## バリデーションエラー機能 (task-validation.spec.ts) - 空タイトルでの送信→エラーメッセージ表示の確認 - 空白のみのタイトルで追加ボタンが無効化される - 有効なタイトルを入力すると追加ボタンが有効になる - タイトルが空の場合、追加ボタンが無効化される - 他のフィールドが空でもタイトルがあれば送信できる - 無効な入力後に正常にタスクを追加できる --- **テスト概要** - テストファイル数: 6ファイル - テストケース数: 30以上 - カバー範囲: ToDoアプリの主要機能を網羅的にテスト |
成果物

サイズのバランスがイマイチ。。。
所要時間
2.5時間
主な機能
- タスクの追加、編集、削除
工夫点など
- どんどんKiroに作業を進めてほしかったので、自動実行でコマンドを許可するときは「Base」で許可しまくってました。
発見と学び
今回は改善の余地がありまくる実装でしたが、
KiroでSDDを行うことでしっかりと設計されたコードが生成される手応えを感じました。
普段使ってるClaude CodeにもSDDを行う仕組み(https://github.com/gotalab/cc-sdd)があることは知ってましたが、試していなかったので使ってみようと思います。
感想
良かった点
普段使っている生成AIツールで満足していたのでKiroは使ってませんでしたが、触ってみると面白いですね。
SDDは知ってましたが、実際にやってみると理解も深まって今後の案件に活かせます。
あと、Kiroのアイコンがピョコピョコ動くのかわいい。
苦労した点
Kiroに対する慣れの問題と思いますが、tasks.mdのタスクごとにタブが大量にできるので、「あのやりとりのどのタブのどこだっけ、、、」ってなりました。
あと、表示しきれていない他のタブへの遷移がしづらいんですが、いい方法あるんだろうか。

今後に活かせること
Kiroを通じてSDDに触れることが出来たことが今回の大きな収穫です。
実際の案件でどのように活かせるか早く試してみたいです。
また、生成AIの登場でめぐるましく開発方法やトレンドが変化しているので、キャッチアップが大変ですが、エンジニアというお仕事は経験したことがそのまま自分の価値につながるお仕事なので、Kiroに触れる機会をくれた運営陣には感謝です。
自分も他のメンバーにいい経験を積んで貰えるような活動していきたいと思えるいい刺激をもらえました。
この記事が、少しでもみなさんのにお役に立てば幸いです。
ここまでお読みいただき、ありがとうございました!
- Amazon Connect + Amazon Bedrock AgentCoreでチャットボットを構築する - 2025-12-10
- 【Kiro・Playwright】社内でフルAI開発バトル!!「1行も書かずに」Todoアプリを完成させた話〜araoの場合〜 - 2025-12-09
- [Amazon Connect]東京リージョンで電話番号取得に時間がかかる理由を調べてみた – Amazon Connect アドベントカレンダー 2024 - 2024-12-22
- sbt-awsを利用してAWS MarketplaceにSaaSを出品する - 2024-12-11
- Macで利用しているお気に入りアプリ8選 - 2024-12-05
【採用情報】一緒に働く仲間を募集しています


