OmniAICreator/Qiita-1.07M huggingface dataset:
2025年人気No.1のNext.jsで、最新ツールとウェブを作る！ | エピソード2 ルーティングとページの基本

## 目標
- Next.jsでのルーティング（routing）の仕組みを理解する。
- App Routerを使った基本的なページ作成を学ぶ。
- 動的ルート（Dynamic Routes）の作り方を習得する。
- ページ間をスムーズに移動するための`Link`コンポーネントを使用する。

---

## 1. App Routerの紹介
Next.js 13以降で導入された**App Router**は、ルーティングの新しい方法です。従来のPages Routerとは異なり、ディレクトリ構造を活用した直感的なルーティングと、Server Componentsによるパフォーマンス向上を提供します。このシリーズでは、最新のトレンドに沿ってApp Routerを使用します。

- **特徴**：
  - `app/`ディレクトリ内にページを定義。
  - ファイル名がそのままルート名に（例：`page.tsx` → `/`）。
  - ネストされたフォルダでサブルートを作成（例：`app/about/page.tsx` → `/about`）。

---

## 2. 基本的なページの作成
早速、`app/`ディレクトリ内でページを作ってみましょう。

### 手順：
1. **ホームページ（Home）**：
   - `app/page.tsx`は既に存在します。エピソード1のコードをそのまま使用。
2. **Aboutページの追加**：
   - `app/about/`フォルダを作成し、その中に`page.tsx`を追加。
   - 以下を`app/about/page.tsx`に記述：
     ```tsx
     export default function About() {
       return (
         <div>
           <h1>Aboutページ</h1>
           <p>これはNext.jsで作ったAboutページです。</p>
         </div>
       );
     }
     ```
3. **Contactページの追加**：
   - `app/contact/`フォルダを作成し、`page.tsx`を追加。
   - 以下を記述：
     ```tsx
     export default function Contact() {
       return (
         <div>
           <h1>Contactページ</h1>
           <p>お問い合わせはこちらから。</p>
         </div>
       );
     }
     ```

**確認**：
- `npm run dev`でサーバーを起動し、ブラウザで以下を確認：
  - `http://localhost:3000/` → ホームページ。
  - `http://localhost:3000/about` → Aboutページ。
  - `http://localhost:3000/contact` → Contactページ。

---

## 3. 動的ルート（Dynamic Routes）の作成
固定ページだけでなく、動的なページも簡単に作れます。たとえば、ブログの投稿ページ（`/post/1`, `/post/2`など）を作成してみましょう。

### 手順：
1. `app/post/[id]/`フォルダを作成（`[id]`は動的パラメータを示す）。
2. その中に`page.tsx`を追加し、以下を記述：
   ```tsx
   import { useParams } from 'next/navigation';

   export default function Post() {
     const params = useParams();
     const { id } = params;

     return (
       <div>
         <h1>投稿 #{id}</h1>
         <p>これはIDが{id}の投稿ページです。</p>
       </div>
     );
   }
   ```

**確認**：
- `http://localhost:3000/post/1` → "投稿 #1" と表示。
- `http://localhost:3000/post/abc` → "投稿 #abc" と表示。
- `[id]`は任意の値を受け取れるので柔軟性が高いです。

---

## 4. `Link`を使ったページ間移動
Next.jsでは、`<a>`タグの代わりに`Link`コンポーネントを使ってページ間を移動します。これにより、ページ遷移が高速化されます。

### 手順：
1. `app/page.tsx`を編集してナビゲーションを追加：
   ```tsx
   import Link from 'next/link';

   export default function Home() {
     return (
       <div>
         <h1>Next.jsからのHello World!</h1>
         <p>2025年のNext.js学習シリーズへようこそ。</p>
         <nav>
           <Link href="/about">Aboutへ</Link> |{' '}
           <Link href="/contact">Contactへ</Link> |{' '}
           <Link href="/post/1">投稿 #1へ</Link>
         </nav>
       </div>
     );
   }
   ```

**確認**：
- ホームページにナビゲーションが表示され、クリックすると各ページにスムーズに移動。

---

## 実践：3つの静的ページと1つの動的ページを持つウェブサイト
これまでの内容を統合して、以下を作成：
- **Home**: `app/page.tsx`（ナビゲーション付き）。
- **About**: `app/about/page.tsx`。
- **Contact**: `app/contact/page.tsx`。
- **動的投稿ページ**: `app/post/[id]/page.tsx`。

**ヒント**：
- 各ページに`<Link>`を使って他のページへのリンクを追加すると、さらに使いやすくなります。

---

## エピソード2の終了
- Next.jsのApp Routerを使ったルーティングの基本を学びました。
- 静的ページと動的ページの作成方法を習得しました。
- `Link`コンポーネントでスムーズなナビゲーションを実現しました。

**次回のエピソード**：スタイリング（Styling）を学び、ウェブサイトに美しいデザインを追加します。

---

この記事が役に立ったと思ったら、ぜひ「いいね」を押して、ストックしていただければ嬉しいです！次回のエピソードもお楽しみに！
【実録】地獄…ッ！SendGridの送信上限に引っかかって…メール、一通も送れないッ！！

## はじめに

ある日、SendGrid経由でメール送信を行っていたサービスで、急に以下のエラーが発生しました。

```json
{
  "message": "Maximum credits exceeded"
}
```
SDK経由でAPIリクエストを送ったところ、上記のようなレスポンスが返ってきて、メールが一切送信できない状態に。
原因を調査したところ、送信通数の上限を超過していたことが分かりました。

しかし、「超過分は従量課金になるはずでは？」という認識だったため、意外な落とし穴に少し戸惑いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993266/12739fc7-0472-4c76-971a-4afb89c35ed2.png)
https://sendgrid.kke.co.jp/plan
より引用

## 原因と背景
調査を進めた結果、SendGridの各プランには明確な送信通数の制限があることが分かりました。
例えば「100kプラン」では、およそ40万通の送信を超えると送信が停止される仕様になっており、それ以上は自動的に従量課金には切り替わらないようです。

実は、上限超過が近づいていることを知らせる事前の通知メールも送られていたのですが、見落としていたため、結果的に完全停止まで気づくことができませんでした。

これは公式では記載がされているのは見つかられず、サポートからのお問合せの返信で判明いたしました。

## どうやってこの制限を解除するか
プランをあげるか、サポートに問い合わせして上限を解放するしかないそうです。

ダッシュボードとかで設定できたりすると嬉しいんですけどね

## 結果と学び
・事前通知メールを見逃さないことが重要
もし止まってしまった
・上限解放をサポートに連絡
・プラン自体引き上げ

「事前通知メールを見逃さないことが重要」が個人的に声を大にしてお伝えしたかったです。
OpenCVでQRコードを読み取るとエラー

## 問題
OpenCVでQRコードを読み取ろうとした際に、
```Library QUIRC is not linked. ```
というエラーが発生し、文字列が取得できない。
（矩形は正常に取れているので、検出は出来ているらしい）

## 原因
インストールされているOpenCVのパッケージに、QRコード読取り（デコード）に必要なライブラリが含まれていない。
（バージョン依存ではありません。あくまでパッケージに含まれるライブラリの問題になります。）

## 対策
① 別のパッケージをインストールする。
　apt で、opencv や opencv-devel などのパッケージを直接インストールした場合に発生することが多いようです。
　pipからPhytyon用のパッケージ(opencv-python)をインストールしてみましょう。

② ソースコードからビルドする。
　自分でソースコードからライブラリを作成すれば問題は解決します。
　（ビルドについては既に多くの記事がありますのでソチラを参考に。）
　重要なのは cmake で Makefile を作成する際に<strong>WITH_QUIRC</strong>オプションを指定することです。このオプションは<strong>デフォルトではOFF</strong>になっているので、指定しないと使用できません。
　```cmake .. -DWITH_QUIRC=ON```
　（要するに、インストールしたビルド済みパッケージが、このオプションを使用せずにビルドされているという事です。）
EFSのパフォーマンスについて

EFSのパフォーマンスに影響を与える設定
- ファイルシステムのタイプ
  - リージョン
  - 1ゾーン
- パフォーマンスモード
  - 汎用モード
  - 最大 I/O
- スループットモード
  - エラスティック
  - プロビジョン
  - バースティング

https://docs.aws.amazon.com/ja_jp/efs/latest/ug/performance.html#performance-overview
<hr>

## ファイルシステムのタイプ
| ファイルシステムのタイプ    | リージョンタイプ             | １ゾーンタイプ                     |
| --------------- | -------------------- | --------------------------- |
| 耐久性             | 99.999999999%（11 9s） | 99.999999999%（11 9s）        |
| 可用性             | 99.99％               | 99.99％                      |
| アベイラビリティゾーン(AZ) | 3つ以上                 | 1つ                          |
| 考慮点             | 特になし                 | AZが喪失した場合、保存されたデータを失う可能性がある |

https://youtu.be/swoxicPWPHE?si=kxUjFPsov5kdkj_F&t=235

<hr>

![efs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492809/fb4ed064-3ab7-4629-9031-e1ca3dc2bbbb.png)
<hr>

## パフォーマンスモード
| モード    | 汎用（Default）                            | 最大 I/O                        |
| ------ | -------------------------------------- | ----------------------------- |
| 用途     | 低いレイテンシーを求めるアプリケーションや汎用なファイルベースのワークロード | 大規模データを扱うアプリケーション             |
| 優位点    | ファイル操作のレイテンシーが最も低い                     | 仮装的に無制限にスケールアウトできるスループットとIOPS |
| トレードオフ | 1秒あたりのファイルシステム操作回数が7000に制限             | レイテンシーがわずかに長くなる               |
| 利用シーン  | ほとんどのワークロードで最適な選択                      | 大規模スケールアウトが必要なワークロードで検討       |
<hr>

https://www.slideshare.net/slideshow/20180704-aws-black-belt-online-seminar-amazon-elastic-file-system-amazon-efs-201889-update/109317453#53
<hr>

## スループットモード

| スループットモード      | スループット性能                                                           | ユースケース                                                 |
| -------------- | ------------------------------------------------------------------ | ------------------------------------------------------ |
| バースト           | ・ストレージサイズに応じてベースラインのスループットが決定する※2<br>・ベースラインを超えた場合、バーストクレジットが消費される | ・ストレージ容量に合わせてスケーリングするスループット                            |
| プロビジョニング済み     | ・プロビジョニングする<br>・プロビジョニングした値を超えた場合、バーストクレジットが消費される                  | ・パフォーマンス要件が予測できる場合<br>・ピーク時のスループットが平均より20倍以下の場合        |
| Elastic スループット | ・自動的にスケールする                                                        | ・パフォーマンス要件が予測できない場合<br>・ピーク時のスループットが平均より20倍以上大きな値となる場合 |

<hr>

https://youtu.be/swoxicPWPHE?si=Fs6WWZK36Z_Z5aGH&t=1525

<hr>

## その他
- アプリケーションが「ls」、「rm」、「mkdir」、「rmdir」、「lookup」、「getattr」、「setattr」などのメタデータを多用するオペレーションを実行する場合
- EC2 インスタンスのリソース不足
- Network File System (NFS) バージョン 
- Linux カーネルバージョン
https://repost.aws/ja/knowledge-center/efs-troubleshoot-slow-performance
2025年人気No.1のNext.jsで、最新ツールとウェブを作る！ | エピソード1 紹介と環境設定

## 目標
- Next.jsとは何か、2025年にウェブサイト構築に適している理由を理解する。
- 開発環境を準備し、最初のNext.jsプロジェクトを作成する。
- 基本的なアプリケーションを実行し、ディレクトリ構造に慣れる。

---

## 1. Next.jsとは？なぜ2025年にNext.jsを選ぶのか？
Next.jsは、Reactを基盤としたフレームワークで、Vercelによって開発されています。高速で最適化された、スケーラブルなウェブアプリケーションを構築するのに役立ちます。React単体（UIライブラリのみ）とは異なり、Next.jsには以下のような組み込み機能があります：
- **サーバーサイドレンダリング（SSR）**: サーバーからコンテンツを読み込み、SEOに有利。
- **静的サイト生成（SSG）**: ビルド時に静的ページを生成し、非常に高速。
- **ファイルベースのルーティング**: ディレクトリ構造に基づく自動ルーティング。
- **APIルート**: バックエンドを別途用意せずにプロジェクト内でAPIを作成可能。

**2025年にNext.jsを選ぶ理由：**
- Googleのトレンドであるスピード最適化に対応する高いパフォーマンス。
- 大規模なコミュニティ、豊富なドキュメント、継続的なアップデート。
- 小規模（ブログ）から大規模（Eコマースアプリ）まで対応可能。
- Tailwind CSS、Vercel、Supabaseなどの最新ツールとの優れた統合。

---

## 2. Next.jsの注目すべき機能
手を動かす前に、Next.jsの主なアプローチを2つ見てみましょう：
- **App Router**: Next.js 13以降の新しい方法で、Server Componentsを中心に、データ取得の簡素化とパフォーマンス最適化を重視。このシリーズではこちらを主に使用します。
- **Pages Router**: 従来の方法で、現在もサポートされていますが、新規プロジェクトにはあまり推奨されません。

その他にも：
- `next/image`による画像の自動最適化。
- 初期からTypeScriptをサポート。
- Vercelやその他のプラットフォームでの簡単なデプロイ。

---

## 3. システム要件とインストール
始めるために必要なもの：
- **Node.js**: バージョン18.x以降（2025年3月31日時点で最新のLTS版を推奨）。
- **npm**または**Yarn**: パッケージ管理ツール（このガイドではnpmを使用）。
- Windows、macOS、またはLinuxが動作するコンピュータ。

**インストール手順：**
1. **Node.jsの確認**：
   - ターミナル（コマンドプロンプト、PowerShell、またはTerminal）を開く。
   - `node -v`を入力してバージョンを確認。未インストールの場合は[nodejs.org](https://nodejs.org)からダウンロード。
2. **npmのインストール**：
   - npmはNode.jsに付属。`npm -v`で確認。
3. **（オプション）Yarnのインストール**：
   - Yarnを使いたい場合、`npm install -g yarn`を実行。

---

## 4. `create-next-app`で最初のNext.jsプロジェクトを作成
最初のプロジェクトを作成します：
1. ターミナルで以下のコマンドを実行：
   ```
   npx create-next-app@latest my-first-nextjs-app
   ```
2. 設定に関する質問に回答：
   - **TypeScript?** Yes（より安全なコーディングのために推奨）。
   - **ESLint?** Yes（構文エラー検出に役立つ）。
   - **Tailwind CSS?** Yes（後でスタイリングに使用）。
   - **App Router?** Yes（新しい方法を選択）。
   - その他のオプション：デフォルトのまま（Enterを押す）。
3. 数秒待つとインストールが完了。

`my-first-nextjs-app`というディレクトリが作成されます。

---

## 5. アプリケーションの実行とディレクトリ構造の確認
**アプリケーションの実行：**
1. プロジェクトディレクトリに移動：
   ```
   cd my-first-nextjs-app
   ```
2. 開発サーバーを起動：
   ```
   npm run dev
   ```
3. ブラウザを開き、`http://localhost:3000`にアクセス。Next.jsのデフォルトのウェルカムページが表示されます。

**ディレクトリ構造の確認：**
- `app/`：ルーティングとメインインターフェースのファイルを格納。
  - `page.tsx`：ホームページ。
  - `layout.tsx`：アプリケーション全体の共通レイアウト。
- `public/`：画像やフォントなどの静的ファイルを保存。
- `package.json`：ライブラリとスクリプトのリスト。
- `.eslintrc.json`, `tsconfig.json`：ESLintとTypeScriptの設定。

---

## 実践：シンプルな「Hello World」ページの作成
1. コードエディタ（例：VS Code）で`app/page.tsx`を開く。
2. デフォルトの内容を削除し、以下に置き換える：
   ```tsx
   export default function Home() {
     return (
       <div>
         <h1>Next.jsからのHello World!</h1>
         <p>2025年のNext.js学習シリーズへようこそ。</p>
       </div>
     );
   }
   ```
3. ファイルを保存し、ブラウザに戻る。ホットリロードのおかげでページが自動更新されます。

---

## エピソード1の終了
- 開発環境のセットアップが完了し、最初のNext.jsプロジェクトが実行できました。
- Next.jsの基本的な仕組みとディレクトリ構造を理解しました。

**次回のエピソード**：ルーティング（routing）について学び、ウェブサイトに複数のページを作成します。

---

この記事が役に立ったと思ったら、ぜひ「いいね」を押して、ストックしていただければ嬉しいです！次回のエピソードもお楽しみに！
Pleasanterの拡張フィールドを使おう～サーバースクリプト連携編～

# はじめに
拡張フィールドの活用方法、今回はサーバースクリプト連携編です。
拡張フィールドの説明ならびに、拡張フィールドとスクリプトの連携については前回の記事をご参照ください。

https://qiita.com/oosugi-t/items/97d69f2a999ea49a3433

# 拡張フィールドとサーバスクリプト
サーバスクリプトを使う際、画面から自由な値(引数)を取得したいと思う方はいないでしょうか。
フィルタの値はサーバスクリプトで取得できますが、フィルタに値を入れてしまうとデータのフィルタリングが行われてしまいます(当たり前ですが)。よって画面に影響を与えない値を入力することは難しいです。
例えば、以下のようなテーブルがあった場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935896/ae9ad7e9-0422-4c1d-896f-0343620b274e.png)
フィルタを適応して期間を絞ることはできますが、複数の期間を指定することができません(例えば1/1～4/30,7/1~12/31のように)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935896/d60e0196-3aa8-432d-8c9d-92092c67d716.png)
サーバスクリプトを使えば複数の期間を指定することはできますが、この場合基本的に固定値になってしまいます。
しかし拡張フィールドの値はフィルタと同じように、サーバスクリプトで取得することができるうえ、拡張フィールド自体はフィルタに影響しない値なので、サーバスクリプトに自由な値を送信し、その値を使ってデータの削除をしたり作成したりすることなどが可能です。

今回は例として、拡張フィルタに入力した条件を使って、サーバスクリプトから特殊なフィルタ条件を設定する方法をご紹介します。

### 拡張フィールド設定
まず拡張フィルタを二つ作成します。
現状、ViewExtentionsをサーバスクリプト側でキャッチする方法がないのでFieldTypeはFilterにします。TypeNameはdatetimeです。
また入力した内容をPostしてサーバスクリプトでキャッチさせるため、AutoPostBackをtrueに設定します。
なお、項目は読み込まれたファイルの逆順に並ぶので、項目1が後に読まれるようにファイル名を設定します。
- 02_ExtendedFirst.json
```rb
{
    "Name": "ExtendedFieldFirst",
    "SiteIdList": [55432],
    "IdList": null,
    "FieldType": "Filter",
    "TypeName": "datetime",
    "LabelText": "期間1",
    "AutoPostBack":  true
}
```
- 01_ExtendedSecound.json
```rb
{
    "Name": "ExtendedFieldSecound",
    "SiteIdList": [55432],
    "IdList": null,
    "FieldType": "Filter",
    "TypeName": "datetime",
    "LabelText": "期間2",
    "AutoPostBack":  true
}
```
### サーバスクリプト設定
拡張フィールドは、view.Filters.[Name]で取得できます。
```rb
let extendedFieldFirst = view.Filters.ExtendedFieldFirst;
let extendedFieldSecound = view.Filters.ExtendedFieldSecound;

if (extendedFieldFirst != null && extendedFieldSecound != null){
    view.Filters.DateA = JSON.stringify(JSON.parse(extendedFieldFirst).concat(JSON.parse(extendedFieldSecound)));
}
```
フィルタで複数の範囲を検索したい場合は、'["2021/1/1,2021/1/31 23:59:59.997","2021/5/1,2021/5/31 23:59:59.997"]' のように範囲を配列にすると指定することができます。
これを利用し、両方の拡張フィールドに値が入っていた場合、DateAのフィルタを各フィールドの値で置き換えるように設計しています。
値は文字列化されたJSONとして取得されるため、一度Parseしたうえで結合し、再度stringifyしています。
なお、null判定を行わないと値が入っていなかった場合、Parseする際にエラーでクラッシュしてしまうので注意してください。

### フィルタ適応
それでは期間1に「2025/1/1 - 2025/3/31」、期間2に「2025/7/1 - 2025/ 12/31」を入力してみます。
いかがでしょうか？
このように、6月のデータだけを排除して表示することに成功しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935896/f784ba8e-1151-4139-b5b7-5ba140f23c3e.png)

# まとめ
今回は、拡張フィールドとサーバスクリプトを連携して特殊なフィルタ条件を作成する方法をまとめました。
このように拡張フィールドを使うと、サーバスクリプトに任意の引数を渡して特殊なフィルタを適応したり、データの書き換えをしたりすることができます。
任意の値をサーバスクリプトに渡す方法はほぼありませんので、かなり便利な機能だと思います。この使い方も、ぜひいろいろ試してみてください！

次回の記事では、拡張フィールドと拡張SQLを連携させる方法をご紹介します。
MQTT: Paho の使い方

こちらを参考にしました。
[paho-mqtt 2.1.0](https://pypi.org/project/paho-mqtt/#single)

## 必要なライブラリーのインストール

```bash
sudo apt install python3-paho-mqtt
```

## Publish

```py:publish.py
#! /usr/bin/python
#
#	publish.py
#
#					Mar/31/2025
#
# ------------------------------------------------------------------
import paho.mqtt.publish as publish
import	sys

sys.stderr.write("*** 開始 ***\n")
message = "Good Afternoon"
topic = "/paho/test/topic"
publish.single(topic, message, hostname="localhost")
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## Subscribe

```py:subscribe_callback.py
#! /usr/bin/python
#
#	subscribe_callback.py
#
#					Mar/31/2025
#
# ------------------------------------------------------------------
import paho.mqtt.subscribe as subscribe
import sys
# ------------------------------------------------------------------
def on_message_print(client, userdata, message):
    print("%s %s" % (message.topic, message.payload))
    userdata["message_count"] += 1
    if userdata["message_count"] >= 5:
        # it's possible to stop the program by disconnecting
        client.disconnect()

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
topic = "/paho/test/topic"
subscribe.callback(on_message_print, topic, hostname="localhost", userdata={"message_count": 0})
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## 確認したバージョン

```text
$ python --version
Python 3.12.7
```

## テストに使ったスクリプト

```sh:go_pub.sh
BROKER="localhost"
TOPIC="/paho/test/topic"
#
echo $BROKER
message="{\"key\": \"A1B2C3D4\",\"version\": \"2025-3-31 AM 11:09\"}"
mosquitto_pub -d -t orz -m "${message}" \
    -h  $BROKER \
    --topic $TOPIC
```

```sh:go_sub.sh
BROKER="localhost"
TOPIC="/paho/test/topic"
#
mosquitto_sub -d -h $BROKER --topic $TOPIC
```
【備忘録】DockerでApacheとTomcatのコンテナを作成する

# はじめに
Dockerを使用してApacheとTomcatのコンテナを作成し，ローカルサーバとして動かすまでにメモしたものです．
内容については後から直していきます．

参考サイトについては各ページのタイトルじゃなくて自分でわかりやすいように変えてます．

## 環境
M2 Macbook Air

DockerでapacheとTomcatのコンテナを作成

## 作成するにあたって
参考サイト[1]先である通りに作成していたところ，http.confファイルを各サーバからコピーしてくる旨が書いてある．しかし，サーバが無いのでホストのMacbookにあるhttp.confを使用したところ，エラーでコンテナを作成できない．
そんな時は一度公式のimageを使用してコンテナを立ち上げて，その中にあるhttp.confファイルをコピーすると良い
```docker
docker pull httpd:2.4
```
自分はこれで1週間近くapacheのコンテナを立ち上げることができなかった...

## メモ

- docker loadコマンドが使えない

```docker
$cat /etc/group | grep docker
```

上記のコマンドでユーザにアクセス権限があるかを確認

```docker
docker:x:126:username
```

が表示されたら問題なし
それ以外(usernameの表記なしなど)の場合は

```docker
$sudo usermod -aG docker 'username'
$newgrp docker
```

でユーザをにアクセス権限を追加

- ログ監視のコマンド

```docker
docker events --filter container=httpd_sample
```

実行停止するまで，dockerコマンドを使用した際のログを表示していく

—filterで対象を指定できる

- runコマンド

```docker
docker run --name httpd_smaple -p 80:80 -dit httpd:sample
```

[参考サイト](https://epic-life.me/archives/5892)では上記のrunコマンドを使用したが，エラーは出ないのにexit code(1)でコンテナが立ち上がった後にすぐ終了してしまう

```docker
docker run --name httpd_sample -p 80:80 -dit -p 80:80 httpd:sample bash
```

と最後に ”bash” を入れる必要がある

- ApacheとTomcatの連携方法

httpd-proxy.confのlocalhostをIPアドレスに変えるだけでは連携できない
tomcat側のserver.xmlファイルからポートを指定する必要がある

- Dockerfileからbuildしたhttpd(Apache)コンテナがrunできない

```docker
docker run -dit -p 80:80 httpd:2.4
```

上記のコマンドで実行したら問題なくコンテナをrunできる

- httpd.conf(httpd-proxy.conf)でProxyPassを設定

ProxyPassを設定するとそのディレクトリを指定するだけでindex.htmlが表示される

ex.) 
webapps/
├ sample/
│ ├ index.html
│ └ index.css
│  
└ test/
  ├ index.html
  └ index.css

となっている時，本来は 
“http://localhsot/sample/index.html” | “http://localshot/test/index.html”
と記入するところを
”http://localshot/sample” | “http://localhost/test”
だけでそれぞれのindex.htmlが表示される

/sampleや/testは変更可能


===== 余談 =====

~/.vimrcファイルで

```docker
:syntax on
```

と記載するとデフォルトで使用されているコメントアウトの色を変える機能をオンにできる


===== 疑問 =====

- ProxyPassとProxyPassReverseの違いは何？
具体的は挙動も知っておきたい

## 参考文献

- [[1]Dockerでapacheとtomcatのコンテナを立ち上げる](https://epic-life.me/archives/5892)
- [[2]docker runしてもコンテナが起動しない時のlog確認](https://qiita.com/ginger-yell/items/8418035f1dfd36151983)
- [[3]sshでファイルを転送する](https://qiita.com/sayama0402/items/c5c2795968ced798150a)
- [[4]Apache ディレクティブ一覧](https://httpd.apache.org/docs/2.4/mod/directives.html)
- [[5]ApacheとTomcatの連携方法1](https://qiita.com/xyz666/items/387251d0aee41a25fec1)
- [[6]ApacheとTomcatの連携方法2](https://miyohide.hatenablog.com/entry/2023/08/13/170814)
- [[7]httpd-foregroundって何だ](https://qiita.com/ryoutaka/items/343f048e6a3e0cefdab5)
- [[8]JavaとPostgreSQLの連携](https://amateur-engineer.com/tomcat-postgresqldocker-compose/)
- [[9]GETとPOSTの違い](https://qiita.com/kanataxa/items/522efb74421255f0e0a1)
windows11で、sketchup6 その36

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題、やってみた。

# 練習問題
sketchupでカラーボックスを描くrubyスクリプトは

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5d672dbf-82cd-44f2-88cf-ab95c543e25e.png)

# 

```
def create_colorbox
	model = Sketchup.active_model
	entities = model.active_entities
	Sketchup.set_status_text "Please wait a little."
	for x in 0..8 do
		for y in 0..8 do
			for z in 0..8 do
				group = entities.add_group
				entitie = group.entities
				pts = []
				pts[0] = [x * 10 +  5, y * 10 +  5, z * 10 + 5]
				pts[1] = [x * 10 + 10, y * 10 +  5, z * 10 + 5]
				pts[2] = [x * 10 + 10, y * 10 + 10, z * 10 + 5]
				pts[3] = [x * 10 +  5, y * 10 + 10, z * 10 + 5]
				base = entitie.add_face pts
				base.pushpull 5
				materials = model.materials
				m = materials.add "joe" + String(x) + String(y)+ String(z)
				m.color = Sketchup::Color.new (x * 32 , y * 32 , z * 32)
				m.alpha = 1.0
				entitie.each{ |e|
					case e
					when Sketchup::Face
						e.material = "joe" + String(x) + String(y)+ String(z)
					end
				}
			end
		end
	end
	UI.beep
end

```

以上。
pipenv から uv に移行するためのコマンドメモ

# 概要
python のパッケージ管理システム uv を使いたい。
https://docs.astral.sh/uv/
pipenv を使ってきたのでコマンドの比較をメモとして残す

# コマンド比較
|  | pipenv | uv |
|:-:|:-:|:-:|
| プロジェクト作成  | (任意のディレクトリで)pipenv --python 3.12  | uv init <新ディレクトリ名> --python 3.12  |
| ライブラリ追加  | pipenv install numpy  | uv add numpy  |
| ライブラリ削除  | pipenv uninstall requests  | uv remove numpy  |
| 実行  | pipenv run hello.py  | uv run main.py  |
| requirements.txt生成  | pipenv requirements > requirements.txt  | uv pip compile pyproject.toml -o requirements.txt  |
| ライブラリ更新  | pipenv install  | uv lock --upgrade  |
| 環境復元  | pipenv sync  | uv sync  |
Oracle SQL基本編

# スキーマ、ユーザ、テーブル・ビューとは？

わかりやすい例は以下。

・<strong>スキーマ</strong> ...カバン
・<strong>ユーザ</strong>...人
・<strong>テーブル・ビュー</strong>...ペン

<strong>「テーブルを作成する」 = 「あなた（ユーザ）がカバン（スキーマ）の中にペン（テーブル）を入れる」</strong>
・ユーザにスキーマは1つまで
・テーブルは何個でも作成できる
windows11で、sketchup6 その35

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題、やってみた。

# 練習問題
sketchupで正十二面体を描くrubyスクリプトは

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/aee39625-8ee9-4999-a200-edadbd15085a.png)


# サンプルコード

```
def create_dode
	dodecaeder = Sketchup.active_model.definitions.add("ItsDode");
	scale = 200 / (Math.sqrt(5) + 1) / 2.54;
	s0 = (Math.sqrt(5) - 1) / 2 * scale;
	s1 = (Math.sqrt(5) + 1) / 2 * scale;
	unit = scale;
	p = Array.new;
	for i in 0 .. 7
		p[i] = [ (i & 4) != 0 ? -unit : unit, (i & 2) != 0 ? -unit : unit, (i & 1) != 0 ? -unit : unit]
	end
	for i in 0 .. 3
		p[i + 8] = [ 0, (i & 1) != 0 ? -s0 : s0, (i & 2) != 0 ? -s1 : s1 ]
		p[i + 12] = [ (i & 1) != 0 ? -s0 : s0, (i & 2) != 0 ? -s1 : s1, 0 ]
		p[i + 16] = [ (i & 2) != 0 ? -s1 : s1, 0, (i & 1) != 0 ? -s0 : s0 ]
	end
	dodecaeder.entities.add_face([ p[8], p[9], p[2], p[16], p[0]])
	dodecaeder.entities.add_face([ p[8], p[9], p[6], p[18], p[4]])
	dodecaeder.entities.add_face([p[10],p[11], p[3], p[17], p[1]])
	dodecaeder.entities.add_face([p[10],p[11], p[7], p[19], p[5]])
	dodecaeder.entities.add_face([p[12],p[13], p[4],  p[8], p[0]])
	dodecaeder.entities.add_face([p[12],p[13], p[5], p[10], p[1]])
	dodecaeder.entities.add_face([p[14],p[15], p[6],  p[9], p[2]])
	dodecaeder.entities.add_face([p[14],p[15], p[7], p[11], p[3]])
	dodecaeder.entities.add_face([p[16],p[17], p[1], p[12], p[0] ])
	dodecaeder.entities.add_face([p[16],p[17], p[3], p[14], p[2] ])
	dodecaeder.entities.add_face([p[18],p[19], p[5], p[13], p[4] ])
	dodecaeder.entities.add_face([p[18],p[19], p[7], p[15], p[6] ])
	trans = Geom::Transformation.new([0, 0, 0]);
	Sketchup.active_model.active_entities.add_instance(dodecaeder, trans);
end

```

以上。
windows11で、sketchup6 その34

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題、やってみた。

# 練習問題
sketchupで正二十面体を描くrubyスクリプトは

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/fb2ff7ec-e848-448e-a479-9f9f417931b9.png)

# サンプルコード

```
def create_ico
	icosaeder = Sketchup.active_model.definitions.add("ItsIco");
	scale = 200 / (Math.sqrt(5) + 1) / 2.54;
	s1 = (Math.sqrt(5) + 1) / 2 * scale;
	unit = scale;
	p = Array.new;
	for i in 0 .. 3
		p[i + 0] = [ 0, (i & 1) != 0 ? -unit : unit, (i & 2) != 0 ? -s1 : s1 ]
		p[i + 4] = [ (i & 1) != 0 ? -unit : unit, (i & 2) != 0 ? -s1 : s1, 0 ]
		p[i + 8] = [ (i & 1) != 0 ? -s1 : s1, 0,(i & 2) != 0 ? -unit : unit ]
	end
	icosaeder.entities.add_face([p[0], p[4], p[5]]);
	icosaeder.entities.add_face([p[2], p[4], p[5]]);
	icosaeder.entities.add_face([p[1], p[6], p[7]]);
	icosaeder.entities.add_face([p[3], p[6], p[7]]);
	icosaeder.entities.add_face([p[0], p[1], p[8]]);
	icosaeder.entities.add_face([p[0], p[4], p[8]]);
	icosaeder.entities.add_face([p[1], p[6], p[8]]);
	icosaeder.entities.add_face([p[0], p[1], p[9]]);
	icosaeder.entities.add_face([p[0], p[5], p[9]]);
	icosaeder.entities.add_face([p[1], p[7], p[9]]);
	icosaeder.entities.add_face([p[2], p[3], p[10]]);
	icosaeder.entities.add_face([p[2], p[4], p[10]]);
	icosaeder.entities.add_face([p[3], p[6], p[10]]);
	icosaeder.entities.add_face([p[4], p[8], p[10]]);
	icosaeder.entities.add_face([p[6], p[8], p[10]]);
	icosaeder.entities.add_face([p[2], p[3], p[11]]);
	icosaeder.entities.add_face([p[2], p[5], p[11]]);
	icosaeder.entities.add_face([p[3], p[7], p[11]]);
	icosaeder.entities.add_face([p[5], p[9], p[11]]);
	icosaeder.entities.add_face([p[7], p[9], p[11]]);
	trans = Geom::Transformation.new([0, 0, 0]);
	Sketchup.active_model.active_entities.add_instance(icosaeder, trans);
end



```

以上。
ビット演算を活用して処理速度を高速化する方法 (for TypeScript)

# 初め
%演算じゃなくビット演算で最適化をすることでどのくらい高速化するのか気になってテストしました。

# Code
```typescript
const startTime0 = performance.now();
const arr = [...Array(1000000)].map((_, i) => i);
const endTime0 = performance.now();
console.log(
  `Execution Initialization: ${(endTime0 - startTime0).toFixed(2)} ms`
);

const startTime1 = performance.now();

// %計算
const evenNumbers = arr.filter((num) => num % 2 === 0);
const endTime1 = performance.now();
console.log(
  `Execution time with % 2: ${(endTime1 - startTime1).toFixed(2)} ms`
);

const startTime2 = performance.now();

//&演算
const evenNumbersBitwise = arr.filter((num) => (num & 1) === 0);
const endTime2 = performance.now();
console.log(
  `Execution time with & 1: ${(endTime2 - startTime2).toFixed(2)} ms`
);
```

# Result
```
$ node test2.js
Execution Initialization: 22.61 ms
Execution time with % 2: 25.86 ms
Execution time with & 1: 24.48 ms
$ node test2.js
Execution Initialization: 29.62 ms
Execution time with % 2: 24.02 ms
Execution time with & 1: 24.64 ms
$ node test2.js
Execution Initialization: 22.40 ms
Execution time with % 2: 24.04 ms
Execution time with & 1: 22.34 ms
$ node test2.js
Execution Initialization: 30.47 ms
Execution time with % 2: 26.98 ms
Execution time with & 1: 23.18 ms
```

# 最後
ビット演算を使用することで、計算速度が大幅に向上することがわかりました。もし、最適化が必要な場合はビット演算を試すことが効果的です。

ただし、ビット演算は理解が難しいと感じるチームメンバーもいるかもしれません。その場合、適切にドキュメントを作成して説明を加えることが重要だと思います。

ps.コードに問題がありました。😭
@yoshi389111 ありがとうございます。
PowerAppsのフォームの表示がおかしい場合の対処法

SharePointリストのデータをPowerAppsで読み込んで編集するアプリを作成しています

垂直ギャラリーでリストのデータを読み込み、フォームで編集する形を取っていますが
ギャラリーでは表示されてもフォーム上で表示されない現象に出くわしたため
解消法を記載します
![2025-03-31_16h12_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540456/f660ee80-b5f3-483c-8720-2725c1a84f9b.png)
左側がギャラリー、右側がフォームです
フォームには名前が表示されずINJECT0と表示されてしまいます



![2025-03-31_16h18_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540456/a39b092d-fc9f-460e-992a-06411fff9db8.png)


フォームの対象のカードの中のカードバリューを選択して、プロパティのフィールド⇒編集ボタンを押します
![2025-03-31_16h18_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540456/eacc2778-6712-47b8-b604-0659e765b28a.png)


フィールドの追加ボタンを押します
![2025-03-31_16h18_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540456/b3efb3e4-687f-4d68-97bb-444a79c0fb89.png)

今回はDisplayNameを選択して、追加ボタンを押します
![2025-03-31_16h18_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540456/33fa618a-693d-4ca9-aba7-e290f6efaa99.png)
表示されました。
Quick Data Insights with Formulas



# Create a Formula Field

これではダメですね

```
today() - DATEVALUE(ActivatedDate)
```

:::note alert
On the 'Days Active' field, we can’t find a formula that subtracts the Activated Date from today.
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3d097ffe-6abd-422c-9fa9-134c518be13b.png)

もしかして、ActivatedDateに値が無い時を考慮する？

```
IF( ISBLANK(ActivatedDate) ,0,today() - DATEVALUE(ActivatedDate))
````

同じエラーですね。

新しいプレイグランドを使えって...

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000FXdSoSAL

お題がちょっと違う？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7762d290-6745-4a2c-a103-2614a462396f.png)

https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifqZASAY

やっぱり同じエラーですね。


そういえば、気をきかして小数点はないだろうとゼロにしていたのを２に戻して、TODAYを大文字にしたら合格しましたね。何を見ているんだろうか...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1835cffa-9cdf-4d9c-a6b3-0985ec70395f.png)

# Use Logic in Formulas

なんだ、次のお題がEndDateがいるんですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a4870e79-fdf5-4bfc-8ddf-9a67def8c200.png)

少しお遊びで少数点を無しにしてみましたが今度が合格ですね。ブラウザのキャッシュ？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8e3b82af-dbba-48f0-ad8f-0c48af6f7074.png)
AWS WAF設定したら発生したバグの原因がCommonRuleSetだった話



## はじめに

AWS WAF（Web Application Firewall）はウェブアプリケーションを様々な攻撃から保護するための強力なサービスです。しかし、適切に設定しないと正常なユーザーリクエストまでブロックしてしまうという事態に陥ることがあります。

この記事では、AWS WAFの`CommonRuleSet`によって発生した実際のトラブル事例と、その解決方法について共有します。これからWAFを導入する方や、現在のWAF設定を見直したい方の参考になれば幸いです。

## 発生した問題

AWS WAFを本番環境に導入したところ、アプリケーションの一部機能にバグが発生。

### 問題の詳細
- WebACLに登録した`CommonRuleSet`のルールの一つ、`SizeRestrictions_BODY`の影響で正常なリクエストがブロックされた
- アプリケーション仕様上、正当に大きなデータを送信する必要がある機能が、データ量超過と判定され検知
- ユーザーからのエラー報告により発覚、WAFのログを確認することで原因を特定

## 原因の分析

`CommonRuleSet`はAWS WAFが提供する一般的な脅威に対する保護ルールセットですが、その中の`SizeRestrictions_BODY`ルールはHTTPリクエストボディのサイズ制限を設けています。

デフォルト設定では、このサイズ制限を超えるリクエストは「潜在的な攻撃」として自動的にブロックされてしまいます。

しかし、以下のような正当なユースケースでも大きなリクエストボディが必要な場合があります：
- ファイルアップロード機能
- リッチテキストエディタの保存
- 大量のフォームデータを送信する画面
- APIによる一括データ処理

今回のケースでは、アプリケーションの正常な機能であるにもかかわらず、WAFルールにより不正なリクエストとして判定・ブロックされてしまいました。

## 対応策

個別のルール内容自体は変更できないため、ルールの「アクション」を変更することで対応。

### 具体的な解決方法
1. AWS マネジメントコンソールからWAFコンソールにアクセス
2. 該当するWebACLを選択
3. ルールグループ内の`SizeRestrictions_BODY`ルールを見つける
4. アクションのオーバーライドを「ブロック」から「カウント」に変更

![AWSWAF-CommonRuleSet_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522661/34123752-2afc-472a-8c17-ad0b7e22dd12.png)

![AWSWAF-CommonRuleSet_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522661/fdd3bc36-e272-4000-87f9-2ac6970ea511.png)



これにより、サイズ制限を超えるリクエストも**ブロックされずに通過**するようになり、アプリケーションの機能が正常に動作するようになりました。

同時に、「カウント」モードにすることで、該当するリクエストのログは引き続き記録されるため、不正なリクエストが増加していないかモニタリングすることも可能です。

:::note warn
注意
このAWS WAFの設定コンソールは2025年3月現在のUIです。
:::

## 教訓と推奨事項

この経験から得られた教訓として、以下を強くお勧めします：

### WAF導入時のベストプラクティス

1. **段階的な導入**
   - 最初は全てのルールを「カウント」モードで設定
   - ログを分析し、正常なトラフィックへの影響を確認
   - 問題がなければ段階的に「ブロック」モードに移行

2. **検証環境での事前テスト**
   - 本番環境への適用前に必ず検証環境でテスト
   - アプリケーションの全機能が正常に動作するか確認
   - 特に大きなデータを扱う機能の動作確認を重点的に

3. **ルールの詳細確認**
   - 特に`CommonRuleSet`や`AWSManagedRulesCommonRuleSet`など定義済みルールセットの詳細を理解
   - 各ルールがどのようなリクエストを検知・ブロックするか把握
   - [AWS公式ドキュメント](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html)で各ルールの詳細を確認

4. **監視体制の整備**
   - WAFのログを定期的に分析
   - 誤検知やブロックの傾向を把握
   - CloudWatchアラームの設定で異常を早期検知

## まとめ

AWS WAFは強力なセキュリティサービスですが、正しく設定しないとアプリケーションの正常な機能までブロックしてしまう可能性があります。特に`CommonRuleSet`のような定義済みルールセットを使用する際は、各ルールの挙動を理解し、アプリケーションの特性に合わせて適切な設定を行うことが重要です。

段階的な導入と丁寧な検証を行うことで、セキュリティとユーザビリティの両立が可能になります。WAF導入時には、この記事で紹介したような潜在的な問題に注意しながら、慎重に設定を進めていきましょう。

## 参考資料
- [AWS WAF ドキュメント](https://docs.aws.amazon.com/waf/latest/developerguide/what-is-aws-waf.html)
- [AWS Managed Rules for AWS WAF](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html)
- [WAF のトラブルシューティング](https://docs.aws.amazon.com/waf/latest/developerguide/waf-troubleshooting.html)

---

※画像はイメージです。実際の設定画面とは異なる場合があります。
【Power Automate】SharePoint にアイテムが追加された時をトリガーにメールの自動送信を試してみよう！

# 概要
Power Automateでメールを自動送信するフローを作成するのは簡単です。
本記事では、指定した条件で自動的にメールを送信するフローを作成する手順を紹介します。

## 作成するフローの概要:writing_hand:
+ 新しいデータが SharePointリストに追加されたとき、その内容を確認し、
特定の条件に基づいてメールを送信する。
+ 例えば、 **`「予約」`** というタグがリスト項目に含まれている場合に、
特定の宛先にメールを送信します。

## フローの作成手順:tools:
1\. Power Automate にログイン
2\. [+ 新しいフロー] を選択し、[自動化したクラウドフローを構築する] を選択します。
3\. トリガーを設定します。
**サイトのアドレス：使用する SharePoint サイトのアドレス**
**リスト名：使用するリストを選択**

4\. [+新しいステップ] で **`[条件]`** アクションを選択します。
5\. 条件設定で **`タイトル`** に **`「予約」`** が含まれているか判定する式を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/4cb797f9-2700-477f-b504-91e0f4c977ab.png)


6\. True の場合にメールの送信を行うアクションを追加します。
　[アクションの追加] で [メールの送信] を選択します。
 　詳細を入力します。
　**宛先：送信先のメールアドレス**
 　**件名：メールの件名**
  　**本文：メールの本文**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/268e4cb9-69fa-47d9-9ec8-2282bcaa2236.png)


7\. フローを保存し、テストを実行します。
SharePoint リストに新しいアイテムを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/2b6c1f58-f643-49d6-82f8-1acef6d2ce74.png)

しばらくすると実行結果が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/d304e62d-80ac-42de-9e78-642c92fcedb5.png)

フローは正常に完了しました。
次に Outlook にメールが届いているかも確認します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/0a4183e2-b057-4fa9-9f2b-e2e27b9a9b99.png)

こちらも問題なく届いていました。
**`「予約」`** というタグがタイトルが含まれていると Outlook にメールが届くことが確認できました。

次は **`「予約」`** というタグが含まれない場合をテストしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/0c58f2f2-10cd-4db5-9b67-cbd37b804659.png)

SharePoint リストに「備品申請」という名前で新しいアイテムを追加してみます。
フローの実行結果を確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/3d7f04b2-b028-47c4-9129-597550582464.png)

条件に当てはまらないため `false` 判定となりフローはそこで終了。
メールも届かないため、設定が問題なく行えているということになります。

## よくあるエラー:warning:
+ メールが送信されない
【原因】メールアドレスが正しく設定されていない
　　　　Power Automate のメール送信コネクタに接続されていない
【対策】メールアドレスとコネクタ設定を再確認し、接続を再認証します

+ 条件がうまく動作しない
【原因】条件式に誤りがある（例えば、フィールド名が正しくない）
【対策】条件式を再確認し、必要なフィー
ルド名や条件を適切に設定します

## まとめ:star:
このフローを活用すれば特定の条件で自動的に通知を送るなど、
さまざまなシナリオに対応できます！
ぜひいろんなパターンで活用してみてください！！
第21回 ネットワーク運用現場でCopilotを使用した業務改善を実施

## 業務課題
あるネットワークの設定変更作業を行う際、**ポート番号の表記**がコンフィグ作成ツールと既存コンフィグでは異なっており
投入業が数十行に増える場合も目視確認に頼らねばならず、**作業当日のコンフィグの漏れ、作成者のコンフィグミスによる作り直しが頻発し、品質の問題が発生していた。**

リーダーにアサインされた際、この課題を解決するため
コンフィグの**重複確認ツール**を作成して運用への導入をメンバーに提案
同時に**生成AIのCopilot**を使用してコンフィグを自動で置換するコードを書いてもらいチェックシートにマクロを導入。

**※本記事の内容は、実務で得た知見をもとに再現・一般化したものです。実際の業務とは異なる構成・データを使用しています。**


## Copilotを使用した業務改善の流れ

#### ①ポート番号80をwwwに置換するためのコードを教えてもらう。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559536/d8ceae3a-ac4a-43e6-b952-4e19c47c7d74.png)

#### ②教えてもらったコードを参考にポート番号500,4500を置換するマクロも作成する。
```ruby:各ポートの置換コード
Sub ポート番号80置換()
    Dim ws As Worksheet
    Dim cell As Range
    For Each ws In ThisWorkbook.Worksheets
        For Each cell In ws.UsedRange
            If InStr(cell.Value, "eq 80") > 0 Then
                cell.Value = Replace(cell.Value, "eq 80", "eq www")
            End If
        Next cell
    Next ws
End Sub
------
Sub ポート番号500置換()
    Dim ws As Worksheet
    Dim cell As Range
    For Each ws In ThisWorkbook.Worksheets
        For Each cell In ws.UsedRange
            If InStr(cell.Value, "eq 500") > 0 Then
                cell.Value = Replace(cell.Value, "eq 500", "eq isakmp")
            End If
        Next cell
    Next ws
End Sub
------
Sub ポート番号4500置換()
    Dim ws As Worksheet
    Dim cell As Range
    For Each ws In ThisWorkbook.Worksheets
        For Each cell In ws.UsedRange
            If InStr(cell.Value, "eq 4500") > 0 Then
                cell.Value = Replace(cell.Value, "eq 4500", "eq non500-isakmp")
            End If
        Next cell
    Next ws
End Sub
```
#### ③ポート番号500,4500はセットで投入する必要があるので両方のマクロを同時に実行するコードを教えてもらう。
![②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559536/34ea9ebe-73f5-43c0-851c-dc59a97ca116.png)
```ruby:ポート500,4500を同時に置換するコード
Sub 複数ポート置換()
    Call ポート番号500置換    
    Call ポート番号4500置換
End Sub
```

#### ④教えてもらったコードをそれぞれVBAのタブへ登録し実行。
![③.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559536/56694a97-ca9e-4cbf-b512-c91596abdd19.png)

#### ⑤各ポート番号の表記が想定の結果に置換され、既存設定と一致しているかの目視確認がしやすくなった。
![④.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559536/f0bc12b4-7330-4d06-badc-76f371b560c6.png)


### 結果
チェックツールを導入したことで、コンフィグの作り直しの件数も**平均１回未満に減少**。
また準備段階でコンフィグの正当性が担保され、**作業当日のコンフィグ漏れ等によるトラブルが激減**したことで**効率化と品質向上を同時に実現。**

## 今後
これまではプログラミングを習得する際、ゼロから調べて作成するため時間もかかり、プログラミングが現場で使用できるのは限られた人しかいないことがよくあった。
しかしCopilotなどの生成AIを使用することで誰でもコードを作成することができ、業務改善に**プログラミングを導入するハードルが一気に下がった**と実感した。
ネットワークエンジニアもプログラミング習得の必要性があるからこそ、積極的に実務で活用し、将来的には**生成AIを活用したネットワークの運用現場**を実現していきたい。

## 次回
生成AIに興味が出たので、ちょっとこれ関連の記事を書いてみようかなと思います。
あくまで予定なので、内容は急にかわるかもしれないです
Copilot 演習シナリオ：プロンプトの最適化をするプロンプト

#### Copilot 無償版

Copilotに投げ込む命令文をプロンプトといいます。
AIは自然言語処理にたけているため、命令が多少揺れても受け入れて処理を始めます。
一方で、命令が曖昧である場合などは、人間の期待から外れる回答を生成する現象が発生します。
このためプロンプトの構成には注意を払う必要があります。

Copilotは日常の些細なタスク負荷を軽減することに価値があります。
精度の高い回答を取り出したいがために、プロンプトの構成に時間を取られてしまっては本末転倒と言えるでしょう。

ん・・・？プロンプトもCopilotに書いてもらえばいいのでは？
やってみましょうか。

### 演習シナリオ
あなたは自動車製造業の営業担当者です。
毎日の日課として、過去7日分の自動車業界に関するニューストピックを確認しています。
主要なニュースサイトはブラウザのお気に入り登録をしていますが、量が多くて確認に時間がかかります。
そのうえ、自分にはあまり関係ないニュースがたくさん含まれており、情報の取捨選択が大変です。
Copilotを活用して、毎朝の情報確認を簡単にできるのでは？と思いつきました。
やってみましたが、期待する生成結果が得られず、ちょっぴり絶望しているところです。

**1.Copilotを開きます。**
https://copilot.microsoft.com/

**2.次のプロンプトをコピーして、Copilotのプロンプトウインドウに張り付けて実行します。**
~~~
私は自動車製造業の営業担当者です。
毎日の日課として、過去7日分の自動車業界に関するニューストピックを確認しています。
主要なニュースサイトはブラウザのお気に入り登録をしていますが、量が多くて確認に時間がかかります。
そのうえ、自分にはあまり関係ないニュースがたくさん含まれており、情報の取捨選択が大変です。
私を満足させる、繰り返し利用できるプロンプトを生成してください。
~~~
**3.次のような結果が生成されました。**

それは大変ですね。効率的にニュースを確認できるように、以下のプロンプトを使ってみてください。このプロンプトを毎日利用することで、過去7日間の自動車業界に関する重要なニュースを素早く把握できます。
#### ニュース確認プロンプト
```
過去7日間の自動車業界に関する主要なニュースを教えてください。特に以下のトピックに関連するニュースを優先してください：
1. 新車の発表やリリース
2. 自動車メーカーの業績や財務報告
3. 業界全体のトレンドや市場動向
4. 主要な企業の戦略的提携や買収
5. 技術革新や新技術の導入
6. 規制や法改正に関する情報
7. その他、営業活動に影響を与える重要なニュース

ニュースの要約と、そのニュースがどのように業界や営業活動に影響を与えるかについても教えてください。
```
このプロンプトを使うことで、関係のないニュースを除外し、重要な情報に集中できるようになります。毎日のニュース確認が効率的になり、営業活動に役立つ情報を素早く得られるでしょう。何か他にお手伝いできることがあれば教えてくださいね。

**4.生成されたプロンプトに対し、情報の過不足を確認します。**
不要な項目があれば削除し、ほしい情報があれば追記しましょう。
例）
自動車産業業界において大きな株価の動きがあれば、あわせて教えてください。
リコールなど、品質に関するニュースは必ず含めてください。

修正したら実行してみましょう。

**4.満足いく結果が出るようなら、プロンプトを保存しましょう。**
高頻度で活用するプロンプトは、この機能で簡単に呼び出せるようにしておきましょう。
・保存手順
実行したプロンプトにマウスポインタを乗せ、表示されるリボンマークをクリックします。
「このプロンプトを保存しますか？」画面が表示されます。適切な名前に変更して保存します。
・呼出手順
プロンプトウインドウの右上にある「プロンプトを表示する」リンクをクリックします。
「プロンプト」ボタンをクリックすると、保存したプロンプトを呼び出すことができます。


----
この演習はこれで終了です。
みなさまの仕事に応用してみましょう。
rspec-mocks の stub/unstub を allow に置き換える

## やりたいこと

[RSpec](https://github.com/rspec/rspec) を使ったテストコードで stub/unstub という古いメソッドを使用している箇所があった。allow[^1]に置き換えたい。

[^1]:allow を使った記法は RSpec 2.14 で rspec-mocks に導入された。そして 2025/03/31 (月) 時点の RSpec の最新バージョンは 3.13.0。

## 方法 1

厳密には unstub と互換性のある方法はない。and_call_original で元のメソッドを呼び出すようにすることで擬似的にスタブを解除する。

```rb
Hoge.stub(:fuga)
Hoge.unstub(:fuga)
```
↓
```rb
allow(Hoge).to receive(:fuga)
allow(Hoge).to receive(:fuga).and_call_original
```

## 方法 2

以下の方法でスタブを解除できるが、公開されている方法ではない (undocumented) ので非推奨。

```rb
Hoge.stub(:fuga)
Hoge.unstub(:fuga)
```
↓
```rb
allow(Hoge).to receive(:fuga)
RSpec::Mocks.space.proxy_for(Hoge).reset
```
分散ストレージ（Ceph）と共有ストレージ（FC・iSCSI）のHWコスト比較

オンプレ仮想基盤を構築する際に、分散ストレージ（Csph）を採用することでコストメリットが出ると思い込んでいたのですが、あれ？と思うことがあったので比較してみました。

想定機器、部品は

サーバ：HP DL360
参考：https://h50146.www5.hpe.com/directplus_ent/library/pdfs_servers/dl360gen11.pdf
　・FC HBA：32Gb 2port ファイバーチャネル ホスト バス アダプター：493,000 円
　・10GbE：Broadcom BCM57416 Ethernet 10Gb 2-port BASE-T Adapter for HPE：105,000 円
　・SSD：HPE 1.92TB SATA 6G Read Intensive SFF BC Multi Vendor SSD：216,000 円

ストレージ：HP MSA2060
参考：https://h50146.www5.hpe.com/directplus_ent/library/pdfs_storage/msa_gen6.pdf
　・FCストレージ：MSA 2060 16Gb FC 2.5 型 ストレージ (2U)：2,350,000 円
　・iSCSIストレージ：MSA 2060 10GBASE-T iSCSI 2.5 型 ストレージ (2U)：2,550,000 円
　・HDD：MSA 1.8TB 12G SAS 10krpm 2.5 型 M2 Enterprise ハードディスクドライブ：200,000 円
　・SSD：MSA 1.92TB 12G SAS 2.5 型 Read Intensive (RI) M2 ソリッドステートドライブ：474,000 円

Ceph用10GbE SW：HPE Networking Instant On 1960
参考：https://www.idaten.ne.jp/portal/page/out/mss/hpe/aruba_instant_on_switches.html
　・HPE Networking Instant On 1960 12XGT 4SFP+ Switch：237,000 円

3ノード想定なのでFCスイッチはなし

Ceph・FC・iSCSIそれぞれで以下の構成で計算しています。
・Ceph構成：サーバごとに2Port 10Gb NICを1枚搭載、10GbE SWを2台
・FC構成：サーバごとに2Port FC HBAを1枚搭載、MSA2060 FCを1台、RAID5/10の2パターン
、スペアディスク1本
・iSCSI構成：サーバごとに2Port 10Gb NICを1枚搭載、MSA2060 iSCSIを1台、RAID5/10の2パターン
、スペアディスク1本

ディスク容量ごとのコストを表にまとめたものが以下です。
（容量目安は1.8TBディスク基準で、Ceph構成では1.92TBディスクになるのですこし増えます）
![cephコスト比較_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3868024/0a302793-b99b-4560-8211-c7d0a5c0e555.jpeg)
この表では、容量次第ですがCeph構成でのコストメリットはかなりありそう。
それでも、10TB超えたところから構成次第で共有ストレージの方が安くなりますね。
Cephの場合データが3多重で保持されるため、容量が大きくなるにつれて共有ストレージにコストが追い付いていきますが、3ノードであればCephの方が安くなることが多そうです。

ちなみに、Ceph構成での10GbE SWをCisco製にすると、おそらくC9200が候補になると思いますが、価格が跳ね上がります。
参考：https://www.it-ex.com/products/maker/cisco/catalyst9200.html
C9200-24PXG-E：1,314,900 円
C9200を採用した場合のコスト比較は以下のようになりました。
![cephコスト比較_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3868024/55011c51-2e81-46da-b442-5b70e67695b7.jpeg)
HDD利用であれば共有ストレージの方が安価になるパターンが多く、SSD利用であってもRAID5なら価格差がかなり縮まりますね。

これが5ノード以上になると、共有ストレージ構成ではFCスイッチ（HPのものだと1台1,429,000円）や10GbE SWが必要になるため、共有ストレージ構成の方がコスト面で不利になりそうです。

とはいえ、ここまでの話は全てHP製品の標準価格での比較のため、製品や値引き等で変わってきますので、あくまで目安ということで。

大した結論はありませんが、容量が増えるほど共有ストレージの方が有利になっていき10TBあたりが目安になりそうなこと、10GbE SWにCisco製品を採用する場合はCephのコストメリットがあまりなさそうなこと、が確認できました。
WindowsServer2022でSMTPサーバーを立てる

# 概要
WindowsServer2022でSMTPサーバーの機能を追加したところ、
「スナップイン エラー」が出てプロパティ設定ができなかったので備忘録

# 手順
### 1. 役割と機能の追加
1. サーバーマネージャーから[管理(M)] - [役割と機能の追加] を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756373/34589be7-1d76-4868-a6d3-e2ae98e691fa.png)

2. 機能 ページで [SMTPサーバー]をチェックして［インストール］ボタンを押下する
※IISがインストールされていない場合は サーバーの役割 ページで [Webサーバー(IIS)] を追加すること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756373/0d377c7f-c047-4776-9ebc-a04bfbc61133.png)

### 2. 設定ファイルの更新
1. C:\Windows\System32\inetsvr\MetaBase.xml を開き、<IIsSmtpService>タグの設定を編集する
RelayIpListの設定値を""に変更する

### 3. プロパティの設定
プロパティが設定できるようになる

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756373/8aa72f5d-d936-475d-ade9-faebc84c3f4e.png)

# 参考
[Windows Server 2022のIIS6.0でSMTPサーバを稼働させる方法を調べてみた](https://www.kaesakura.com/2022/08/windowsserver2022-smtpserver/)
[Terraform] TerraformとGithub CICDパイプラインの組み合わせ

## 前書き
​Terraformは、インフラストラクチャをコードとして管理するための強力なツールです。​これをGitHubのCI/CDパイプラインと組み合わせることで、インフラの変更を自動的にテストし、適用するプロセスを構築できます。​本記事では、Terraformコードを作成し、GitHub Actionsを使用してCI/CDを設定する手順と、定義ファイルのサンプルコードを紹介します。

## 前提条件
・GitHubリポジトリが作成されていること
・Terraformがローカル環境にインストールされていること
・デプロイ先のクラウドプロバイダー（例：AWS、GCP）の認証情報が取得済みであること

### ステップ1: Terraformコードの作成
まず、Terraformを使用して管理したいインフラストラクチャのコードを作成します。​以下は、AWS上にS3バケットを作成するシンプルな例です。

```main.tf
provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_s3_bucket" "example" {
  bucket = "my-unique-bucket-name"
  acl    = "private"
}
```
このコードは、ap-northeast-1リージョンにプライベートなS3バケットを作成します。

### ステップ2: GitHubリポジトリへのプッシュ
作成したTerraformコードをGitHubリポジトリにプッシュします。​リポジトリのルートディレクトリに.github/workflowsディレクトリを作成し、ここに後述のワークフローファイルを配置します。

### ステップ3: GitHub Actionsワークフローの設定
GitHub Actionsを使用して、Terraformのplanとapplyを自動化するワークフローを設定します。​以下のYAMLファイルを.github/workflows/terraform.ymlとして作成します。
```.github/workflows/terraform.yml
name: Terraform CI/CD

on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
    - name: code check
      uses: actions/checkout@v2

    - name: Terraform install
      uses: hashicorp/setup-terraform@v1

    - name: Terraform init
      run: terraform init

    - name: Terraform fmt check
      run: terraform fmt -check

    - name: Terraform plan
      if: github.event_name == 'pull_request'
      run: terraform plan

    - name: Terraform apply
      if: github.event_name == 'push'
      run: terraform apply -auto-approve
```
このワークフローは、プルリクエスト時にterraform planを実行し、mainブランチへのプッシュ時にterraform applyを自動的に実行します。

### ステップ4: クラウドプロバイダーの認証設定
Terraformがクラウドプロバイダーにアクセスするための認証情報をGitHub Actionsに設定する必要があります。​例えば、AWSの場合、以下のようにAWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYをGitHubのシークレットとして設定し、ワークフロー内で使用します。​

```.github/workflow/terraform.yml
    - name: AWS認証情報の設定
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ap-northeast-1
```
これにより、GitHub Actions内でAWSへの認証が可能となります。

### ステップ5: ワークフローのテスト
設定が完了したら、プルリクエストを作成してterraform planが実行されることを確認し、mainブランチにマージしてterraform applyが実行されることを確認します。​これにより、インフラストラクチャの変更が自動的に適用されることを検証できます。​

## まとめ
本記事では、Terraformコードを作成し、GitHub Actionsを使用してCI/CDパイプラインを構築する手順を紹介しました。​この設定により、インフラストラクチャの変更を自動的にテストし、適用するプロセスを実現できます。​さらに詳細な設定やベストプラクティスについては、以下の参考記事もご参照ください。​
・ [Terraform+GitHubActionsでGoogleCloudのCI/CD構築入門](https://zenn.dev/optimind/articles/googlecloud-githubactions-terraform-cicd
 "Terraform+GitHubActionsでGoogleCloudのCI/CD構築入門")
 ・ [The complete CI/CD solution](https://github.com/solutions/use-case/ci-cd
 "The complete CI/CD solution")

これらの記事も参考にしながら、ご自身のプロジェクトに適したCI/CDパイプラインを構築してみましょう！
#0090（2024/03/31）データウェアハウスとは

## データウェアハウス（Data Warehouse）とは？

**データウェアハウス（Data Warehouse）** は、組織内外の多様な情報源から収集した大量のデータを統合し、分析や意思決定支援を目的として構築された大規模なデータリポジトリです。特に、OLAP（Online Analytical Processing）と呼ばれる分析処理のために設計されています。

---

### データウェアハウスの特性

データウェアハウスの基本的特性は、Inmonによる定義に従い、以下の4つで構成されます。

- **統合性（Integrated）**
  - 異なるデータソースから収集したデータを一貫性ある形式で統合。

- **時系列性（Time-variant）**
  - 過去のデータ履歴を保持し、時系列分析を可能にする。

- **非更新性（Non-volatile）**
  - 一旦格納したデータは基本的に変更・削除を行わず、安定性を確保。

- **主題指向性（Subject-oriented）**
  - 組織の特定領域（売上、顧客、製品など）の分析に特化した構造。

---

### データウェアハウスの主要な用途

データウェアハウスは主に以下のような高度な分析用途に活用されます。

- 経営戦略・意思決定支援
- 市場分析・顧客行動分析
- トレンド分析と予測分析
- 業務効率の評価・改善

---

### データウェアハウスの構成要素

データウェアハウスシステムは以下の要素から構成されます。

1. **データソース（Data Sources）**
   - 組織内外の多種多様な業務システムや外部データからデータを収集。

2. **ETLプロセス（Extract, Transform, Load）**
   - データ抽出（Extract）、データ変換（Transform）、データ格納（Load）を行い、分析可能な状態へ整備。

3. **データウェアハウス（DWH）本体**
   - ETLで処理されたデータを蓄積し、分析が効率よく行える構造に整理。

4. **分析・可視化ツール（BIツール）**
   - データウェアハウスに格納されたデータを多次元分析し、レポーティングや視覚的分析を実施。

---

### 代表的なデータウェアハウス製品

- **Amazon Redshift**（AWS）
- **Google BigQuery**（Google Cloud Platform）
- **Snowflake**（クラウドベースのDWHソリューション）
- **Azure Synapse Analytics**（Microsoft Azure）

---

### データウェアハウスと一般的なデータベース（OLTP）との比較

| 項目       | データウェアハウス（OLAP） | データベース（OLTP） |
|------------|---------------------------|----------------------|
| 主な用途   | 意思決定支援、分析処理      | 日常業務のトランザクション処理 |
| 操作特性   | 大量データの読み取り中心     | リアルタイムな読み書き |
| データの特徴 | 時系列の履歴データ保持       | 最新の状態を保持      |

- **OLAP（Online Analytical Processing）** は、多次元データを用いた高度な分析処理。
- **OLTP（Online Transaction Processing）** は、リアルタイムな業務データ処理。

---

データウェアハウスは大量データを統合し、効果的な分析を通じて企業や組織の戦略的意思決定を支援する重要な基盤となります。特にビッグデータや高度な分析技術の進展により、現代の情報戦略においてその重要性が一層高まっています。
もうエンジニア2年目が終わってしまう... 振り返ろう

こんにちは。

もう今日でエンジニア2年目（社会人2年目）が終わってしまうので、この一年を振り返ってみました。

一年前はこんな記事を書いていたようです。

https://qiita.com/PDC-Kurashinak/items/ca6d30c0f2c6220d306e

ちょっと自己評価みたいになっちゃいます...！

## 自分の業務について

今年は何やってたっけ？って考えてたら、ざっくりとこんな業務をやってました。

* 社内向けWebアプリケーションの開発（実装/試験/リリース）
* 生成AIを使用したチャットアプリの開発（設計/実装/試験/リリース）
* インターンシップの募集・運営
* 学生アルバイトの教育

割合はこんな感じかな？

| 業務内容 | 割合 |
| --- | --- |
| 社内向けWebアプリ開発 | 6割 |
| 生成AIチャットアプリ | 1割 |
| インターンシップ | 1割 |
| アルバイト | 1割 |
| その他 | 1割 |

結構色々やってんのよなぁ

## 社内向けWebアプリ開発

Webアプリ開発で使用しているフレームワークは、Ruby on Railsです。

### よかったこと

* 1年目からずっとやっていた内容ではあるが、**コーディング技術**は明らかに成長した
* 上司からの設計に対して、**不足分や疑問点に自分で気づき、迅速に確認**することができた
* 他部署とのコミュニケーションを取ることで、**仕様の細かい部分まで考慮しながら実装を行う**ことができた

### 反省点

* RubocopやRSpec、E2Eテストなどの**自動テストのメンテナンス**まで手が回っていなくて、品質を担保できていなかった
* **試験仕様書の考慮漏れによるバグ**が多く、再リリースが何度も発生してしまった

## 生成AIチャットアプリ

### よかったこと

* **普段の業務で使用しない技術を使用して開発**を行うことができた
* **社内でよく使用するツール（SlackやTeams）の中でシステムを構築**することができた
* **社内業務の細かい部分まで考慮しながらシステムを構築**することができた

### 反省点

* 当初は「AI使ってる！すごい！」ってなったが、**時間が経つにつれて使用されなくなってしまった**

## 3年目はこうなる！

### とにかくバグを減らすための努力をする！

具体的には、

* 自動テストを定期的にメンテナンスする
    * メンテナンスする工数が足りなくて欲しい場合は上司と交渉する
* 試験仕様書の作成のステップを充実させて、考慮漏れが発生しないようにする
    * 試験仕様書作成計画 → 試験仕様書作成計画レビュー → 試験仕様書作成 のステップを踏むようにする

あとは、 **DBのバックアップ**はマジで取得しておきましょう...

### Qiita,noteの記事の執筆をする！

備忘録として、107個の記事を書いてきました（本記事執筆時点）が、もっと深い内容の記事を書いていきたいなぁって思っています。
あとは、Qiitaだけじゃなくてnoteの方でも非技術的なことを書いていけたらいいなって思っています

https://note.com/kurakenkuraken

### 個人開発頑張る

自分の業務が楽になるように、システム開発部の業務が楽になるように、個人的にシステムの開発はやっていきたいなぁって思っています。
今開発したいと考えているものは以下です。

* ChatGPTに代わる生成AIチャットアプリ → Next.jsを使用したサーバレスアーキテクチャで開発中
* 試験仕様書作成CLI → いつかはRailsに組み込めるライブラリとしてリリースしたいなぁ
* データベース仕様書自動作成CLI → これはすぐにできそう

# まとめ

たくさんご迷惑をおかけしましたが、これからもたくさんご迷惑おかけします。
よろしくお願いいたします！

以上
個人的備忘録：仕事中にSysprepでつまずいたので、自分用のメモとしてまとめてみた

## はじめに
Sysprep（System Preparation Tool）は、Windows OSを汎用化するためのMicrosoft提供のツールです。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

マスターイメージを複数台のPCに展開する際に使用され、SID（セキュリティ識別子）の重複やその他固有情報を初期化する役割を果たします。

---

## 書こうと思ったきっかけ
Windows端末のキッティング作業で、同じイメージを複数台に展開したところ、ネットワーク上で重複による問題が発生したことが一度ありました。

**Sysprepとは？**

https://www.yrl.com/column/what-is-sysprep.html

SIDやコンピュータ名の重複を避けるため、Sysprepの重要性を再認識し、備忘録としてまとめることにしました。

---

## Sysprepの主な目的
- SID（セキュリティ識別子）の初期化
- ドライバや一部の設定を初期化
- 初回起動時にOOBE（Out-of-Box Experience）を実行
- イメージの再利用を可能にする
- Windowsの汎用イメージ化（展開前提の整備）

---

## 基本的な使い方
### 実行方法（GUI）
1. `C:\Windows\System32\Sysprep\sysprep.exe` を実行
2. システム準備ツールが起動
3. 以下を選択：
   - システムクリーンアップアクション → 「システムのOOBEに入る」
   - チェックを入れる → 「一般化（Generalize）」
   - シャットダウンオプション → 「シャットダウン」
4. 「OK」をクリックして実行

**参考文献**

https://a-zs.net/windows10-kitting-9/

### 実行方法（コマンドライン）
```cmd
sysprep /oobe /generalize /shutdown
```

**参考文献**

https://learn.microsoft.com/ja-jp/windows-hardware/manufacture/desktop/sysprep-command-line-options?view=windows-11

---

## 注意点
- 一度Sysprepを実行したイメージに対しては、3回までしかSysprepが実行できない制限がある（Windows仕様）
- ドメイン参加した状態でSysprepを実行すると、意図しない動作になる場合があるので注意
- 実行前にWindows Updateやストアアプリの更新を止めると安定しやすい
- 特定のアプリ（特に一部のUWPアプリ）はSysprepの妨げになることがある

**参考文献**

https://macruby.info/windows/what-time-sysprep-done.html#google_vignette

---

## おすすめの活用パターン
- 教育機関や企業で同一環境を複数台展開する場合のベースイメージ作成
- テスト環境の迅速な構築（Hyper-Vなどと組み合わせ）
- 一度設定を済ませたPC環境を別マシンに複製
- Windows展開サービス（WDS）やMDTとの連携での自動化利用

---

## まとめ
SysprepはWindows展開の現場では必須ともいえるツールです。特に複数台の端末に同じ環境を配布する際には、SIDや設定の初期化を通じてトラブルを未然に防ぐことができます。

また、OOBEや一般化を活用することで、ユーザーごとに環境を柔軟に整えることが可能になります。

:::note alert
**失敗しないためには、実行前の状態確認と、実行時のオプション選択が非常に重要です。**
:::

備忘録として残すことで、今後の展開作業の効率化と安定化につなげたいと思います！