OmniAICreator/Qiita-1.07M huggingface dataset:
OpenSSFのアップデート(2023年12月版)

日立製作所　中村 雄一

# OpenSSFとは
 [OpenSSF(Open Souce Security Foundation)](https://openssf.org/)とは、2020年に設立されたThe Linux Foundation傘下の団体であり、「OSSのセキュリティ全般（OSSの開発側, OSSを使う側双方）」を活動のスコープとしています。2021年末のlog4jのインシデントを受けサプライチェーンセキュリティにおけるOSSの懸念が高まり、米国政府の要請で、OpenSSFがOSSセキュリティ実行計画(10 streams)を取りまとめ、メンバ加入や活動が加速しています。特に注目すべきプロジェクトをいくつか紹介します。

* [OpenSSF Best Practice Badge](https://www.bestpractices.dev/)
 OSSプロジェクトが準拠すべきベストプラクティスを定めており、ベストプラクティスを満たしたOSSプロジェクトにBadgeと呼ばれるロゴを授与しています。2023年12月9日現在、6445ものOSSプロジェクトにBadgeが授与されています。

* [SLSA(Supply chain Levels for Software Artifacts)](https://slsa.dev/)
 ソフトウェアサプライチェーンにおける、ソフトウェア開発から実装までのプロセスに注目して、どの段階でも「確実に真正であること＝第3者によって破壊されていないこと」を実証することで、すべてのプロセスが意図された通りに開発、ビルド、パッケージ、デプロイされたことを確認するためのフレームワークです。OSSの開発のみならず、OSSを用いたソフトウェア開発全般が意図されています。SLSAに準拠した開発では、パッケージがどのように構築されたかを示すprovenance(来歴）を作成し、パッケージ利用者が、パッケージ構築時に不正が行われていないことを確認できるようにします。

* [Sigstore](https://www.sigstore.dev/)
 ソフトウェアを署名・検証するためのツールです。ソフトウェア以外にもSBOMやSLSAのprovenanceの署名にも使われます。類似のツールとの大きな違いは、OpenID Connectの認証サーバを用いた、[キーレス署名](https://docs.sigstore.dev/signing/overview/)に対応しているところです。キーレス署名により、署名鍵の管理の手間がなくなります。

# OpenSSF Day Japan 2023で発表されたアップデート
  2023年12月4日にOpenSSF Day Japanが開催されました。基調講演では、OpenSSFの代表であるOmkhar Arasaratnamさんより、OpenSSFの最新のアップデートが発表されました。以下に、主なアップデートを紹介します。

* [Secure Software Development guideline principle(SSDGP)](https://github.com/ossf/wg-best-practices-os-developers/blob/main/docs/SecureSoftwareGuidingPrinciples.md)
セキュアなソフトウェア開発の10の原則が、ソフトウェア開発プロジェクトにおける誓約書の形でまとめられています。ソフトウェア開発プロジェクトは本原則に署名し公開することで、セキュリティを十分に考慮することをプロジェクト内外にアピールすることができます。

* [CVE Numbering Authority Guide](https://github.com/ossf/wg-vulnerability-disclosures/blob/main/docs/guides/becoming-a-cna-as-an-open-source-org-or-project.md)
CVE(Common Vulnerabilities and Exposures)では、脆弱性の開示のプロセスを定めており、脆弱性の識別子を発行するプロセス定められています。本ガイドでは、OSSのプロジェクトがCVEの脆弱性識別子を発行する機関になるための手順を解説しています。

* [Compiling Options Hardening Guide for C and C++](https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html)
C/C++言語のコンパイラは、生成されたバイナリを攻撃されにくくするための機能を有しています。本ガイドでは、そのような機能を有効に活用するため、コンパイラのオプションを解説しています。

* [Souce Code Management Guide](https://best.openssf.org/SCM-BestPractices/)
  GithubやGitlabのようなソースコード管理プラットフォームを使う際のセキュリティ上の留意点をまとめたガイドです。
  

* [Malicious packages repository](https://github.com/ossf/malicious-packages)
悪意のあるソフトウェアに、有名なパッケージと類似の名前を命名し、開発者のtypoを通じて、悪意のあるソフトウェアが混入するケースが多発しています。Malicious packages repositoryでは、そのような悪意のあるパッケージの報告を受け付け、悪意のあるパッケージのリストをまとめています。


OpenSSF Day Japan 2023では、この他にもOpenSSFに関連した最新の取り組みが発表されました。資料が公開されているセッションもありますので、興味のある方は[こちら](https://openssfdayjapan2023.sched.com/)を参照ください。
テスト自動化ツールのPlaywrightについて学んだ結果

## はじめに
社会人10年目になり、ソフトウエア開発系の会社に転職したはいいものの、「コーディングまるでわからん(´・ω・｀)」状態に陥ってしまった中の人です。

前職の会社もソフトウエア開発系ではあったものの、社会人4年目くらいから転職するまで、ずっと開発もしなけりゃ設計もしない、そんな別の会社に出向していたので、VSCode すら触ったことがありませんでした。

CSS とか JavaScript とか HTML とか学んではみましたが、やはりちんぷんかんぷん。一から作り上げることの難しさを痛感したものです。
見かねた上長が、助け舟を出してくれて、とあるテスト自動化ツール使ってみてほしいと言ってくれました。


## ツール何使ったの
[Playwright](https://playwright.dev/dotnet/)をとりあえず使ってみました。
社内の勉強会で紹介されていたというのと、上述した上長からの勧めでとりあえずこれからはじめてみました。

## Playwrightの特徴

### どういうシーンで使うのか
Playwrightは、以下のシーンで使われます。
1. ブラウザテスト: 自動化されたブラウザテストスクリプトの作成や実行をするとき。
2. スクレイピング: ウェブサイトからデータを収集するためのスクレイピング作業をするとき。
3. UIテスト: ユーザーインターフェースの動作や表示をテストをするとき。
4. クロスブラウザテスト: 複数の主要なブラウザでのテストをカバーするとき。
5. パフォーマンステスト: ブラウザのパフォーマンスや負荷に関するテストを実施するとき。

### 一からコードを書かなくていい
Excelマクロを作るときのごとく、画面をポチポチすると勝手にコードを作ってくれます。
多少の手直しが必要なケースは発生しますが、一からコーディングしなくて済むのはコーディングあまり出来ない勢からしたらとてもありがたい話です。


### お値段フリー
やはりイニシャルコスト、ランニングコストが不要だといろいろ試せて良いですね。

### マルチブラウザサポート
以下のブラウザに対応しているようです。一気に複数のブラウザでテストすることも可能です。

- Chromium
- WebKit
- Firefox

### マルチOSサポート
よく使われる OS には対応されています。

- Windows
- macOS
- Linux

### 歴史が浅く書籍が無い（技術書は紙でも読みたい派なので、個人的に困ったのがこれです）

2020年に誕生した Playwright ですが、まだ歴史が浅いためこれに特化した書籍は2023年12月時点では発売されていません。Qiita記事やZenn記事ではいろんな人が書いてくれていますが、Selenium や Puppeteer のように書籍で学びたい人はまだまだ時間がかかりそうです。

## 他のテスト自動化テストツールは？
#### 他のE2Eテスト
- [Selenium](https://www.selenium.dev/ja/)：Playwright と似たようなテスト自動化ツールで、歴史もあり、書籍も充実している。

- [Puppeteer](https://pptr.dev/)：Chrome のみのサポートではあるが、従来から利用されている自動化ツールである。ただ、現時点で Playwright ではできないが、 Puppeteer でできるというものはほぼない模様。

npm trends（npm上に登録されているパッケージのDL数の変遷をグラフとして可視化できるWebサイト）で、それぞれどのくらい使われているか見てみたところ・・・
https://npmtrends.com/playwright-vs-puppeteer-vs-selenium-webdriver

2023年12月3日時点ではまだまだ Puppeteer が大人気ですね。
ただ、このグラフの遷移を見る限り Playwright と Puppeteer のDL数逆転が起きるのも時間の問題かもしれません。
今から新しく学ぶなら Playwright がよいのかもしれません。きっと今後書籍やQiita記事がどんどん増えていくでしょう。


## 最後に
- 社内の勉強会(動画の視聴)で1時間ほど使い方を学んでいたものの、そのときの情報から Playwright アップデートしていたため、結局公式サイトをかなり読み込むことになりました。
- 記述方法は JavaScript か TypeScript が選べたのですが、TypeScript が JavaScript のスーパーセットだからという理由で TypeScript をチョイスしました。おかげで、TypeScript についても多少学ぶ~~羽目~~ことになりました。
- Puppeteer と Playwright のどっち使うか？みたいな状態になった場合、Playwright を選択するのがベターのようです。
- 技術記事をQiitaのような情報共有サービス上で書くという機会が今回もらえましたが、自分が学んだことの棚卸的なこともでき、Markdown も使うことができたので、アウトプットすることの大事さを久しぶりに体感しました。
Github Actions にて Public IP Install で失敗した時の対応

# はじめに
[こちら](https://qiita.com/kaino5454/items/bae4bca47e6f409e072f)で設定したGithub actions　にて自動デプロイのworkflowが失敗していた。
view workflow file内のbuildメニュー内の実行履歴を確認すると

haythem/public-ip@v1.2というpublic ip installのためのライブラリからの取得に失敗していた。


![スクリーンショット_2023-12-11_10_48_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/4376c3bb-0d20-75c0-fa46-a0b91482aed7.png)

# やったこと
まずhaythem/public-ipというオープンソースを配置しているGithubを確認しにいく。
(指定しているバージョンが古いかもと思いながら...）

Github：
https://github.com/haythem/public-ip

見に行ってみると
READMEに下記の記載がありました。

 ```
 name: Public IP

on: push

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Public IP
      id: ip
      uses: haythem/public-ip@v1.3

    - name: Print Public IP
      run: |
        echo ${{ steps.ip.outputs.ipv4 }}
        echo ${{ steps.ip.outputs.ipv6 }}
 ```


 uses: haythem/public-ip@v1.3
 が最新みたいでした。

 いま使っているのが1.2なのでそのバージョンを更新

修正前
 ![スクリーンショット 2023-12-11 11.01.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/ebd1686e-945e-2d09-5c82-1e7b68c48204.png)

↓

修正後

![スクリーンショット_2023-12-11_11_04_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/39e9b3d4-df86-b76d-3745-dfe75691f4ec.png)

これで自動デプロイが問題なく実行できるようになりました。
以上になります。
[ワンライナー]使っていないFloating IPの一覧を表示する

# はじめに
IBM CloudのVPCでは、VPC内に作成したインスタンスへ、直接インターネットから通信可能なGlobal IPを付与する `Floating IP` という機能があります。

https://cloud.ibm.com/docs/vpc?topic=vpc-fip-working&locale=ja

検証等が終わって、サーバーの削除やVPCごと削除しようとする際に、Floating IPは独立して残ったりするので、ついつい忘れがちです。

Floating IPは1つにつき月額$1.05程度なので、少額ではあるのですが、不要で使っていないものが溜まると勿体ないです。

掃除漏れが無いか確認したいので、一覧で表示するコマンドを用意しました。

# IBM Cloud Shellで表示する

IBM Cloud Shellについては、こちらで紹介されています。

https://qiita.com/Kakimoty_Field/items/f79120e6bfa42c5e2d9b

IBM CloudのCLIをローカルPCにインストールしていなくても使えるのでとても便利です。

さて、IBM Cloud Shellでは仮想Linux環境が立ち上がるので、次のコマンドを実行してください。

```shell
for region in us-south us-east br-sao ca-tor eu-gb eu-de eu-es jp-tok jp-osa au-syd ; do echo "## ${region} ##" ; ic target -r $region 1>/dev/null 2>&1 ; ic is ips --output json | jq '.[] | sort_by(.created_at) | .[] | select(.target|not) | .created_at + " " + .address + " " + .name' --slurp; done
```

IBM Cloudの各リージョン毎に、Floating IPでどのインスタンスにも紐づいていないものを表示します。各リージョン毎に作成日付でソートして表示するようにしています。
例えば私が使っている環境だと30人くらいが開発/検証していたりするので、いろんなロケーションに残骸があるように見受けられますね。
`作成日付`, `IPアドレス` ,`Floating IP名称` が表示されるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/3fd3cd24-abb2-27cb-c79a-3f029d4fddc8.png)

# さいごに
いかがでしたでしょうか？
年末の大掃除ではないですが、Cloud環境に不要なものが溜まってないかを見直して整理するチャンスに使っていただければ幸いです。
Salesforceと自動化ツール


# Amazon アプリフロー 

データを双方向に流す

### Salesforce データ キャプチャ (CDC) とプラットフォーム イベントをセットアップして、Salesforce データを AppFlow に自動的に送信します。

Salesforce から AWS にデータを自動的に送信するには、フロー作成プロセス中に Salesforce で変更データ キャプチャ (CDC) を有効にし、AppFlow でプラットフォーム イベントを有効にします。これは簡単なクリックで実行できます。まず、Salesforce 組織に移動します。

CDC とイベントトリガーが有効になっていると、次の場合に Salesforce が新しいデータを AWS に送信します。

+ 新しいレコードを作成します。
+ フィールドデータを変更します。

これらのイベントは、Amazon AppFlow の [実行履歴] タブで監視できます。

### Amazon Simple Storage Service (Amazon S3) から Salesforce にデータを送信するフローを設定します。

AWS から Salesforce へのデータ転送
次に、AWS から Salesforce への逆方向のデータの流れを見てみましょう。別の Salesforce インスタンスなど、利用可能なさまざまなソースから選択することも、Amazon S3 を選択することもできます。準備する必要があることがいくつかあります。

1. まだ作成していない場合は、最初にS3 バケットを作成します。
2. 次に、そのバケット内にフォルダーを作成します。
3. 次に、更新する Salesforce オブジェクトにマッピングする CSV ファイルを作成し、それを S3 にアップロードします。

# MuleSoft RPA

### 統合コネクタの区別

+ **ユースケース 1**: お客様は、単一または複数の Salesforce 組織をターンキー自動化された方法で大規模に統合する必要があります。お客様は、継続的な管理作業を最小限に抑えながら、クラウドで Heroku Postgres データベースを使用することに興味を持っています。 

  解決策: Heroku Connect は、統合コネクタの推奨事項です。前の単元で学習したように、Heraku Connect は、Salesforce 組織と Heroku Postgres データベース間の完全に自動化されたターンキー統合を提供します。フルマネージドの統合コネクタであるため、お客様は接続の稼働時間やメンテナンスの維持管理について心配する必要がありません。 


+ **ユースケース 2**: 顧客は、Salesforce 組織の単一または複数のインスタンスを、オンプレミスまたはクラウドにある Oracle または SQL データベースに統合する必要があります。お客様は、継続的に接続を設定および維持するための DevOps リソースを持っています。この顧客は、データをデータベースに保存する前に、データの変換および集計操作を構築することにも関心を持っています。 

   解決策: **MuleSoft Salesforce Connector** が推奨されるオプションです。なぜ？Oracle データベース、SQL データベース、および Postgres データベースをサポートします。さらに、MuleSoft Salesforce Connector は、クラウドに存在しないデータベースに接続するように設定できます。MuleSoft Anypoint Platform を使用すると、顧客はデータベースに保存する前にデータの集約や変換などの操作を実行できます。 

+ **ユースケース 3**:顧客は、複数の Salesforce 組織のデータを Postgres、Oracle、MySQL などのリレーショナル データベースに統合する必要があります。データ量は時間の経過とともに増加すると予想されます。たとえば、最初の量は 10,000 レコードで、12 か月以内に 100 万レコードに増加します。お客様は予算を重視しており、ライセンス費用を抑制したいと考えています。 

  解決策: このシナリオでは、ライセンス モデルの観点から、**MuleSoft Anypoint** コネクタを選択することが最良の選択です。Heroku Connect の価格は、Salesforce と Postgres データベース間で同期されるレコードの数に基づいています。これは、レコードの量が増加すると、ライセンス コストも増加することを意味します。MuleSoft Anypoint コネクタのライセンスは同期されるレコードの数に基づいていないため、より優れたコスト管理オプションになります。データ量の増加に応じて接続を管理および維持する責任は顧客にあることに留意することが重要です。 

### トレイルヘッド

+ [Manage MuleSoft RPA Solutions](https://trailhead.salesforce.com/content/learn/trails/manage-mulesoft-rpa-solutions)
+ [Get Started with MuleSoft RPA](https://trailhead.salesforce.com/content/learn/trails/get-started-with-mulesoft-rpa)
+ [Get Started with MuleSoft RPA Builder](https://trailhead.salesforce.com/content/learn/trails/get-started-with-mulesoft-rpa-builder)
+ [Build and run flows to automatically sync data between Salesforce and NetSuite using MuleSoft Composer.](https://trailhead.salesforce.com/content/learn/trails/sync-salesforce-with-netsuite)
Railsで環境変数を設定する

# 1. gemインストール

```:gemfile
gem 'dotenv-rails'
```
※ある記事で、 `gem 'dotenv'`と記載があったが、これでは上手くインストールできないので注意。

https://github.com/bkeepers/dotenv

# 2. 環境変数を設定する
リポジトリの一番上の階層で、`.envファイル`を手動作成

以下のように設定したい環境変数を設定
```:.env
ID=123a
```
''シングルクオーテーションは不要。key=value形式で良い。

# 3. サーバ再起動
環境変数はサーバ起動時に読み込まれる。
そのため、サーバ起動しているのであれば、再起動する。

# 4. 環境変数の確認
rails c でコンソールを起動し、以下の形式で確認ができる。

```:コンソール
irb(main):001> ENV["ID"]
=> 123a
```
AI-102試験対策のまとめ「LUISアプリにおけるアクティブラーニング」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
### LUISアプリにおけるアクティブラーニング
#### **アクティブラーニング**
* 正しく予測するためにエンドポイントの発話を見直すプロセス
    1. エンドポイントに送信されたクエリをキャプチャし、不明なユーザー発話が選択される
    1. 選択された発話を確認して意図を選択し、実際の発話に対するエンティティをマーク
    1. アプリをトレーニングして公開
    1. LUISでの発話識別の正確さが向上

#### **アクティブラーニングの有効化**
* ユーザークエリをログに記録する必要がある  
    ⇒予測エンドポイントクエリに`log=true`を追加  
* LUISポータルを使用する場合は、クエリパラメーターの変更から「Save logs」をOnにする

<br>

* 参考
    - https://learn.microsoft.com/ja-jp/azure/ai-services/luis/how-to/improve-application

## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「Text Analytics for healthコンテナの検証」**

https://qiita.com/fsd-jume/items/7a921eaaf75c31c35e29

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
OCIバケットのライフサイクル・ルールが作成できない場合の解決方法

このシリーズの他の記事は、[オラクル・クラウドの個人ブログ一覧 ](https://qiita.com/letian/items/10152a4fec813c1b7d98)からご覧いただけます。

# 現象
OCIコンソールに管理者権限を持つユーザーでログインし、オブジェクト・ストレージ・バケットにライフサイクル・ルールを追加しようとすると、次のエラーが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/dd456a85-b220-8eec-e66a-af604aee9ed0.png)

エラーメッセージ：
`Permissions granted to the object storage service principal "objectstorage-<Region_ID>" to this bucket are insufficient`

# 解決方法
OCIテナンシの<strong>ルート</strong> コンパートメントに次のポリシーを作成します。

ポリシー・ステートメントの例：
`Allow service objectstorage-ap-tokyo-1 to manage object-family in tenancy`
※、東京リージョン以外の場合、リージョンIDを置き換えてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b438721f-3661-e5b0-165d-0f11b627d6dd.png", width="500">

ポリシーを作成した後、再度試してみたら、ライフサイクル・ルールが作成できることを確認しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/1424fdcd-4139-ae63-16b8-cfcce872fc08.png)

以上

----
__関連記事__  
[オラクル・クラウドの個人ブログ一覧](https://qiita.com/letian/items/10152a4fec813c1b7d98) 
[OCIオブジェクト・ストレージへのファイル転送方法のまとめ](https://qiita.com/liu-wei/items/4d955d10aeae4d61eea8)

__参考資料__
MOSドキュメント：
[Permissions granted to the object storage service principal "objectstorage-xx-yyyyyyy-1" to this bucket are insufficient (Doc ID 2772944.1)](https://support.oracle.com/knowledge/Oracle%20Cloud/2772944_1.html)
要素の削除・挿入 Python3編

https://paiza.jp/works/mondai/array_primer/array_primer__elm_erase

忘れてしまったので調べて書いた。
要素削除には`pop()`か、`del`をつかう。
違いは、popは（）内に（●−１）番目を書き、
delは、配列[●−１]とかく

```py
N,M = map(int,input().split())
A = list(map(int,input().split()))
A.pop(M-1) # この行は　del A[M-1]　でもOK
print(*A,sep="\n")
```
次は挿入

https://paiza.jp/works/mondai/array_primer/array_primer__elm_insert

要素挿入には`insert()`
下記のように使う。

```py
N,M,K = map(int,input().split())
A = list(map(int,input().split()))
A.insert(M-1,K)
print(*A,sep="\n")
```
KnexのMySQLにupsertがやってきたぞ！

使用法
- updateの代わりにupsertにするだけです。なければinsert, あればupdateという挙動になります。

```ts
const result = await client<Todo>('todo').upsert(todoItem).where(なんらかの条件);
```

もともとCockroachDBにしか対応していなかったのですが、3.1.0で実装されたようです。ドキュメントは更新されていませんが、実際に3.1.0にあげてみたらmysqlで動きました。これまではupdateしてrowが0ならinsertみたいな小細工をしていたのですが、これですっきり書けますね。

発行されたSQL文を確認してみましたが、REPLACE INTOが使用されているようです。insert on duplicate key update ではないんですね。一度削除してから入れ直しになるので、created_atみたいなカラムがあるときは要注意です。まあ、これはknexというよりREPLACE INTOのハマりですが……。

……もうみんなprismaを使っており、knexなんて使ってない？
Qiitaに何を書けばよいか ~蛇にピアス~

# Qiitaに何を書けば良いか

わかんない。あると思います。
そんなあなたに捧げるQiitaです。

# 蛇にピアス

過去にも何度かツイッターでバズっているこれ。
今年もバズってました。

https://x.com/nukeme/status/1733005143749345738?s=20

文學界という小説家の登竜門となる賞の審査員コメント。
様々な観点がある中、ひときわ目を惹くのが
『蛇にピアス』などで有名な金原ひとみさんのコメントです。

勇気づけられますね。

**「本当に何でもいいよ！小説書けたら送ってみて！」**

この画像は、過去のものですが、今年のコメントもこれでした。


# 「本当に何でもいいよ！小説書けたら送ってみて！」

これを勝手にQiitaに置き換えてみます。

***「本当に何でもいいよ！Qiita書けたら送ってみて！」***



# まとめ

Qiitaに何を書けば良いか。
その答えはこれです。

**「本当に何でもいいよ！書けたら送ってみて！」**

以上、ポエム記事でした。
まだアドベントカレンダーはやっと折り返したくらいですね。
アドベントカレンダーで何を書くか迷われてる方、そもそも書くか迷われている方など参考になれば幸いです。


# 関連記事

何書けば良いか問題の参考になる記事です。

https://qiita.com/e99h2121/items/2a092393fc772e743742

https://qiita.com/kabik/items/53655f8fc81c7844f055
Datadog の自動化テスト機能の使い勝手について

半年ほど前から、自社プロダクトの検証コスト低減を目的に数社のソリューションを検討、Datadogさんの製品を導入しました。

主軸のサービス監視・分析のソリューションに追加されたテスト自動化機能のようなのでまだまだこれからの製品なのかもしれません。
設計・開発の経験がないテスターが自身でコスト削減のためにこのツールでテストケースをさくさくと作れるというものではありません。

・テストケースを部品化し計画的に構成する必要があります（１シーケンスでだらだらと長いテストケースはメンテナンスにのちのちコストがかかります）
・提供はしているが、制約があるのか動作しない機能があります。
・上記を解決するため等で、javascriptコードで目的の値を選択、取得する必要がけっこうな頻度で発生すると思われます（例えば登録データが可変のドロップボックスに対し、特定の登録データを選択するケース）
・操作をレコーディングしテストケースを作成することができますが、作成したテストケースの動作確認は必要です。また、テストケースの即時実行のパフォーマンス（速度）が遅いため、それなりにコストがかかります。
・お世辞にも、使い勝手は良くありません（それなりの学習コストがかかります）
・（契約規模等にもよるのかもしれませんが）サポートの解決力は高くありません。

結局のところ、
・最低でも２〜３名、基本的なwebアプリ開発とクラウドサービス運用経験のあるメンバーが常駐していること
・バージョンアップを繰り返す息の長いプロダクト／サービス向け（単発開発では初期コストがかかるだけでコストメリットなし）

であることを考慮し、導入を検討する必要がある製品だと思いました。
AWS社主催　大阪リージョンセミナーに行ってきた！

今回、二回目の投稿になります。
新卒一年目のyuchamです:sunny:

この度、AWSのセミナーに１つの会社から２名限定で参加できるイベントの案内がきたので参加させていただきました！

アジェンダは以下になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/0c952afe-1f96-6b61-0545-ccffb2533272.png)

### １．大阪リージョンについて

今回のイベントはAWS大阪支社で開催されたので、大阪愛が強いセミナーでした（笑）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/a66ffeb9-c023-badf-7685-f053023215a9.png)
画像出典：[AWS大阪リージョン](https://www.google.com/url?sa=i&url=https%3A%2F%2Faws.amazon.com%2Fjp%2Flocal%2Fosaka-region%2F&psig=AOvVaw2Yt2O6QJKleUlMWE2KW5nq&ust=1702427305737000&source=images&cd=vfe&opi=89978449&ved=0CBMQjhxqFwoTCNiJvonSiIMDFQAAAAAdAAAAABAD)

「サブリージョンである」という認識から脱却したい！という強い思いを感じました
僕も関西なので、積極的に大阪リージョンを使っていこうと思います。

### ２．Cloud WANについて

Cloud WANが大阪リージョンで2023年6月から利用可能になったので、サービスの紹介がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/b27dbdea-3cb0-e14b-7c37-ffea2479ab4f.png)
画像出典：[AWS Black Belt 「AWS Cloud WAN 概要 」](https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2022_AWS_Cloud_WAN_Part01_1125_v1.pdf)

ルーティング情報、ネットワークポリシー、自動化を一元管理でき、一元管理の対象サービスはVPC、VPN、SD-WAN、Transit Gateway Route Tableなど多くあります

このサービスにより、ネットワーク管理およびセキュリティタスクを集中的に構成、自動化できるので、とても便利だなと感じました。

### ３.Direct Connectハンズオンについて

今回のセミナーで最もボリュームがあり、ハードだったのがこのハンズオンです。
限られた時間の中、ひたすら手を動かしたのでいい経験になりました。

以下のAWS公式サイトで、Direct Connectのハンズオンがどのようなものか掴むことができます。

https://catalog.us-east-1.prod.workshops.aws/workshops/fc276e2b-38dd-4a19-bd46-36da91674230/ja-JP

Direct Connectは業務以外ではなかなか構築する機会はないと思うので、このような機会を頂き、ありがたいです。

### 4.まとめ
大阪リージョンについての歴史から、ハンズオンでまで幅広く知見を広げることができ、とても良い刺激を受けることができました。

セミナー後には懇親会もあるので、様々な会社の方と話せる機会もあります。
(ぼくは用事で参加できませんでしたが、、）

次の機会も参加させていただきたいと思いました。
Azure AI Document Intelligence Serviceがgetaddrinfo failedで失敗する

# はじめに
Azure OpenAIとAzure AI Searchのデモアプリを作りたく、参考に添付のAzureのサンプルコードをデプロイしてみたのだが、躓いた部分があったので備忘録を兼ねて記事にした。

# 問題
ドキュメントのアップロードとインデックス作成に失敗していた。私の通信環境の問題なのかもしれないが、Azure AI Document Intelligence Serviceに最初にアクセスしに行くときに接続に失敗する。

# 解決方法
根本原因が不明のままで恐縮ではあるのだが、公式ドキュメントのサンプルPDFを使ったコードを最初に通しておくと、次回以降は同じコードでもうまく接続できるようになる。

https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/quickstarts/get-started-sdks-rest-api?view=doc-intel-4.0.0&pivots=programming-language-python#general-document-model

# おわりに
根本原因の解決でないのですっきりしないが誰かの役に立てばうれしい。

# 参考

https://github.com/Azure-Samples/azure-search-openai-demo
Eloquentのfresh()とrefresh()の違い

## 概要
モデルオブジェクトで使えるfresh()とrefresh()メソッドの違いを記述します。

## fresh()
fresh()は、最新のモデルの状態を返却するメソッドです。
メソッドを生やした元のモデルオブジェクトは最新になりません。

### 例

```php
$user1 = User::firstWhere('name','John');
$user2 = User::firstWhere('name','John');

$user2->update([
    'name' => 'hoge'
]);

$freshUser = $user1->fresh();
dd($user1->name,$freshUser->name);
// John         hoge
```


## refresh()
refresh()は、メソッドを実行したモデルオブジェクトを最新の状態にします。

### 例

```php
$user1 = User::firstWhere('name','John');
$user2 = User::firstWhere('name','John');

$user2->update([
    'name' => 'hoge'
]);

$user1->refresh();
dd($user1->name);
// hoge
```


## 参考
SaaSにおける最適なインフラコストを考える

こんにちは。Supershipでプロダクト周りでいろいろやっております中村と申します。

:::note warn
この記事は、[Supershipグループ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/supership)の11日目の記事になります。
:::

## はじめに
昨今の世界情勢による円安、資材高騰などの煽りを受けて、プロダクトの原価でもあるインフラコストに頭を悩ましている方は大勢いらっしゃるのではないでしょうか？
私もその一人です。
クラウド化により、オンプレ時代よりははるかにコスト最適がしやすくなってきており、FinOpsなど様々な方法論も提唱されてきておりますが、ここでは、そもそもプロダクトにおける最適なインフラコストとはどの程度であるべきなのか。という点について考えていきたいと思います。

### 調査対象
- 前提
　- 東証上場SaaS企業
　- ARR100億円以上

### SanSan
引用資料：[決算説明資料](https://data.swcms.net/file/corp-sansan-ir/dam/jcr:aeb19fc3-68d2-4455-ba74-ebcc194f1913/140120231012565551.pdf)

サーバー費用の明細は見つけられませんでした。。
一方で、売上高に対する売上原価は12-15%を推移しております。
一般的にはインフラサーバー費は原価扱いになっているかと思いますので、そう考えると少なくともこの割合より下回るのでしょう。
また、R&Dは20%前後でそこまで変化はありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2338070/afb66e73-1c5a-5b9b-456c-bfc540490bd6.png)


### freee
引用資料：[決算説明資料](https://contents.xj-storage.jp/xcontents/AS08692/d1f7b213/efe3/415b/9ce6/e2e655e2561c/20231114144429116s.pdf)

同じようにサーバー費として明確な記載はありませんでしたが、売上原価は売上高-売上総利益と考えると、20%前後を推移してそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2338070/c1415958-296b-ee8d-d0c2-2583a45b2aab.png)

また販管費のR&D比率は25%から35%へ徐々に増加傾向です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2338070/c169dfb9-8ce7-af4e-fb4c-4377ac068ca2.png)

### マネーフォワード
引用資料：[決算説明資料](https://ssl4.eir-parts.net/doc/3994/ir_material_for_fiscal_ym/140394/00.pdf)

こちらもやはりサーバー費は売上原価に含まれていそうです。
右側のSaaS事業のみをとらえた場合には14%-17%程度でしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2338070/bdd8cb59-d064-6c6e-6547-1a8819db6911.png)

また下記の注釈が気になりますが、プロダクト開発に関わる人件費はグローバルでは原価ではなく、国内の会計基準だと売上原価に含まれるとのこと。各企業の売上原価に開発人件費が含まれているのかいないのかは今後要注意ですね。

:::note warn
*2 Businessドメイン（バックオフィスSaaS）に限定し、一般的なグローバルSaaS企業における定義に基づいて計算。原価部分には、プロダクトの開発に関わる通信費やシステム利用料、AWSなどのサーバー費用、API接続費用、カスタマーサポートに関わる人件費、サービス基盤に関わる人件費、
『STREAMED』のオペレーターの人件費などを含む。なお、プロダクト開発にかかるエンジニア・デザイナー人件費は国内会計基準上・当社損益計算書上は売上原価に含まれる。
:::

販管費の割合についての記載は見つけられませんでしたので、今後要調査としたいと思います。


## おわりに
プロダクトに関わるサーバー費の適正値だけを知りたかったのですが、なかなか明確に公開している企業はないものですね。
総論としては売上原価が20%未満であることを考慮すると、10%-15%程度が一般的なのでしょうか。

一方で、そもそもSaaS企業における計上のルールや考え方は理解が進んだので整理しておきます。

- 売上原価(売上高の15%-20%)
    - プロダクトの開発に関わる通信費やシステム利用料、サーバー費
    - カスタマーサクセスに関わる人件費
    - プロダクト開発にかかるエンジニア・デザイナー人件費(※グローバルと国内会計基準で異なりそう)
    
- 販管費
    - R&D(Research & Development)(売上高の20%-30%)
        - 研究開発に関するエンジニアの人件費
        - 研究開発に関するサーバー費
    - S&M(Sales & Marketing)(売上高の40%-60%)
        - 営業・マーケティング担当者の人件費
        - 広告宣伝費
    - G&A(General & Administrative)(売上高の15%-25%)
        - 総務などバックオフィス人件費や税金・企業の保険等

あくまでも目安であり、プロダクトの性質によっても状況は異なるとは思うのですが、お金の使い道を考える上でざっくりとした指標として理解したいと思います。

また外資のSaaSKPIについての記載は下記がとても参考になるので引用しておきます。
[SaaS企業で大切なS&M比率とは|R&DやG&Aとの違いも解説](https://scalecloud.jp/blog/about-sandm/#:~:text=S%26M%E6%AF%94%E7%8E%87%E3%81%AE%E8%A8%88%E7%AE%97%E5%BC%8F,%E9%83%A8%E9%96%80%E3%81%AE%E4%BA%BA%E4%BB%B6%E8%B2%BB%E3%81%A7%E3%81%99%E3%80%82)

:::note
**最後に宣伝です。**

Supershipではプロダクト開発やサービス開発に関わる人を絶賛募集しております。
ご興味がある方は以下リンクよりご確認ください。
[Supership 採用サイト](https://supership.jp/recruit/)
是非ともよろしくお願いします。
:::
タグ確認業務をデータ駆動テストで楽にした

# はじめに
株式会社LIFULLでQA/SETとして頑張ってます、山下です。

弊社ではとあるタグマネージメントシステムを使用し、ユーザーの行動データを収集しています。

そのタグマネージメントシステムを使用するにあたり、「意図したタグが埋め込めているか」を手動で確認していることで開発チームの工数が多く取られていました。
今回はその確認工数を自動テストで削減できたので、その事を書きます。

自分の調べた範囲ではこういったタグの確認を自動テストで実施している例は見当たらなかったため、悩んでいる方の参考になればと思います。

## 使用技術
- Playwright
- TypeScript

# 問題
弊社では以下の問題がありました
- タグが仕様通り埋め込めているか確認する工数が多くかかっている
- 開発フロー的に、機能実装が終わる前にタグの実装を進める場面がある。
    - タグの実装後の機能実装のタイミングで機能のロジックが変わることもあり、タグの実装にも手戻りが発生してしまう。
- タグが問題なく埋め込まれているか？の確認は機能テスト、リグレッションテストを含め頻繁に実施されていた


# 解決方法
E2Eテストをデータ駆動テストの形で応用し、タグを確認できるようにしました。
具体的には、"ページ : タグ" のデータを用意して配列に入れ、同じシナリオでデータだけ変えて繰り返し実行できるようにしています。

そうすることでタグの確認にかかる工数が大きく削減出来ます！

※ミニマムで進んでいくという意図で、今回実装した範囲はviewイベント(ユーザーが特定のページを開いたときに実施されるイベント)のみです

処理の流れは以下です
1. 配列に以下を格納しておく
    1. タグの確認をしたいページのURL
    1. タグの期待値
1. 配列をループし、それぞれのページでTSを実行しタグを出現させる
    1. タグを出力できるメソッドはされていました
1. タグの実際値と期待値を比較

## 実装(書き換えてます)

```TypeScript
import { test, expect } from '@playwright/test';
import { Util } from './utility/util';

test.describe('View イベントで送信されるタグを確認する', () => {
  test.describe('ページを開いた直後(ユーザ操作なし)に確認する', () => {
    const testCases = [
      { path: '/hoge', tagEvent: 'hoge_view' },
      { path: '/hoge/fuga', tagEvent: 'fuga' },
      { path: '/hoge/hoo', tagEvent: 'hoo' }
      ...
    ];

    type TagData = Record<string, string>;

    testCases.forEach(({ path, tagEvent }) => {
      test(`${path}のページでTagのEvent:${tagEvent}が送信される`, async ({ page }) => {
        await page.goto(path);
        await Util.wait(5000); //waitメソッドは別で定義してます
        await expect(page).toHaveURL(path);
        const data: TagData = await page.evaluate((): TagData => (window).tag);
        expect({ data, url: page.url() }).toMatchTags(tagEvent, 'hoobar'); // toMatchTagTagsは別で定義してます
      });
    });
  });
});
```

## 今後の課題
- 「ページAにタグA以外が含まれていないこと」は確認できない。
    - 今回のテストでは「ページAにタグAが含まれていること」の確認はとても楽に出来ますが、例えば「ページAにタグAとタグBが含まれていた場合(要件ではタグBはページAでは不要)」テストは成功してしまいます
    - ソフトウェアテストの7原則の「テストは欠陥があることは示せるが、欠陥がないことは示せない」の事なのかもなと勝手に考えてます

# おわりに
他のチームにも横展開して開発者体験を更に向上させて行きたいです
AWSのアカウント移管をしました！

ITデジタル部所属の岡田(@knt-okada)です。
JINS Advent calendar 11日目の記事を書かせていただきます。

### AWSのアカウント移管をしました！

## 背景
ジンズではこれまで外部ベンダーさんに任せていた運用を自分たちでグリップして管理していこう！という方針をたて、ITコストを最適化していこう！というプロジェクトが始まり、サービスやシステムの断捨離、ITコストの見直しを行う必要性が出てきました。
そのため、作業を全て外部のベンダーさんに依頼するのではなく、自分たちでAWS運用を行える状態にする必要があり外部ベンダーが契約していたAWSアカウントをジンズ側で管理できるようAWSアカウント移管を行いました。


## アカウント移管に必要なタスク

ざっと以下のようなタスクが発生します。

1．（移管先）AWSへ譲渡同意書発行依頼 
2．（AWS）AWSより譲渡同意書発行　※発行依頼から発行まで1~2週間程度要する
3．（移管元、AWS、移管先）譲渡同意書へサイン
4．（移管先）コンソール上での転入作業
5．（移管元、移管先）運用タスクの洗い出しおよび各種アカウント情報収集

## アカウント移管後の運用タスク
以下のようなAWS運用タスクが発生するため、運用工数はそれなりにかかります..

- IAM運用(ユーザ作成、権限変更)
- S3運用(バケット作成、権限変更)
- SSL/TLS証明書更新
- RDSバージョンアップ
- インスタンスタイプ変更
- ディスク容量追加
- バックアップ取得
- セキュリティスキャン
- パッケージアップデート
- Lambdaのランタイム変更
- AWSアカウント間の接続
- 新規システム設計/構築 
- サービス利用状況確認およびコスト見直し
- リソース監視
- 障害対応
など

## 成果
以下の成果がありました。
- AWSランニング費用を月額十数%削減
- 設計/構築作業の委託費削減
- AWS運用タスクの迅速化

## 最後に
実際に自分たちでAWS運用をしていくとなると、移管前に見えていなかったタスクもあり、AWS運用の難しさを実感しております。ただ、`自分たちがジンズのインフラを支えているんだ！`というやりがいや、`AWS運用を効率化するこんな便利なサービスがあるのか・・・`といった発見もあり、AWS運用の楽しさも感じられます。

運用タスクを如何に効率的に実施するかを検討し、実際の運用に乗せていく必要がありますが、ジンズで実施している具体的な運用方法については追々何かしらの形で外部へ発信していこうと思います...！

明日12日目は8日目にシステムアーキテクチャの記事を投稿された@Takuma_Satoがアジャイル内製開発のチャレンジについての記事を投稿される予定ですので、お楽しみに！☆
Kullback-Leibler情報量の解釈に関する備忘録

[Kullback-Leibler情報量](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%83%BB%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%BC%E6%83%85%E5%A0%B1%E9%87%8F)は何度聞いてもよく分からないのだが、先日、[面白い解釈を読んだ](https://stats.stackexchange.com/a/99550)。

> Imagine that you have an random variable of probability distribution Q. But your friend Bob thinks that the outcome comes from the probability distribution P. He has constructed an optimal encoding, that minimizes the number of expected bits he will need to use to tell you the outcome. But, since he constructed the encoding from P and not from Q, his codes will be longer than necessary. KL-divergence measure how much longer the codes will be.
> 
> Now lets say he has a coin and he wants to tell you the sequence of outcomes he gets. Because head and tail are equally likely he gives them both 1-bit codes. 0 for head, 1 for tail. If he gets tail tail head tail, he can send 1 1 0 1. Now, if his coin lands on the edge he cannot possibly tell you! No code he sends you would work.

(ChatGPT訳:)
> 友達のボブが考えている確率分布をQとし、それに従うランダム変数があると想像してみてください。しかし、ボブは、その結果は確率分布Pに従うと考えています。彼は最適な符号化を構築しましたが、その符号化は、必要以上にコードが長くなる可能性があります。なぜなら、彼が構築した符号化はPからではなくQから来ているためです。KLダイバージェンスは、どれだけコードが不要に長くなるかを測定します。
>
> さて、彼がコインを持っており、そのコインの出目のシーケンスを教えてほしいとします。表と裏が同じくらいの確率で発生するため、それぞれ1ビットのコードを割り当てます。表に0、裏に1のコードを与えます。たとえば、裏・裏・表・裏が出た場合、彼は1 1 0 1と送ることができます。しかし、もしコインが縁に着地した場合、彼は不可能になります！彼が送るどんなコードも機能しないでしょう。

つまり、Kullback-Leibler情報量とは、Bobが真の分布を知らないことにより追加で必要になる情報量であると言っている。

こういうものの理解に、あまりに単純すぎるモデルを持ってきて議論しても意味がない気はしなくもないが、試しにやってみよう。

## 例
コイン投げソフトウェアがある。このソフトウェアを動作させると、乱数を振り、0, 1のいずれかの数字を3つ表示する。しかし、実はこのソフトウェアにはバグがあって、2つ目と3つ目は必ず同じ数が表示される。このことをBobは知らない。

Bobは、3つの乱数が等確率で振られるものだと思っているため、出た目を人に伝えるには3ビット必要だと考えている。しかし、実際には2つ目と3つ目は同じ数であるため、3つ目は伝える必要がなく、2ビットを伝えれば十分である。
Kullback-Leibler情報量は、この差分の1ビット分となる、ということを主張している。

計算して確かめてみる。

コイン投げソフトウェアが出す目iとその確率P(i)は、以下の表で書き表される。この表を真の分布Pとおく。

|i|P(i)|
|--|--|
|000|1/4|
|100|1/4|
|011|1/4|
|111|1/4|

Bobは、このソフトウェアを、どの目も当確率で出ると考えている。つまり、以下の分布Qのように思っている。

|i|Q(i)|
|--|--|
|000|1/8|
|100|1/8|
|010|1/8|
|110|1/8|
|001|1/8|
|101|1/8|
|011|1/8|
|111|1/8|

このとき、PのQに対するKullback-Leibler情報量は、

$$D_{KL}(P||Q) = \sum_i P(i) \log \frac{P(i)}{Q(i)} = 4\frac{1}{4} \log \frac{1/4}{1/8} = \log 2$$
となる。

ちょうど1ビット分の情報量となった。

### おまけ

今回の例では、QのPに対するKullback-Leibler情報量$D_{KL}(Q||P)$は求まらない。数式的にはゼロ除算が出てくるからであり、解釈としては、後ろの2ビットが常に同じとみなして前の2ビットだけ送る方法が、後ろが同じでないかもしれない場合には使えないからである。
【Mac】パスワードつきZIPファイルの解凍でハマった

## はじめに

あまりMacでパスワードつきの圧縮(Zip)はやったことありませんでした。

結構前にMacでパスワードをかけた圧縮Zipファイルがあり、それを解凍するときにハマりました。**出力されたエラーは、CRCエラー(破損エラー)です。**

（前提：パスワードはあっている）

## ZipCloak でパスワードつきZipにしていたらしい

調べると以下のサイトがとても参考になりました(感謝)。

https://wporep.com/apple/unzip-advice/

学んだことは以下の３つです。
**①Mac：ZipCloak でパスワード付き圧縮は危険**

**②Windowsの7zipで解凍を試してみよう**
一部のデータが破損のままでしたが大部分は復活。救われました。
　
**③Mac：パスワード付き圧縮は、Zipコマンドを使うこと**


## Zipファイル操作コマンドの参考
https://qiita.com/griffin3104/items/948e38aab62bbb0d0610

ファイルの圧縮
~~~bash:ターミナル
$ zip -e ps_hoge.zip hoge.txt
~~~

フォルダの圧縮
~~~ bash:ターミナル
$ zip -er ps_hogedir.zip hogedir/
~~~

## まとめ
解凍できない問題に久々に直面しましたが、エラーのときの絶望感と解凍できたときの高揚感は、独特のものです。
オペミス防止を考えてみたい

運用保守に限らず、ヒューマンエラーのオペミスを完全に防ぐことは難しく、どうやったら極限まで可能性を下げれるかを考える機会が多いので、備忘やアイデア共有のために書いてみます。

自身の経験をベースで、どうしたら無くせるかなという観点で書いてみるので、少しでも何かの改善のきっかけになれば幸いです。

## 事例）メールでBCCに入れるべきところをCCで送付してしまった
### 何が起こったか？
お客さんからメールの発出依頼を対応した際に、BCCで送らないといけないところを、CCで送付してしまいました。
時折ニュースでも見かける事例ですね。この時は幸いにもメーリングリストで送付していたので、個人が特定できない＆メーリングリスト自体も周知されているものでCCでも問題はなかったものでした。
当時、新人だった私は指摘されて血の気が引いたことを今でもよく覚えています。
（社会人で最初のオペミス）

### なぜオペミスは起こったのか？
1. 普段ダブルチェックする先輩社員が不在で一人で対応していた（客先で二人体制だった）
1. お客さんからすぐに送付して！と急かされた

### どうすればよかった？
1. 先輩社員に遠慮してしまったが、電話で口頭確認しながら実施するべきだった
1. 数分遅れても影響のないメールで、ただお客さんが帰りたいだけだったので焦る必要がそもそもなかった（ただ、新入社員にはそこまではわからなかった）

## 根本から問題を考える
この記事で伝えたいのはここからです。
上で書いたような要因も確かに事実なのですが、「どうすればよかった？」のところは暫定対処レベルでしかないと思っています。
この問題の根本原因はメーラーソフト側のUIデザインだと思っています。

MSのOutlookを使っており当時のVerとは違いますが、今もここは変わっていないと思います。
で、何が問題かというと、「CCとBCCという言葉が似すぎている」ことと、「宛先・CC・BCCが直列に並んでいる」ことがです。
なぜ、「宛先」は日本語なのに、CCとBCCはアルファベットで書くのだろう？？
見栄えはいいかもしれませんが、入力欄が近いのはヒューマンエラーの大好物・・・。

## じゃあどうする？
* デフォルトの入力欄はBCCで強調
* なんなら宛先とCCは非活性にしておき、別操作で一々開かないと設定できない

![メーラー案.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633166/f4155974-0a23-2c89-0e86-b87222a22d62.png)
※極端だけど、これくら大袈裟だと誤送信の確率はかなり減ると思う
（見栄え？ヒューマンエラーがなくなるなら大歓迎）

## 結論
商用システムなどお客様向けのものは、ここまで大袈裟なデザインは難しいかもしれません。
でも、作業手順書や、内部のツールなど運用保守の現場で使うツールについては、見栄えよりも事故防止のほうが大事だと思っています。

何かを作成したとき、「これなら出来るかな？」よりも「これで間違えるとしたらどういうときか？」の視点でなるべく考えるといいと思います（それでも予想の斜め上の動きをする人もいますが）

ということで・・・
ヒューマンエラーを防止したいなら、大袈裟よりもさらに大袈裟くらいがちょうどいい
Salesforce Lightning Platform のアプリケーション統合パターン



https://trailhead.salesforce.com/content/learn/modules/app-integration-patterns/app-integration-patterns-1?trail_id=explore-integration-patterns-and-practices

**統合タイプ**

|統合イニシアチブ|説明|
|:---------------------------|:-------------------------|
|アプリケーションの統合|このカテゴリは、システム全体にわたる機能の拡張に重点を置いています。これには、UI によってトリガーされるイベント、API 統合、フロー、コネクタが含まれます。|
|データ統合|このカテゴリは、2 つ以上のシステム間のデータの統合と同期に焦点を当てています。これには、データの整合性、データ ガバナンス、データ フロー設計、データ移行の側面が含まれます。|
|プロセスの統合|このカテゴリは、ビジネス プロセスとサービスをシステム全体に拡張することに焦点を当てています。これには、1 つのシステムからアクティビティをトリガーしたり、2 つのシステム間でトランザクションを実行したりするイベントなどの統合ソリューションが含まれます。 |

**Salesforce Lightning Platform 統合パターンのリスト**

||説明|タイミング|
|:---------------------------|:-------------------------|:-------------------------|
|リモートプロセス呼び出し - 要求と応答|Salesforce はリモート システム上でプロセスを呼び出し、応答を待ちます。 |同期|
|リモート プロセス呼び出し - 起動して忘れる|Salesforce はリモートシステムのプロセスを呼び出しますが、プロセスの完了を待ちません。|非同期|
|バッチデータ同期|外部システムまたは Salesforce Lightning Platform でデータが更新されると、更新はいずれかのシステムに反映されます。更新はバッチ方式で適用されます。|同期|
|リモートコールイン|リモートシステムは、Lightning Platform に保存されているデータを作成、取得、更新、または削除します。|実装ソリューションに基づく同期または非同期|
|データ仮想化 |Salesforce は外部データにリアルタイムでアクセスします。|非同期|
|高頻度のデータ複製|ソース システムは、ほぼリアルタイムで大規模にデータをターゲット システムに非同期的にレプリケートします。|実装ソリューションに基づく同期または非同期|
|発行/購読|Salesforce は、誰が受信側になるかを認識せずにイベント (レコードの作成、変更、削除など) を公開します。任意の数のサブスクライバがこれらのイベントをリッスンし、それに応じて処理します。|非同期|

同期 通信とは、クライアントがサーバーにリクエストを送信し、その応答を待ってから別のリクエストを発行することを意味します。たとえば、リモート プロセス呼び出し - 要求と応答の統合パターンは同期通信です。アプリケーションはメッセージを送信し、応答を待ってから続行します。  

非同期 通信とは、システムが続行する前に応答を待たないことを意味します。アプリケーションはメッセージを送信し、リソースが利用可能になるとすぐにシステムが応答を返します。元のメッセージを送信したシステムには、応答を待たずにメッセージの送信を続ける機能があります。返信メッセージの処理は個別に制御されます。


**各パターンの方向**

||方向|
|:---------------------------|:-------------------------|
|リモートプロセス呼び出し - 要求と応答|Salesforce → システム|
|リモート プロセス呼び出し - 起動して忘れる||
|発行/購読||
|高頻度のデータ複製||
|データ仮想化||
|リモートコールイン|システム → Salesforce|
|バッチデータ同期||
恥ずかしくて大声では言えないけど最近知った2つのgitコマンド

コードを管理するのにgitは利用されていると思います。
私も利用していますが、恥ずかしながら最近2つのコマンドを知りましたので紹介したいと思います！

## `git rm -r --cached .`

.gitignoreが反映されずに、プルリクエスト（マージリクエスト）にignoreされるはずのファイルの変更が表示されてしまう場合があります。

:::note warn
ignoreしたファイルが差分として表示されるのはキャッシュが残っているためです。
:::

`git rm -r --cached [ファイル名]`でファイル名を直接指定することも可能です！


## `git switch`
これまでブランチを切り替えるために`git checkout`を利用してきました。
ただ、`checkout`はブランチを切り替える以外にもファイルの変更を元に戻すためにも利用できます。

:::note info
1つのコマンドで2つの役割を備えているわけです！
今まで考えたことなかったですが、高機能なコマンドですね！
:::

`switch`コマンドはブランチの作成と移動のみを実行できます。
`checkout`コマンドより限定的なコマンドです。

`checkout`を利用したブランチの作成と切り替えは次のようになります！

```bash
git branch [ブランチ名]
git checkout [ブランチ名]

# フラグ -b を利用することでブランチの作成と移動を同時に行うこともできます
git checkout -b [ブランチ名]
```

`switch`を利用したブランチの作成と切り替えは次のようになります！

```bash
git switch -c [ブランチ名]
```

コマンド1つで切り替えと作成ができます！

## 【gitの2つのコマンド】まとめ
普段利用していながら知識を更新できてなかったです…。

:::note warn
1つのコマンドをさまざまな用途で利用できるコマンドは便利ですが、誤った操作をしてしまう可能性もあります…
:::

これからはgitのコマンドも利用用途に応じて適切なコマンドを選択したいものです！
SPACEフレームワークでチーム・個人の生産性を爆上げする

# はじめに

業務で生産性を上げろとよく言われる。
しかし、生産性とは何か？生産性を測定し、その生産性がビジネス目標にどう貢献しているかを明らかにする。

# SPACEフレームワークとは

開発者の生産性を計測するためのフレームワークで、個人・チーム・システムの3つにおいて、以下の５つのカテゴリで測定する。

* Satisfaction & Well-being
* Performance
* Activity
* Communication & Collaboration
* Efficiency & Flow

# 生産性の5つの間違った認識

* 生産性はdeveloperのアクティビティだけでは測れない
* 生産性は個人のパフォーマンスに限るものではない
* 一つの指標だけで全てを語るのは不可能
* 生産性はマネージャーだけみるものではない
* 生産性はエンジニアリングシステムと開発者ツールにのみ関係する

# Satisfaction & Well-being

満足度と生産性は相関関係にある。満足度が生産性の先行指標となる。

## Satisfaction(満足度)

開発者がツール、仕事、チーム、カルチャーに対して、いかに満足しているか。

## Well-being(幸福度)

いかに健康で幸せであるか。
仕事が健康にどのような影響を与えているか。

## メトリクスの例

一般的にアンケートを用いて定性的に測定される。

* 従業員満足度(ES) 
* eNPS
* チームの健康チェック
* KTLOの量
* バーンアウトとワークエンゲージメント

## Performance

パフォーマンス。
パフォーマンスを最も単純化すると、開発者が書いたコードは、想定されたことを確実に実行した度合いとなる。
一般的にソフトウェアはチームで開発されているので、チームのパフォーマンスが求められる。チームのパフォーマンスに対し、個人のパフォーマンスは定量化が難しい。

### メトリクスの例

* 顧客満足度(CS)
* NPS
* 信頼性
* 変更失敗率
* サービスヘルスの継続率
* 機能の使用状況
* コスト削減率

## Activity

業務で完了したアクションまたはアウトプットの数。
わりと容易に定性化できる。

### メトリクスの例

* 完了したチケット数
* 導入頻度
* PR数
* コミット、レビュー数
* ドキュメント数
* インシデント数、および重大度に基づく分布

## Communication & Collaboration

いかにチームがコミュニケーション、情報共有できているか。

### メトリクスの例

* 同じ機能に取り組んでいる人の数
* チームのヘルスチェック(サイロ化とコミュニケーション)
* プルリクエストのレビュー時間
* 共有インデックス
* コラボレーションマップ

## Efficiency & Flow

個別に、またはシステムを通じて、中断や遅延を最小限に抑えて作業を完了、進行させる能力。

### メトリクスの例

* チームのヘルスチェック(サイロ化とコミュニケーション)
* 流れを維持して仕事を完了する能力の認識
* リードタイムと復旧までの時間
* ストーリー/問題のサイクルタイム
* チーム間でのハンドオフの数
* 流れを維持して仕事を完了する能力
* 付加価値時間
* 待ち時間

## SPACEフレームワークの組織レベル

* 個人
* チームまたはグループ(一緒に働く人々)
* システム: システムを通じたエンドツーエンドの作業 (例: 設計から実稼働までの組織の開発パイプライン)

## SPACE フレームワークの活用方法のベストプラクティス

1. 少なくとも 3 つのカテゴリからの指標を含める
2. チームレベルの指標から始める
3. エンジニアの参加に投資する
4. 集計を超えてパターンを検出し、バイアスを削減する
4. 少なくとも一つの評価指標に、アンケートなどの定量的な指標を含める
4. 計測項目を絞る(全てのカテゴリを含む必要はない)


### The SPACE of Developer Productivityでのメトリクス例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/58515db4-abff-e1b8-f4c0-b5b698ce7b8e.png)


# 最後に

SPACE フレームワークは、あくまでフレームワークである。
なので、測定すべき指標を正確に示しているわけではないため、そのまま採用することは推奨されていない。
自分達の組織、チームやコンテキストに合わせて変更しよう。
また、[Four Keys](https://qiita.com/twrcd1227/items/f2fb26b441f35fc3796d)などの他のフレームワークと組み合わせることによって、より改善点が明らかになり、生産性を上げることが可能になる。

# 参考文献

1. [The SPACE of Developer Productivity](https://queue.acm.org/detail.cfm?id=3454124)
1. [Your organization’s guide to the SPACE framework](https://www.swarmia.com/blog/space-framework/?utm_term=the%20space%20of%20developer%20productivity&utm_campaign=SRH-SPACE-ANZ-EN&utm_source=adwords&utm_medium=ppc&hsa_acc=6644081770&hsa_cam=19643105953&hsa_grp=145044306959&hsa_ad=646939742387&hsa_src=g&hsa_tgt=kwd-1671002623637&hsa_kw=the%20space%20of%20developer%20productivity&hsa_mt=e&hsa_net=adwords&hsa_ver=3&gad_source=1&gclid=CjwKCAiAsIGrBhAAEiwAEzMlC-1dLiQbUqIhJW5swiyQYzo2rKrA5wr8_ij4ShSNCC7zr93UxYwBiBoCiEkQAvD_BwE)
1. [Four Keysだけじゃない開発者生産性フレームワーク](https://zenn.dev/loglass/articles/28c565a875e9bd#space)
Four Keysで生産性を向上する

# Four Keysとは

[DevOps Research and Assessment（DORA）](https://dora.dev/)が提唱したソフトウェア開発チームのパフォーマンスを示す４つの指標。

* デプロイの頻度 : 組織による正常な本番環境へのリリースの頻度
* 変更のリードタイム : commit から本番環境稼働までの所要時間
* 変更障害率 : デプロイが原因となり、本番環境で障害が発生する割合（%）
* サービス復元時間 : 組織が本番環境での障害から回復するのにかかる時間

:::note
Accelerate State of DevOps 2021 で、5つ目の指標として **信頼性** が追加され、***Software Delivery and Operational (SDO) Performance*** と呼ばれる。
:::

Four Keysの指標については、ハイパフォーマンスであればあるほど、チームのパフォーマンス(収益性, 市場占有率など)の向上に繋がることが、明らかになっている。

# Four Keysとトレードオフ

Four Keysは高スループットと安全性を追求するものなので、トレードオフはあるが、高スループットと安全性の両方を兼ね備えたプラクティスが、抜きん出てハイパフォーマンスとなることがある。

# Four Keysの具体例

例えば、リファクタリングによって、以下のようにFour keysの4つの指標が向上されるので、ソフトウェアデリバリーのパフォーマンス向上につながる。

* デプロイの頻度 : 疎結合で、小さくリリースが可能となる
* 変更のリードタイム : 変更に強くなり、短縮する
* 変更障害率 : 可読性が向上し、ミスが減少
* サービス復元時間 : 可読性の向上で、原因特定が容易になる

# Four Keysにおけるハイパフォーマンスとは

Four Keys を High, Midium, Low の3つのレベルで分けた調査結果は以下のようになる。

|  |  High(11%) | Midium(69%) | Low(20%) |
|:-:|:-:|:-:|:-:|
| デプロイの頻度  | 1日複数回  | 1週間〜1ヶ月 | 1ヶ月〜6ヶ月  |
| 変更のリードタイム  | 1日〜1週間  | 1週間〜1ヶ月  | 1ヶ月〜6ヶ月  |
| 変更障害率  |  0〜15% | 16〜30%  | 46〜60%  |
| 平均復旧時間  | 1日以内  | 1日〜1週間  | 1週間〜6ヶ月  |

# それぞれの改善案

## デプロイ頻度

* 変更のリードタイムを改善することで同時に改善する
* MVP開発
* 開発プロセスの最適化
* CI/CDツールによる自動化の導入
* ペアプロや勉強会等によるチームのスキルアップ
* リリース手順の簡素化

## 変更のリードタイム

* CIの高速化
* レビュー時間の短縮化
* 作業単位とリリース単位の短縮化
* QA作業の軽量化
* リリースフローの最適化

## 変更障害率

*  PRは小さく分割すること
*  セルフレビューを行う
*  テストの自動化
*  トランクベース開発

## 平均復旧時間 (MTTR)

* 監視による障害検知
* ログによる障害の原因特定
* ロールバックによる復旧
* 障害対応訓練
* 障害対応テンプレートの整備

# 最後に

Four Keysにはすでに色々な測定ツールが存在しているので、使っていなければチームに導入して可視化してみよう。ただし、やり過ぎには注意(デプロイ頻度を1日1回するなど)。きちんとFour Keysを向上すると生産性が上がる理由を理解して導入する。また、Four Keysだけでなく、SPACEフレームワークなどを併用すると、より生産性向上につながってくる。

# 参考文献

1. [30分でわかるFour Keysの基礎と重要性](https://speakerdeck.com/yigarashi/30fen-dewakarufour-keysnoji-chu-tozhong-yao-xing)
1. [エリート DevOps チームであることを Four Keys プロジェクトで確認する](https://cloud.google.com/blog/ja/products/gcp/using-the-four-keys-to-measure-your-devops-performance)
1. [GoogleCloudPlatform/fourkeys を使って Four Keys を計測する](https://note.com/scg_tech/n/n720466ca7317)
1. [DORA](https://dora.dev/)
1. [デプロイ頻度・変更のリードタイムを向上させる意味とアクションーFour Keys運用](https://zenn.dev/offersmgr/articles/b8f4c394702d1d)
PHPの filter_var 関数の使用方法と応用

# 基本的な使い方
filter_var 関数はPHPで提供される非常に便利な機能で、様々なタイプのデータを検証およびサニタイズするために使用されます。

```
mixed filter_var(mixed $variable, int $filter = FILTER_DEFAULT, mixed $options = 0)
```

* $variable : フィルタリングする変数。
* $filter : 使用するフィルタFILTER_VALIDATE_EMAIL,FILTER_VALIDATE_BOOLEAN などがあります。
* $options : フィルタに追加のオプションを指定するための連想配列またはビットフィールド。

# 応用例
## メールアドレスの検証
```
filter_var('user@example.com', FILTER_VALIDATE_EMAIL)
```
## 真偽値の検証
```
filter_var('true', FILTER_VALIDATE_BOOLEAN)
```
※注意点として、文字列の'yes'はtrueになり、'no'はfalseとなる

## IPアドレスの検証
```
filter_var('127.0.0.1', FILTER_VALIDATE_IP)
```

filter_varでチェックできる項目については下記のURLで確認できます。
http://www.php.net/manual/ja/filter.filters.php
dbtからBigQueryに接続する際にADC経由で認証する

:::note info
本記事は [ZOZO Advent Calendar 2023](https://qiita.com/advent-calendar/2023/zozo) シリーズ 7 の 12 日目の記事です。
:::

# 概要
dbt-core (OSS版)を Google Cloud 上の何らかの実行環境で動かす場合、 BigQuery に接続する際に json キーなしで認証できるとセキュリティ面で安心です。
今回は Application Default Credentials (ADC)  を使って認証するために dbt 側で行う設定を紹介します。

# dbtの profiles.yml の設定
結論としては以下のように method として `oauth` を使用して BigQuery に接続するようにします。

```yaml:profiles.yml
your_project:
  target: dev
  outputs:
    dev:
      dataset: your_dataset
      job_execution_timeout_seconds: 300
      job_retries: 1
      location: US
      method: oauth # ADC経由で認証する場合は oauth を指定
      priority: interactive
      project: your_project_id
      threads: 8
      type: bigquery
```

dbt の公式ドキュメントを読むと、サービスアカウント経由の場合は method として `service-account` を使用しなければならないのかと思い混乱しましたが、「Why would I want to impersonate a service account?」をクリックして開くとちゃんと書かれていました。
https://docs.getdbt.com/docs/core/connect-data-platform/bigquery-setup#service-account-impersonation

# 検証
試しにサービスアカウントを作成し、そのサービスアカウントと紐づけた Compute Engine (GCE) の VM インスタンスを立ち上げます。
この方法は公式のドキュメントを参照ください。

https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances?hl=ja

VM インスタンス上で dbt インストールを行います。
```bash
pip install dbt-core dbt-bigquery
```

次に`dbt init` を実行します。
デフォルトでサンプルモデルが実装されているので、そのまま `dbt build`を実行します。
![スクリーンショット 2023-12-08 22.49.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221323/046e35dc-0251-c73e-368b-f64a2763d4f3.png)

BigQuery のコンソールからジョブ履歴を閲覧すると、最初に紐づけたサービスアカウントでクエリ実行されていることを確認できました。
![スクリーンショット 2023-12-08 22.54.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221323/884f8141-21d0-481c-ab01-a82c01578c9b.png)


# まとめ
本記事では dbt か らBigQuery に接続する際に ADC 経由で認証する方法を紹介しました。
ドキュメントをよく読めば書いてあるのですが、恥ずかしながら見落としてハマってしまったので記事にしてみました。
使ってみたいNuxt3のモジュール5選

この記事はウェブクルー Advent Calendar 2023 12日目の記事です。
昨日は@wc-takahara さんの「TypeScriptのふわっとしている部分を再確認」でした。


## Nuxt3のモジュールについて
これまで私はモジュールを必要に応じて導入することが多く、追加の利点を考える余地はあまりありませんでした。しかし、Nuxt公式サイトのモジュール一覧を見ると、実に多岐にわたる分野で役立つモジュールがたくさん存在していることがわかります。

https://nuxt.com/modules

この記事では、「開発効率の向上に貢献できそうなNuxt3のモジュール」を5点紹介します。

### Nuxt Web Vitals
Web Vitalsに関する情報を取得し、それをGoogle Analytics（GA）と連携できるようになります。

このモジュールを使用することで、ページの読み込み速度やレンダリングの品質に関する計測結果を取得できます。これにより、改善のための洞察を得ることが可能であり、サイトの速度とパフォーマンス向上に貢献することができます。また、設定方法がシンプルであるため、カスタマイズも容易に行えるのが特徴です。

https://nuxt.com/modules/web-vitals

### nuxt-seo-kit
6種類のSEO対策用モジュールを1つのパッケージにまとめたものです。

このパッケージを使用することで、`sitemap.xml`の生成やサイトのクロール、JSON-LDの生成など、基本的なSEO対策を実装できます。


Nuxtを使用したSEOの設定には、通常多くのモジュールをインストールする必要がありますが、このパッケージを利用することで手軽にそれらの機能を取り入れることができます。新規サイトの開発において、このパッケージを試してみたいと思うポイントですね。

https://github.com/harlan-zw/nuxt-seo-kit

### typed-router
`nuxt-link`の`to`属性などでパスを指定する際に、ルートを自動補完してくれる機能を持っています。

具体的には、`NuxtLink`、`useRouter`、`navigateTo`、`useRoute`、`useLocalePath`などの機能をサポートしています。この自動補完機能があれば、開発効率を大幅に向上させることができます。

例えば、パスやルート名を手動で入力する必要がなくなり、モジュールがそれらを補完してくれるため、開発作業がスムーズに進むことが期待できます。

https://nuxt.com/modules/typed-router

### html-validator
ハイドレーションエラーが起きる原因など一般的な問題を自動的に検出し、解決へと導いてくれます。ハイドレーションエラーの原因特定には時間がかかることがありますが、このモジュールを使うことでそれらの問題を素早く特定し、解決することができます。

また、設定オプションの一部として`usePrettier`などを設定すれば、ソースコードを整形してくれる機能も備えています。これにより、エラーの検出だけでなく、ソースコードの整形や修正も自動化されるため、開発効率の向上に非常に役立つでしょう。

https://html-validator.nuxtjs.org/

### link-checker
誤って記述されたリンクやパスなどでSEOに悪影響を及ぼす可能性のあるエラーを検出し、修正する機能を提供しています。例えば、`/test/`というパスを誤って`/testooo/`などと誤記述した場合に、エラーを検知してくれます。

また、[nuxt-simple-sitemap](https://nuxt.com/modules/simple-sitemap)と連携しており、正しいリンクかどうかを判断して補正する仕組みが備わっています。

特に便利な機能として、「ライブ検査」があります。これは、実際の画面上で誤ったリンクを設定した箇所を特定し、カーソルを合わせるとエラーを表示してくれます。さらに、正しいリンクを提案してくれるだけでなく、修正まで支援してくれる点が特徴です。記述ミスによるリンク切れ対策に非常に効果的なモジュールですね。ライブ検査のデモは[こちら](https://nuxtseo.com/link-checker/guides/live-inspections)で確認できます。

https://nuxt.com/modules/link-checker

## まとめ
いかがでしょうか。どれもとても役立ちそうな機能なのではないでしょうか。自分も是非使ってみたいと思います。
また、いずれも日本語のドキュメントが少ないモジュールなので、
実際に使ってみて使い方や感想などを記事にできたら良いなと思っています。

Nuxt3には他にも様々なモジュールが存在しているので、機会がありましたら是非チェックしてみてください。

明日は@kentaro-arai さんの投稿になります。お楽しみに！

ウェブクルーでは一緒に働いていただける方を随時募集しております。
私たちと一緒に働きましょう！
https://www.webcrew.co.jp/recruit/
【Elixir アンチパターン】 エラーは隠さないで！

引き続き、Elixir アンチパターンを読んでみます。

今日は、[propagating-invalid-data](https://hexdocs.pm/elixir/1.16.0-rc.0/design-anti-patterns.html#propagating-invalid-data)です。

エラーが発生してて、その個所はわかるんだけど、この原因がどこにあるのかわからない。こんな事ありますよね。
開発中なら、全体像がわかってるのですぐわかる場合も多いですが、運用中に発生したり、他の人が作ったものだったりするとほんと苦労します。安心して眠れません。

このアンチパターンは、そんな事態にならないようするのに役立つと思います。

foo()は引数をもっていて、この値をほかの関数に渡して、その結果を返しています。

```Elixir
defmodule MyLibrary do
  def foo(invalid_data) do
    # Some other code...

    MyLibrary.Internal.sum(1, invalid_data)
  end
end
```

foo渡すデータは整数である必要があるのに、文字列が渡されたとしたら、どうなるか。
MyLibrary.Internal.sumの中でエラーになります。

お勧めの実装は、

```Elixir
defmodule MyLibrary do
  def foo(data) when is_integer(data) do
    # Some other code

    MyLibrary.Internal.sum(1, data)
  end
end
```

foo()の引数の値が整数であることをguard節で明示しておきます。
これで、foo()を呼び出すところでエラーになります（fooでエラーが発生するのではなくその前の、本当の原因の所でエラーが発生します。

これで安心して眠れます。

契約プログラミングにつながる話でした。
転職活動を10年続けてたら人生行き詰ってきた話

この記事は[エンジニア転職 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/change-jobs)の11日目になります。

10日目は[newta](https://qiita.com/newta)さんの「[やりたいことをするための環境を探そう](https://qiita.com/newta/items/443bba984e09e79652e2)」でした。「野球をやっててもサッカーはうまくならない」というのには膝を叩いて納得してしまいました。確かにその通りですね。今後の参考にしたいと思います。

さて、この記事はアラフィフのおっさんエンジニアによる転職失敗談です。皆様の成功談のなかで恐縮ですが、他人の失敗から学べることもあると思いますので、よろしければご覧ください。

## ざっくり自分の経歴

* 新卒でベンチャー企業に就職。約10年働くも倒産で解雇。
* フリーランスのエンジニアになる。約10年働くも諸事情で廃業。
* 派遣でエンジニアとして働く。合間に転職活動も行って、何度か転職したこともあるけれど諸事情で数年で退職を繰り返すこと約10年。現在も転職活動中。

トータルで約30年のキャリアがあるわけですが、ほぼ全てでエンジニアでしたし、今後もエンジニアを続けたいと思っています。

ここ10年は断続的に転職活動を行ってるわけですがなかなかうまくいかず、気が付いたらアラフィフになっててこりゃまずいんじゃないかなと思っているのがイマココってところです。

## どの辺が人生行き詰ってきたか

### 専門性が磨かれていない

ウェブ系で主にサーバサイドのエンジニアをしていますが、その中で特に何が得意というものがありません。過去の経験でも、言語もフレームワークもばらばらです。また、転職の度に業種が変わっているため、ビジネス的な専門知識も身についていません。

幅広い経験があることはメリットでもありますが、やはり特定の専門分野を持っている人は強いなと感じます。浅く広くと共に、何か一つ狭く深く知っていることは大事だなと。そういうものを持たずにやってきたことは、今の自分の弱みになっていると感じます。

### 経験内容がメンバーレベル

特定の言語やフレームワークの経験者として転職しても、会社によって細かなやり方の違いはどうしたってあります。業務知識も必要になります。なので転職して最初のうちは言われたことを言われたとおりにこなすメンバーレベルの業務になります。メンバーレベルを数年経験することでその会社での深い業務に入っていけるわけですが、その前に退職しているため深い業務経験を積めていません。どこに行っても万年新人状態です。

### 履歴書が激汚れ

短期転職を繰り返したことで、履歴書の職歴欄が入りきらないくらいの量になってしまいました。履歴書を書くのが大変というのもありますが、採用側から見たら「どうせすぐに辞めるよね」って判断されがちなのはありそうです。結果、書類選考で落ちるということがほとんどです。実際の不採用の理由は教えてくれませんけどね。

### 年齢による転職難易度激化

企業側の視点にたつと、年齢があがると当然にそれに伴った期待の変化があります。具体的にはマネージャーやリーダー経験、後輩の指導育成経験などが求められます。もしくはスペシャリストとして特定の言語やフレームワーク、ミドルウェアやクラウドなどの深い知識と経験。

それらの経験が無い私の場合、では同程度のスキルを持っている若手の候補者がいればそちらを採用しますよねってなるのは自然な流れでしょう。

### 付け焼刃スキルの賞味期限切れ

エンジニアですから当然に勉強はしてます。ただ、やってる勉強って今目の前の案件をこなすための泥縄勉強なんですね。必要なことをピンポイントで学んでる。要はスキルが常に付け焼刃状態。

コンピュータサイエンスの根本原理は変わりませんが、10年20年という年月の中で様々な新しい概念や技術が登場しています。そうした知識をググって出てきた紹介記事をその場限りで消費することを繰り返していると、体系的な知識が不足しているなぁと感じることが多々あります。

### 会社評論家になってしまっている

あちこちの会社を転々としていると、それぞれの会社の良い点を全て併せ持った理想の会社像が自分の中に出来上がってしまいます。そんな理想の会社はどこにもありませんから、どこの会社に行っても理想の会社との違いが欠点に見えてしまいます。

しまいには求人票を見ただけで「この会社はここが欠点。こう直せばもっと伸びるのに」なんて、勝手に評論してしまう始末です。そんな自分に気が付いたとき、これは結構まずい姿勢だなと思ってしまいました。

### 仕事人生の納得感がない

言われたことをただこなすだけのメンバーレベルの仕事しかしていないため、人からどんな仕事をしているんですかと聞かれても説明できません。要は「アレオレ(あの仕事は実は俺がやった)」というものが無い。アレオレ詐欺ではなく、本当に関わったという意味でですね。

他人に説明するのはともかくとして、自分自身に対して納得感がありません。約30年の仕事人生で一体何を成し遂げたのかと。人に誇れるような有名プロジェクトに関われなかったとしても、ああ自分はこれを成し遂げるためにエンジニアになったのだなぁと思えるものがあると納得感があると思うのですが、今のところそういうものがありません。

## どうしたらよかったか

問題点の大半は、短期離職を繰り返したことによるものです。では我慢して辞めなければよかったかというと、それも違うなと。それぞれ正確な理由はここには書けませんが、どうしても辞めざるを得ない理由というのがあったのですよ。辞めずに済む状況であればよかったなと今でも思いますが、現実に自分の人生に起こったことなので、それは受け入れるしかないかなと。

一方、専門性が磨かれていないとか、スキルが付け焼刃になってしまっているというのは自分自身の問題です。仕事を通してそうしたスキルが身に付けられればよいのですが、私の場合はそうではなかった。では仕事外で身に着けるしかないですね。人生いつだって今日が一番若くて時間がある。これから深めていけばいいんですよね。Qiita に記事を書いたり個人開発をしたりというのもその一環なのですが、今後は更に深めていければなと思います。

そもそも自分が何をしたいのかを突き詰めて考えていなかったという問題もあります。何をしたいかを見定め、それを実現できる職場に転職するとか、プライベートでスキルを磨くとか出来ていればよかったんですよね。そういったことをせず、ただ単に状況に流されるままに過ごしてきたために今があるとしたら、自分の仕事人生に軸が無さ過ぎたのだなという反省があります。

人生100年時代と言われていますから、アラフィフの私にもまだ50年の時間が残されています。50年間ずっとエンジニアとして働き続けるかというと微妙ですが、少なくともあと10年20年は働くでしょう。であればまだまだ時間は残されているわけです。この記事をこれまでの失敗の振り返りとして、今後の改善としていければなと思います。