OmniAICreator/Qiita-1.07M huggingface dataset:
Rancher DesktopのDocker Daemon／クライアントにプロキシを設定する

# What's？

Rancher Desktopで使うDocker Daemon／クライアントのプロキシ設定まとめということで。

# 環境

Rancher Desktop 1.18.2。

```powershell
PS > docker version
Client:
 Version:           27.5.1-rd
 API version:       1.45 (downgraded from 1.47)
 Go version:        go1.22.11
 Git commit:        0c97515
 Built:             Thu Jan 23 18:14:31 2025
 OS/Arch:           windows/amd64
 Context:           default

Server:
 Engine:
  Version:          26.1.5
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.22.5
  Git commit:       411e817ddf710ff8e08fa193da80cb78af708191
  Built:            Fri Jul 26 17:51:06 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.7.17
  GitCommit:        3a4de459a68952ffb703bbe7f2290861a75b6b67
 runc:
  Version:          1.1.14
  GitCommit:        2c9f5602f0ba3d9da1c2596322dfc4e156844890
 docker-init:
  Version:          0.19.0
  GitCommit:
```

# Docker Daemonのプロキシ設定

Rancher DesktopのGUI上で設定します。この設定はDockerイメージをpullする時に作用します。

Preferences → WSL → Proxyで設定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309669/dbbeec43-e004-4fad-9a5e-0c27a38a82d9.png)

こちらのドキュメントの内容です。

https://docs.rancherdesktop.io/1.18/ui/preferences/wsl/proxy

# Dockerクライアントのプロキシ設定

こちらは、Dockerコンテナ内で実行するコマンドに作用します。

`%USERPROFILE%\.docker\config.json`を開きます。

手元の環境ではこんな内容でした。

```json:%USERPROFILE%\.docker\config.json
{"credsStore":"wincred","cliPluginsExtraDirs":["C:\\Program Files\\Rancher Desktop\\resources\\resources\\win32\\docker-cli-plugins"]}
```

以下のように変更。

```json:%USERPROFILE%\.docker\config.json
{"credsStore":"wincred","cliPluginsExtraDirs":["C:\\Program Files\\Rancher Desktop\\resources\\resources\\win32\\docker-cli-plugins"],
  "proxies": {
    "default": {
      "httpProxy": "http://your-proxy.server.com:your-proxy-port",
      "httpsProxy": "http://your-proxy.server.com:your-proxy-port"
    }
  }
}
```

これで、コンテナ側に`http_proxy`、`https_proxy`、`HTTP_PROXY`、`HTTPS_PROXY`環境変数が設定された状態になります。

ドキュメントとしてはこちらの内容です

https://docs.docker.com/engine/cli/proxy/
JavaScriptにおける再帰処理設計：末尾再帰・トランポリン・パフォーマンス考慮の制御戦略


## 概要

再帰とは「自分を呼び出す関数」ではない。  
それは**“分割と再構築を制御し、状態と深さを扱いながら計算の本質を定義する構造”**である。

JavaScriptは再帰に対して強力だが、**スタックサイズの制限 / パフォーマンスの劣化 / ブラウザ依存の動作不安定**など、  
再帰設計を誤ると **実用レベルでは破綻** する。

本稿では、**末尾再帰・トランポリン・再帰→反復の変換**など、  
JavaScriptで再帰処理を安全かつ効率的に扱うための設計手法を解説する。

---

## 1. 再帰とは「自己参照による分割と帰納」

```ts
function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
```

- ✅ 再帰とは「状態の縮小と組み合わせによる答えの構築」
- ❌ スタックサイズにより `RangeError: Maximum call stack size exceeded` を起こす可能性

---

## 2. 末尾再帰（Tail Call Optimization）の理論と罠

```ts
function factorial(n, acc = 1) {
  if (n <= 1) return acc;
  return factorial(n - 1, acc * n);
}
```

- ✅ 最後の処理が再帰呼び出し → **TCO対象**
- ❌ **JavaScriptはTCOが仕様上定義されているが、現在は未サポート**
  - 2025現在：Safari以外では末尾再帰は**最適化されない**

---

## 3. トランポリン構造：再帰の分解による実行

```ts
function trampoline(fn) {
  while (typeof fn === 'function') {
    fn = fn();
  }
  return fn;
}

function sum(n, acc = 0) {
  if (n === 0) return acc;
  return () => sum(n - 1, acc + n); // 関数を返す
}

trampoline(() => sum(100000));
```

- ✅ 関数を返し続けて**1ステップずつ実行 → スタック破綻しない**
- ✅ 深さのある処理でも**安全に扱える再帰エミュレーション**

---

## 4. 再帰 → 反復への変換

```ts
function factorialIterative(n) {
  let result = 1;
  for (let i = 2; i <= n; i++) {
    result *= i;
  }
  return result;
}
```

- ✅ **再帰は設計が直感的**  
- ✅ **反復は実行が効率的（GC、最適化）**

---

## 5. 再帰パターンの分類と選定

```text
- 単純再帰（n → n-1） → TCO / トランポリンで安全に
- 木構造 / グラフ探索（DFS） → スタック管理 or Stack併用
- 巡回再帰（状態記憶） → メモ化再帰 or DPに展開
```

---

## 設計判断フロー

```text
① この再帰は「深さが大きくなる可能性」があるか？ → トランポリン or 反復へ変換

② 状態保持（キャッシュ、accumulator）が必要か？ → 末尾再帰設計 or メモ化再帰

③ パフォーマンス上限（ms / call depth）に触れていないか？ → GC/最適化観点から再設計

④ コードの直感性を優先するか？ → 読みやすさと安全性のバランス設計
```

---

## よくあるミスと対策

### ❌ 10万回再帰でブラウザがクラッシュ

→ ✅ **トランポリン化 + 関数返却構造で安全化**

---

### ❌ TCOを期待して末尾再帰を書いたが何も変わらなかった

→ ✅ **JavaScriptではTCOは非実装 → 明示的に再設計が必要**

---

### ❌ 複雑なロジックを再帰で書いてスタックと戦っている

→ ✅ **スタックは有限 → 明示的に自分で制御する設計へ変換**

---

## 結語

再帰とは「自分を呼び出す関数」ではない。  
それは**“状態を縮小し、構造を保ちながら、帰納的に意味を定義する制御の方法”**である。

- JavaScriptでは **TCOは理論上のみ存在**し、実用性は限られる  
- **トランポリン構造**は再帰安全性の強力な手法  
- **再帰 → 反復の変換**はパフォーマンス上の王道  
- 設計時に **深さ・安全性・速度・見通し**をすべて考慮する

**JavaScriptにおける再帰処理設計とは、  
“スタックという制限下で意味と構造を共存させるための表現と制御の設計戦略”である。**
JavaScriptにおける非同期処理設計パターン：Promiseチェーン / async-await / 並列・直列・条件分岐処理の構造設計

## 概要

非同期処理とは「async/awaitで書くこと」ではない。  
それは**“処理の流れ・構造・失敗・依存を意図通りに制御し、読みやすさと再利用性を両立させるための構造設計”**である。

JavaScriptにおける非同期処理は、**Promise、async/await、thenチェーン、並列実行、順次処理、条件付き非同期**など多様なパターンが存在する。  
それらを目的に応じて設計・選択しなければ、**見通しの悪いコードやバグの温床**となる。

---

## 1. 非同期制御の基本形：Promise vs async/await

```ts
// Promiseチェーン
doA()
  .then(doB)
  .then(doC)
  .catch(handleError);

// async/await
async function execute() {
  try {
    const a = await doA();
    const b = await doB(a);
    await doC(b);
  } catch (e) {
    handleError(e);
  }
}
```

- ✅ **同じ処理でも書き方は2通り**
- ✅ async/await は **同期的に見える非同期**で可読性が高い

---

## 2. 直列処理（順番が大事）

```ts
for (const item of items) {
  await process(item); // 直列処理
}
```

- ✅ 順序保証が必要なときは直列が正解
- ❌ `forEach + async` は **awaitを無視される** →注意！

---

## 3. 並列処理（速度最優先）

```ts
await Promise.all(items.map(item => process(item)));
```

- ✅ 順序不要で **すべて成功する必要がある**とき
- ❌ 途中で失敗するとすべてキャンセルされる点に注意

---

## 4. 条件付き非同期処理

```ts
if (shouldFetch) {
  await fetchData();
}

const data = isCached ? getFromCache() : await fetchFresh();
```

- ✅ 状態や条件に応じて非同期を選択
- ✅ 条件によって **同期/非同期が混在するパターン**はテスト観点で要注意

---

## 5. レース構造（先に返ってきたものを使う）

```ts
const fast = await Promise.race([fromAPI(), fromCache()]);
```

- ✅ 最も早いレスポンスを使いたい場合に有効
- ❌ **タイムアウト / エラーハンドリング**との組み合わせ設計が重要

---

## 6. タイムアウト付き非同期処理

```ts
function withTimeout(promise, ms) {
  const timeout = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), ms)
  );
  return Promise.race([promise, timeout]);
}
```

- ✅ ネットワークなど **不確実性の高い処理の安全弁**
- ✅ `AbortController` と組み合わせるとキャンセルも可能

---

## 設計判断フロー

```text
① この非同期は順序が必要か？ → 直列設計

② 複数処理は独立しているか？ → 並列設計 + Promise.all

③ 条件によって非同期が変化するか？ → 分岐を明示的に

④ 早く返ってきたものを採用すべきか？ → Promise.race構造

⑤ ネットワーク不安定 or 外部依存があるか？ → タイムアウト構造を導入
```

---

## よくあるミスと対策

### ❌ forEach に async を使って順番が崩れる

→ ✅ **for...of + await に置き換える**

---

### ❌ すべて並列にしてしまい、エラー原因が特定できない

→ ✅ **エラーハンドリングは `try-catch` or `Promise.allSettled` を活用**

---

### ❌ 条件で await するかしないかが混乱している

→ ✅ **同期・非同期どちらでも統一的に扱えるよう設計**

---

## 結語

非同期処理とは「awaitをつければ済む」ものではない。  
それは**“実行順、依存関係、例外、時間制約など、あらゆる変数を制御するための設計的選択の集合体”**である。

- 順序と独立性に応じて直列 / 並列を選び  
- 条件やレスポンスタイムに応じて制御構造を設計し  
- 例外・タイムアウト・キャンセルを含めて全体をデザインする

**JavaScriptにおける非同期処理設計とは、  
“不確実性を構造で飲み込み、意図を保証するための非同期の設計戦略”である。**
JavaScriptにおけるメモリリークとリソース解放戦略：イベント解除・参照解放・自動破棄設計の基礎と実践



## 概要

メモリリークとは「メモリが多く使われること」ではない。  
それは**“本来解放されるべき参照が保持されたままとなり、永続的にリソースを占有する構造的な不具合”**である。

JavaScriptのガベージコレクション（GC）は、**「参照が切れた」ことをトリガーに自動解放**を行う。  
つまり、**参照がどこかに残っていれば、永遠に解放されない**。  
この問題を予防・発見・解決するための構造と戦略を、本稿で解説する。

---

## 1. よくあるメモリリークの原因パターン

```text
① DOMを削除したのにリスナーが残っている  
② クロージャで不要な値をキャプチャしている  
③ setInterval が clear されない  
④ キャッシュ・Map/Setが参照を保持し続ける  
⑤ グローバル変数で参照が残る
```

---

## 2. イベントリスナーの解除

```ts
const el = document.getElementById('btn');
const handler = () => doSomething();

el.addEventListener('click', handler);

// ✅ 破棄時に解除
el.removeEventListener('click', handler);
```

- ✅ UIコンポーネントのライフサイクルに応じて **明示的な remove**
- ✅ **匿名関数のままでは remove できない**ので注意

---

## 3. setInterval / setTimeout の解放忘れ

```ts
const id = setInterval(() => {
  update();
}, 1000);

// ✅ コンポーネント破棄時に必ず clear
clearInterval(id);
```

- ✅ `setInterval` は **永続的にメモリを占有**しがち
- ✅ `setTimeout` も複数が蓄積しないよう注意

---

## 4. クロージャで外部値を不要に捕まえない

```ts
function createHandler() {
  const largeData = getHeavyData(); // 重いデータ

  return function handler() {
    // 実際には使っていないがクロージャでキャプチャされる
    console.log('clicked');
  };
}
```

- ❌ `largeData` は使っていないのに **参照が保持され続ける**
- ✅ クロージャ内で使わない変数は **持ち込まない設計**

---

## 5. Map / Set による参照保持と WeakMap の使い分け

```ts
const cache = new Map();
cache.set(domElement, someData); // domElementを永続保持してしまう

// ✅ WeakMap を使えば、GC対象になれば自動で解放される
const weakCache = new WeakMap();
weakCache.set(domElement, someData);
```

- ✅ オブジェクトをキーにする場合、**WeakMap/WeakSetを優先**

---

## 6. ライブラリ / フレームワークとの連携（React / Vue）

### React: useEffect内の副作用破棄

```ts
useEffect(() => {
  const id = setInterval(fetch, 1000);
  return () => clearInterval(id);
}, []);
```

### Vue: `onUnmounted`で後処理登録

```ts
onMounted(() => {
  const id = setInterval(...);
  onUnmounted(() => clearInterval(id));
});
```

- ✅ フック内で **「始めたら終わらせる」構造をセットで書く**

---

## 設計判断フロー

```text
① DOMやイベントは「解除処理」が設計されているか？

② クロージャでキャプチャしている値は本当に必要か？

③ setInterval / setTimeout はライフサイクルに紐づいているか？

④ キャッシュ構造に WeakMap を使えるか？

⑤ 状態の永続保持を意図していないのに参照が残っていないか？
```

---

## よくあるミスと対策

### ❌ イベントを add するだけで remove を忘れる

→ ✅ **イベント登録関数には remove を返す設計に**

---

### ❌ モーダルが開かれるたびに setInterval が増殖する

→ ✅ **初期化と破棄を1対1で設計**

---

### ❌ キャッシュ用の Map に DOM をキーにしてしまう

→ ✅ **自動解放されないので WeakMap に切り替え**

---

## 結語

メモリリークとは「放置してたら重くなった」ではない。  
それは**“構造的に不要な参照を保持し、解放の設計が破綻している状態”**である。

- イベント、タイマー、クロージャは開始と同時に終了設計を持ち  
- Map/Setの代替として Weak構造を選択し  
- フレームワークのライフサイクルと合わせて設計し  
- 参照の「終わり」を設計に含める

**JavaScriptにおけるメモリリーク対策とは、  
“見えない領域で破綻を起こさないために、構造そのものに「解放」を織り込む設計戦略”である。**
JavaScriptにおけるクロスブラウザ対応戦略：標準APIの差異吸収、フォールバック設計、ポリフィル運用の技術的設計

## 概要

クロスブラウザ対応とは「古いブラウザを使えるようにする」ことではない。  
それは**“あらゆる実行環境で、想定通りに動作し、体験の破綻を回避するために構造的に差異を吸収する設計”**である。

特定APIが使えない、CSSが反映されない、イベント挙動が異なる。  
このような**「仕様に忠実すぎる」JavaScript**は、**逆に動作保証ができないことが多い**。

---

## 1. “想定外環境”の種類を把握する

```text
- 古いAndroidブラウザ（WebViewベース）
- Safariの制限（input挙動・IntersectionObserver）
- Firefoxのセキュリティ制約
- iOS WebKit独自仕様
- 企業端末（IE11相当 or Edge Legacy）
```

- ✅ モダン環境だけを前提にしない
- ✅ 少数ユーザーでも「使えない」は UX破綻

---

## 2. 標準APIの利用前に feature detection（存在確認）を行う

```ts
if ('IntersectionObserver' in window) {
  new IntersectionObserver(callback).observe(el);
} else {
  // フォールバック処理
  window.addEventListener('scroll', fallbackCheck);
}
```

- ✅ `in` 演算子、`typeof`、`try-catch` で確認
- ✅ 存在しないならフォールバック or 機能無効化へ

---

## 3. ポリフィル vs フォールバックの選択基準

```text
- ポリフィル：動作そのものを「再現する」ライブラリ（例: core-js, smoothscroll-polyfill）
- フォールバック：機能を「簡易化 or 無効化」する（例: lazyload → 即時表示）
```

| 技術         | ポリフィル | フォールバック     |
|--------------|------------|--------------------|
| Promise      | 必須       | 再設計困難         |
| Fetch API    | ポリフィル可 | XMLHttpRequest等代替 |
| LazyLoad     | 任意       | loading属性削除で即読み込み |

---

## 4. UA判定ではなく “機能ベース” の検出に徹する

```ts
// ❌ NG: UAによる判定は壊れやすい
if (navigator.userAgent.includes('Safari')) {}

// ✅ OK: 機能存在確認による分岐
if ('scrollBehavior' in document.documentElement.style) {
  scrollTo({ top: 0, behavior: 'smooth' });
} else {
  window.scrollTo(0, 0);
}
```

- ✅ ユーザーエージェントは**偽装や変更で簡単に壊れる**

---

## 5. ビルド時に環境差異を吸収する（Babel + core-js）

```bash
npm install --save core-js
```

```js
// Babel設定
"presets": [
  ["@babel/preset-env", {
    "useBuiltIns": "usage",
    "corejs": 3
  }]
]
```

- ✅ 使用した機能に応じて**自動的にポリフィルを挿入**
- ✅ JSファイルサイズと保守性の最適化が可能

---

## 6. CSSとの連携：@supports で挙動制御

```css
@supports (backdrop-filter: blur(10px)) {
  .frosted {
    backdrop-filter: blur(10px);
  }
}

@supports not (backdrop-filter: blur(10px)) {
  .frosted {
    background: rgba(255, 255, 255, 0.7);
  }
}
```

- ✅ CSSも**モダンとレガシーの二層構造を想定**
- ✅ JavaScript側から `classList.toggle()` で上書き補正も可能

---

## 設計判断フロー

```text
① このAPIは本当に全ブラウザで使えるか？ → MDN / caniuse で確認

② フォールバック手段 or ポリフィルが存在するか？

③ Feature detection（存在確認）で安全に使っているか？

④ ビルド時にBabelやcore-jsで自動挿入できるか？

⑤ CSS含めて、非対応時の視覚的破綻が起きないか？
```

---

## よくあるミスと対策

### ❌ UAでSafariを判定し、ピンポイントバグを修正

→ ✅ **機能ベース判定で壊れにくいロジックに**

---

### ❌ モダンAPIだけで構成し、古いWebViewで真っ白になる

→ ✅ **最低限の動作にフォールバックする構造を設計**

---

### ❌ Promiseやasync/awaitを使ってるのにポリフィルを入れてない

→ ✅ **Babel + core-js で自動化し、破綻を防止**

---

## 結語

クロスブラウザ対応とは「対応表を見て個別処理すること」ではない。  
それは**“実行環境の差異を機能レベルで吸収し、どのブラウザでもユーザー体験を保証するための設計構造”**である。

- 標準APIの可否を明示的に確認し  
- 存在しない環境では代替手段で機能を担保し  
- ポリフィル + フォールバックを設計に組み込み  
- UI・JS・CSSすべてのレイヤーで環境差を吸収する

**JavaScriptにおけるクロスブラウザ戦略とは、  
“仕様と現実のギャップを設計的に埋めるための技術と構造の防衛線”である。**
JavaScriptにおけるイベントバブリング / キャプチャ設計：UI階層の伝播制御と意図的なイベント構造の戦略設計


## 概要

イベント伝播とは「イベントが上に伝わる仕組み」ではない。  
それは**“UI階層を設計し、意図したハンドリングポイントにのみイベントを到達させる構造的制御”**である。

DOMイベントには **キャプチャフェーズ（上から下へ）** と **バブリングフェーズ（下から上へ）** が存在する。  
この2つの流れを **設計としてコントロール** できなければ、  
**意図しないイベント処理 / グローバル誤反応 / UI整合性崩壊** を引き起こす。

---

## 1. イベント伝播の流れ（基本構造）

```text
| キャプチャフェーズ |   ↓   |
| ターゲットフェーズ |   •   |
| バブリングフェーズ |   ↑   |
```

- ✅ **addEventListener の第3引数 / options.capture: true** でキャプチャ対応  
- ✅ 通常はバブリング（下 → 上）でハンドラが発火

---

## 2. キャプチャ・バブリングの使い分け

```ts
// キャプチャフェーズ
element.addEventListener('click', handler, { capture: true });

// バブリング（デフォルト）
element.addEventListener('click', handler);
```

- ✅ **グローバルな UI 制御（例: モーダル閉じ）** → キャプチャで先手制御  
- ✅ **ローカルな操作（例: ボタン押下）** → バブリングで処理

---

## 3. stopPropagation / stopImmediatePropagation の意味と用途

```ts
element.addEventListener('click', (e) => {
  e.stopPropagation(); // 親への伝播を阻止
});
```

```ts
element.addEventListener('click', (e) => {
  e.stopImmediatePropagation(); // 同一要素上の他ハンドラも停止
});
```

- ✅ 明示的に伝播を止めることで **意図した箇所だけにイベントを集中**
- ❌ 無差別に stop すると他の処理を破壊する → **局所用途で慎重に**

---

## 4. UI階層設計におけるイベント伝播戦略

```text
- グローバル系: ドキュメントやルート → キャプチャで抑止  
- ローカル系: コンポーネント内部 → バブリングで分岐制御
- モーダル / ドロップダウン: 「外をクリックしたら閉じる」の設計
```

```ts
document.addEventListener('click', (e) => {
  if (!modal.contains(e.target)) closeModal();
}, true); // キャプチャフェーズ
```

- ✅ **UI閉じロジックや解除判定はキャプチャが強力**
- ✅ **「中で押したら閉じない」** → `stopPropagation` と組み合わせ

---

## 5. コンポーネント設計におけるイベント伝播設計

```ts
// Button.vue
<button @click.stop="submit">送信</button>

// Modal.vue
<div @click.self="close"> <!-- 外側クリックのみ反応 -->
  <div class="modal-inner">...</div>
</div>
```

- ✅ Vue/Reactでは `.stop`, `.self`, `.capture` 等の **構造的イベント修飾**が推奨
- ✅ **イベント構造はUIコンポーネントの責務**として扱う

---

## 6. イベントバブリングとパフォーマンス設計

```ts
document.addEventListener('click', handleAll); // NG: 無差別処理

// OK: イベントデリゲーション + セレクタフィルタ
container.addEventListener('click', (e) => {
  if (e.target.matches('.item')) handleItemClick(e.target);
});
```

- ✅ イベントはなるべく **親1点で受けるデリゲーション方式**を採用  
- ✅ セレクタベースで対象を限定し、**性能と構造を両立**

---

## 設計判断フロー

```text
① このイベントは「階層内」か「階層を超える」か？ → バブリング / キャプチャ設計

② stopPropagation は本当に必要か？ → 他UIへの影響を検討

③ イベント対象が複数あるか？ → デリゲーションで構造化

④ UIが「クリックされるべき範囲」を持っているか？ → .self や contains() の活用

⑤ イベントハンドラの設置位置が、構造的に正しいか？
```

---

## よくあるミスと対策

### ❌ モーダル内クリックで外部イベントが発火して閉じてしまう

→ ✅ `.stopPropagation()` または `.self` + キャプチャ設計で制御

---

### ❌ 全体イベントでクリックが過剰検知される

→ ✅ **セレクタフィルタ or contains() で正確な条件分岐**

---

### ❌ イベントが動作する理由がコード上で分からない

→ ✅ **キャプチャ or バブリングか明示し、コメントで意図を記述**

---

## 結語

イベント伝播とは「ブラウザの仕様」ではない。  
それは**“UI階層を正確に意識し、構造的に制御し、意図した反応だけを保証する設計の仕組み”**である。

- キャプチャとバブリングを明確に使い分け  
- stopPropagation は責任を持って限定的に使用し  
- UIの構造と意図に沿ってイベント制御を設計する

**JavaScriptにおけるイベント伝播設計とは、  
“意図を持った反応だけを許す、階層的インタラクションの設計戦略”である。**
JavaScriptにおける状態遷移設計：状態モデル・ステートマシン・UIの状態爆発を防ぐ構造的制御


## 概要

状態管理とは「変数に値を持たせること」ではない。  
それは**“状態の意味・遷移の可能性・UIの整合性を制御するための構造的制約”**である。

状態が「自由すぎる」ことで、**「ローディング中にボタンが押せる」「エラーなのに結果が表示されている」「完了後に再度送信される」**といった **「状態爆発」** が発生する。

この問題を解決するには、状態を **列挙・制御・可視化可能な構造**として設計することが重要である。

---

## 1. 状態遷移の定義と「状態爆発」の理解

```ts
// NG: 多値フラグによる組み合わせ爆発
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [completed, setCompleted] = useState(false);
```

- ❌ フラグの組み合わせが無限に広がり、**UIとの整合性が崩壊**

---

## 2. 列挙型による状態の一元管理

```ts
type FormState = 'idle' | 'loading' | 'error' | 'success';

const [state, setState] = useState<FormState>('idle');
```

- ✅ 状態は「意味のある列挙値」で持つ  
- ✅ フロー上の**状態遷移図に従った移行のみを許可**

---

## 3. 遷移を制御するステートマシン的構造

```ts
const transition = {
  idle: ['loading'],
  loading: ['success', 'error'],
  error: ['loading'],
  success: [],
};

function canTransition(from: FormState, to: FormState) {
  return transition[from].includes(to);
}
```

- ✅ 不正な遷移（例: `success → loading`）を防ぐ
- ✅ 状態と遷移を**構造として宣言**

---

## 4. UIは状態ごとのレンダリング責務を分離

```tsx
switch (state) {
  case 'idle':
    return <SubmitButton />;
  case 'loading':
    return <LoadingIndicator />;
  case 'error':
    return <ErrorBanner onRetry={submitAgain} />;
  case 'success':
    return <ThankYouMessage />;
}
```

- ✅ 各状態ごとに **UI責務を切り分ける**  
- ✅ `if-else`や条件フラグではなく、**状態 = UI** の構造を明示

---

## 5. 状態モデルの単位とスコープ設計

```text
- ページ単位（例: 読み込み状態, 完了状態）
- セクション単位（例: 投稿フォーム, 検索結果）
- エンティティ単位（例: 各ユーザーのローディング / フォロー状態）
```

- ✅ 状態モデルはスコープごとに設計  
- ✅ 複数コンポーネントに影響を与えるものは store管理やstate machine導入

---

## 6. ステートマシンライブラリの導入（例: XState）

```ts
import { createMachine } from 'xstate';

const formMachine = createMachine({
  id: 'form',
  initial: 'idle',
  states: {
    idle: { on: { SUBMIT: 'loading' } },
    loading: {
      on: {
        SUCCESS: 'success',
        FAILURE: 'error',
      },
    },
    error: { on: { RETRY: 'loading' } },
    success: {},
  },
});
```

- ✅ 宣言的に状態と遷移を定義可能  
- ✅ **実行不能な状態遷移が構造的にブロックされる**

---

## 設計判断フロー

```text
① 状態は列挙型で表現されているか？ → 多フラグの爆発を防げているか？

② 状態間の遷移が意図的に制御されているか？

③ UIの各部品は状態と責務が1対1で対応しているか？

④ 状態が変更されたとき、他UIに破壊的影響が出ない設計か？

⑤ 状態の定義と遷移ルールがコード上で明示されているか？
```

---

## よくあるミスと対策

### ❌ 複数のフラグで状態を表現し、矛盾したUIになる

→ ✅ **状態を列挙型で一本化し、単一の責務を持たせる**

---

### ❌ 状態遷移が暗黙的で、何が起きているかわからない

→ ✅ **ステートマシン or トランジション定義で明示化**

---

### ❌ UIで「完了後に再送信できてしまう」などの不整合が発生

→ ✅ **遷移元・遷移先の制限を構造的に設計**

---

## 結語

状態管理とは「状態を持つこと」ではない。  
それは**“変化を制御し、流れを制限し、UIと機能の整合性を守るための設計戦略”**である。

- 状態を列挙型で管理し  
- 遷移を定義し、構造的に制約を与え  
- UIと状態を1対1で対応させ  
- ステートマシンを使い、爆発する組み合わせを制御する

**JavaScriptにおける状態遷移設計とは、  
“UIとロジックの整合性を保証し、複雑性に耐えるアプリの設計基盤”である。**
JavaScriptにおけるエラーハンドリング戦略：try-catchを超えた責務分離と構造的エラーフロー設計


## 概要

エラーハンドリングとは「失敗したときに止めること」ではない。  
それは**“失敗の型と責任を明確にし、どこで何を補足し、どう伝達し、どう復旧するかを構造的に定義する設計”**である。

JavaScriptは `try-catch` に頼るだけではなく、**返却型（Result）・throwable型・UI伝播型**など、多層的なエラーフローが可能。  
正しいエラーハンドリングは、**層ごとの責務を守り、ユーザーにも開発者にも安心を提供する**。

---

## 1. エラーの責務分離：誰がどこで処理するべきか？

```text
| 層           | 責務                                 |
|--------------|--------------------------------------|
| API/ドメイン | エラーを定義し、throwまたは返却     |
| ユースケース | エラーを分類し、状態やUIに変換       |
| UI層         | 表示制御、再試行、通知               |
```

---

## 2. 明示的なエラー構造の設計（Result型）

```ts
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };

async function fetchUser(id: string): Promise<Result<User, 'NotFound' | 'NetworkError'>> {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) return { ok: false, error: 'NotFound' };
    return { ok: true, value: await res.json() };
  } catch {
    return { ok: false, error: 'NetworkError' };
  }
}
```

- ✅ `throw` しない構造 → **UIで確実に分岐処理可能**
- ✅ `ok: false` は構造的エラー → try-catch不要

---

## 3. 例外型（throw）と返却型（Result）の使い分け

```text
- Result型 → UI/業務処理など **期待される失敗**
- throw型 → 不正入力 / 想定外バグ / 破壊を防ぐ例外
```

```ts
function parseJson(input: string): object {
  try {
    return JSON.parse(input);
  } catch {
    throw new Error('Invalid JSON');
  }
}
```

- ✅ 「例外 = 想定外」「Result = 想定済み」という分類設計

---

## 4. 非同期エラーとキャンセルの分離制御

```ts
try {
  const res = await fetch('/api', { signal: controller.signal });
} catch (e) {
  if (e.name === 'AbortError') return;
  notify('ネットワークエラーが発生しました');
}
```

- ✅ **キャンセル（Abort）とエラーを分離**
- ✅ UIや再試行に必要な情報として整理

---

## 5. エラー型の定義と分類戦略

```ts
type LoginError =
  | { type: 'InvalidCredentials' }
  | { type: 'TooManyAttempts'; retryAfter: number }
  | { type: 'ServerError'; message: string };
```

- ✅ Union型で「エラーの種類」を明示的に管理  
- ✅ UIは type で分岐 → 表示 / 再試行 / リダイレクト など制御

---

## 6. UI層でのエラーUI / 再試行 / アラート設計

```ts
if (!result.ok) {
  switch (result.error.type) {
    case 'InvalidCredentials':
      showError('パスワードが間違っています');
      break;
    case 'TooManyAttempts':
      showRetry(result.error.retryAfter);
      break;
    default:
      showError('不明なエラーが発生しました');
  }
}
```

- ✅ UI側の責務は「通知」「選択肢提示」「体験制御」

---

## 設計判断フロー

```text
① そのエラーは「想定済みの失敗」か？ → Result型で扱う

② 例外は「不正入力 / バグ / 想定外」か？ → throwで構造を破壊

③ 非同期キャンセルと失敗が同一扱いになっていないか？

④ UIは「なぜ失敗したか」を受け取れる構造になっているか？

⑤ 再試行可能性 / ユーザー通知 / UI復帰が実装できる構造か？
```

---

## よくあるミスと対策

### ❌ try-catch で全部握って何が起きたかわからない

→ ✅ **想定済みはResult型、例外は分類して構造管理**

---

### ❌ UIで「エラー」としか表示されない

→ ✅ **Union型で分類し、UIに伝える構造に**

---

### ❌ API失敗で画面が白くなる or 無反応になる

→ ✅ **失敗時の状態反映・通知・再試行UIを用意**

---

## 結語

エラーハンドリングとは「止める」ことではない。  
それは**“失敗を分類し、意味を構造に落とし、層ごとに責務を分けて、安心して壊れるための戦略”**である。

- Result型とthrow型を設計的に使い分け  
- UIと非同期の整合性を保ち  
- 状態に失敗を織り込み、UXに転化する

**JavaScriptにおけるエラーハンドリング戦略とは、  
“壊れても制御可能で、意図を持って回復可能な、構造設計の最終防衛線”である。**
JavaScriptにおけるローディング設計戦略：状態管理と非同期制御の整合性、UIへの明示的反映、UXとしての体験設計


## 概要

ローディングとは「くるくる回すUI」ではない。  
それは**“ユーザーが何を待っているのかを可視化し、操作の意味を伝え、非同期とUIの整合性を保証する制御設計”**である。

非同期処理においてローディングの設計が曖昧だと、**多重リクエスト・無反応・誤認識**などが発生し、UXを損なう原因になる。  
正しいローディング設計は、**非同期制御 + 状態管理 + UI制御の接点として構築される**必要がある。

---

## 1. ローディング設計の3原則

```text
① 状態管理：何に対して待機しているかを識別可能に  
② UI反映：表示されているUIに対して明示的に可視化  
③ 制御連携：非同期の開始 / 成功 / 失敗 / 中断 との整合性
```

---

## 2. 状態単位のローディング制御

```ts
const [isLoading, setLoading] = useState(false);

async function handleSubmit() {
  setLoading(true);
  try {
    await api.submitForm(form);
  } finally {
    setLoading(false);
  }
}
```

- ✅ 非同期と同期してローディングが開始 / 終了する
- ✅ try-finally を徹底し、**失敗やキャンセルでも確実に終了**

---

## 3. コンテキストごとの粒度設計

```text
- ボタン単位：ボタン操作に限定したローディング
- セクション単位：リスト・フォームなど局所的待機
- ページ全体：ページ切替・初期取得など全体反映
```

```ts
const loadingState = reactive({
  createUser: false,
  fetchList: false,
});
```

- ✅ **ローディングは一つではなく、意味単位に分離すべき**

---

## 4. UI操作制御との連携（ボタン制御）

```ts
<button disabled={isLoading}>
  {isLoading ? '送信中...' : '送信'}
</button>
```

- ✅ **待機中の多重クリック防止**  
- ✅ ボタンやUI部品の状態変化を通じて**体験としての一貫性**を担保

---

## 5. キャンセルとの整合性（AbortController 連携）

```ts
const controller = new AbortController();

setLoading(true);
try {
  await fetch('/api', { signal: controller.signal });
} catch (e) {
  if (e.name === 'AbortError') console.log('キャンセル');
} finally {
  setLoading(false);
}
```

- ✅ ローディングは**キャンセル時も必ず終了**
- ✅ **中断されたUI**を表示するか、スルーするかを設計する

---

## 6. UXとしての“待ち方”を設計する

```text
- ページ初回 → スケルトン / プレースホルダ表示
- 操作中 → ボタン/フォームUIの変化
- 非同期長時間 → ステップバー・残り時間表示
```

- ✅ 視覚的に待っていることを伝えるだけでなく  
- ✅ **何を待っているか**を明確に設計することがUXに直結

---

## 設計判断フロー

```text
① どの処理に対してローディングが発生するか？ → 意味単位で定義されているか？

② UIに明示的にローディング状態が反映されているか？

③ 非同期が失敗・中断した場合もローディング終了しているか？

④ UIコンポーネントの状態制御とローディングが連動しているか？

⑤ “なぜ待っているのか”がユーザーに伝わる設計になっているか？
```

---

## よくあるミスと対策

### ❌ fetch の外に setLoading(false) を置いて終了しないことがある

→ ✅ **try-finally で常にローディング終了を保証**

---

### ❌ 1つの isLoading に全ての処理を集約して状態が破綻

→ ✅ **機能単位にローディング状態を分離管理**

---

### ❌ ローディングは表示されるが、ユーザーは何が起きているか分からない

→ ✅ **“何を待っているか”を文言と構造で明示**

---

## 結語

ローディングとは「読み込み中を表示すること」ではない。  
それは**“処理の整合性を保証し、ユーザーに待機を伝え、誤操作を防ぎ、安心を設計するUIと非同期の接点”**である。

- 非同期と同期した明示的な状態管理を行い  
- UIに応じて粒度ごとにローディングを分離し  
- 状態変化・キャンセル・失敗にも確実に対応し  
- UXとして「待ち方」までを含めて設計する

**JavaScriptにおけるローディング設計戦略とは、  
“非同期の不確実性を制御し、ユーザーに安心と一貫性を届けるためのUX構造”である。**
JavaScriptにおける非同期キャンセル設計：AbortController、競合制御、UIと連動する中断構造の設計


## 概要

非同期キャンセルとは「中断できるようにする」ことではない。  
それは**“UI・ユーザー行動・アプリ状態に連動して、不要な非同期処理を明確に終了させ、意図通りの動作を保証するための制御構造”**である。

ユーザーが入力を変えた瞬間、ページを遷移した瞬間、送信ボタンを押した直後など、**キャンセルされるべき非同期は無数に存在する**。  
JavaScriptでは `AbortController` を用いることで、**構造的なキャンセル可能設計**が可能になる。

---

## 1. AbortController の基本構造

```ts
const controller = new AbortController();
const signal = controller.signal;

fetch('/api/data', { signal })
  .then((res) => res.json())
  .catch((err) => {
    if (err.name === 'AbortError') {
      console.log('fetch aborted');
    }
  });

controller.abort(); // 中断
```

- ✅ `signal` を fetch に渡すことでキャンセル可能に  
- ✅ 中断時は `AbortError` が投げられる

---

## 2. UIと連動するキャンセル設計（例：検索フォーム）

```ts
let controller: AbortController;

async function fetchSearch(query: string) {
  if (controller) controller.abort(); // 既存リクエスト中断
  controller = new AbortController();

  try {
    const res = await fetch(`/api/search?q=${query}`, {
      signal: controller.signal,
    });
    const data = await res.json();
    showResults(data);
  } catch (err) {
    if (err.name === 'AbortError') return;
    console.error('検索失敗:', err);
  }
}
```

- ✅ 入力変化ごとに前回リクエストをキャンセル  
- ✅ UIの連動によって「今必要なものだけ」を残す構造に

---

## 3. コンポーネントライフサイクルと連動（React/Vue等）

```ts
useEffect(() => {
  const controller = new AbortController();

  fetch('/api/data', { signal: controller.signal });

  return () => controller.abort(); // アンマウント時に中断
}, []);
```

- ✅ コンポーネントが破棄されても**fetchが動き続けることを防止**
- ✅ 副作用の生存期間を明示的に制御する設計が重要

---

## 4. 複数非同期のキャンセル制御（競合防止）

```ts
const createCancelableTask = () => {
  let controller = new AbortController();
  return {
    run: (url: string) => {
      controller.abort();
      controller = new AbortController();
      return fetch(url, { signal: controller.signal });
    },
  };
};

const task = createCancelableTask();
task.run('/api/a');
task.run('/api/b'); // 前回はキャンセルされる
```

- ✅ 複数リクエストが**最後の1つ以外不要な場合**に有効

---

## 5. 状態とUIに「中断」を反映する設計

```ts
const [loading, setLoading] = useState(false);
const [aborted, setAborted] = useState(false);

const fetchData = async () => {
  const controller = new AbortController();
  setLoading(true);
  try {
    const res = await fetch('/api/data', { signal: controller.signal });
    await res.json();
    setAborted(false);
  } catch (e) {
    if (e.name === 'AbortError') {
      setAborted(true);
    }
  } finally {
    setLoading(false);
  }
};
```

- ✅ **UI状態として「中断された」ことも反映**すべき
- ✅ ローディングだけではなく「結果が無効化された」ことをUIで扱う

---

## 設計判断フロー

```text
① 非同期処理が「ユーザー操作によって不要になる可能性」があるか？

② 現在の非同期処理が「今のUI」に関連しているか？ → スコープの明示

③ キャンセル時に状態破壊やエラー発火が起きていないか？

④ 複数非同期を扱うとき、競合や古いレスポンス処理が混入していないか？

⑤ UIが「キャンセルされた状態」を反映できる構造になっているか？
```

---

## よくあるミスと対策

### ❌ キャンセルしない fetch が UI 破棄後に状態を更新

→ ✅ `AbortController` と `useEffect` の return で中断

---

### ❌ 前回の検索が遅延して結果が上書きされる

→ ✅ **キャンセル可能設計 or タスク番号で一意化**

---

### ❌ キャンセルされたリクエストもローディング中扱いになる

→ ✅ **「中断された」ことをUI状態で反映**

---

## 結語

非同期のキャンセルとは「止めること」ではない。  
それは**“不要な処理を明確に切り捨て、今必要なものだけを残す、ユーザー体験と整合性のための制御構造”**である。

- AbortControllerで非同期を構造化し  
- UIやライフサイクルと連動して中断制御し  
- 今表示すべきデータ・状態を明示的に守る

**JavaScriptにおける非同期キャンセル設計とは、  
“中断を制御し、整合性を保証することでUXと安全性を両立する戦略”である。**
JavaScriptにおけるロジック再利用戦略：Hooks/Composablesの抽出、依存最小化、横断的関心事の構造化

## 概要

ロジックの再利用とは「共通関数にすること」ではない。  
それは**“横断的に使われる処理を、意味と責務で切り出し、依存から切り離して拡張可能にする戦略的設計”**である。

Vueの Composables、Reactの Custom Hooks は、ただの「便利関数」ではなく、**UI層とロジック層を分離し、アプリを構造的に再利用可能にするための設計装置**である。

---

## 1. Composables / Hooks の定義と責務

```ts
// React
function useUserLoader(id) {
  const [user, setUser] = useState(null);
  useEffect(() => {
    fetch(`/api/users/${id}`).then(res => res.json()).then(setUser);
  }, [id]);
  return user;
}

// Vue
export function useUserLoader(id) {
  const user = ref(null);
  onMounted(async () => {
    user.value = await api.fetchUser(id);
  });
  return { user };
}
```

- ✅ 外部から **値や関数を受け取り、副作用や状態を内部で完結**
- ✅ UIに依存せず、**意味単位で再利用可能**

---

## 2. 「再利用される」ではなく「再利用可能である」が設計基準

```text
❌ UIと密結合 → 他のコンポーネントで使えない
✅ ロジックを抽象化 → UIに依存しないComposableに
```

```ts
export function useToggle(defaultValue = false) {
  const state = ref(defaultValue);
  const toggle = () => (state.value = !state.value);
  return { state, toggle };
}
```

---

## 3. 横断的関心事（Cross-cutting Concerns）の分離設計

```text
- ローディング制御 → useLoading
- エラーハンドリング → useError
- APIフェッチ汎用化 → useFetch
- モーダル開閉 → useModal
```

- ✅ どの画面にも関係する処理は **横断ユースケースとして切り出す**

---

## 4. UIとの境界を明確に保つ

```text
❌ useXxx の中で DOM に直接アクセス  
✅ UIイベントは親で受け取り、Composableには状態とロジックのみを閉じ込める
```

- ✅ Composables / Hooks は **ロジックレイヤーに留める**
- ✅ 表示・入力との直接操作は UI側に残す

---

## 5. Composables / Hooks の構成粒度と依存戦略

```text
- useUser → 小さすぎて曖昧  
- useFetchUser → 責務明確
- usePaginatedUserList → 意味単位で再利用可能
```

- ✅ データ・副作用・UI操作が混ざらないよう設計  
- ✅ API依存・状態依存は引数注入にすると柔軟性が高まる

---

## 6. テスト可能な構造を保つ（Pure & Injected）

```ts
export function useUserFetcher(apiClient) {
  const user = ref(null);
  const fetch = async (id) => {
    user.value = await apiClient.fetchUser(id);
  };
  return { user, fetch };
}
```

- ✅ 外部依存（API）を注入可能に → **テスト時はモックに置き換え**
- ✅ Composables / Hooks を **プレーンなロジックレイヤーとして扱う**

---

## 設計判断フロー

```text
① この処理は他でも使えるか？ → 目的単位でComposableに切り出す

② UIに依存していないか？ → DOM / props に密結合していないか確認

③ 状態管理・副作用・UI操作が1ファイルに混在していないか？

④ 外部依存を内部に閉じ込めていないか？ → 引数注入で柔軟化

⑤ Composable内の構造がテスト可能か？ → 外部に出す責務を定義
```

---

## よくあるミスと対策

### ❌ Composable の中でUI状態まで握ってしまう

→ ✅ **状態はロジックに限定し、UI制御は外に出す**

---

### ❌ 毎回似た処理を書いてコピペ地獄に

→ ✅ **useFetch系や useToggle系など汎用Composableを整備**

---

### ❌ Composableが肥大化して読めなくなる

→ ✅ **1関数1責務 + 機能単位でファイル分離**

---

## 結語

ロジックの再利用とは「まとめること」ではない。  
それは**“意味で分け、責務で切り出し、構造として再利用可能にする設計行為”**である。

- 状態・副作用をComposableに閉じ込め  
- UIとロジックを明確に分離し  
- 外部依存を注入構造で制御し  
- 横断的なロジックを柔軟に再利用する

**JavaScriptにおけるロジック再利用戦略とは、  
“破綻せず拡張可能な構造を作り出す、責任と柔軟性のデザイン”である。**
JavaScriptにおけるスタイルガイド設計：チーム横断の可読性と一貫性を支える記述原則と自動化


## 概要

スタイルガイドとは「キレイに揃える」ためではない。  
それは**“コードの設計意図を伝達可能にし、変更耐性と開発効率を支える、チームの言語設計”**である。

JavaScriptの柔軟性は強力だが、チームやプロジェクトによって書き方がバラけると、  
**レビュー品質・保守速度・設計の統一感が失われていく**。  
本稿では、**構文・命名・レイアウト・責務の記述指針と、それを守らせる自動化戦略**を解説する。

---

## 1. スタイルガイド設計の基本5原則

```text
① 可読性：読む人間が最速で理解できるか
② 一貫性：誰が書いても同じ構造になるか
③ 拡張性：変更・追加が破綻しないか
④ 明示性：意図と責務がコードに現れているか
⑤ 自動化：人間判断に依存せず適用できるか
```

---

## 2. 命名規約：構造と責務を反映したルール

### ✅ 基本形

```ts
camelCase       → 関数・変数  
PascalCase      → クラス・React/Vueコンポーネント  
UPPER_SNAKE_CASE → 定数  
kebab-case      → ファイル名（Vue, React, etc）
```

- ✅ 接頭辞で関数の意図を明示：`get`, `set`, `fetch`, `is`, `should`, etc
- ✅ UIコンポーネントは構造名 + 意図：`UserCard`, `SubmitButton`

---

## 3. 構文と構造：最小構造で最大の明示性を

```ts
// ✅ OK
const getUserName = (user: User): string => user.name;

// ❌ NG: 無意味なラップ
function getName(a) { return a.name; }
```

- ✅ 短くても**意味が明示されているかが重要**
- ✅ `return`の省略 / ブロックの簡素化など **読みやすさ優先**

---

## 4. ファイル・ディレクトリ構成ルール

```text
- usecases/      → アプリの振る舞い（動詞ベース）
- components/    → UI部品（名詞ベース）
- stores/        → 状態管理（ドメインごと）
- utils/         → 汎用関数（プレフィックス + 意図）
- types/         → 型定義（ドメイン・用途別に分割）
```

- ✅ 命名規則と構造がリンクしていると保守がスムーズ

---

## 5. コメントと関数責務のガイドライン

```ts
// ✅ 意図を説明
// APIレスポンスをドメイン型に変換する
function parseUserResponse(res: ApiUser): User { ... }

// ❌ 処理の繰り返し説明（無意味）
/* 変数aを定義する */ const a = 10;
```

- ✅ コメントは「何を」より「なぜ」を書く
- ✅ 関数は1責務 → コメント不要なレベルに意味を持たせる

---

## 6. 自動化：ESLint / Prettier / husky / CI連携

### ESLint（構文 + 構造チェック）

```bash
# install
npm install eslint --save-dev

# config
.eslintrc.json
```

### Prettier（フォーマット統一）

```bash
npm install prettier --save-dev
.prettierrc
```

### Husky + lint-staged（コミット前に自動適用）

```bash
npx husky install
```

### GitHub Actions / CIで強制適用

```yaml
# .github/workflows/lint.yml
- run: npm run lint
- run: npm run format:check
```

---

## 設計判断フロー

```text
① 誰が読んでも同じように理解できる命名か？

② ファイルとディレクトリ構造が意味に基づいて構成されているか？

③ コメントは意図を伝えているか？ → 処理内容の繰り返しで終わっていないか？

④ 記述の構文が一貫しているか？ → ESLint / Prettierで強制

⑤ 書いたスタイルがコミット・CIレベルで担保されているか？
```

---

## よくあるミスと対策

### ❌ プロジェクト内で複数の書き方が混在（`function` / `arrow` / `class` etc）

→ ✅ **スタイルガイドで統一し、ESLintで強制**

---

### ❌ 命名が個人依存で属人化

→ ✅ **命名規則と意味設計をドキュメント化し、レビュー基準にする**

---

### ❌ レビューで毎回スタイル修正に時間がかかる

→ ✅ **Prettier / lint-staged で自動整形 & チェックを事前実行**

---

## 結語

スタイルガイドとは「美しさ」ではない。  
それは**“チームの設計意図を統一し、品質を維持し、設計を可視化するための記述構造”**である。

- 命名に意味と構造を込め  
- ファイル構造に意図を反映し  
- スタイルと構文を自動で統一し  
- コメントと構造で設計を語る

**JavaScriptにおけるスタイルガイド設計とは、  
“コードベースを言語化し、チーム全体で意図を共有するための文化的戦略”である。**
JavaScriptにおけるテスト戦略：ユニット・統合・E2Eの設計分離、依存の隔離とテストしやすい構造設計


## 概要

テストとは「動くかの確認」ではない。  
それは**“コードが意図通りであることを検証し、将来の変更で壊れないことを保証する構造的契約”**である。

特にJavaScriptのように動的で柔軟な言語では、**設計上の一貫性と構造の保証がテストによって初めて成立する**。

本稿では、**ユニット / 統合 / E2E テストの責務分離、依存隔離の技法、構造をテストしやすく保つための設計戦略**を解説する。

---

## 1. テストの3レイヤーを明確に分ける

| レイヤー    | 目的                          | テスト対象            |
|-------------|-------------------------------|------------------------|
| ユニット    | 最小単位の動作検証             | 純粋関数 / 小ロジック |
| 統合        | 複数モジュール間の整合性確認   | API + 状態 + ロジック |
| E2E         | ユーザー視点での最終結果検証   | ブラウザ + 操作       |

- ✅ 各レイヤーで責務を明確に → **役割を混在させない設計が必要**

---

## 2. テストしやすい構造の原則

```ts
// NG: 副作用を含む
function fetchUserAndSet() {
  const res = await fetch('/api');
  store.set(res.data);
}

// OK: 分離された構造
function parseUser(raw: any): User {
  return { id: raw.id, name: raw.name };
}
```

- ✅ テストしたい処理は**副作用から分離**
- ✅ 状態更新・I/O は **ユースケースやラッパー関数に限定**

---

## 3. 依存を注入可能に設計する（DI構造）

```ts
const fetchUserUseCase = (api: UserApi) => async (id: string) => {
  const user = await api.get(id);
  return user.name;
};
```

- ✅ テストでは `api` をモックに差し替えるだけ → **テスト容易性の担保**
- ✅ 本番では `realApi` を注入 → **切り替え設計が柔軟**

---

## 4. テスト対象を「構造単位」で分離する

```text
❌ 1つの関数でデータ取得 → 変換 → 状態更新 → UI表示まで全て実行  
✅ データ取得 → パース → 状態更新 を分割し、各関数をテスト可能に
```

```ts
// e.g.
function transformUser(data: ApiResponse): User { ... }
```

- ✅ 関数粒度の適切な分割により、**各関数をユニットテスト可能に**

---

## 5. テスト構造のディレクトリ戦略

```text
src/
├─ usecases/
│   └─ loginUser.ts
├─ __tests__/
│   └─ usecases/
│       └─ loginUser.test.ts
```

- ✅ ファイル単位でペアにすることで **変更とテストの関係を明示**
- ✅ コンポーネントごと or ユースケースごとに粒度を合わせる

---

## 6. ユースケース単位でテストを書く意義

```ts
// test: loginUser
it('ログイン成功時にセッションが保存される', async () => {
  const deps = { authApi: mockApi, sessionStore: memoryStore };
  const result = await loginUser(mockInput, deps);

  expect(result.ok).toBe(true);
  expect(memoryStore.set).toHaveBeenCalledWith(expect.anything());
});
```

- ✅ 「成功パス」+「失敗パス」+「例外パス」を明示的に網羅  
- ✅ UIやAPIが変わっても **ユースケースの設計と保証は維持できる**

---

## 設計判断フロー

```text
① この処理は分離できるか？ → 副作用からピュアな関数に切り出す

② 依存は注入可能になっているか？ → モックを差し替えられるか？

③ ユースケース単位で振る舞いをテストできているか？

④ テストレイヤーが混在していないか？ → ユニット / 統合 / E2E を明確に

⑤ 結果の検証だけでなく、状態変化や呼び出しも追えているか？
```

---

## よくあるミスと対策

### ❌ UIコンポーネント内で fetch → set → render 全部を直接書く

→ ✅ **ユースケースにロジックを切り出し、テスト対象を構造的に抽出**

---

### ❌ モック注入ができず、テストで毎回APIを叩いてしまう

→ ✅ **依存注入（DI）で柔軟に差し替え可能な設計へ**

---

### ❌ 1テストで全体を検証しようとしてE2Eが巨大化

→ ✅ **単体テスト / 統合テスト / E2E を明確に分離し、役割を限定**

---

## 結語

テストとは「動作確認」ではない。  
それは**“構造の設計を検証し、変更に耐える保証を作るための安全戦略”**である。

- 責務ごとにテストレイヤーを分離し  
- 副作用を避けて構造を分割し  
- 依存注入でテスト性を確保し  
- ユースケース単位でアプリの動作を保証する

**JavaScriptにおけるテスト戦略とは、  
“コードの信頼性と未来への自由を両立するための構造的設計”である。**
#0091（2025/04/02）NewSQL

## NewSQLとは？

**NewSQL（ニューエスキューエル）** は、従来のリレーショナルデータベース（RDBMS）の特徴である厳密なトランザクション整合性（ACID特性）を保ちながらも、NoSQLデータベースが持つ高いスケーラビリティや分散処理能力を取り入れた新世代のデータベースシステムです。

---

### NewSQLの登場背景

従来のリレーショナルデータベース（Oracle、MySQL、PostgreSQLなど）は、ACID特性を厳密に実現しますが、大規模なシステムにおいてスケールアウト（水平分散）が難しいという課題を抱えていました。一方、NoSQLデータベースはスケールアウトが容易で高性能な処理が可能ですが、多くの場合ACID特性の一部を犠牲にしています。

NewSQLは、こうしたRDBMSとNoSQLの利点を融合させ、両者の課題を克服することを目的に開発されました。

---

### NewSQLの主な特徴

- **ACID特性の維持**
  - トランザクションの原子性、一貫性、独立性、永続性を厳密に保証。

- **高いスケーラビリティ**
  - クラスタ環境での水平分散を前提とし、大規模トランザクションを効率的に処理。

- **SQLインターフェースの利用**
  - 標準的なSQLをサポートしているため、既存のアプリケーションとの親和性が高い。

- **高性能なトランザクション処理**
  - インメモリ技術や効率的な分散トランザクション制御により、高いスループットを実現。

---

### 代表的なNewSQLデータベース

- **CockroachDB**
  - Google Spannerにインスパイアされた分散型のオープンソースデータベース。マルチリージョンでの一貫性を維持。

- **Google Cloud Spanner**
  - 世界規模で分散処理を実現し、グローバルなACID整合性を保証する。

- **Amazon Aurora**
  - AWSが提供するクラウド型データベース。MySQL・PostgreSQL互換の高スケーラビリティと高性能を提供。

- **TiDB**
  - オープンソースの分散型データベースで、MySQLとの互換性を持ち、高度なスケールアウトが可能。

---

### NewSQLが適しているシナリオ

- 銀行・金融取引のように高い整合性が必須となる大規模トランザクション処理。
- グローバル展開を行うサービスで、地域を超えて一貫性を保証したいケース。
- 急激な成長により即座にスケールアウトが求められるオンラインサービス。

---

### RDBMS、NoSQL、NewSQLの比較表

| 特性・項目                 | RDBMS（従来型）   | NoSQLデータベース | NewSQLデータベース  |
|----------------------------|-------------------|-------------------|---------------------|
| ACID特性                   | 完全サポート      | 部分的または緩和  | 完全サポート        |
| 水平スケーラビリティ       | 限定的            | 高い              | 高い                |
| SQL標準サポート            | 完全              | 限定的またはなし  | 完全または高度な互換性 |
| トランザクション処理性能   | 中程度～高        | 高い（ただしACIDは緩和）| 非常に高い（ACID維持） |

---

### まとめ

NewSQLは、高い一貫性を求める大規模トランザクション処理とスケールアウトの両立を可能にし、次世代の分散型データベースとして、金融やグローバルなWebサービスを中心に注目されています。今後のシステム設計やデータベース選定において重要な選択肢となっています。
JavaScriptにおける命名戦略：構造を語る名前、意図を伝える接頭辞、責務を示す一貫性のある命名パターン

## 概要

命名とは「呼び方」ではない。  
それは**“構造の意図・責務の区別・ロジックの役割を伝えるための最小の設計記述”**である。

悪い命名は読み手の理解を妨げ、保守を困難にし、設計の意図を曖昧にする。  
良い命名は構造を明示し、責務を区別し、コードそのものがドキュメントとして機能する。

本稿では、**命名の型、粒度、接頭辞の戦略、構造的命名の一貫性設計**を解説する。

---

## 1. 動詞 vs 名詞：関数とデータの基本分離

```ts
const user = { id: 'u01', name: 'Toto' };     // 名詞：データ
function fetchUser() { ... }                 // 動詞：操作
```

- ✅ データ → 名詞、操作 → 動詞 を厳密に使い分ける  
- ✅ `getUser` / `setUser` / `updateUser` など **動詞は行為を明示する**

---

## 2. 接頭辞で責務を明示する（プレフィックス戦略）

```ts
- get → 値を取得する（同期）
- fetch → 値を取得する（非同期）
- create → 新しいエンティティを生成
- is / has / can → booleanを返す
```

```ts
function isValidEmail(email: string): boolean
function fetchUserList(): Promise<User[]>
```

- ✅ 読んだ瞬間に**返り値と動作が予測できる**

---

## 3. UIコンポーネント命名：構造と再利用性を示す

```text
- Button → 汎用ボタン
- SubmitButton → 特定用途（送信）
- UserCard → 特定データ構造表示用
```

- ✅ 汎用コンポーネント → 単語ベース  
- ✅ 特化コンポーネント → ドメイン名 or 機能 + 構造名の複合

---

## 4. ユースケース・ドメイン操作の命名

```ts
createUserAccount  
updateUserEmail  
deleteUserSession
```

- ✅ **ドメイン + 操作名** の構造で責務を明確に  
- ❌ `handleSomething` / `doTask` → 意味が希薄

---

## 5. 命名の粒度：意味を保持したまま短縮する

| NG名     | 改善案              | 理由                           |
|----------|---------------------|--------------------------------|
| `res`    | `response` or `apiResponse` | 意図が曖昧、文脈依存         |
| `d`      | `data` or `userData`       | 意味の不在                   |
| `list`   | `userList` / `todoList`    | 単語が抽象的すぎる           |

- ✅ 「短い = 良い」ではなく、「**意味が保たれている = 良い**」

---

## 6. 名前の一貫性は設計の一貫性

```text
- getUser → fetchUser に統一（非同期）
- isActive → hasActiveUser → canActivate
```

- ✅ プロジェクト全体で **“動詞セットの選定と統一”** を行う
- ✅ 命名は**個人スタイルではなく、設計スタイル**

---

## 設計判断フロー

```text
① その名前は構造を語っているか？ → 意味が文脈依存でないか確認

② データ vs 関数で名詞と動詞が区別されているか？

③ 接頭辞が一貫して使われているか？ → 命名規約を定義

④ UIコンポーネントが再利用性を反映しているか？

⑤ 命名の粒度がプロジェクト全体で統一されているか？
```

---

## よくあるミスと対策

### ❌ `handleData`, `doStuff`, `processInfo` のような曖昧な動詞

→ ✅ **「何を」+「どうする」まで書く：sendUserData, sortByDate**

---

### ❌ 命名が短すぎて意味を失う（`res`, `x`, `temp`）

→ ✅ **ドメイン・構造・意図を最小限含めた名前に**

---

### ❌ 命名が属人化・一貫性がなくなる

→ ✅ **接頭辞・ドメイン名・役割ごとの命名ルールを明文化**

---

## 結語

命名とは「名前をつけること」ではない。  
それは**“構造を語り、意図を伝え、責任を明示するための設計の言語”**である。

- 動詞と名詞で役割を分け  
- 接頭辞で責務を区別し  
- 一貫した命名で構造を美しく保つ

**JavaScriptにおける命名戦略とは、  
“コードそのものが設計書となるための言語的戦略”である。**
TypeScriptにおけるユースケース層設計戦略：責務の隔離、ロジックの集約、依存注入による柔軟性の確保

## 概要

ユースケース層とは「関数をまとめる場所」ではない。  
それは**“アプリケーションの振る舞いを、責務ごとに構造化し、依存から切り離す設計層”**である。

JavaScript/TypeScriptでアプリケーションを設計する際、  
**UI・状態管理・非同期処理・API通信**が混在してしまい、**テスト性・再利用性・保守性**が著しく損なわれるケースが多い。

ユースケース層を設計することで、**振る舞いを意味単位に分離し、責任ある構造を組む**ことが可能になる。

---

## 1. ユースケース層の定義と責務

```text
- UIをトリガーとして
- 状態・API・ドメインロジックを統合
- 成功・失敗を状態やUIに返す
```

```ts
export const loginUser = async (
  input: LoginForm,
  deps: { authApi: AuthApi; sessionStore: SessionStore }
): Promise<Result<void, LoginError>> => {
  const res = await deps.authApi.login(input);
  if (!res.ok) return { ok: false, error: res.error };

  deps.sessionStore.set(res.data.session);
  return { ok: true };
};
```

---

## 2. UIとの連携：Presentationからロジックを切り出す

```ts
// UI層 (React / Vue)
const onSubmit = async () => {
  const result = await loginUser(form, { authApi, sessionStore });
  if (!result.ok) showError(result.error.message);
};
```

- ✅ UIは「結果を受けて状態や画面を制御する」のみに集中
- ✅ ロジックは「何をどうするか」をユースケース層に集約

---

## 3. 依存注入（DI）による柔軟性の確保

```ts
type Deps = {
  userApi: UserApi;
  userStore: UserStore;
};

export const fetchUserDetail = (deps: Deps) => async (id: string) => {
  const res = await deps.userApi.fetch(id);
  if (res.ok) deps.userStore.set(res.data);
};
```

- ✅ 外部依存（API, Store, DB）は**引数として明示的に注入**
- ✅ テスト時に**モック依存へ差し替え可能**

---

## 4. ユースケースは「意味単位」で分離する

```text
❌ userService.ts にすべての操作を詰め込む  
✅ usecases/user/createUser.ts  
   usecases/user/deleteUser.ts  
   usecases/user/updateUser.ts
```

- ✅ 1ユースケース = 1ファイル / 1関数に分離
- ✅ ロジックの意図が明確になり、再利用可能になる

---

## 5. エラーハンドリングと結果構造の統一

```ts
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
```

- ✅ UIや呼び出し元が**try-catchに依存せず分岐処理可能**
- ✅ 結果を構造的に返すことで**UXと制御が明確になる**

---

## 6. テスト性と非同期制御の分離

- ✅ 副作用は全て注入
- ✅ `fetchUserDetail({ api: mockApi, store: memoryStore })('u01')` のようにテスト可能

---

## 設計判断フロー

```text
① UIやAPIがロジックと密結合していないか？ → ユースケースに分離

② 外部依存（API, DB, Store）が直接使われていないか？ → DIで注入構造へ

③ ロジックがユースケース単位に意味を持っているか？ → 1責務 = 1ユースケース

④ 結果構造が曖昧 or try-catch依存になっていないか？ → Result構造で明示的に

⑤ テスト時にモック依存で差し替え可能か？ → 引数注入設計がされているか
```

---

## よくあるミスと対策

### ❌ UIコンポーネント内でfetchと状態更新をすべて実行

→ ✅ **ユースケース関数で責務を分離し、UIは状態制御に集中**

---

### ❌ APIの仕様変更で複数箇所が壊れる

→ ✅ **APIとの直接依存をユースケースに集約し、他層と切り離す**

---

### ❌ 非同期処理のテストが不可能

→ ✅ **ユースケース関数に依存を注入する設計でモック可能に**

---

## 結語

ユースケースとは「処理をまとめる場所」ではない。  
それは**“アプリケーションの意味を分離し、責務を集中させ、構造を再現可能に保つ設計層”**である。

- 振る舞いをユースケースに集約し  
- UIから依存とロジックを追い出し  
- 成果と失敗を構造として返し  
- 柔軟な依存注入でテスト性を担保する

**JavaScript/TypeScriptにおけるユースケース層設計とは、  
“構造と拡張性を保証する、アプリケーション制御の心臓部”である。**
TypeScriptにおける型設計戦略：型安全、構造的部分型、ドメイン型の設計と型の再利用戦略



## 概要

型定義とは「書きやすくする」ものではない。  
それは**“構造の意図を示し、意味を保証し、破壊を防ぐ設計上の契約”**である。

TypeScriptを使うと、つい自動補完や型推論に頼って設計を軽視しがちだが、  
型は**「書いた型」ではなく「設計された型」が本質**である。

本稿では、**型安全の原則、構造的部分型、ドメイン型・DTO型・UI型の責務分離、型の再利用と依存戦略**まで、**堅牢で再利用可能な型設計戦略**を解説する。

---

## 1. 型安全：anyの放置は構造破綻の入口

```ts
function send(data: any) { /* ❌ 型安全を喪失 */ }
```

- ✅ 明確な型を定義し、**意図された構造を表現する**
- ✅ 曖昧な `any`, `unknown`, `Object` の氾濫を防ぐ

```ts
type User = {
  id: string;
  name: string;
};
function send(data: User) { /* OK */ }
```

---

## 2. 構造的部分型：インターフェースを超える柔軟性

```ts
type HasId = { id: string };
function logId(entity: HasId) {
  console.log(entity.id);
}
```

- ✅ 構造が一致していれば互換性を持つ → **柔軟かつ安全**
- ✅ 過剰な extends よりも、**“必要な構造だけに依存”** する設計が正解

---

## 3. ドメイン型 / DTO型 / UI型 の責務を分離

```text
- Domain型: 業務的な意味を持つ（例: User, Plan）
- DTO型: API通信専用のデータ構造
- UI型: UI状態・エラーなど、表示構造に特化
```

```ts
type DomainUser = {
  id: string;
  name: string;
  age: number;
};

type ApiUserResponse = {
  user_id: string;
  full_name: string;
  age: number;
};

type UserFormState = {
  name: string;
  error?: string;
};
```

- ✅ **ドメインと実装とUIを分離**
- ✅ 一貫性の崩壊を防ぐ構造レイヤーを定義する

---

## 4. 型の再利用は「責務」ベースで分解して設計する

```ts
type User = {
  id: string;
  name: string;
  email: string;
};

type UserPreview = Pick<User, 'id' | 'name'>;
```

- ✅ `Pick`, `Omit`, `Partial` で**構造の責務ごとに切り出す**
- ✅ 「再利用できそう」ではなく、「意味で切り出す」

---

## 5. Never / Unknown / Literal型 の明示利用

```ts
function fail(message: string): never {
  throw new Error(message);
}
```

- ✅ `never` → 到達不能な分岐の設計
- ✅ `unknown` → **不明な入力に対して安全に処理**
- ✅ `"open" | "closed"` → **状態管理の列挙型として設計**

---

## 6. 型依存の構造化と隔離

```text
❌ 型を全ファイルで直import → 依存が循環して崩壊

✅ 型定義モジュールを `/types`, `/models`, `/schemas` で分離
```

- ✅ 型の階層を整理し、**UI/ロジック/APIの構造依存を明示的に分ける**

---

## 設計判断フロー

```text
① この型は業務的意味を持っているか？ → ドメイン型として明示

② 通信やUIに引っ張られていないか？ → DTO型/UI型を分離

③ 使用箇所が異なる粒度で共通化されていないか？ → Pick / Omitで再構築

④ any / unknown / literal が適切に設計されているか？

⑤ 型のimport元が過剰に集中していないか？ → 分離モジュールを検討
```

---

## よくあるミスと対策

### ❌ APIレスポンスの構造をそのままアプリ全体で使いまわす

→ ✅ **DTO → ドメイン変換関数で一度意味変換を通す**

---

### ❌ 型が肥大化し再利用不能に

→ ✅ **責務ごとに型を構造分離（構文型 / 意味型）**

---

### ❌ Literal型を定数管理せず、散在する `"open"` `"closed"`

→ ✅ **Literalは `as const` or Enum的管理に集約**

---

## 結語

型とは「型注釈」ではない。  
それは**“構造の意図、意味の明示、安全性の契約”であり、設計の言語そのものである。**

- 型の意味を分離し  
- 粒度で構造を切り出し  
- 依存と責任で分け  
- 自動補完ではなく設計で型を使う

**TypeScriptにおける型設計とは、  
“安全と意味と拡張性を同時に手に入れるための構造戦略”である。**
JavaScriptにおけるバリデーション設計戦略：構文・構造・意味の3層検証、UIとの同期、スキーマベース設計

## 概要

バリデーションとは「正しさを確認すること」ではない。  
それは**“データが破壊しないこと、流通できること、意味があること”を保証する設計戦略**である。

バリデーションは「フロントで形式だけ」「バックでエラー時だけ」ではなく、  
**全層で意味を持ち、UI・状態管理・データ設計を貫く構造として設計されるべきもの**である。

本稿では、**3階層の検証モデル、UI連携戦略、非同期検証、スキーマベースの共通化設計**を解説する。

---

## 1. バリデーションの3階層モデル

```text
1. 構文（Syntax）…形式の正当性（例：email, 数字）
2. 構造（Structure）…関連間の整合性（例：開始日 < 終了日）
3. 意味（Semantic）…業務的意味の正当性（例：未成年は契約不可）
```

→ ✅ **チェック項目をこの3階層で分類し、責務を分離**

---

## 2. 即時バリデーションとリアルタイムUX制御

```js
<input
  type="text"
  value={email}
  onChange={(e) => {
    setEmail(e.target.value);
    setError(validateEmail(e.target.value));
  }}
/>
```

- ✅ 入力 → 即時検証 → UIエラー表示 ＝ フローの一体化
- ✅ エラーは**「UI構造の一部」として設計**する

---

## 3. 非同期バリデーションの統合設計

```js
async function checkEmailDuplicate(email) {
  const res = await fetch(`/api/check?email=${email}`);
  return res.ok ? await res.json() : { valid: false };
}
```

- ✅ 同期チェックと非同期チェックは**構造的に合成可能に**
- ✅ 非同期中の状態（loading）や pending 表示もUIに統合

---

## 4. スキーマベース設計（例：Zod / Yup / Joi）

```ts
import { z } from 'zod';

const userSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  age: z.number().min(18),
});
```

```js
const result = userSchema.safeParse(formData);
if (!result.success) {
  showErrors(result.error.format());
}
```

- ✅ **UI / API / バックエンド で同一バリデーション構造を共有**
- ✅ 安全な解析（safeParse）により破壊を防止

---

## 5. UIの状態とバリデーションの一体管理

```ts
const [form, setForm] = useState({ email: '', age: '' });
const [errors, setErrors] = useState({});

const validate = () => {
  const result = schema.safeParse(form);
  if (!result.success) setErrors(result.error.format());
  return result.success;
};
```

- ✅ 入力値とバリデーション結果は**状態として一体管理**
- ✅ フォーム送信前・リアルタイムの**2モード設計**が基本

---

## 6. 複合ロジック・意味チェックの設計位置

```ts
if (user.age < 20 && user.plan === 'premium') {
  errors.plan = '未成年はプレミアムプランに加入できません';
}
```

- ✅ 意味的チェックは**ドメインロジック or バリデータ層に委譲**
- ❌ UI層に業務的ルールを埋め込まない

---

## 設計判断フロー

```text
① 検証ルールが構文/構造/意味に分離されているか？ → 責任分担の見直し

② UIで即時チェックが機能しているか？ → 入力体験と整合性を確保

③ 非同期バリデーションの状態が破綻していないか？ → 状態管理と統合

④ API層・UI層・ストア層でバリデーションが重複していないか？ → スキーマ共通化へ

⑤ 意味的なチェックがUIに混在していないか？ → ドメイン層での検証に抽出
```

---

## よくあるミスと対策

### ❌ UIでのみチェック → APIに通って壊れるデータが流入

→ ✅ **UIとAPIで同一スキーマ構造を適用**

---

### ❌ 重複チェックが多重リクエストを生む

→ ✅ **DebounceとAbortControllerで非同期制御設計**

---

### ❌ バリデーションエラーが表示だけで済み、実行不能に

→ ✅ **バリデーション状態 = 操作制御のロジックに直結**

---

## 結語

バリデーションとは「正しいか」ではなく、  
**“壊れない構造と、意味が通る世界を担保する設計層”**である。

- 構文・構造・意味の3階層で設計し  
- UIと同期し、非同期も統合し  
- スキーマで共有し、エラーを体験へ昇華する

**JavaScriptにおけるバリデーション設計とは、  
“データを守り、UIとロジックを信頼で繋ぐ構造戦略”である。**
Coral Cloud リゾートが対象とする領域の確認

前回は、Coral Cloud Resortsのサイト設定を紹介しました。

https://qiita.com/Mijinko-kun/items/32c58cbc2809c6b6eac7


Coral Cloud Resortsが対象とする領域を確認していきます。



https://developer.salesforce.com/jpblogs/2024/10/jp-agentforce-handson-coral-cloud-resorts-sampleapp.html

上記の説明サイトの中身を見ていきます。

## Coral Cloud Resortsが含むデータ

Coral Cloudでは、次の3つの領域をカバーしています。

1. Data Cloud
2. プロンプト
3. エージェント

データモデルは次の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/140b3f7f-12d7-439c-8371-74f8235045dd.png)


- Amazon S3のデータを、Data Cloudへ`DLO`として取り込みます。
  - それを`DMO`としてマッピングします。
- Salesforce CRMのデータを、Data Cloudへ`DLO`として取り込みます。
  - それを`DMO`としてマッピングします。



## (1) DataCloud

このサンプルアプリでは、Data Cloudの以下の内容を取り扱っています。

- Salesforce CRM からコンタクトを取り込む
- Amazon S3 からゲストおよび予約を取り込む
- ID解決機能を使用することで、さまざまなデータソースからの統合プロフィールを作成する
- Salesforce からの計算済みインサイトの使用


### Data Cloudの主要用語

DataCloudを理解するうえで、いくつか用語が出てきているので、現段階で一度まとめておきます。

DataCloudの主要オブジェクトの流れ

1.  **データソース (Source):** Salesforce CRM, S3, Webサイトなど
    * Data Cloudに取り込むデータの提供元であり、多様なシステムやデータ形式が接続対象となる。
2.  **データストリーム (Data Stream):** データソースからの接続と取り込み設定
    * : データソースとの接続を確立し、データの取り込み頻度（スケジュール）や更新方法（全件/差分）を定義する。
3.  **DLO (Data Lake Object):** 取り込まれた生データが最初に格納される場所
    * 役割/特徴Data Cloud内のデータレイクにおけるストレージコンテナとして機能し、ソースシステムの構造に近い形でデータを保持する。
4.  **データマッピング (Data Mapping):** DLOのデータをDMOの構造に紐付けるプロセス
    * 役割/特徴DLOの項目とDMOの項目を視覚的または設定ベースで関連付け、異なるソースのデータをData Cloudの標準データモデルに統合する。
5.  **DMO (Data Model Object):** 標準化・構造化されたデータが格納されるオブジェクト
    * 役割/特徴統合・整理されたデータを保持し、セグメンテーション、計算済みインサイト、有効化（Activation）など、データ活用のための基盤となる。
6.  **(活用):** DMOのデータを使って計算済みインサイト (CI) を作成したり、セグメントを作成したりする。

### DataKit(データキット)とは


Data Cloudメタデータをデプロイする主な方法は、データキットを使用するとのことです。

「データキット」とは、Data Cloudのメタデータ（データストリーム、モデル等）をまとめた専用バンドルです。これをSalesforceの標準パッケージに含めることで、Data Cloudの設定を他の組織へ容易に配布・管理できるようにする仕組みです。これにより、Data Cloud構成の再利用や展開が効率化されます

DataKitの使用方法は次の通りです。

https://help.salesforce.com/s/articleView?id=data.c360_a_data_package_kits.htm&type=5

このHelpページに、動画で紹介されています。


こちらのTrailHeadでも学習できます。

https://trailhead.salesforce.com/ja/content/learn/modules/packaging-and-data-kits-in-salesforce-cdp





## (2) プロンプト

プロンプトとは、LLMへの指示文です。質問、命令、文脈、データ、出力形式などを指定し、期待する応答を引き出すためのテキストです。

このサンプルアプリでは、プロンプトの以下の機能を取り扱っています。

- 項目生成
- セールスメール
- Flex

これらのプロンプトテンプレートは、項目のマージ、フロー、または Apex を使用してグラウンディングを実施します。

ブラウンでィングとは、AIが生成する情報や回答の根拠となる信頼できるデータや知識源を参照することです。


## (3) エージェント

エージェントとは、AIを活用し、自律的に目標達成を目指すソフトウェアシステムです。状況を認識・判断し、推論・計画に基づいユーザーを支援・代行します。

この、サンプルアプリでは、Agentforce を使用したエージェント構築を開始するために、トピックとカスタムアクションの組み合わせを使用しています。


---

次回は、Agentforce WorkshopのData Cloud側の確認をしていきたいと思います。

↓まず、SalesforceCRMと接続します。

https://qiita.com/Mijinko-kun/items/9aa89e622de7cbab2e2c