diff --git a/docs/ipo_card_template.md b/docs/ipo_card_template.md
index 8409646..cfb95e9 100644
--- a/docs/ipo_card_template.md
+++ b/docs/ipo_card_template.md
@@ -11,13 +11,13 @@
## IPOカード
-### 機能名: __________
+### 機能名: ____返答処理______
| 項目 | 内容 |
|------|------|
-| **Input (きっかけ)** | ユーザーが何を入力し、何をするか? |
-| **Process (裏側の処理)** | サーバーは何を受け取り、DBに何を保存/削除するか? |
-| **Output (結果)** | 処理後、画面はどう変化し、データはどうなっているか? |
+| **Input (きっかけ)** | ユーザーは時間に応じた挨拶をインプット
+| **Process (裏側の処理)** | サーバーは言葉を受け取り、現在時刻に応じた挨拶文を生成する
+| **Output (結果)** | 時間帯に応じた挨拶文を返す
---
diff --git a/docs/phase2/00_overview.md b/docs/phase2/00_overview.md
new file mode 100644
index 0000000..d405c2a
--- /dev/null
+++ b/docs/phase2/00_overview.md
@@ -0,0 +1,116 @@
+# Phase 2: Webアプリの3層構造を体感する
+
+## 目的
+
+**データがどこにあり、どう流れるかを体感する。**
+Phase 1で体験した「消えるデータ」の問題を、Client → Server → Database と層を1つずつ追加しながら解決していく。
+
+コードの実装はAIが行う。人間がやることは以下の4つ。
+
+1. **IPOカードをAIに渡してコードを生成させる** — 教材のIPOカードをコピーしてAIに渡す
+2. **生成されたファイルを確認する** — どのファイルがどの層に対応するかを理解する
+3. **実験を実施する** — 教材の手順に従い、データの挙動を観察する
+4. **実験レポートを書く** — 観察した結果を自分の言葉で記録する
+
+---
+
+## 全体像: 3層構造とデータの流れ
+
+```
+┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
+│ Client │ HTTP │ Server │ ORM │ Database │
+│ (ブラウザ) │ ────► │ (Node.js) │ ────► │ (SQLite) │
+│ │ ◄──── │ │ ◄──── │ │
+├─────────────────┤ ├─────────────────┤ ├─────────────────┤
+│ 確認: F12 │ │ 確認: ターミナル │ │ 確認: Prisma │
+│ 編集: HTML/JS │ │ 編集: server.js │ │ Studio/DBファイル│
+└─────────────────┘ └─────────────────┘ └─────────────────┘
+```
+
+Phase 2では、この3層を **1日1層ずつ** 追加して理解する。
+
+| Day | 層の構成 | 学ぶこと |
+|-----|---------|---------|
+| Day 6 | **Client のみ** | データはブラウザの中にある |
+| Day 7 | **Client + Server** | データをサーバーに送れる |
+| Day 8 | **Client + Server + DB** | データをDBに保存できる(Create) |
+| Day 9 | **全層を往復** | DBのデータを画面に表示できる(Read) |
+| Day 10 | **永続化の証明** | 再起動してもデータが残る |
+
+---
+
+## 開発環境の準備
+
+Phase 2を始める前に、以下の環境を整える。Windows の WSL(Ubuntu)上で作業する。
+
+### 1. WSL + VS Code の確認
+
+VS Code がインストール済みであること。WSL 内のフォルダを VS Code で開いて作業する。
+
+1. VS Code の拡張機能「**WSL**」(Microsoft製)がインストールされていることを確認する
+2. WSL のターミナルを開き、作業フォルダで `code .` を実行すると VS Code が WSL に接続して開く
+3. VS Code 内のターミナル(`Ctrl + `` `)は WSL のシェルになる — ここでコマンドを実行する
+
+### 2. Node.js の確認
+
+WSL のターミナルで以下を実行し、バージョンが表示されることを確認する。
+
+```bash
+node -v
+# v20.x.x のように表示されればOK
+```
+
+表示されない場合は、nodenv でインストールする(講師に確認すること)。
+
+### 3. npm の確認
+
+```bash
+npm -v
+# 10.x.x のように表示されればOK
+```
+
+> npm は Node.js と一緒にインストールされる。パッケージ(ライブラリ)を管理するツール。
+
+### 4. ブラウザの開発者ツール
+
+Windows 側の Google Chrome を使う。以下を確認する。
+
+1. Chrome を開く
+2. **F12キー** を押す → 開発者ツールが開く
+3. **Console タブ** をクリック → ここにブラウザ側のログが表示される
+
+> WSL で起動したサーバー(`http://localhost:3000`)には、Windows 側のブラウザからそのままアクセスできる。
+
+### 5. 作業ディレクトリの準備
+
+```bash
+# 自分のPhase 2フォルダに移動(名前は自分のものに変える)
+cd members/[あなたの名前]/phase2_web
+```
+
+---
+
+## Phase 2 チェックリスト
+
+| Day | テーマ | 層の構成 | 実験レポート | 完了 |
+|-----|-------|---------|------------|------|
+| Day 6 | データはブラウザの中にある | Client | `day6_report.md` | [ ] |
+| Day 7 | データをサーバーに送る | Client + Server | `day7_report.md` | [ ] |
+| Day 8 | データをDBに保存する | Client + Server + DB | `day8_report.md` | [ ] |
+| Day 9 | DBのデータを画面に表示する | Client + Server + DB | `day9_report.md` | [ ] |
+| Day 10 | 永続化の証明 & 総まとめ | 全体まとめ | `day10_report.md` | [ ] |
+
+---
+
+## 次のPhaseへ
+
+Phase 2を完了したあなたは、以下を学びました。
+
+- **3層構造** — Client / Server / Database の役割と場所
+- **データの流れ** — 書き込み(Client → Server → DB)と読み取り(DB → Server → Client)
+- **永続化** — データベースを使えばデータは消えない
+- **ファイルとレイヤーの対応** — どのファイルを編集すると、どこが変わるか
+
+Phase 3では、**チーム開発** の作法を学びます。
+複数人で同じコードを編集するとき、どうやって衝突を避けるか?
+Gitのブランチ、プルリクエスト、コンフリクト解決を体験します。
diff --git a/docs/phase2/day06_client_only.md b/docs/phase2/day06_client_only.md
new file mode 100644
index 0000000..710957b
--- /dev/null
+++ b/docs/phase2/day06_client_only.md
@@ -0,0 +1,119 @@
+# Day 6: Client のみ — データはブラウザの中にある
+
+## 学習目標
+
+- データが「ブラウザの中(JavaScriptの変数)」に存在することを理解する
+- F12(開発者ツール)の Console でデータを確認する方法を覚える
+- ページを更新するとデータが消えることを体験する(Phase 1と同じ揮発性)
+
+## ファイル構成とレイヤーの対応
+
+```
+day6_client_only/
+└── index.html ← これが Client(ブラウザ)で動く唯一のファイル
+```
+
+| ファイル | レイヤー | 確認場所 | 役割 |
+|---------|---------|---------|------|
+| `index.html` | Client(ブラウザ) | F12 Console | 画面表示、ユーザー操作の受付、データの一時保存 |
+
+> Day 6ではサーバーもDBも使わない。HTMLファイルをブラウザで直接開くだけ。
+
+## AIへのプロンプト(IPOカード形式)
+
+以下のIPOカードをコピーしてAIに渡し、コードを生成させる。
+
+> **IPOカード — Day 6: Client のみ(メッセージボード)**
+>
+> | 層 | Input (きっかけ) | Process (処理) | Output (結果) |
+> |----|-----------------|---------------|--------------|
+> | **Client** | ユーザーがメッセージを入力し「追加」ボタンをクリック | JavaScript が入力値を受け取り、配列(messages)に追加する | 画面のリストにメッセージが表示される。Console にデータが出力される |
+>
+> **ファイル構成:**
+> - `day6_client_only/index.html`(Client層)— これ1ファイルだけ
+>
+> **仕様:**
+> - `index.html` 1ファイルだけで動くメッセージボード
+> - テキスト入力欄と「追加」ボタンがある
+> - メッセージを追加すると画面のリストに表示される
+> - データはJavaScript の配列(`messages`)に保存する
+> - メッセージを追加するたびに `console.log` で配列の中身を出力する
+> - ログには `[CLIENT]` プレフィックスをつける
+>
+> **データの流れ:**
+> ```
+> ユーザー入力 → [Client: JavaScript の配列に追加] → 画面のリストに表示
+> ↓
+> F12 Console で確認
+> ```
+
+## 準備・実行
+
+### プロジェクト準備
+
+```bash
+mkdir -p day6_client_only
+```
+
+> Day 6では `npm` は使わない。HTMLファイル1つだけで動く。
+
+### 実行方法
+
+サーバーは不要。HTMLファイルをブラウザで直接開く。
+
+**ブラウザで `index.html` を開く手順:**
+
+1. Windows のエクスプローラーのアドレスバーに `\\wsl$\Ubuntu` と入力して Enter
+2. WSL 内の作業フォルダまで移動する(`home/[ユーザー名]/...`)
+3. `day6_client_only/index.html` を見つける
+4. ファイルを右クリック → **プログラムから開く** → **Google Chrome** を選択
+
+> WSL のターミナルから `explorer.exe .` を実行すると、カレントディレクトリをエクスプローラーで開くこともできる。
+
+## ファイルの確認
+
+AIがコードを生成したら、以下を確認する。
+
+- [ ] ファイルは `index.html` の1つだけか?
+- [ ] データの保存先は JavaScript の配列(変数)か?
+- [ ] `console.log` で `[CLIENT]` プレフィックス付きのログが出るか?
+- [ ] サーバーやデータベースのコードは含まれていないか?
+
+## 実験
+
+### 実験1: メッセージを追加する
+
+1. ブラウザで `index.html` を開く
+2. **F12キー** → **Console タブ** を開く
+3. メッセージを3つ追加する
+4. **Console に `[CLIENT]` のログが表示されることを確認する**
+5. ログの中の配列データを見て、3件のメッセージが入っていることを確認する
+
+### 実験2: ページを更新する(F5)
+
+1. メッセージを3つ追加した状態で、Console でデータが3件あることを確認する
+2. **ブラウザのページを更新する(F5キー)**
+3. 画面とConsole を確認する
+
+## 実験レポート
+
+`day6_report.md` として保存し、コミットすること。
+
+```
+実験1: メッセージを追加する
+ F12 Console に表示されたログ:(実験後に書く)
+ 画面の変化:(実験後に書く)
+
+実験2: ページを更新する(F5)
+ 予想:(実験前に書く — ページを更新したらデータはどうなると思うか?)
+ 結果:(実験後に書く — 何が起きたか、画面とConsoleに何が表示されたか)
+ わかったこと:(なぜそうなったかの考察)
+```
+
+## 完了条件
+
+- [ ] `index.html` だけでメッセージボードが動作する
+- [ ] F12 Console でデータ(配列の中身)を確認できた
+- [ ] ページ更新後にデータが消えることを確認した
+- [ ] 実験レポート(`day6_report.md`)を提出した
+- [ ] コミット&プッシュ完了
diff --git a/docs/phase2/day07_client_server.md b/docs/phase2/day07_client_server.md
new file mode 100644
index 0000000..cd18867
--- /dev/null
+++ b/docs/phase2/day07_client_server.md
@@ -0,0 +1,140 @@
+# Day 7: Client + Server — データをサーバーに送る
+
+## 学習目標
+
+- Client(ブラウザ)から Server(Node.js)にデータを送る方法を学ぶ
+- データが **2つの場所**(F12 Console と ターミナル)に現れることを確認する
+- `fetch` によるHTTP通信の基本を理解する
+
+## ファイル構成とレイヤーの対応
+
+```
+day7_client_server/
+├── server.js ← Server(Node.js): ターミナルで動く 【Day 7 で新規追加】
+├── package.json ← npm の設定ファイル(npm init で自動生成)
+└── public/
+ └── index.html ← Client(ブラウザ): ブラウザで動く
+```
+
+| ファイル | レイヤー | 確認場所 | 役割 |
+|---------|---------|---------|------|
+| `public/index.html` | Client(ブラウザ) | F12 Console | ユーザー操作の受付、サーバーへのデータ送信 |
+| `server.js` | Server(Node.js) | VS Code ターミナル | Client からのデータ受信、データの一時保存 |
+
+> Day 6 と比べて、`server.js` が追加された。データの流れが Client → Server に広がる。
+
+## AIへのプロンプト(IPOカード形式)
+
+以下のIPOカードをコピーしてAIに渡し、コードを生成させる。
+
+> **IPOカード — Day 7: Client + Server(メッセージ送信)**
+>
+> | 層 | Input (きっかけ) | Process (処理) | Output (結果) |
+> |----|-----------------|---------------|--------------|
+> | **Client** | ユーザーがメッセージを入力し「送信」ボタンをクリック | JavaScript が入力値を取得し、`fetch` で Server(`POST /api/messages`)にデータを送信する | Console に送信ログが表示される。画面に「送信しました」と表示される |
+> | **Server** | Client から `POST /api/messages` でメッセージデータ(JSON)を受け取る | 受け取ったデータをターミナルに表示し、配列に保存する | Client に `{ success: true }` をJSONで返す |
+>
+> **ファイル構成:**
+> - `day7_client_server/public/index.html`(Client層)
+> - `day7_client_server/server.js`(Server層)
+>
+> **server.js の仕様:**
+> - Express を使った Node.js サーバー(ポート3000)
+> - `public/` フォルダの静的ファイルを配信する
+> - `POST /api/messages` エンドポイント: Client からメッセージ(JSON)を受け取り、サーバーの配列に保存する
+> - 受信時に `console.log` でデータを表示する(`[SERVER]` プレフィックス)
+> - 成功時に `{ success: true }` を返す
+>
+> **public/index.html の仕様:**
+> - テキスト入力欄と「送信」ボタンがある
+> - ボタンをクリックすると `fetch` で `POST /api/messages` にデータを送信する
+> - 送信前後に `console.log` でログを出す(`[CLIENT]` プレフィックス)
+> - 送信完了後、画面に「送信しました」と表示する
+>
+> **データの流れ:**
+> ```
+> ユーザー入力 → [Client: fetch POST で送信] → [Server: データを受信、配列に保存]
+> ↓ ↓
+> F12 Console で確認 VS Code ターミナルで確認
+> ```
+
+## 準備・実行
+
+### プロジェクト準備
+
+```bash
+mkdir -p day7_client_server
+cd day7_client_server
+npm init -y
+npm install express
+```
+
+> `npm init -y` で `package.json` が作られる。`npm install express` で Express(Webサーバーのライブラリ)がインストールされる。
+
+### 実行方法
+
+```bash
+node server.js
+```
+
+ブラウザで `http://localhost:3000` を開く。
+
+> Day 6 と違い、HTMLファイルを直接開くのではなく、サーバー経由でアクセスする。
+
+## ファイルの確認
+
+AIがコードを生成したら、以下を確認する。
+
+- [ ] `server.js` と `public/index.html` の2ファイルがあるか?
+- [ ] `server.js` は Server レイヤー(ターミナルで動く)のコードか?
+- [ ] `public/index.html` は Client レイヤー(ブラウザで動く)のコードか?
+- [ ] Client は `fetch` でサーバーにデータを送っているか?
+- [ ] Server は `console.log` で受信データを表示しているか?
+- [ ] データベース関連のコードは含まれていないか?
+
+## 実験
+
+### 実験1: メッセージを送信する
+
+1. **ターミナル** で `node server.js` を実行
+2. **ブラウザ** で `http://localhost:3000` を開く
+3. **F12キー** → **Console タブ** を開く
+4. メッセージを入力して「送信」をクリック
+5. **2つの場所でログを確認する:**
+
+| 確認場所 | 表示されるログ | 意味 |
+|---------|--------------|------|
+| ブラウザの F12 Console | `[CLIENT] ...` | Client(ブラウザ)側の処理 |
+| VS Code のターミナル | `[SERVER] ...` | Server(Node.js)側の処理 |
+
+### 実験2: サーバーを再起動する
+
+1. メッセージを3つ送信する
+2. ターミナルでデータが3件保存されていることを確認する
+3. ターミナルで **Ctrl+C** を押してサーバーを停止する
+4. `node server.js` でサーバーを再起動する
+5. ターミナルを確認する
+
+## 実験レポート
+
+`day7_report.md` として保存し、コミットすること。
+
+```
+実験1: メッセージを送信する
+ F12 Console に表示されたログ:(実験後に書く)
+ ターミナルに表示されたログ:(実験後に書く)
+ なぜログが2か所に表示されるか:(考察を書く)
+
+実験2: サーバーを再起動する
+ 予想:(実験前に書く — サーバーを再起動したらデータはどうなると思うか?)
+ 結果:(実験後に書く — ターミナルに何が表示されたか、以前のデータはあるか)
+ わかったこと:(なぜそうなったかの考察。Day 6 との共通点は何か)
+```
+
+## 完了条件
+
+- [ ] Client から送信したデータが Server のターミナルに表示される
+- [ ] `[CLIENT]` ログと `[SERVER]` ログが別の場所に出ることを確認した
+- [ ] サーバー再起動後にデータが消えることを確認した
+- [ ] 実験レポート(`day7_report.md`)を提出した
+- [ ] コミット&プッシュ完了
diff --git a/docs/phase2/day08_with_db.md b/docs/phase2/day08_with_db.md
new file mode 100644
index 0000000..a767bb8
--- /dev/null
+++ b/docs/phase2/day08_with_db.md
@@ -0,0 +1,167 @@
+# Day 8: Client + Server + DB — データをDBに保存する(Create)
+
+## 学習目標
+
+- データベース(SQLite)にデータを永続的に保存する方法を学ぶ
+- 3層すべてを通るデータの流れ(Client → Server → DB)を理解する
+- ORM(Prisma)の基本的な使い方を学ぶ
+
+## ファイル構成とレイヤーの対応
+
+```
+day8_with_db/
+├── server.js ← Server: API処理 + DB操作
+├── package.json ← npm の設定ファイル
+├── public/
+│ └── index.html ← Client: 画面表示 + データ送信
+└── prisma/
+ ├── schema.prisma ← DB定義: テーブルの構造を定義 【Day 8 で新規追加】
+ └── dev.db ← Database: データが保存されるファイル(自動生成)【Day 8 で新規追加】
+```
+
+| ファイル | レイヤー | 確認場所 | 役割 |
+|---------|---------|---------|------|
+| `public/index.html` | Client(ブラウザ) | F12 Console | 画面表示、データ送信 |
+| `server.js` | Server(Node.js) | VS Code ターミナル | API処理、Prisma を使った DB 操作 |
+| `prisma/schema.prisma` | DB定義 | — | テーブルの構造(カラム名、型)を定義 |
+| `prisma/dev.db` | Database(SQLite) | Prisma Studio | データが物理的に保存されるファイル |
+
+> Day 7 と比べて、`prisma/` フォルダが追加された。Server がデータを受け取った後、変数ではなく **DBファイルに保存** する。
+
+## AIへのプロンプト(IPOカード形式)
+
+以下のIPOカードをコピーしてAIに渡し、コードを生成させる。
+
+> **IPOカード — Day 8: Client + Server + DB(メッセージ保存 — Create)**
+>
+> | 層 | Input (きっかけ) | Process (処理) | Output (結果) |
+> |----|-----------------|---------------|--------------|
+> | **Client** | ユーザーが名前とメッセージを入力し「送信」ボタンをクリック | JavaScript が入力値を取得し、`fetch` で Server(`POST /api/messages`)にデータを送信する | Console に送信ログが表示される。入力欄がクリアされる |
+> | **Server** | Client から `POST /api/messages` で名前・メッセージのJSONデータを受け取る | Prisma を使って、受け取ったデータを Database の `Message` テーブルに INSERT する | ターミナルに保存ログが出力される。Client に `{ success: true, message: {...} }` を返す |
+> | **Database** | Server(Prisma)から INSERT 命令を受け取る | `Message` テーブルに新しい行(レコード)を追加する。`id` と `createdAt` は自動生成 | 保存したレコード(id, name, content, createdAt)を Server に返す |
+>
+> **ファイル構成:**
+> - `day8_with_db/public/index.html`(Client層)
+> - `day8_with_db/server.js`(Server層)
+> - `day8_with_db/prisma/schema.prisma`(DB定義)
+> - `day8_with_db/prisma/dev.db`(Database — migrate 後に自動生成)
+>
+> **prisma/schema.prisma の仕様:**
+> - Message モデル: id(自動採番)、name(文字列)、content(文字列)、createdAt(日時、自動生成)
+>
+> **server.js の仕様:**
+> - Express サーバー(ポート3000)
+> - PrismaClient を使ってDBにアクセスする
+> - `POST /api/messages` エンドポイント: name と content を受け取り、DBに保存する
+> - 保存時に `console.log` で `[SERVER]` プレフィックス付きのログを出す
+> - 成功時に保存したデータを返す
+>
+> **public/index.html の仕様:**
+> - 名前とメッセージの2つの入力欄と「送信」ボタン
+> - `fetch` で `POST /api/messages` にデータを送信する
+> - `console.log` で `[CLIENT]` プレフィックス付きのログを出す
+>
+> **データの流れ:**
+> ```
+> ユーザー入力 → [Client: fetch POST] → [Server: Prismaで保存命令] → [DB: ファイルに書き込み]
+> ↓ ↓ ↓
+> F12 Console VS Code ターミナル prisma/dev.db に保存
+> (Prisma Studio で確認)
+> ```
+
+## 準備・実行
+
+### プロジェクト準備
+
+```bash
+mkdir -p day8_with_db
+cd day8_with_db
+npm init -y
+npm install express @prisma/client
+npm install -D prisma
+npx prisma init --datasource-provider sqlite
+```
+
+> `npx prisma init` を実行すると `prisma/schema.prisma` が自動生成される。
+
+### schema 定義後に実行するコマンド
+
+AIが `prisma/schema.prisma` を生成した後、以下を実行する。
+
+```bash
+npx prisma migrate dev --name init
+```
+
+> このコマンドで `prisma/dev.db` ファイルが作成される。これがデータベースの実体。
+
+### 実行方法
+
+```bash
+node server.js
+```
+
+ブラウザで `http://localhost:3000` を開く。
+
+## ファイルの確認
+
+AIがコードを生成したら、以下を確認する。
+
+- [ ] 以下の4つのファイル/フォルダが存在するか?
+ - `public/index.html`(Client)
+ - `server.js`(Server)
+ - `prisma/schema.prisma`(DB定義)
+ - `prisma/dev.db`(Database ファイル — migrate 後に生成)
+- [ ] `server.js` の中で `PrismaClient` を使っているか?
+- [ ] `server.js` の中で `prisma.message.create()` でDBに保存しているか?
+- [ ] Day 7 のように配列(変数)に保存するコードは**ないか**?
+
+## 実験
+
+### 実験1: メッセージを送信して3か所で確認する
+
+メッセージを送信した後、**3つの場所** でデータを確認する。
+
+| 確認場所 | 確認方法 | 何が見えるか |
+|---------|---------|------------|
+| ブラウザ F12 Console | F12 → Console タブ | `[CLIENT] ...` 送信ログ |
+| VS Code ターミナル | サーバー実行中のターミナル | `[SERVER] ...` DB保存ログ |
+| Prisma Studio | 別ターミナルで `npx prisma studio` を実行 | テーブルにレコードが追加されている |
+
+Prisma Studio の開き方:
+```bash
+# サーバーとは別のターミナルを開いて実行
+npx prisma studio
+```
+ブラウザで `http://localhost:5555` が開き、DBの中身を直接見ることができる。
+
+### 実験2: サーバーを再起動する
+
+1. メッセージを3件送信する
+2. Prisma Studio で3件のレコードを確認する
+3. ターミナルで **Ctrl+C** を押してサーバーを停止する
+4. `node server.js` でサーバーを再起動する
+5. Prisma Studio でDBの中身を確認する
+
+## 実験レポート
+
+`day8_report.md` として保存し、コミットすること。
+
+```
+実験1: メッセージを送信して3か所で確認する
+ F12 Console に表示されたログ:(実験後に書く)
+ ターミナルに表示されたログ:(実験後に書く)
+ Prisma Studio で見えたデータ:(実験後に書く)
+
+実験2: サーバーを再起動する
+ 予想:(実験前に書く — サーバーを再起動したらデータはどうなると思うか?Day 7 と同じか?)
+ 結果:(実験後に書く — Prisma Studio でデータは残っていたか)
+ わかったこと:(なぜ Day 7 と違う結果になったかの考察)
+```
+
+## 完了条件
+
+- [ ] メッセージがDBに保存される(Prisma Studio で確認)
+- [ ] F12 Console、ターミナル、Prisma Studio の3か所でデータを確認した
+- [ ] サーバー再起動後もDBのデータが残ることを確認した
+- [ ] 実験レポート(`day8_report.md`)を提出した
+- [ ] コミット&プッシュ完了
diff --git a/docs/phase2/day09_read.md b/docs/phase2/day09_read.md
new file mode 100644
index 0000000..a768748
--- /dev/null
+++ b/docs/phase2/day09_read.md
@@ -0,0 +1,130 @@
+# Day 9: 全層を往復 — DBのデータを画面に表示する(Read)
+
+## 学習目標
+
+- データの**逆方向の流れ**(DB → Server → Client)を理解する
+- GET API でデータを取得する方法を学ぶ
+- 画面にデータベースの内容を表示する
+
+## ファイル構成とレイヤーの対応
+
+Day 8 と同じプロジェクト(`day8_with_db/`)に機能を追加する。
+
+```
+day8_with_db/
+├── server.js ← Server: POST API + GET API(★ GET を追加)
+├── package.json
+├── public/
+│ └── index.html ← Client: 送信機能 + 一覧表示機能(★ 表示を追加)
+└── prisma/
+ ├── schema.prisma ← DB定義(変更なし)
+ └── dev.db ← Database(変更なし)
+```
+
+| ファイル | Day 9 で追加する内容 |
+|---------|-------------------|
+| `server.js` | `GET /api/messages` エンドポイントを追加 |
+| `public/index.html` | ページ読み込み時にメッセージ一覧を取得・表示する処理を追加 |
+| `prisma/schema.prisma` | 変更なし |
+| `prisma/dev.db` | 変更なし(Day 8 で保存したデータがそのまま入っている) |
+
+## AIへのプロンプト(IPOカード形式)
+
+Day 8 のプロジェクトに機能を追加する。以下のIPOカードをコピーしてAIに渡し、既存コードに追加させる。
+
+> **IPOカード — Day 9: 全層を往復(メッセージ一覧表示 — Read)**
+>
+> | 層 | Input (きっかけ) | Process (処理) | Output (結果) |
+> |----|-----------------|---------------|--------------|
+> | **Client** | ページが読み込まれたとき(自動実行) | `fetch` で Server(`GET /api/messages`)からデータを取得する | 取得したメッセージ一覧を画面のリストに表示する |
+> | **Server** | Client から `GET /api/messages` リクエストを受け取る | Prisma を使って Database の `Message` テーブルから全件取得する(新しい順) | 取得したメッセージの配列をJSONで Client に返す |
+> | **Database** | Server(Prisma)から SELECT 命令を受け取る | `Message` テーブルから全レコードを `createdAt` の降順で取得する | レコードの配列を Server に返す |
+>
+> **編集対象ファイル(Day 8 のプロジェクトに追加):**
+> - `day8_with_db/server.js` — `GET /api/messages` エンドポイントを追加
+> - `day8_with_db/public/index.html` — ページ読み込み時のデータ取得・表示処理を追加
+> - `prisma/schema.prisma` — 変更なし
+>
+> **server.js に追加する仕様:**
+> - `GET /api/messages` エンドポイント: DB から全メッセージを新しい順で取得し、JSON で返す
+> - 取得時に `console.log` で `[SERVER]` プレフィックス付きのログを出す(取得件数を表示)
+>
+> **public/index.html に追加する仕様:**
+> - ページ読み込み時に `fetch` で `GET /api/messages` を呼び、メッセージ一覧を取得する
+> - 取得したメッセージを画面のリストに表示する(名前、内容、日時)
+> - 取得時に `console.log` で `[CLIENT]` プレフィックス付きのログを出す
+> - メッセージ送信後にも一覧を再取得して表示を更新する
+>
+> **データの流れ(Read — 今日追加する流れ):**
+> ```
+> ページ読込 → [Client: fetch GET] ← [Server: Prismaで取得命令] ← [DB: データを返す]
+> ↓ ↓ ↓
+> 画面にリスト表示 ターミナルにログ dev.db から読み出し
+> ```
+
+## 準備・実行
+
+Day 8 のプロジェクト(`day8_with_db/`)をそのまま使う。新しいフォルダは作らない。
+
+```bash
+node server.js
+```
+
+ブラウザで `http://localhost:3000` を開く。
+
+## ファイルの確認
+
+AIがコードを編集したら、以下を確認する。
+
+- [ ] `server.js` に `GET /api/messages` が追加されたか?
+- [ ] `server.js` で `prisma.message.findMany()` を使ってDBからデータを取得しているか?
+- [ ] `public/index.html` にページ読み込み時のデータ取得処理が追加されたか?
+- [ ] `public/index.html` で取得したデータを画面に表示する処理があるか?
+- [ ] `prisma/schema.prisma` は変更されていないか?
+
+## 実験
+
+### 実験1: ページを開いてデータを取得する
+
+1. `node server.js` でサーバーを起動する
+2. ブラウザで `http://localhost:3000` を開く
+3. **Day 8 で保存したメッセージが自動的に画面に表示されることを確認する**
+4. F12 Console とターミナルのログを確認する:
+
+| 確認場所 | 表示されるログ |
+|---------|--------------|
+| F12 Console | `[CLIENT] 取得したメッセージ: [{...}, {...}, ...]` |
+| ターミナル | `[SERVER] DBから取得: 3 件` |
+
+5. 新しいメッセージを送信し、一覧に追加されることを確認する
+
+### 実験2: サーバーを再起動してデータの往復を確認する
+
+1. サーバーを停止する(Ctrl+C)
+2. サーバーを再起動する(`node server.js`)
+3. ブラウザで `http://localhost:3000` を開く
+4. 以前のメッセージが表示されるか確認する
+
+## 実験レポート
+
+`day9_report.md` として保存し、コミットすること。
+
+```
+実験1: ページを開いてデータを取得する
+ 画面に表示されたメッセージ:(実験後に書く — Day 8 で保存したデータが出たか)
+ F12 Console に表示されたログ:(実験後に書く)
+ ターミナルに表示されたログ:(実験後に書く)
+
+実験2: サーバーを再起動してデータの往復を確認する
+ 予想:(実験前に書く — サーバーを再起動した後、ページを開いたらデータは表示されるか?)
+ 結果:(実験後に書く — メッセージは表示されたか)
+ わかったこと:(Read のデータの流れを自分の言葉で書く。Create との方向の違いは何か)
+```
+
+## 完了条件
+
+- [ ] ページを開くとDBに保存済みのメッセージが表示される
+- [ ] 新しいメッセージを追加すると一覧に即反映される
+- [ ] サーバー再起動後もメッセージが表示される
+- [ ] 実験レポート(`day9_report.md`)を提出した
+- [ ] コミット&プッシュ完了
diff --git a/docs/phase2/day10_summary.md b/docs/phase2/day10_summary.md
new file mode 100644
index 0000000..97587e6
--- /dev/null
+++ b/docs/phase2/day10_summary.md
@@ -0,0 +1,125 @@
+# Day 10: 永続化の証明 — 全てを再起動する
+
+## 学習目標
+
+- データベースによる永続化を最終確認する
+- Phase 1(揮発性)と Phase 2(永続性)の違いを整理する
+- 3層構造の全体像を自分の言葉で説明できるようになる
+
+## 実験
+
+### 実験1: 永続化の最終確認
+
+以下の手順を実行し、**データが消えないこと** を確認する。
+
+1. ゲストブックにメッセージを3件以上登録する
+2. サーバーを停止する(Ctrl+C)
+3. **PCを再起動する**(または数時間後に再開)
+4. `node server.js` でサーバーを起動する
+5. ブラウザで `http://localhost:3000` を開く
+6. メッセージが残っているか確認する
+
+### Day 6〜9 の比較表
+
+| 項目 | Day 6 (Client のみ) | Day 7 (Client + Server) | Day 8-9 (Client + Server + DB) |
+|------|---------------------|------------------------|-------------------------------|
+| データ保存場所 | ブラウザの変数 | サーバーの変数 | SQLite ファイル |
+| ページ更新後 | **消える** | 残る(サーバーが動いていれば) | **残る** |
+| サーバー再起動後 | — | **消える** | **残る** |
+| PC再起動後 | **消える** | **消える** | **残る** |
+| 永続性 | 揮発性 | 揮発性 | **永続性** |
+
+### ファイルとレイヤーの対応 総まとめ
+
+```
+day8_with_db/
+│
+├── public/
+│ └── index.html → Client(ブラウザ)
+│ ・ユーザー操作を受け付ける
+│ ・fetch でサーバーにデータを送る(Create)
+│ ・fetch でサーバーからデータを取得する(Read)
+│ ・取得したデータを画面に表示する
+│ ・確認場所: F12 Console
+│
+├── server.js → Server(Node.js)
+│ ・Client からのリクエストを受け付ける
+│ ・Prisma を使って DB にデータを保存する(Create)
+│ ・Prisma を使って DB からデータを取得する(Read)
+│ ・結果を JSON で Client に返す
+│ ・確認場所: VS Code ターミナル
+│
+└── prisma/
+ ├── schema.prisma → DB定義
+ │ ・テーブルの構造(カラム名、型)を定義する
+ │ ・人間が読んで「どんなデータが保存されるか」を理解する
+ │
+ └── dev.db → Database(SQLite)
+ ・データが物理的に保存されるファイル
+ ・サーバーを止めてもPCを再起動しても消えない
+ ・確認場所: Prisma Studio
+```
+
+### データフロー 総まとめ
+
+```
+【Create(書き込み)の流れ → → →】
+
+ ユーザーが入力
+ ↓
+ [Client: index.html]
+ fetch POST /api/messages でサーバーに送信
+ ↓ F12 Console で確認
+ [Server: server.js]
+ prisma.message.create() で DB に保存命令
+ ↓ ターミナルで確認
+ [DB: dev.db]
+ Message テーブルにレコードを追加
+ Prisma Studio で確認
+
+
+【Read(読み取り)の流れ ← ← ←】
+
+ ページを開く
+ ↓
+ [Client: index.html]
+ fetch GET /api/messages でサーバーにリクエスト
+ ↓
+ [Server: server.js]
+ prisma.message.findMany() で DB から取得命令
+ ↓
+ [DB: dev.db]
+ Message テーブルから全レコードを取得
+ ↓
+ [Server: server.js]
+ 取得したデータを JSON で Client に返す
+ ↓ ターミナルで確認
+ [Client: index.html]
+ 受け取ったデータを画面のリストに表示
+ F12 Console + 画面で確認
+```
+
+## 実験レポート
+
+`day10_report.md` として保存し、コミットすること。
+
+```
+実験1: 永続化の最終確認(PC再起動後)
+ 予想:(実験前に書く — PC再起動後、データは残っていると思うか?)
+ 結果:(実験後に書く — メッセージは表示されたか)
+ わかったこと:(なぜデータが残ったか / 消えたかの考察)
+
+Phase 2 全体のまとめ:
+ Phase 1 のToDoリストはなぜデータが消えたか:
+ Phase 2 のゲストブックはなぜデータが残るか:
+ Client、Server、DB それぞれの役割(1文ずつ):
+ Create(書き込み)のデータの流れ:
+ Read(読み取り)のデータの流れ:
+```
+
+## 完了条件
+
+- [ ] PC再起動後もデータが残ることを確認した
+- [ ] Day 6〜9 の比較表の違いを説明できる
+- [ ] 各ファイルがどのレイヤーに対応するか説明できる
+- [ ] 実験レポート(`day10_report.md`)を提出した
diff --git a/members/kurihara/phase2_web/day6_client_only/day6_report.md b/members/kurihara/phase2_web/day6_client_only/day6_report.md
new file mode 100644
index 0000000..0e0307c
--- /dev/null
+++ b/members/kurihara/phase2_web/day6_client_only/day6_report.md
@@ -0,0 +1,38 @@
+## 実験レポート
+
+### 実験1: メッセージを追加する
+**方法**
+"Hello, world!", "This is a test.", "Day6"の3つのメッセージを順に追加した.
+
+**結果**
+ F12 Console に表示されたログ:
+index.html:60 [CLIENT] messages: ['Hello, world!']
+index.html:60 [CLIENT] messages: (2) ['Hello, world!', 'This is a test.']
+index.html:60 [CLIENT] messages: (3) ['Hello, world!', 'This is a test.', 'Day6']
+
+ 画面の変化:
+メッセージボックスの下に,箇条書きで
+Hello, world!
+This is a test.
+Day6
+という文字が追加されていった.
+
+### 実験2: F5キーを押してページを更新する
+ 予想:
+ページを更新するとコンソールが一度破棄されて,データは消える.
+
+ 結果:
+画面,コンソールともに,何も書かれていないものに切り替わった.
+
+ 分かったこと:
+画面を更新したことでindex.htmlが読み直されて,JavaScriptの配列の中に追加したデータが,追加される前の状態,つまり空の状態になったと考えられる.実際,index.htmlの
+
+
+
+
+の部分を書き換え,
+
+
+
+
+としてページを更新すると,メッセージ入力欄の文字も変化したからである.
\ No newline at end of file
diff --git a/members/kurihara/phase2_web/day6_client_only/index.html b/members/kurihara/phase2_web/day6_client_only/index.html
new file mode 100644
index 0000000..e255b44
--- /dev/null
+++ b/members/kurihara/phase2_web/day6_client_only/index.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+ Day 6 Client Only Message Board
+
+
+
+ メッセージボード
+
+
+
+
+
+
+
+
+
+
+
diff --git a/members/kurihara/phase2_web/day7_client_server/day7_report.md b/members/kurihara/phase2_web/day7_client_server/day7_report.md
new file mode 100644
index 0000000..dbb7012
--- /dev/null
+++ b/members/kurihara/phase2_web/day7_client_server/day7_report.md
@@ -0,0 +1,56 @@
+*** 実験1 ***
+
+## 方法
+メッセージ"This is a test."を送信した.
+
+## 結果
+ F12 Console に表示されたログ:
+[CLIENT] 送信前データ: {message: 'This is a test.'}
+(index):67 [CLIENT] 送信後レスポンス: {success: true}
+
+ ターミナルに表示されたログ:
+[SERVER] 受信データ: { message: 'This is a test.', receivedAt: '2026-02-21T11:42:27.902Z' }
+
+ 考察(なぜログが2か所に表示されるか):
+cliant 側のindex.htmlについて,
+const payload = { message };
+console.log('[CLIENT] 送信前データ:', payload);
+
+server 側のserver.jsについて,
+app.use(express.json());
+app.use(express.static(path.join(__dirname, 'public')));
+...
+app.post('/api/messages', (req, res) => {
+ const { message } = req.body;
+ const item = {
+ message,
+ receivedAt: new Date().toISOString(),
+ };
+ ...
+}
+)
+
+ messages.push(item);
+ console.log('[SERVER] 受信データ:', item);
+
+の部分から,cliantがブラウザからメッセージを送ると,ブラウザのコンソールにNode.jsのExpressに送信前データが,serverのExpressがメッセージを受け取ると,サーバー側のコンソールに受信データがconsole.logによって表示されるためだと考えられる.
+
+
+*** 実験2 ***
+
+## 方法
+1. メッセージ"hop", "step", "jumping"を送信した.
+2. ターミナルでデータが3件保存されていることを確認した.
+3. ターミナルで **Ctrl+C** を押してサーバーを停止させた.
+4. `node server.js` によってサーバーを再起動させた.
+5. ターミナルを確認した.
+
+## 結果
+ 予想:
+サーバーを再起動すると,server.jsを読み込み直すため,javaScriptのリストに保存してあったデータは消える.
+
+ 結果:
+サーバーに以前のデータはなく,データを保存するためのリストは空のリストになっていた.
+
+ 分かったこと:
+サーバーを再起動させると,server.jsを読み込み直すため,以前リストに保存してあったデータは消える.これは,Day6で,ファイルを読み込み直してデータが消えたという点で共通している.
\ No newline at end of file
diff --git a/members/kurihara/phase2_web/day7_client_server/package-lock.json b/members/kurihara/phase2_web/day7_client_server/package-lock.json
new file mode 100644
index 0000000..befc79b
--- /dev/null
+++ b/members/kurihara/phase2_web/day7_client_server/package-lock.json
@@ -0,0 +1,827 @@
+{
+ "name": "day7_client_server",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "day7_client_server",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "express": "^5.2.1"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
+ "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.7.0",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.1",
+ "raw-body": "^3.0.1",
+ "type-is": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
+ "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "license": "MIT"
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/express": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.1",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "license": "MIT"
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
+ "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
+ "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.7.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.1",
+ "mime-types": "^3.0.2",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
+ }
+ }
+}
diff --git a/members/kurihara/phase2_web/day7_client_server/package.json b/members/kurihara/phase2_web/day7_client_server/package.json
new file mode 100644
index 0000000..4403297
--- /dev/null
+++ b/members/kurihara/phase2_web/day7_client_server/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "day7_client_server",
+ "version": "1.0.0",
+ "description": "",
+ "main": "server.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "start": "node server.js"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "type": "commonjs",
+ "dependencies": {
+ "express": "^5.2.1"
+ }
+}
diff --git a/members/kurihara/phase2_web/day7_client_server/public/index.html b/members/kurihara/phase2_web/day7_client_server/public/index.html
new file mode 100644
index 0000000..3041c65
--- /dev/null
+++ b/members/kurihara/phase2_web/day7_client_server/public/index.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+ Day7 Client-Server
+
+
+
+ Client / Server メッセージ送信
+
+
+
+
+
+
+
+
+
+
+
diff --git a/members/kurihara/phase2_web/day7_client_server/server.js b/members/kurihara/phase2_web/day7_client_server/server.js
new file mode 100644
index 0000000..ef94eca
--- /dev/null
+++ b/members/kurihara/phase2_web/day7_client_server/server.js
@@ -0,0 +1,29 @@
+const express = require('express');
+const path = require('path');
+
+const app = express();
+const PORT = 3000;
+const messages = [];
+
+console.log('messages:', messages);
+
+app.use(express.json());
+app.use(express.static(path.join(__dirname, 'public')));
+
+app.post('/api/messages', (req, res) => {
+ const { message } = req.body;
+ const item = {
+ message,
+ receivedAt: new Date().toISOString(),
+ };
+
+ messages.push(item);
+ console.log('[SERVER] 受信データ:', item);
+
+ res.json({ success: true });
+ console.log('messages:', messages);
+});
+
+app.listen(PORT, () => {
+ console.log(`[SERVER] http://localhost:${PORT} で起動しました`);
+});