OmniAICreator/Qiita-1.07M huggingface dataset:
感謝駆動開発エンジニア

# はじめに

この記事は[ファンタラクティブ 2024 年アドベントカレンダー](https://qiita.com/advent-calendar/2024/funteractive-inc) 12月20日の記事です

初めまして、ファンタラクティブ株式会社でフロントエンドエンジニアをしております、nuintee (ナインティー)です。

皆さんは普段どのように仕事のモチベーションを維持していますか？

筆者は「怒られる恐怖心」によるモチベーションについて、昨年このような記事を書きました。

https://qiita.com/nuinteedev/items/aeb06b68744caa232816

本記事では、筆者がそんな「怒られる恐怖心」によるモチベーションコントロールから、「感謝される嬉しさ・感謝する喜び」を原動力としたモチベーションコントロールへと移行していった個人的な成長過程と「感謝駆動開発」の魅力について書きました。

## 想定読者

- 仕事のモチベーションを高めたい方
- 感謝の表現に自信が持てない方
- より前向きな職場環境を求めている方

## 感謝駆動開発とは

開発の世界には、チケット駆動、テスト駆動、ドメイン駆動（設計）など様々な駆動方式が存在します。いずれも実体を持つものが主体となって進められますが、「感謝駆動開発」のアプローチは少し異なります。このアプローチは、感謝される喜びと感謝する行為そのものから生まれる心地よさを原動力に変えるモチベーションコントロール方法です。

(参考: [**感謝駆動開発 TDD (Thanks Driven Development)**](https://gongo.hatenablog.com/entry/20110304/1299213582))

### 感謝が原動力に

「感謝駆動開発」とは、エンジニアとしての仕事において「感謝される嬉しさ・期待感」と「感謝をする充実感」をモチベーションの中心に据える開発スタイルです。自分の仕事が誰かの役に立ち、感謝されることで、次の仕事へのエネルギーと意欲が自然と生まれるサイクルを作り出します。

### ありがとうが嫌な人はいない

「ありがとう」は魔法の言葉と呼ばれるほど、人の心を温かくし、前向きにする力があります。

「ありがとう」を伝えることは、相手の貢献を認め、その価値を直接的に伝える上でとても効果的な方法です。

この言葉を伝えることで：

- 相手は自身の仕事と努力が正当に評価されていると実感できます
- チーム内のコミュニケーションがより活性化されます
- メンバー間の相互信頼と尊敬が深まります

たとえ些細な貢献であっても、「ありがとう」の言葉は相手のモチベーションを劇的に高める可能性を秘めています。

感謝の気持ちを素直に、そして具体的に伝えることが重要なのです。

### 感謝される以上に感謝をする

感謝駆動開発において、「感謝されること」と同様に、「感謝すること」もまた重要な要素です。自ら進んで感謝する姿勢を持つことで、チームや職場全体にポジティブで生産的な雰囲気が自然と醸成され、結果として個々の仕事の質と効率が向上します。

## 怒られ駆動開発エンジニアの課題

筆者は以前、「怒られる恐怖心」をモチベーションの主な源泉として仕事をしていました。

納期を守らなければ叱責される、失敗すれば厳しく指摘される、そんな恐怖が仕事を進める原動力となっていた時期がありました。

しかし、このアプローチには本質的な限界があります。

短期的なモチベーションとしては有用なタイミングもありますが、
恐怖心という特性上、常に恐怖を感じる環境でない限り長期的なモチベーション維持が困難であり、持続可能な仕事の推進力として使って行くことは難しそうです。

## 「怒られ駆動」から「感謝駆動」へ

今でも怒られる事は正直怖いです。

しかし、この 1 年を通じて、気づかぬうちに「人の役に立つ仕事」「感謝される仕事」そのものにモチベーションを見出すようになっていました。

これは、挑戦と失敗に寛容なファンタラクティブの企業文化を通じて、良いものを作りたい、良い仕事をしたいという内発的な欲求が、徐々にポジティブなモチベーションへと昇華されていった結果だと考えています。

## 感謝駆動開発の魅力

### 心理的安全性の向上

「感謝駆動開発」によって職場に感謝の文化が根付くと、チーム全体の心理的安全性が自然と高まります。心理的安全性とは、失敗や意見を恐れることなく、安心して仕事ができる状態を指します。

感謝が日常的に交わされる環境では、チームメンバーが互いに助け合い、率直なフィードバックや建設的な提案がしやすくなります。結果として、チーム全体の生産性が向上し、より優れた成果を生み出しやすくなると思っています。

### 継続的なモチベーション維持

「怒られる恐怖」に基づくモチベーションは一時的で不安定ですが、「感謝される喜び」によるモチベーションは本質的に持続的です。

小さな感謝の積み重ねが、日々の業務に対する前向きな姿勢と内発的な動機づけを生み出します。特に長期的なプロジェクトや困難なタスクにおいて、この継続的なモチベーションが大きな原動力となります。

## 感謝駆動開発の実践方法

### とりあえず感謝

感謝駆動開発の最初のステップは、シンプルに「感謝すること」です。大げさな言葉や形式的な表現である必要はありません。

「ありがとう」と自然に伝えるだけで、チームの雰囲気は良くなります。

些細なことでも感謝を口にすることで、相手と自分の両方の気持ちが前向きになります。

例えば：

- 返信の最初に「ありがとうございます！」
- コードレビューをしてもらったら「ありがとうございます！」
- ちょっとしたサポートを受けたら「助かりました！」

感謝を習慣化することで、チーム全体が自然と感謝の輪を広げていくでしょう。

### スタンプで感謝

言葉で感謝を伝えるのが苦手な人は、チャットツールのスタンプや絵文字でも十分です。「いいね」や「ハート」のスタンプを押すだけでも、感謝の気持ちは相手に伝わります。感謝を示すハードルを下げて、気軽に共有しましょう！

## 1 年間の感謝振り返り

![ありがとう.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294810/7f1f2909-02a0-17c0-8bd3-e7380e22a7f9.png)

色々書きましたが、

そんな筆者が今年送った「ありがとう」を Slack 上で計測してみたところ、 `1,316`件でした！ (正確なカウントは難しいので概算)

来年もさらにもっと多くの感謝を伝えていきます 💪

## おわりに

ここまで読んでくれた皆さんに、感謝します！

今まで言語化できていなかったですが、
この 1 年の感謝を振り返ってみて、いかに自分が意識的な「ありがとう」を言えていたか、言われる事がいかに仕事の良いモチベーションとなっていたかを改めて再認識できました。

この調子でこれからも「ありがとう」を絶やさない人でいようと思います。

皆さんも今年は何回「ありがとう」を伝えられたか是非振り返ってみて下さい。

また「感謝駆動開発」の経験がある方、感謝エピソード等々、ぜひコメントをお待ちしております。

## 次の記事

次回は、星本さんの記事です！どうぞお楽しみに！
AI時代の新職業！プロンプトエンジニアとは？必要なスキルと将来性

「プロンプトエンジニア」とは
プロンプトエンジニアとは、AIモデルに対して適切な指示（プロンプト）を与え、AIの出力結果を最適化する専門家のことを指します。特に、自然言語処理モデルや生成AIなどに対して、ユーザーが求める回答や結果を引き出すために、適切な言葉や構造を考慮したプロンプトを作成するスキルが求められます。AIに対する「指示の出し方」をデザインする仕事であり、正確かつ望ましい結果を得るための知識と技術が必要です。

プロンプトエンジニアの役割
プロンプトエンジニアは、ユーザーがAIを使って効率的に目的を達成できるようサポートします。これには、AIモデルの限界を理解し、最適な入力を与えることで、期待される結果に近づけることが含まれます。例えば、テキスト生成モデルでは、適切な文脈やヒントを与えることで、自然で正確な文章を生成することが可能になります。

必要スキル
プロンプトエンジニアには、いくつかの特定のスキルが求められます。以下に、必要なスキルをリストとしてまとめました。

1. 自然言語処理の理解
AIモデルは自然言語を理解し、処理するために設計されています。プロンプトエンジニアは、モデルがどのように言語を理解し、生成するかを把握している必要があります。これにより、より正確で効果的なプロンプトを作成できるようになります。

2. プログラミングスキル
基本的なプログラミングスキルは、
<a href="https://dad-union.com/ai-prompt-engineer-skills-future">詳しくはこちら >></a>
[OCI]ComputeインスタンスからADBへの接続設定(OL8)

# 1.はじめに
Autonomous DatabaseはDatabaseの運用管理などが自動化される一方、Base Database等と異なりOSへのログインができないため、LinuxからSQL*Plusで接続できる環境が欲しいといった場合、別途Computeインスタンスを作成し、接続設定を行う必要があります。

この記事ではAutonomous Databaseを作成し、ComputeからSQL*Plusで接続するまでの環境構築手順を記載します。

### 前提条件
Oracle Cloudへの登録が済んでおり、OCIのWebコンソールへ接続できること。

# 2.仮想クラウド・ネットワークの作成
ネットワーキング > 仮想クラウド・ネットワーク より、VCNの作成を行います。
その際、「VCNの作成」ではなく、「VCNウィザードの起動」から作成すると以下の関連するリソースも同時に作成されるため便利です。
- パブリック・サブネット
- プライベート・サブネット
- インターネット・ゲートウェイ
- セキュリティ・リスト
- ルート表

※言語を日本語で進めると、関連するリソースが「パブリック・サブネット-VCN_XXX」のような日本語名になるようです。気になる方は言語を英語に変えて作成することを推奨します。

# 3.Computeインスタンスの作成
コンピュート > インスタンス より、インスタンスの作成を行います。
イメージとシェイプ でComputeインスタンスのイメージ（Linuxのバージョン）を確認し、必要に応じて変更します。※執筆時点のデフォルトはOracle Linux 8でした。
プライマリVNIC情報欄で先ほど作成したVCN及びパブリック・サブネットが設定されていることを確認します。
SSHキーの追加では秘密キーと公開キーをダウンロードしておきます。

作成ができたらパブリックIPを確認しておきます。

# 4.Autonmous Databaseの作成
Oracle Database > Autonomous Database よりAutonomous Databaseの作成を行います。
データベース・バージョンの選択では23aiを選択しました。
管理者資格証明の作成でADMINユーザーのパスワードを設定します。

作成ができたらデータベース接続より、インスタンス・ウォレットをダウンロードします。

# 5.Computeインスタンスの設定
## 5-1.Computeインスタンスへの接続
teratermの設定 > SSH認証で「ユーザ名」に「opc」、「RSA/DSA/ECDSA/ED25519鍵を使う」にComputeインスタンス作成時にダウンロードした秘密鍵を指定し、設定を保存します。
ファイル > 新しい接続より、ComputeインスタンスのパブリックIPを指定して接続します。

## 5-2.Oracleユーザーの作成
    $ sudo su - 
    # /usr/sbin/groupadd -g 54321 oinstall
    # /usr/sbin/useradd -u 54321 -g oinstall oracle

## 5-3.Oracle Instant Clientのインストール
Oracle Instant ClientはOSやClientのバージョンによりインストール方法が異なります。
以下ページを参考にインストールします。
https://yum.oracle.com/oracle-instant-client.html
    
    # dnf install oracle-instantclient-release-el8
    # dnf install -y oracle-instantclient-sqlplus

インストールが完了したら、インストールされたClientのlibディレクトリを/etc/profileに追記します。
oracle-instantclient-release-el8でインストールされるInstant Clientのバージョンは21で、パスは/usr/lib/oracle/21/client64/libです。

    # cat <<'EOL' >> /etc/profile
    export ORACLE_HOME=/usr/lib/oracle/21/client64/lib
    export NLS_LANG=Japanese_Japan.AL32UTF8
    export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH
    EOL
    # source /etc/profile

## 5-4.Walletの配置
4章でダウンロードしたADBのウォレットをComputeインスタンスにWinSCPなどで転送して配置します。
Walletファイルを解凍し、sqlnet.oraを編集します。
tnsnames.oraで接続文字列も確認します。

    $ cd /home/oracle/wallet
    $ unzip Wallet~.zip
    $ cat tnsnames.ora
    ⇒接続文字列を確認
    $ vi sqlnet.ora
    ⇒DIRECTORYの値を$TNS_ADMINに変更
    DIRECTORY=$TNS_ADMIN

## 5-5.接続確認
TNS_ADMINの変数を設定し、接続確認を行います。

    export TNS_ADMIN=/home/oracle/wallet
    sqlplus admin/<password>@<tnsnames.oraで確認した接続文字列>

接続が確認できたらoracleユーザーの.bashrcなどに記載しておくと便利です。

以上でComputeインスタンスからADBへ接続する環境の構築ができました。
VagrantでUbuntu立てるメモ

UbuntuのLTSにはコードネームがある。

1. Vagrantfileの作成
vagrant init ubuntu/bionic64
ubuntu/bionic64 (Ubuntu 18.04 LTS)
ubuntu/focal64 (Ubuntu 20.04 LTS)
ubuntu/jammy64 (Ubuntu 22.04 LTS)

2. Vagrantfileの確認
例
```ruby:Vagrantfile
# Vagrant構成ファイルバージョン2
Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"
  config.vm.network "private_network", type: "dhcp"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
    vb.cpus = 2
  end
end
```

3. 仮想マシンを起動
```sh
vagrant up
```

4. 接続
```sh
vagrant ssh
```

5. 停止
```sh
vagrant halt
```

6. 削除
```sh
vagrant destroy
```

### コードネーム対応表
Ubuntuバージョン: コードネーム
20: ubuntu/bionic64
22: ubuntu/focal64
24: ubuntu/jammy64

### config.vm.network
* フォワードネットワーク
config.vm.network "forwarded_port", guest: 80, host: 8080
Host側にNATを作り、ポートを対応させる
ホストマシンからゲストマシン上の特定ポートへアクセス。開発環境向け

* プライベートネットワーク
config.vm.network "private_network", ip: "192.168.33.10"
Hostにvethを立てて、VMと接続する。IPアドレスを利用して通信するが、ルーターはない。インターフェースをの間にスイッチをおいて、同一リンクにする。
ホストマシンとゲストマシン間の通信専用。DHCPまたは静的IPが必要。

また、外部へのアクセスにおいては、VirtualBoxが管理するルーター(筆者の環境だと10.0.2.0/24)があり、VMはインターフェースとして、外部アクセス用ももつ。

オプション:
ip: "192.168.33.10"
type: "dhcp"
ipとtypeはどちらかのみを設定するものなのだと思う。

* パブリックネットワーク
config.vm.network "public_network"
ホストマシン と ゲストマシン は物理ネットワーク（LAN）を共有
外部ネットワークから直接VMへアクセス可能。注意が必要

オプション:
bridge: "ホストのインターフェース名"

ホストのインターフェース名を指定すると、そのインターフェースとスイッチで繋ぐイメージ。

ip aコマンドの出力
lladdr: Link-Layer Address。MACアドレスのこと。
dev: Device。NICのこと。
scope: IPアドレスのスコープ。global=global接続に利用できるアドレス、link=リンク通信のみに利用できるアドレス、host=そのマシンでのみ利用できるアドレス(localhostアドレス)。
地方からFlutterKaigi2024に参戦してきました！

## はじめに
初めまして、株式会社デジタルバリューでモバイルアプリの開発をしている小野です。普段は石川県に住みながら仕事をしています。
FlutterKaigi2024に現地参戦してきました。またありがたいことに、LT登壇の機会もいただき無事終えられ、かなり遅くなってしまいましたがそのレポートになります。

## 登壇編
[Flutterテスト戦略の再考 〜品質と効率のバランスを求めて〜](https://2024.flutterkaigi.jp/session/02ab1faa-508e-418e-a682-6443148fba5c)というタイトルでLT(10分)登壇してきました。登壇資料は[こちら](https://speakerdeck.com/toshiki9/fluttertesutozhan-lue-nozai-kao-pin-zhi-toxiao-lu-nobaransuwoqiu-mete-359961ba-a684-483b-b13d-ae90c6156b3c)になります。よければ覗いてみてください。
このタイトルに至った経緯として、これまでテスト戦略について深く関わった経験がなかったからです。ないからこそ向き合ってみたいというモチベーションの元プロポーザルを書きました。
プロポーザルの採択通知のメールを受け取ったのが現職の入社日で、余計に焦ったのを覚えています（笑）
オンボーディングと並行して資料の準備を始めました。準備をし始めて気づいたことは、10分という時間の短さです。あれも話したい！これも話したい！という思いはあるものの、10分と時間は限られているので資料を作っては読み返し、修正を繰り返しました。
登壇を終えた今でも、あれも話したかったな、、と思う話題もありますが無事初めての登壇を時間内に終えられてよかったです。来年以降もプロポーザルの提出を続けて、40分の一般セッションでの登壇目指して成長していきたいと思えました。
![IMG_3282.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946066/1492aa18-2f9f-e60a-6fcb-ea98490f71e4.jpeg)

## 参戦編
6月13日、14日で開催された[FlutterNinjas](https://ti.to/flutterninjas/tokyo-2024)が自分の初めて参戦したカンファレンスで、FlutterKaigiで他の方のセッションを聞くのを本当に楽しみにしていました。全てのセッションが面白かったですが、特に印象に残っているものはたまねぎさんの[Effective Form ~ Flutterによる複雑なフォーム開発の実践 ~](https://speakerdeck.com/chocoyama/flutterkaigi2024-effective-form-flutterniyorufu-za-nahuomukai-fa-noshi-jian)です。
入力フォーム1つとっても、こんなにも考慮できる点があるのかと感動しました。自分自身開発するプロダクトのUXに向き合うことはすごく好きで、力を入れて取り組んできた自負が多少なりとありました。しかし今回の聴講を経て、自分がこれまで見ていた/考えられていたことは表面に過ぎないと思えました。よりよいユーザ体験を求めて、フォーム以外にも考え方を落とし込めるようにやっていきたいです。
余談になりますがFlutterNinjasではゲット出来なかった、Dashくんをスタンプラリーの景品としてゲットすることが出来ました！来年こそは大きいDashくんを迎え入れてあげられたらと思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946066/e3e70c3c-3a93-1604-2fd2-b8a74d13c77f.jpeg" width="30%" height="30%" >

## 感想
実は自分は新卒入社するまではサーバーサイドエンジニアとしてRailsを書いていました。新卒入社のタイミングでモバイルエンジニアへ転向し、Flutterを書いています。FlutterKaigiは初めて憧れたカンファレンスであり、登壇出来て幸せな時間を過ごすことが出来ました。また、他の方のセッションを通じてチームに持ち帰りたいと思う考え方や技術がたくさんありました。次は40分の一般セッションでの登壇を目指して、日々成長していきたいです。
普段はフルリモートなので初めてオフラインで会う同じ会社の人であったり、前職の方、初めてお会いしたFlutterエンジニアの方などなど、本当にたくさんの方と情報交換することが出来ました。ありがとうございました！
Vivliostyleで脚注のスタイルを変更する

[CSS組版 Advent Calendar 2024](https://adventar.org/calendars/10448) 10日目の記事です。昨日はhidarumaさんでした。明日はきっとhidarumaさんです。先日12月4日の[Vivliostyle開発者会議](https://vivliostyle.connpass.com/event/339118/)で教わった、脚注のスタイルについて紹介します。

本記事投稿時点のVivliostyleでは、` @-adapt-footnote-area`というobsoletedな機能で脚注のスタイルを調整できます[^1]。

[^1]: https://github.com/vivliostyle/vivliostyle.js/issues/1045

```css
@page {
    size: A5;
}

.footnote {
    float: footnote;
    font-size: 80%;
    text-indent: 0;
}

::footnote-marker {
    content: "*" counter(footnote);
    margin-right: 1em;
}

::footnote-call {
    content: counter(footnote);
    font-size: 70%;
    position: relative;
    inset-block-start: -0.5em;
}
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1550728/0515e2a2-2142-3f92-8490-ba0fb9d78973.png)

```diff_css
  @page {
      size: A5;
  }
  
  .footnote {
      float: footnote;
      font-size: 80%;
      text-indent: 0;
  }
  
  ::footnote-marker {
      content: "*" counter(footnote);
      margin-right: 1em;
  }
  
  ::footnote-call {
      content: counter(footnote);
      font-size: 70%;
      position: relative;
      inset-block-start: -0.5em;
  }
+ 
+ @-adapt-footnote-area ::before { 
+    border-block-start-style: dashed;
+    border-block-start-color: red;
+    border-block-start-width: 10px;
+    margin-inline-end: 0;
+ }
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1550728/689f79a5-716b-69ae-a631-ad1c6ee18580.png)

他のCSS組版システムへの移植性はなく、「InDesignで用意されたフォーマットにどうしても合わせたい」といった場合にやむなく使う程度に留めたほうがよいでしょう。手元の技術書を何冊か見る限り、幸いなことに脚注のスタイルはそれほど多様ではないようです。
副業に1mmも興味がなかったのに、データラーニングギルド内の募集で副業を始めてみた件

## はじめに  
昨今、副業が話題になることが増えましたが、私の周りでは副業をしている人はほとんどおらず、稀にいる人も「収入に困っているから」という理由で始めたケースがほとんどでした。そのため、日々の生活で最低限の収入が得られていた私は、副業に対して興味を持つことがありませんでした。  

そんな中、データラーニングギルド（以下：DLG）で「PPTの編集」という副業募集がありました。ちょうど勉強している最中の内容だったことに加え、少し前に参加した勉強会で「仕事は身近な人から取る」という話を聞いたのも後押しとなり、「今がそのタイミングではないか？」と思い切って応募してみることにしました。結果は採用され、晴れて人生初の副業に挑戦することになるのです。


## 副業をして印象的だった4つのポイント
結論から言うと、本当にやって良かったと思います（笑）。収入を得られたことはもちろんですが、それ以上に気づきや学びが得られました。以下に、特に印象的だった4つのポイントを紹介します。

### 1. 学びがお金になることを実感  
今回の副業を通じて、勉強したことが直接お金に変わる感覚を初めて味わいました。「これが自分のスキルで収入を得るということか！」と実感し、大きな感動を覚えました。普段の仕事でもPPTを使用しますが、契約内容によらず成果が収入に直結しないため、この感覚を味わうことはできませんでした。今回の「PPT作業を契約内容とする」という明確な形があったからこそ、こうした気づきが得られたのだと思います。  

### 2. 多様な人とのやり取りが新鮮  
副業では、普段仕事で接することのない多様な人々とやり取りをする機会があり、とても新鮮でした。特に海外在住の方とのやり取りは、仕事上で「時差」がどのように影響するのかを学ぶ良い経験となりました。また、一緒に作業した皆さんがとても仕事しやすい方々だったことも、大変ありがたかったです。

### 3. リモートだからこそ、丁寧な対応が必要  
今回の副業はフルリモートで、主なやり取りはSlackです。オフィス勤務であれば、直接席を訪れて「○○の件はどうですか？」と確認したり、「△△の件、口頭で補足させてください」と口頭で補足説明を加えたりすることが可能ですが、リモートではそれができません。だからこそ、進捗や状況報告をこまめに行い、疑問点や説明は「文章でわかりやすく」伝えるスキルが必要なのです。リモート環境では、丁寧な対応が仕事の円滑さを大きく左右することを改めて学びました。

### 4. 時間の使い方について今後の課題  
副業をすることで、当然ながら仕事以外の自分の時間は減少します。その結果、勉強や趣味に使える時間が少なくなり、やりたいことができない時期もあるのです。振り返ると、慣れない中でももう少し工夫できた部分があったかもしれません。この経験を踏まえ、時間管理の見直しが今後の大きな課題です・・・。


## 最後に: 副業を考える人へ  
副業に興味がある方は、ぜひ挑戦してみてください。本業やプライベートとの調整がつくのであれば、思い切って第一歩を踏み出す価値は十分にあります。副業は収入だけでなく、私のように学びや新しい経験をもたらしてくれるかもしれません。  
「やってみたいけど不安」という方も、身近なところから始めることで意外とスムーズにスタートできるはずです。今回の私の経験が、副業を始めたいと思っている方の参考になれば嬉しいです。
Let's Encrpyt の証明書形式が変わったせいで自動更新スクリプトがコケてしまった件

## Let's Encrpyt の証明書形式がRSA2048からECDSA P-256にかわった

### 気付いた経緯
- Bashスクリプトで自動更新していたが、今月動いてなかった
- 手動でrenewコマンドを叩いてみたら、正常に取得できていた模様
- 証明書や秘密鍵を確認すると、秘密鍵ファイルが超短くなっていた
- ？？？と思いながら、opensslコマンドで確認すると、暗号化形式がECDSA P-256に

### Letsencrypt自動更新スクリプトについて
1. certbot certonly を叩いて証明書を取得する
1. aws acm list-certificates で、既存の証明書一覧をとってきて、対象のARNを抽出する
1. aws acm import-certificate で、取得したARNの証明書を更新する

### なぜこけたのか
- 結論
    - aws acm list-certificates で一覧表示できる証明書は、RSA1024とRSA2048だけだから！

### 対応内容
- オプションで明示的に一覧表示に出てくるようにする
  ```
  $ aws acm list-certificates --includes keyTypes="RSA_2048,EC_prime256v1"
  ```
- これで一表示に、ECDSA P-256 も含まれるようになる

### おまけ
- 秘密鍵の長さが、ECDSA P-256は、RSA_2048にくらべて超短いが、実はセキュリティ強度は上がっているので、心配しなくても大丈夫
  ```
  RSA 2048: 約112ビットのセキュリティ強度
  ECDSA P-256: 約128ビットのセキュリティ強度
  ```
AstroでView Transitionsを利用したときの挙動に少し気を遣う

## この記事の概要

View Transitions APIを使った画面遷移はスムーズで見栄えも良いです。

ただしtransitionの対象が画面外にあると一瞬表示崩れにも見える挙動をします。

上記の内容に対する、Astroでの解消方法を記事にしました。

## 起きることと、対処した後の結果

次のgifでは以下の操作をしています

1. ページ遷移→すぐさま（= transition対象が画面内に**ある**状態で）ブラウザバック
1. ページ遷移→スクロールし（= transition対象が画面内に**ない**状態で）ブラウザバック

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/7a445cd0-c5bf-4b32-3637-69516ad27c5f.gif)

transition対象が画面内に**ない**状態でのブラウザバックでは、画面外から画像が降ってくるような挙動になっており、やや違和感があります。

これを、次のように「transition対象が画面内に**ない**状態で遷移した場合、単なるディゾルブ効果」に変更します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/6418d737-64f3-6793-6b76-7018154df10c.gif)

## やること

遷移させるにあたって、次のようなコードがあるはずです。

```jsx
<div transition:name={someName}>何かしらの要素</div>
```

:::note warn
AstroでView Transitionsを実装する方法自体はこの記事では触れません。[公式ドキュメント](https://docs.astro.build/en/guides/view-transitions/)などをご覧ください。
:::

遷移対象の要素に`id`を付与します。

```diff_jsx
- <div transition:name={someName}>何かしらの要素</div>
+ <div id="something" transition:name={someName}>何かしらの要素</div>
```

その上で以下のコードを追加します。

```jsx
<script>
  function setupImageTransition() {
    const somethingElement = document.querySelector("#something");
    if (!somethingElement) return;

    const initialScope = somethingElement.getAttribute("data-astro-transition-scope");
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting && initialScope) {
            somethingElement.setAttribute("data-astro-transition-scope", initialScope);
          } else {
            somethingElement.removeAttribute("data-astro-transition-scope");
          }
        });
      },
      {
        threshold: 0.1,
      },
    );

    observer.observe(somethingElement);
  }

  document.addEventListener("astro:page-load", setupImageTransition);
</script>
```

ポイントは2点です。

1. `setAttribute`, `removeAttribute`する対象は`transition:name`ではなく`data-astro-transition-scope`
1. `initialScope`として最初の状態の`data-astro-transition-scope`を保持しておく

### `setAttribute`, `removeAttribute`する対象は`transition:name`ではなく`data-astro-transition-scope`

Astroに同一要素として判断してもらうためには`transition:name`を記載する必要があります。
しかし、この値そのもので同一化を判断しているわけではありません。
この値をもとにして生成された`data-astro-transition-scope`が判断材料です。

`removeAttribute`で`transition:name`を消しても、既に`data-astro-transition-scope`が付与されてしまっており、最初に貼ったgifから動きは変わりません。
そのため`data-astro-transition-scope`を操作します。

### `initialScope`として最初の状態の`data-astro-transition-scope`を保持しておく

当たり前ですが、一度`data-astro-transition-scope`を削除したら、単に`setAttribute`したところで値は戻ってきません。

そのため、最初の`data-astro-transition-scope`を保持しておく必要があります。
WordPress外部で wp_mail() を利用する方法

# WordPress外部で wp_mail() を利用する方法

WordPress の便利なメール送信関数 wp_mail() を、WordPressのインストールディレクトリ外で利用する方法を紹介します。この手法を使うと、WordPressの設定やプラグイン（例: WP Mail SMTP）を引き継いだ形でメールを送信できます。

## 0. 今回なぜこのような形を検討する必要があったか
クライアント様は、WordPressのサイトとは別に、LPを作成しており、LPのページについては、WordPressを利用していなかった。そのLPの申し込みフォームのメールがgmail宛に送信できない事象が発生しており、それに対処するため実装しました。

## 1. 前提条件

1. WordPressがインストールされていること。
2. 外部スクリプトから wp_mail() を利用する環境が整っていること。
3. SMTPプラグイン（例: WP Mail SMTP）を設定済みの場合、これらの設定も引き継がれます。
＊難しく書いてありますが、同じURL (example.com) でWordPressが正しく表示されていれば、いいのです。

## 2. 実装例

以下に、wp_mail() を外部スクリプトで利用する方法を示します。

### ファイル構成
#### パターン1
/path/to/wordpress
    ├── wp-load.php  (WordPressロード用)
    └── mail-test.php (今回作成するスクリプト)

#### パターン2
/path/to/wordpress
    └──wp-load.php  (WordPressロード用)
/path/to/lp
    └── mail-test.php (今回作成するスクリプト)

どちらもコードを実装するのは: mail-test.php

``` PHP
// WordPress の wp-load.php を読み込む
require_once('/path/to/wordpress/wp-load.php');

// マルチバイトメール設定（日本語対応）
mb_language('ja');
mb_internal_encoding('UTF-8');

// メール送信情報を設定
$to = 'recipient@example.com'; // 送信先メールアドレス
$subject = '外部スクリプトからのメール送信テスト';
$message = 'このメールは WordPress の wp_mail() を利用して送信されています。';

// ヘッダー設定
$domain = 'example.com'; // ドメイン名
$from = '〇〇歯科医院'; // 送信者名
$email = 'info@example.com'; // 送信元メールアドレス

$headers = [];
$headers[] = "From: {$from} <info@{$domain}>";
$headers[] = "Reply-To: {$from} <{$email}>";
$headers[] = "Sender: {$from}";
$headers[] = "Return-Path: info@{$domain}";

// メールを送信
if (wp_mail($to, $subject, $message, $headers)) {
    echo 'メールが正常に送信されました！';
} else {
    echo 'メール送信に失敗しました。';
}
```

## 3. 動作確認
上記コードをサーバー上に配置します。
ブラウザやターミナルからこのスクリプトを実行して、メールが送信されるか確認します。
例: https://example.com/mail-test.php をブラウザで開く。
## 4. 注意点
1. wp-load.php のパス:
WordPressの設置場所に合わせて require_once のパスを適切に変更してください。
2. From アドレスの上書き:
WP Mail SMTP などのプラグインを使用している場合、送信元アドレスが設定に従って上書きされることがあります。
3. セキュリティ:
このスクリプトは公開される場所に配置しないでください。不正利用を防ぐために、認証やアクセス制限を設けることをお勧めします。

## 5. まとめ
WordPress外部でも wp_mail() を利用することで、WordPressの便利なメール送信機能を活用できます。この方法は、WordPressの設定をそのまま利用できるため、外部スクリプトからも簡単にメール送信が可能です。

##### このスクリプトを活用して、メール通知やシステム連携を実現してみてください！
【Swift】論理演算子の連結

# この記事は何？

Swift Language Guideの[Basic Operators](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/basicoperators)について調べたので、備忘録を残します。

> Swiftを基礎から学ぶには
自著、工学社より発売中の「[まるごと分かるSwiftプログラミング](https://amzn.asia/d/7YPWJwl)」をお勧めします。変数、関数、フロー制御構文、データ構造はもちろん、構造体からクロージャ、エクステンション、プロトコル、クロージャまでを基礎からわかりやすく解説しています。

> Swiftプログラミングを基礎から動画で学びたい方には、Udemyコース「[今日からはじめるプログラミング](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwii1qTuj_2BAxV4hlYBHbj5BqEQFnoECBYQAQ&url=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Fstart-programming-today%2F&usg=AOvVaw2vs4Sccq-bpfA4ZD2rCyNm&opi=89978449)」をお勧めします。

## Combining Logical Operators

いくつかの論理演算子を組み合わせて、より長い論理式を作成できます。

```swift:
let enteredDoorCode = true        // コードを正しく入力した
let passedRetinaScan = false      // 網膜スキャンは不合格
let hasDoorKey = false            // 鍵を持っていない
let knowsOverridePassword = true  // 上書きパスワードを知っている

// コード入力と網膜スキャンを合格したか、鍵を持ってるか、上書きパスワードを知っている場合、入室を許可
if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"
```

`&&`演算子`||`演算子は依然として2つの値でのみ動作します。
そのため、これは実際には3つの小さな式が連鎖した単一の式です。
この例は次のように読むことができます。

*コード入力と網膜スキャンを合格したか、有効なキーがあるか、上書きパスワードを知っている場合は、入室を許可する*

`enteredDoorCode`、`passedRetinaScan`、`hasDoorKey`の値に基づくと、最初の2つの条件式（`enteredDoorCode && passedRetinaScan`と`passedRetinaScan || hasDoorKey`）はいずれも`false`です。
ただし、上書きパスワードを知っているので、式全体（`false || knowsOverridePassword `）は`true`と評価されます。

> メモ
Swiftの`&&`演算子と`||`演算子は、左結合です。
つまり、いくつかの論理演算子を評価する式では、左端の部分から評価されます。

## Explicit Parentheses

複雑な論理式は意図が汲み取りにくくなりがちです。
厳密には不要な括弧`()`を使って、意図を明確できる場合があります。

```swift:
if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"
```

括弧`()`のおかげで、「論理式全体において、`enteredDoorCode`と`passedRetinaScan`だけは別個の条件として評価される」ことが明確になっています。
以前よりも全体的な意図は明確ですが、出力結果に影響はありません。
常に、簡潔さよりも読みやすさに配慮してください。
歴史を振り返りながらIBM MQの価値をお話しします

# はじめに

IBM MQは、その堅牢性と汎用性から多くの企業で標準的なメッセージング製品として採用されており、Forbes Global 2000の上位100社の90%が利用しています。銀行間の送金、証券決済、半導体工場の装置制御、航空券座席予約、オフィス複合機の利用情報収集、新聞記事配信など、消費者の目には見えにくい部分で社会を支える重要な技術です。

この記事では、30年以上にわたるMQの歴史を振り返り、その普及の過程、進化、そして本質的な価値について解説します。


# 90年代のMQ　：　異機種間連携の時代

IBM MQ（当時の名称はMQ Series）は1993年に発表されました。この時代、企業のITシステムはメインフレーム（例: System 390）、オフコン（例: AS/400）、UNIXを中心に多様化し始めており、さらにWindows PC上でのクライアント・アプリケーションやグループウェアの利用が広がっていました。

異なるOSやプログラミング言語を使用するアプリケーション同士のデータ連携が求められる中、MQは以下の特徴を持つことで急速に普及しました。

- 多様な通信プロトコル対応: SNAやTCP/IPをサポート
- 幅広いプラットフォーム対応: メインフレーム、AS/400、UNIX、Windowsで稼働可能
- 文字コード変換: EBCDICとEUC/Shift_JIS間のコード変換を提供
- 非同期メッセージング: メッセージをキューに格納し、システムが稼働次第処理可能

このような特性により、異機種間連携のためのソリューションとして広く利用されるようになりました。また、同時に企業間取引やワークフローを支援するメッセージング基盤としても採用されていきます。

# 2000年代 : SOAの時代
2000年代を通じて業務アプリケーションはWeb対応が進み、その中心を担ったのがJavaと.NETです。
Java EEではベンダーに依存しない標準メッセージングAPIとしてJMSが策定されました。IBMはいち早くJMSへのサポートを行い、Javaの世界におけるメッセージングに対する需要に対応しました。
同様に.NET向けのAPIを提供することでWindowsの世界にもMQを通じた相互運用を保証しました。
さらに、ERP, CRMの多くの業務パッケージ製品もIBM MQを標準的なインターフェースとしてサポート提供していたため業務システムの統合の中心にMQが活用される例が数多く生まれました。

2000年代を通じてMQは様々な金融、製造、航空、流通など幅広い業種の業界ネットワークを支える通信基盤としても採用されており、現在も社会の根幹を支える技術となっています。

# 2010年代 : クラウド・コンピューティングの進展

### クラウド・コンピューティングの普及
2010年代になると企業の基幹系を含むIT資産をクラウド上にリフトする流れが加速していきます。
また、SaaSの普及も進み業務システムをSalesforceを代表されるクラウド・サービスに移行する流れも生まれてきます。企業はオンプレミスのデータセンター以外に複数のクラウド環境でITシステムを稼働させるようになり、それらのシステム同士を統合するニーズが生まれてきます。

MQは以下の点でその価値を発揮しました。
- オンプレミスとクラウドを跨いだハイブリッド環境での信頼性の高いデータ連携
- MQTT対応によるIoTとの連携やAMQPを用いた他のメッセージングシステムとの互換性強化
- REST APIのサポートでクラウドネイティブアプリケーションへの適用範囲を拡大


# 2020年代 : クラウド・ネイティブの時代へ
2020年代に入ると、企業はクラウドネイティブアーキテクチャやマイクロサービスの採用を進め、迅速なリリースや動的なスケーリングを実現しています。MQも以下の特徴を備えることでクラウド・ネイティブなソフトウェアへと進化しています
- コンテナ対応: KubernetesやOpenShiftでの稼働をサポート。
- 高可用構成: データセンター障害発生時にも迅速な復旧が可能。
- KEDAサポート: メッセージ数に応じたアプリケーションの自動スケーリング。

クラウド・ネイティブな世界の非同期メッセージングではApache Kafkaが大きな注目を集めていますが、MQにはKafkaには無い次のような特性があります。

- 少ないリソースで運用可能
    - Kafkaの構成にはKafkaサーバー, Zookeeper, Kafka Connect含め比較的大きなリソースが必要ですが、MQは例えば0.1コアのコンテナでも運用可能です。
- 特定の相手へのメッセージ送信
    - Kafkaでは個別のConsumerに対してメッセージを送信するにはConsumerの数だけTopicの作成が必要となり、個別宛先の数が多いとコストが高くなりますが、MQは特定の相手向けのキューやトピックを作成することのコストは全く高くありません。
- 複数リソースへの同期点処理
    - Kafkaでは複数テーブルを単一同期点内で更新した場合に同期点の境界を伝搬することは非常に困難ですが、MQの場合にはグループ・メッセージの機能などで容易に実現可能です
    - MQではデータベースなど外部リソースとのXAによる同期点更新が可能ですがKafkaにおいてはアプリケーションで整合性の担保が必要です。

一方でKafkaの持つ秒間数百万件のオーダーでのメッセージ処理や、メッセージの再消費などはMQにない特性です。どちらかが優れているというわけではなく、使い分けることが重要になります（重複するユースケースが数多くあることは事実です）。
大まかに言ってMQが得意とするのは特定相手に対する処理の依頼（コマンド・メッセージの処理）です。一方、Kafkaが得意とするのは処理結果発生するイベントの伝搬（イベント・メッセージの処理）です。つまり、MQのネットワークによって実行される処理によって生まれるイベントをKafkaを通じて様々な（不特定の）アプリケーションが活用するというのが二つのメッセージングの使い分けということになります。


# MQの価値：時代を越える普遍性
MQは、その30年の歴史の中で、メインフレーム、Java/.NET、クラウド、コンテナ上のマイクロサービスといった多様なIT環境に対応し、進化を続けています。その強みの一つは、後方互換性を保ちながら時代のニーズに適応してきた点です。

この特性により、例えばKubernetes上の最新のマイクロサービスと30年前から稼働しているメインフレームアプリケーションを簡単に統合することが可能です。
今後も様々なアプリケーション・アーキテクチャーが誕生していくことでしょう。
しかしMQとともに投資されるITの価値は時代を超えて将来に引き継ぐことが可能となるのです。


# 参考
[IBM TechXchange Integration Group Japan](https://ibm.biz/JapanIntegrationUG)
LeetCodeを1日1題解いてみる (day39)

39日目に取り組んだ問題はこちら！

# 511. Game Play Analysis I

https://leetcode.com/problems/game-play-analysis-i/description/?lang=pythondata

## 問題文
Table: `Activity`
```
+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| player_id    | int     |
| device_id    | int     |
| event_date   | date    |
| games_played | int     |
+--------------+---------+
```
(player_id, event_date) is the primary key (combination of columns with unique values) of this table.
This table shows the activity of players of some games.
Each row is a record of a player who logged in and played a number of games (possibly 0) before logging out on someday using some device.
 

Write a solution to find the first login date for each player.

Return the result table in any order.

## 僕の回答
```py
import pandas as pd

def game_analysis(activity: pd.DataFrame) -> pd.DataFrame:
    df = activity.sort_values(by=["player_id","event_date"], ascending=[True, True])
    result1 = df.iloc[:1]
    print(result1)
    result2 = df[df["player_id"].shift(1) != df["player_id"]]
    result = pd.concat([result1, result2], ignore_index=True)
    return result.rename(columns={"event_date": "first_login"})[["player_id", "first_login"]]
```

## より効率の良い回答例

```py
import pandas as pd

def game_analysis(activity: pd.DataFrame) -> pd.DataFrame:
    df = activity.sort_values(by='event_date')
    df.drop_duplicates(subset=['player_id'], keep='first', inplace=True)
    df.rename(columns={'event_date': 'first_login'}, inplace=True)
    return df[['player_id', 'first_login']]
```

## 学んだこと
- `df.iloc[:1]`でヘッダーと１個目のデータを取り出す
- `pd.concat([df1, df2])`で2つのdfを結合する。`ignore_index=True`を指定すると、indexを再構築してくれる。

## コメント
回答例を読んだら確かにそっちの方が簡単に実装できるな、と思った。けど、以前に学習した`shift`を活用できて嬉しい。

## 次の問題はこちら!
https://qiita.com/h_y_s_d/items/37f46705c7762dc2ea93
Windows Terminal の外観（見た目）を変えよう！！！

# はじめに
<!-- 発端や概要を記載 -->

最近，**Windwos Terminal**について色々知ったので，備忘録も兼ねてブログにしました．（※フォント・カラーなどの外観・見た目に関することがメインです）

:::note
筆者の環境は，Windows11です．
それ以外では試していないので，意図した動作が行えないかもしれません
:::


# 目次
1. Windows Terminal とは
1. 外観を変えよう！！
1. おわり



# Windows Terminal とは

<font size=20> 

Windowsのデフォルトターミナル ~ 

</font>
Powershell, コマンドプロンプト, WSL(Windows Subsystem for Linux)などが使用できる．

###### 開き方
- `Windowsマーク`を右クリック -> `ターミナル` を選択
- `Windowsキー` + `R` -> `cmd`と入力

いわゆるこれ↓
\<Windows Terminalの例>
![スクリーンショット 2024-12-10 092114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/ef045903-79b8-4a8b-c6d0-a8b06bfcc6b6.png)



# 外観を変えよう！！
まず，`設定` を開こう．（1,2 どちらの方法でもよい）
1. "+"の横の "下カッコ" (以下画像の赤矢印が示すところ) -> `設定` を選択（以下の画像）
2. `ctrl` + `,`

\<上の `設定` の開き方の例>
![スクリーンショット 2024-12-10 100028.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/df461f76-81ad-0457-9783-634166f8c70b.png)

`設定` を開けたら，`プロファイル` -> 外観を変えたいディストリビューションを選択 -> `追加の設定` -> `外観` で外観を変更するページに移動できる！

\<筆者のUbuntu22.04.5 LTSの例>
![スクリーンショット 2024-12-10 101109.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/91e30a15-c398-5b9a-92f3-4c6914eaf2d9.png)


その後は自分の好きなようにカスタマイズしよう！
###### カスタマイズ出来るものの一例
- 配色
- フォント，フォントサイズ
- カーソルの形
- 背景画像
- ターミナルの透明度
- スクロールバーの表示・非表示


<details><summary>筆者のカスタマイズ</summary>

「目に優しい」をテーマにダーク系でカスタマイズしてみました．
![スクリーンショット 2024-12-10 102101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/703fd64d-aec7-d12d-15a9-4b705a98f0ba.png)

```
aaa
```

</details>


# おわり
みんなもターミナルの外観をカスタマイズしてみてね！！！
重要なアラートが発生したときにSlackに繰り返し通知させたい

※本記事は[**網屋 Tech Blog Advent Calendar 2024**](https://qiita.com/advent-calendar/2024/amiya)の12月15日分の記事です。

こんにちは。@RefactorRavenです。
みなさんのクラウドサービスではエラー監視をやっていますか？

サービス内での不具合を運用者が監視するための手段として、予期されるエラーの発生時にSlackへ通知を飛ばすというものがあります。

しかし、実際に運用してみると通知が思いのほか多く、重要な通知が埋もれて気づかれにくくなってしまうということもあるあるなんじゃないかなと思います。

そこで今回は、重要なアラート通知をできるだけ派手にする方法について書いていきます。

## やりたいこと

- 運用中のクラウドサービスで緊急度高めのアラートが発生したときに派手に通知させたい
    - 緊急度高めのアラート: ヘルスチェックに失敗してますよとか
    - 誰かが気づくまで繰り返し通知してほしい

こんなイメージ↓

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957443/3beea0cb-46fc-629d-90a1-3da2dc8a5f75.png" alt="緊急アラートの繰り返し通知" width="400"/>

## この記事の趣旨

### 書くこと

通知機構を実現するためのAWSアーキテクチャの概要

### 書かないこと

実装の詳細

## 想定読者

- AWS・Slack appsに関する基本的な知識がある
    - LambdaからのSlack通知方法が知りたい方には [@ymat19さんの記事](https://qiita.com/ymat19/items/9c34e81ebe042e29450e) がオススメです！
- 運用中のクラウドサービスにおいて重要な問題が発生した際、Slackに派手に通知がきてほしいと思っている

## 構成

![architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957443/18e9c473-b58b-1a17-5aae-fda7fe35063b.png)

左上あたりから順にみていきます。

- サービスに重要なエラーが発生した際、何らかの経路で緊急用のSNSトピック（Critical）にpublishされることが前提
- Lambda関数 `CriticalNotifierStarter` がSNSトピック（Critical）をサブスクライブしており、トピックに対するpublishをトリガーとして呼び出される
- `CriticalNotifierStarter` はStep Functionsのステートマシン `CriticalNotification` をスタートする
- `CriticalNotification` の冒頭ではSystems Manager Parameter Storeのパラメータ `/Monitoring/IsAlertingCritical`（後述）が `true` にセットされる
- `CriticalNotification` の内部では Lambda関数 `CriticalNotifierMain` が10秒おきに繰り返し呼び出される
    - 無限ループはしてほしくないのでタイムアウト値や繰り返し上限値を設定しておくとよい
- `CriticalNotifierMain` はSlackのチャンネルに通知を行う
    - 1回の呼び出しごとに1回通知する
- 通知の繰り返し続行条件はSSMパラメータ `/Monitoring/IsAlertingCritical` が `true` であること
- Slack通知メッセージ内のボタンを押すとAPI GatewayにGETリクエストが送られ、Lambda関数 `CriticalNotifierStopper` が `/Monitoring/IsAlertingCritical` を `false` にセットして通知を止める
- SFn内でエラーが発生した場合はSNSトピック（Info）にpublishし、その旨を通知する
    - 通知手段は本通知同様Slackでも、メールでもなんでもOK

### 補足

- SFnステートマシンの起動にLambda関数を経由しているのはSNSから直接SFnを起動する手段が見つからなかったから
- ステートマシンの処理冒頭でSSMパラメータを `true` にセットしているのは、パラメータがAPI経由で `false` にされていた場合に処理が行われなくなってしまうのを防ぐため
- Lambda関数の繰り返し実行をSFnで制御しているのは、非自明なループの形成によるLambda関数の再帰実行を恐れているため
    - たとえばLambda関数が別のLambda関数を呼び出すという構成にはしていない
    - Lambdaのタイムアウト値上限が短いこともあり、関数内部でのループは行っていない
- Slack通知のボタンからAPI Gatewayにアクセスするところの詳細は認証などをちゃんとやろうとすると面倒で、本記事では割愛します

## 繰り返し通知機構を使ってみて

本機構を実際に実装して使ってみたところ、

ｽｯｺｺｺ

ｽｯｺｺｺ

なんかめっちゃSlackの通知来てるな～何かあったのかな？

重要なアラートが発生している！　対処しなきゃ！

と重要な通知にすぐ気づくことができるようになりました。
simple_formatって？

# 概要
`simple_format` は、テキストをシンプルなHTML形式に変換するRailsのヘルパーメソッドです。主に、改行をHTMLタグに変換する用途で使用されます。

https://railsdoc.com/page/simple_format

以下の条件で文字列が加工されます。

:::note info
- 文字列全体を `<p>` タグで括る
- 改行は `<br />` に変換
- 連続した改行は新たな `<p>` タグに変換
:::

**具体例**
```erb
<%= simple_format("Hello\nWorld") %>
```

**出力結果**
```html
<p>Hello<br />
World</p>
```
改行コードが`<br>`に変換され、文字列全体が`<p>`で囲まれました。

## 注意点
HTMLタグを含むテキストに適用する場合、タグがエスケープされずにそのまま表示されます。

**具体例**
```erb
<%= simple_format("<h1>Hello\nWorld</h1>") %>
```

**出力結果**
```html
<h1>Hello<br />
World</h1>
```
`<h1>`タグはエスケープされずにそのまま出力されています。

エスケープされないことにより、意図しないタグが表示されたりXSS攻撃のリスクがあります。

:::note warn
#### クロスサイトスクリプティング (XSS) とは
フォームやURLパラメータなどに実行可能なスクリプトを挿入し、ユーザーの環境で悪意のある操作を実行させる攻撃です。
:::

https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0

## オプション

### h

`h`メソッドは、HTMLをエスケープして安全に表示するために使用されます。
このメソッドを使用することで、テキスト内のHTMLタグをそのまま文字列として出力することが可能です。

**具体例**
```erb
<%= simple_format(h("<h1>Hello\nWorld</h1>")) %>
```

**出力結果**
```html
<p>&lt;h1&gt;Hello<br />
World&lt;/h1&gt;</p>
```
`<h1>`タグがエスケープされ、ブラウザには文字列として表示されます。

### sanitize

`sanitize` は、不要なHTMLタグを除去し、必要なタグだけを許可するために使用されます。
これにより、HTMLを部分的に許可しつつ安全性を確保できます。

**具体例**
```erb
<%= simple_format(sanitize("<h1>Hello\nWorld</h1><script>alert('XSS!攻撃!');</script>")) %>
```

**出力結果**
```html
<p><h1>Hello<br />
World</h1></p>
```
`<script>` タグは除去され、`<h1>` タグのみが残ります。

### hメソッドとsanitizeオプションの違い

- hメソッド
すべてのHTMLタグをエスケープして無効化します。ユーザー入力を完全に文字列として表示したい場合に使用します。

- sanitizeメソッド
不要なHTMLタグを除去し、必要なタグのみを残します。一部のHTML装飾（例: 太字や斜体）を利用したい場合に適しています。


これらのオプションを活用することで、`simple_format` の出力を安全かつ正確に制御できます。


## 参考

https://qiita.com/mojihige/items/c01682774e8ef29b361f


https://ud-ike.hatenablog.com/entry/2022/02/28/165539
チャレンジしてはパニクった経験

## 図らずもチャレンジの舞台に立つこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426622/2aaf07e7-664c-76a5-db6d-0a7b8243b467.png)

意識的にチャレンジすること。
そんなつもりなくてもその場に立たされること。
それを余儀なくされること。
単純に認識が甘かったこと。

そのようなことによって、自分の力量に合わない仕事や立場に立つこと。
コンフォートゾーンを大きくそれてパニックゾーンに入ってしまうことがあります。

仕事において、難しすぎず簡単すぎず、そして丁度よく学びのあるラーニングゾーンだけで安定することは不可能でしょう。（あるとすれば、以前に書いた『[消費者への道](https://qiita.com/koji-yamauchi/items/2cbb7360cda4b441e8e2#%E8%88%97%E8%A3%85%E3%81%95%E3%82%8C%E3%81%9F%E9%81%93%E3%81%AF%E6%B6%88%E8%B2%BB%E8%80%85%E3%81%B8%E3%81%AE%E9%81%93)』だけです。）

物事は多少ブレが発生するものです、それでもなおパニックゾーンに入らないとするならば、きっとコンフォートゾーンど真ん中から出ないようにしているだけかもしれません。

顧客にとって、自分が明らかに価値を出せないような分野であれば断りますが、若手の頃にはそのような裁量はありませんし、ほとんどのことはやってみないとわからない。
仕事は知らないこと、不明瞭なこと、心配ごとがある状態から始まるものです。

## 数々の後悔、失敗、思い知らされる力量不足

このようなことから、チャレンジの舞台に立つものの、後悔したり失敗したり、力量不足を痛感することが何度もありました。

そのタイミングにおいては、目の前が真っ暗になっている感覚、どうにも出来ない気持ちになりますが、熱いものが喉を通り過ぎたあとは、少し冷静に振り返ることも出来ます。

後悔や失敗、力不足を痛感した経験があるからこそ、今の自分に繋がっています。

https://qiita.com/koji-yamauchi/items/99a7f1df2a68fbbea305



## 経験と座学はセットで力となる

プロジェクトマネージメントの経験が全く無い状態でPMBOKを学ぶのと、日々の業務の中で迷いや課題を持った中で学ぶのでは大きな差があります。

これはプロジェクトマネジメントに限った話でありません。
日々の課題への意識とそのヒントや助けを学ぶという意識が大切だと思います。

パニックになるほどの強いストレスはなるべく避けたいところですが、新しいことへの挑戦はいかに自分が無知で無力であるか気付き、学習へのきっかけにもなります。

## チャレンジの機会がない場合

### 現状の環境で相談してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426622/f29eff0e-9f45-68b6-7f93-271543200646.png)

本当はラーニングゾーンに身を置きたいと考えていても、日々の業務は定型で同じ繰り返しかもしれません。
もし、その状況を打開したい場合、所属組織自体に不満がなければ一度、上長に相談してみてはいかがでしょうか。

会社や上司にとっては、とても嬉しい相談かもしれませんし、希望するキャリアや今の業務状況でどのような選択肢が考えられるか親身になってくれる可能性もあります。

### 今の環境で希望を満たせない場合は転職も視野に

チャレンジしたいことが、今の職場環境では満たせないこともあるでしょう。
その場合は転職も視野に入れてみるのも良いと思います。

この記事を書くきっかけになった転職ドラフト Advent Calendar 2024 では下記の記載があります。

> 転職ドラフトでは、技術やビジネスの変化の激しいIT業界において、自らチャレンジの機会をつくり、時には変化に流されながらキャリアの意思決定をしていく「探索型キャリア設計」が重要だと考えています。探索型キャリア設計において大事な要素は、”機会の創出” と ”振り返り” です。

自身のチャレンジしたい分野と企業のミスマッチを減らすにはこのようなサービスを用いたり、カジュアル面談などで自分に何ができるか、どのようなことにチャレンジしたいかをすり合わせると良いでしょう。

https://job-draft.jp/

転職については[転職活動して気づいた「これをやっていれば.../やってよかった」をシェアしよう by 転職ドラフト Advent Calendar 2024](https://qiita.com/advent-calendar/2024/engineering-careers-2)で書いた下記の記事もよければどうぞ。

https://qiita.com/koji-yamauchi/items/ffc4e1be3c7cfc50e0ff
[TypeScript] ?? と ||

完全に自分用のメモ。
毎回「あれ？どっちがどっちだっけ？」ってなる:cry:

## x = a ?? b
a が  `null` または `undefined` の場合にのみ b を返す。
```typescript
let a = '';
let b = 'default';

let x = a ?? b; // x は '' になる
```
## x = a || b
a が「falsy」な値（`false`, `0`, `''`, `null`, `undefined`, `NaN`）の場合に b を返す。
```typescript
let a = '';
let b = 'default';

let x = a || b; // x は 'default' になる
```
はじめてのCentOSで最小限インストールしてしまい、GUIが使えず、結局再インストールした話

# はじめに
5, 6年前に買ったノートパソコンを再利用したいと思いCent OS Streamをインストールしたが、最小限(minimal)でインストールしてしまったがためにGUIが使えず、結局再インストールしました。

## インストール


### Minimal Install とは
CentOSのインストール時、「ソフトウェアの選択」はデフォルトでServer with GUIになっているのですが、最小限インストール(Minimal Install) を選択しました。

Minimal Installはインストール時間が短く、CLIベースかつインストールに必要な容量が少なく、最低限のもののみインストールされるため、PCのスペックも低くて済みます。

### GUIを利用できるものは？
ベース環境には、
- Server with GUI
- Server
- Minimal Install
- Workstation
- Custom Operating System
- Virtualization Host

の6つがあります。

その中でGUIベースは「**Server with GUI**」と「**Workstation**」の2つです。

### なぜMinimal Installを選んだのか？
私はGUIベースのものが使いたかったのですが、上記のことを知らずに適当にインストールしてしまいました。
Server with "**GUI**"と書いているもののServerとなるとサーバー向けなのではないかと勝手に思ったので別のものを選択してしまったのですね。もう一つWorkstationというものがあるようですが、こちらはServer with GUIと何が違うのかは検証していないのでわかりません。

https://massie0414.com/index.php/virtualbox/3493/#Workstation

ただ、上記のmassie's programming様のページによるとWorkstationはServer with GUIよりアプリが少しだけ増えてるそうです。

### インストール後 (Minimal Install)
CLIベースで無事起動できましたが、GUIで使いたかったため、GNOMEデスクトップをインストールしようとしてみました。
```sh
sudo yum groupinstall "Server with GUI"
```
ここで、Server with GUI をインストールするにもそもそもインターネットに接続できてませんでした。

ネットワークの設定を試みましたが、結局のところできなかったのでServer with GUIを選択して再度インストールをし直しました。

### なぜネットワークの設定ができなかったのか
そもそも私に知識がないという理由が大きいのですが、自宅で作業していなかったため、大学のWi-FiにはWPA Enterpriseが使われていました。

今さら調べてみてRed HatのドキュメントによるとnmtuiはそもそもWPA Enterpriseに対応していませんでした。

> nmtui は、すべての種類の接続に対応しているわけではないことに注意してください。特に、VPN、WPA Enterprise を使用したワイヤレスネットワーク接続、802.1X を使用したイーサネット接続は編集できません。

https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/7/html/networking_guide/sec-configuring_ip_networking_with_nmtui#sec-Configuring_IP_Networking_with_nmtui

WPA Enterprise を使って接続するには以下のドキュメントがよさそうでした。

https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/7/html/networking_guide/sec-configuring_802-1x_security#sec-Configuring_802-1X_Security_for_Wi-Fi_with_nmcli

そもそも学校のネットワークがWPA Enterpriseということを把握していなかったというのが問題だったわけです。

とりあえずわからなくなったら最初は再インストールするのもありかもですね。
まあ諦めてもなぜできなかったのかはあとあと突き止めるのがよさそうです。

# 最後に
CentOS Stream 9 を初めて使ってみましたが、古めのノーパソにはちょうどいいですね。
学習日記アプリ作成（要件定義編）

## 1\. ユーザー要件
#### 対象ユーザー
学習内容を記録・管理したい個人ユーザー
学生や自己学習者が主な対象

#### 目的
日々の学習内容を簡単に記録し、振り返りを容易にする

## 2\. 機能要件
+ ユーザー管理
  + ユーザー登録
  + ログイン/ログアウト (セッション管理)
  + ユーザープロフィールの編集


* 学習日記管理
  * 学習内容の登録 (タイトル、日付、内容)
  * 登録した日記の閲覧 (一覧、詳細)
  * 日記の編集・削除

+ 学習履歴機能
  + 過去の日記の検索・フィルタリング (日付やキーワードで検索)

## 3\.非機能要件
+ 性能要件
  + 1秒以内のレスポンスを目指す
  + 同時アクセス数50件を想定

* セキュリティ要件
  * パスワードの暗号化
  * JWTトークンを使用した認証
  * 入力値のバリデーション (SQLインジェクション、XSS対策など)

+ 可用性要件
  + サービスの稼働率: 99%以上を目指す
  + データバックアップを定期的に実施

## 4\.技術要件
+ バックエンド: Java (Spring Boot)
+ フロントエンド: Vue3 + Vuetify
+ データベース: PostgreSQL
+ インフラ: Apache, Docker, AWS CodeBuild/CodeDeploy
+ コンテナ化: Dockerを用いてアプリケーションを分離・管理

## 5\.UI/UX要件
+ UIデザイン
  + シンプルで直感的な操作性
  + モバイルフレンドリーなレスポンシブデザイン

* ユーザー体験:
  * 操作のステップを最小限に
  * 操作失敗時の明確なエラーメッセージ
  
## 6\. スケジュール要件
* 2週間で開発・デプロイまで完了
  * 設計: 2日
  * 実装: 7日
  * テスト: 3日
  * デプロイ: 2日
API Best Practices ~小さなデータを操作するメソッドを作成しクライアントがそれらの複数RPCをバッチ処理してUIを構成することを期待する

## 小さなデータを操作するメソッドを作成しクライアントがそれらの複数RPCをバッチ処理してUIを構成することを期待する

https://protobuf.dev/programming-guides/api/#create-methods-manipulate-small-bits

複数の狭く指定されたデータを操作するRPCを用意し、クライアントに必要なものを構成させることで、
サーバーを変更することなく、より幅広いUXオプションが可能になる。

これはフロントエンドとミドルティアサーバーにとって最も関連性があります。

多くのサービスは独自のバッチング API を公開しています。

---

と、ほぼ直訳してみたが、正直あまりピンとこない。
内部APIの場合、トランザクションかけたいケースが殆どのためと思われる。
Volta + Corepack + pnpm で Node.js 開発環境をセットアップ

# Volta + Corepack + pnpm で Node.js 開発環境をセットアップ

Node.jsの開発環境を効率的にセットアップするには、Volta、Corepack、pnpm の組み合わせが非常に便利です。本記事では、この3つを使って開発環境をセットアップする手順を解説します。

## 特徴

- 効率的なバージョン管理: [Volta](https://volta.sh/)でNode.jsのバージョンを簡単に管理
- シームレスなパッケージ管理: [Corepack](https://nodejs.org/api/corepack.html)でプロジェクトごとに最適なパッケージマネージャーを利用
- 高速な依存関係解決: [pnpm](https://pnpm.io/)でディスクを効率的に使用し、高速なパッケージインストールを実現

Volta はまだ正式に pnpm をサポートしていないので、 pnpm のバージョン管理は Corepack で実施します。

## Volta のインストール

[Volta のドキュメント](https://docs.volta.sh/guide/getting-started)に従ってインストールしていきます。

```bash
curl https://get.volta.sh | bash
```

MacOS/Linux または WindowsのWSL環境の場合、環境変数とパスを忘れずに設定して下さい。
また、PNPMを有効にするため、 `VOLTA_FEATURE_PNPM` も有効にします。

[Volta - pnpm Support](https://docs.volta.sh/advanced/pnpm)

#### MacOS の場合

```:.zshrc
export VOLTA_HOME=$HOME/.volta
export VOLTA_FEATURE_PNPM=1
PATH="$VOLTA_HOME/bin:PATH"
```

設定ファイルを再読み込みします:

```zsh:zsh
source ~/.zshrc
```

#### Linux または Windows WSL Ubuntu の場合

```:.bashrc
export VOLTA_HOME=$HOME/.volta
export VOLTA_FEATURE_PNPM=1
PATH="$VOLTA_HOME/bin;PATH"
```

設定ファイルを再読み込みします:


```bash:bash
source ~/.bashrc
```

インストールが完了したら、Volta が実行できることを確認します:


```bash
volta --version
```

## Node.js と Corepack のインストール

Voltaを使って、Node.jsとCorepackをインストールします:

```bash
volta install node
volta install corepack
```

## Corepack を有効化

Corepackを有効化し、プロジェクトで利用できるようにします:

```bash
corepack enable
```

## Node.jsプロジェクトを初期化

次の手順で、試しに新しいNode.jsプロジェクトを作成し、pnpmで初期化してみましょう。

### 1. プロジェクトディレクトリを作成

```bash
mkdir my-nodejs-app
cd my-nodejs-app
```

### 2. 空の `package.json` を作成

```bash
echo '{}' > package.json
```

### 3. pnpm を使用する

指定したバージョンのpnpmをCorepackで有効化します:

```bash
corepack use pnpm@latest
```

pnpmのバージョンを確認します:

```bash
pnpm --version
```

### 4. プロジェクトをpnpmで初期化

次のコマンドでプロジェクトを初期化します:

```bash
pnpm init
```

以上で、Volta + Corepack + pnpm を活用したNode.js開発環境のセットアップが完了です。この環境を使えば、効率的で快適な開発体験を得ることができます！
インターフェースデザインにおける、モックアップのコンポーネントの堅牢さレベル

## この記事の概要

一口にモックアップ（デザインデータ）といっても、作り方によって堅牢さには幅が生まれます。
堅牢であればあるほど良いわけではありませんが、ある程度は堅牢な方が使いまわしやすく、制作の指針にもなります。

この記事では、私がこれまで見てきたデータをもとに、堅牢さをレベル分けしてみました。
自分達の組織が○レベルとか、今後○レベルを目指したいとか、そういった指標に使っていいただけたら嬉しいです。

:::note
あくまで私が見たことのあるものを基準にしているだけなので「レベル1と2の間にこれくらいの堅牢度があると思う」などの意見は歓迎です。
:::

:::note warn
分かりやすさの都合上、この記事では「堅牢であること」を高レベルなものとして記載しています。

しかし実際は「堅牢であればあるほど良い」というものではなく、あくまで「自分達の組織とデザインデータがフィットしているかどうか」が重要です。
その前提で読んでいただければ幸いです。
:::

## レベル0：コンポーネントがない

同一の情報[^1]を表す要素であるにも関わらず、コンポーネント化せずコピー＆ペーストで対応している状態です。

[^1]: 例えば通販サイトにおける`商品名と画像と価格がセットになったもの`など。場所によって微妙に情報が違うことはあれど、メンタルモデル的には`商品サムネイル`などと同一のものとして認識されるであろうものを指します。

このレベルでは、何か1つの情報に変更があっただけでもデザインデータ全域を見て変更・修正する必要があります。

また、見た目に関するちょっとした不統一（色の違い、枠線の有無、影の濃さなど）は、大抵の場合気づかれません。

結果的に意味を持たないバリエーション違いが乱立し、後になって「いつどのデータを使うのが正なのか分からず制作やレビューに時間がかかる」などの問題を引き起こしがちです。

## レベル1：コンポーネントがあるが、統一されていない

以下のような場合があります。

- コンポーネントにはなっているものの
    - デザイントークンが使われず、直接色や数値が指定されている
    - バリエーション違いのものなのに、グルーピングや命名や一貫しておらず乱立している

レベル0と比べればコンポーネント化されているだけ堅牢ではあります。
しかし、同じもののはずなのに別の値、別のコンポーネントとして定義されている場合、段々とバラバラになってしてしまいがちです。

使用頻度の低いコンポーネントがあると「当時はこの内容で正しかったけど、今では間違っている」「このバージョンにだけこの情報が残ってしまっている」などの状態になりがちで、それを察知するのも大変です。

また、もともとがバラバラだと、つい「少し使い勝手が悪いから、どうせ乱立しているし、私の考えた最強の別バージョンコンポーネントを新たに作ろう」という動きが生まれがちです。

## レベル2：コンポーネントがあり、見た目の観点としては統一されている

同一の情報は同一のコンポーネントであり、見た目の観点としては問題ない（ただしコードの観点では不十分な）状態をレベル2としています。

少し古い話ですが、よくある例で言えば、同じような内容のDOMを複数描画し、条件にあわせて`display: none`を付け替えてバリエーション違いを表現するような実装です。
多くの場合、もともとのデザインデータがちゃんと考えられていれば、最低限のDOMだけで済みます。

これに限らず、見た目上（あるいは人間の知覚上）は問題なくても、コードの観点ではやや問題あり、というデータはよく見ます。

最終的にはコードで表現するのがWebやアプリなので、見た目の観点だけでの制作だと堅牢さは半減します。

## レベル3：コンポーネントがあり、コードとしての観点とも合致している

デザインデータ上で表現されるレイヤーの有無と、コード上で求められるバリエーションなどの有無が一致しているような状態を指します。

どこまでいっても完全な一致は難しいとは思いますが、概念的には一致しているとか、例外はあれどメモ書きを読めば理解できるとか、そういう状態まで持っていけると良いでしょう。

どこはカスタムできてどこは固定にするのか、どんな型のデータを受け取れる（弾く）かとか、そういう部分まで考えられているといないとでは大きな違いがあります。

## レベル4：レベル3までを踏まえたコンポーネントがあり、かつデザインデータとしても例外を生みづらい

例えばFigmaでいえば、テキスト内容や要素の表示非表示はpropertyで制御されているとか、simplify all instancesが適用されいているとか、そういった観点です。

複数人でデザインデータを制作すれば、どうしても「ここを変更したい」とついつい（変更すべきでない場所ですら）変更してしまう人もいます。
組織でインターフェースデザインをする場合、そういう「うっかり変更」を発生しづらくする必要がありますが、人間に任せるのではなく「うっかり」では変更できないデータを作るのが重要です。

自由さと堅牢さは相反する関係で「デザインシステムの導入や浸透を頑張りたい」という意見があるのであればまず間違いなく「不必要な箇所をうっかりでは変更できない」データを作るのは大事です。

## レベル5：実装をベースにデザインデータが存在しており、そこから外れたものはレビューで弾かれる

既存のコンポーネントは完全にコードと合致しており、新規に作る際コードと合致しないような部分があればレビューが通らずリリースできないような状態です。

ここまでくるとデザインデータだけの問題だけではなく、レビュー体制など組織的な話の方が多いかもしれません。

よくある「デザイナーが見た目を作成→エンジニアがコードで再現」というフローでは「実装上の都合が考慮されていないデザインデータ」は大なり小なり生まれます。
そしてそれが生まれる度に議論をしたり落とし所を探っていては時間がかかります。

そのため、はじめから実装上の制約を前提とし、それにそぐわないデザインデータが生まれた時点でリジェクトする方がスムーズではあります。

実装をした後に、振り返りや次の企画を円滑にするためのものとして、デザインデータを視覚的に整理し直す、という考えは堅牢にはなります。
CodeAGIを使って開発を行っていきます。

## **【連載第1回】CodeAGIで設計書からプログラムまでを自動化する流れを解説します**

こんにちは。私は「SoppraDX」という会社で働いており、当社では「CodeAGI」という製品を開発しています。CodeAGIは、AIを活用して設計書からプログラムまでを効率的に作成できる画期的なツールです。

この連載では、CodeAGIを使って実際に設計書からプログラムを作成する一連の流れを解説していきます。この記事を通して、AIを活用した開発プロセスの具体的な方法や、ツールの便利さを体験していただけるよう努めます。

---

### **連載の目的と内容**

この連載では、以下の内容をステップバイステップで解説していきます：

1. **CodeAGIの概要**  
   - CodeAGIがどのようなツールで、どのように利用するのかを説明します
   - 基本的なセットアップ方法や必要な準備について解説します

2. **設計書の準備とCodeAGIへの取り込み方法**  
   - 設計書の形式や、効率的にAIが読み取れるようにするためのヒントを紹介します

3. **CodeAGIを活用したプログラムの自動生成**  
   - 設計書から生成されるコードの仕組みや、注意すべきポイントを解説します
   - 実際の生成例を紹介し、成果物がどのようになるかを示します

4. **生成されたプログラムの修正・改良方法**  
   - AIが生成したコードをさらにブラッシュアップする手順やTipsについて説明します

5. **最終動作確認と実行**  
   - 完成したプログラムを実際に動かし、どのように検証を行うかを紹介します

---

### **この連載で得られるもの**

- AIを活用した効率的な開発プロセスの理解
- CodeAGIを使った具体的な操作方法と実践例
- 実際に動くプログラムを完成させる経験

---

### **次回予告：CodeAGIの概要とセットアップ**

次回は、CodeAGIの基本的な概要やセットアップ手順について詳しく解説します。また、使用前に準備しておくべきポイントについても触れる予定です。

---

「CodeAGI」の詳細については、以下のリンクをご覧ください：  
👉 [https://codeagi.ai/](https://codeagi.ai/)  

次回をお楽しみに！ 


### 連載一覧　CodeAGIを使って開発を行っていきます。
**1.【連載第1回】CodeAGIで設計書からプログラムまでを自動化する流れを解説します**
**[2.【連載第2回】「CodeAGI」の概要](https://qiita.com/to_sprdx/items/e5a065fe01ec588880af)**
**[3.【連載第3回】設計書の準備とCodeAGIへの取り込み方法](https://qiita.com/bellpepper/items/c0f71e8c2274ae290041)**
**[4.【連載第4回】CodeAGIを活用したプログラムの自動生成](https://qiita.com/k_nomo/items/468198abdd4abdf05230)**
**[5.【連載第5回】生成されたプログラムの修正・改良方法](https://qiita.com/sono1/items/cc977ae9b71d645ecd59)**
**[6.【連載第6回】最終動作確認と実行](https://qiita.com/sprdx_c_en/items/b03ed16b237cb35708b5)**
【Amazon Connect】デスクフォンを使用した受電方法

## はじめに

Amazon Connectでは、電話タイプはソフトフォンとデスクフォンの２つが用意されています。
ソフトフォンは物理的な電話機は不要で、インターネット接続とヘッドセットまたは内蔵マイクとスピーカーがあれば利用できます。
デスクフォンは物理的な電話機であり、スマートフォンや固定電話機を使用した受電を行います。
Amazon Connectへ移行するが、今まで通りの受電方法を採用したい場合はデスクフォンを選択することとなります。

この記事では、Amazon Connectを使用したデスクフォンの設定方法と、ソフトフォンとデスクフォンの料金の違いを説明します。

## デスクフォンの設定方法

デスクフォンの設定は、エージェントそれぞれに対して行います。

1.Amazon Connectユーザ設定画面で電話の種類を切り替える

赤枠内の電話の種類をデスクフォンとします。
デスクの電話番号に、スマートフォンまたは固定電話の電話番号を入力します。

![スクリーンショット 2024-12-10 10.53.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/5a4228c3-de5b-dcdb-a00b-82498bd46924.png)

2.CCPを開き、電話の種類がデスクフォンになっていることを確認

![スクリーンショット 2024-12-10 10.55.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/ac8c3a11-ae51-251e-6802-d9e6893e5be5.png)

3.電話をする

CCP画面では入電していることは確認できますが、受電はできません。
設定を行ったスマートフォンか固定電話に入電していることが確認できます。

![スクリーンショット 2024-12-10 10.56.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/61f541cb-f546-2913-c455-6acbfe680fb6.png)

## デスクフォン設定の注意点

- デスクフォン設定を行う場合、受電を行うのはAmazon ConnectのCCPではありませんが、常にCCPを開いておき、エージェントステータスを`Available（通話可能）` としておく必要があります
- デスクフォンの設定を行った場合、同時通話数のサービスクォータに引っかかる可能性があります
    - デスクフォンとCCP両方を使用していることとなるため、実際には1つの通話でも、AWS上では2つとしてカウントされます
    - 同時通話数の上限はデフォルトで10となっているため、全員がデスクフォンを使用する場合、5つの同時通話で上限に達することとなります
    - ※認識間違いあれば誰かご指摘ください

## デスクフォン 料金について

デスクフォンをご利用の場合、 Amazon Connect で取得した番号にインバウンドコールが発生すると、Amazon Connect がデスクフォン側の番号にアウトバウンドを行う挙動となります。

そのため、Amazon Connectインスタンスを所有しているAWSアカウントに対しては通話中のインバウンド (顧客 → Amazon Connect) とアウトバウンド (Amazon Connect → デスクフォン) 両方の料金が発生いたします。

① 通話中のインバウンド (顧客 → Amazon Connect)
② アウトバウンド (Amazon Connect → デスクフォン)

![スクリーンショット 2024-12-10 11.25.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/3f9597e4-2ea4-4999-a99a-2f3f58f6964d.png)
LT開催してみた

この記事は <a href="https://qiita.com/advent-calendar/2024/trail-blazer">株式会社TRAILBLAZER アドベントカレンダー</a> の14日目の記事です。

---
こんにちは、株式会社TRAILBLAZER データコンサルティング事業部でデータサイエンティストをしている朝倉です。
TRAILBLAZERはまだできて1年ちょっとの会社なので、いわゆる組織づくり的な取り組みを絶賛推進中のフェーズです。今回はその一環として、社内で初めてのLTを開催したことについて振り返ってみたいと思います。



# LTってなに？
LT（ライトニングトーク）は、短時間で行うプレゼンテーションの形式です。具体的な発表時間は場合によるのですが、おおよそ3分から長くても10分程度の時間で一つのテーマについて話します。

# なぜ社内LTをするのか
気軽に自分のしゃべりたいことをサクッとアウトプットする、そんな場が必要だと思っているからです。クライアントワークがメインになるTRAILBLAZERでは、どちらかというと「きっちり準備してプレゼンをする」という機会のほうが多くなりがちです。もちろんそれも重要なのですが、誰もが気軽にアウトプットできる機会を作ることも同じくらい大切なことだと考えています。

誰かがアウトプットをすることで、聞く側はもちろんのこと、アウトプットをした本人にとっても大きな学びになります。そしてそのアウトプットは、将来別の誰かのアウトプットの糧にもなったりします。こういったアウトプットの好循環を作っていくことが、良い組織文化の醸成に繋がってくるのです。

もっとシンプルに、LTが楽しいからというのも大きな理由の一つです。弊社の場合ではリモートでのLT開催がメインになるのですが、それでもリアルタイムでリアクションを貰えるのはうれしいですし、励みになります。また聞く側の視点に立ってみても、特に普段仕事で一緒になることが少ない方のLTを聞くのが新鮮で好きです。

# ハードルを下げるためにやったこと
そんなわけでTRAILBLAZERでは初めてとなる社内LTを企画してみました。特に初回のLT開催では参加する心理的なハードルが上がってしまいがちなので、そのハードルを少しでも下げることに注力して企画・宣伝を行いました。いかに「なーんだ、LTってこんなものか」と良い意味で思ってもらえるかが勝負です。

ということで、具体的にどのようなハードルを、どのように下げにいったのかを簡単に書き連ねたいと思います。

## 宣伝時に、LTにあるあるな誤解を解く
宣伝活動の初手として、今まであまりLTに触れてこられなかった方が抱きがちな誤解を解くことをしました。以下に、実際に社内LT開催の宣伝のために作成したスライドを抜粋していますが、ありがちな誤解を解いて、気軽に発表してほしいというメッセージを込めています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932355/30ccb2f3-3526-97ab-8577-9b9b43608e45.png)
 LTの宣伝時には、細かい決まりや建付け云々よりも、こういった誤解を解いてハードルを下げることに重点を置いて説明をしていました。
 
## 発表時間オーバーもある程度は許容する
LTによっては、あらかじめ決められた発表時間をオーバーすると、プレゼンの途中であっても強制終了するようなルールを設けているところもあります。
もちろんこういったルール自体を否定するわけではないですし、限られた時間で運営していくためには重要なルールです。また、限られた時間内にプレゼンを終わらせるのも立派なスキルです。一方でハードルを下げるという視点でみれば、ハードルが上がる要因になってしまうので、今回は多少の時間オーバーは目をつむるという方針にしました。

## テーマの壁打ち役（という名の促し役）になる
「○○なテーマで発表しようと思うんだけど大丈夫かな？」といった相談を受ける壁打ち役をやりました。といっても、公序良俗に反するテーマ以外は基本「うん、いいと思いますよ( ･∀･)=b」で返していました。LTはルールがないのがルールなので。壁打ち役と言いつつ促し役になっていました。

# 所感
ここまで書いたようなできることはやりつつも、発表者0人なんていうオチもあるのではないかとドキドキしながら当日を迎えました。が、フタを開けてみると計4人もの発表者に登壇いただきました。LT開催の対象にしていた部門の人数が30名ほどだったことを考えると、それなりのヒット率でした。（発表者の内一人は私なのですが、それを差し引いても十分な集まりだったかと思います。）
また、LT開催直後に登壇の立候補が増えたり、「自分もこんなテーマで発表してみたい！」といった相談もいただきました。アウトプットに触発されて、更なるアウトプットが連鎖していくような流れができつつあるのが非常に喜ばしい限りです。

# 今後やりたいこと
今回は、TRAILBLAZERの中でもデータコンサルティング事業部という1部門だけでの実施でしたので、今後はハードルの低さを踏襲しつつ全社展開していく予定です。機会があれば社外LTなど外部に発信する場も企画できればと考えています。

また、発表順に関しては、初回開催では私の独断と偏見で決めてしまいました。しかし、こういった恣意的な決定方法は不正などの温床になりがちです。ということで次回は公平なルーレットによって決めたいと思います。これで不正なんて起こりようがありませんね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932355/0eb33ff3-1cba-5188-e4b1-11778cbb7937.png)


# 最後に
最後に、TRAILBLAZERでは一緒に働くメンバーを募集中です。
ちょっとでも興味が出たそこのあなた、ぜひクリックして覗いてみてください。
ということで、本日の記事はここまでとなります。
読んでくれたみなさん、ありがとうございました。

https://hrmos.co/pages/trail-blazer