OmniAICreator/Qiita-1.07M huggingface dataset:
Document Clause Sets

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)

-------------

+ [【ヘルプ】Document Clause Sets](https://help.salesforce.com/s/articleView?id=ind.sf_contracts_document_clause_sets.htm&type=5)
+ [【モジュール】Salesforce Contracts Integration with Microsoft 365 >Discover Reusable Clauses](https://trailhead.salesforce.com/ja/content/learn/modules/salesforce-contracts-integration-with-microsoft-365/discover-reusable-document-clauses)


# 特別版の開発者環境ってあるのか？

+ [「ドキュメント句セット」が見つからないため、「DocGen」を作成できません](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pf60jSAB)
+ [Activating Einstein via Dev Edition Org](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KB4HY)
初心者はレジストリに手を出すな

:::note warn
未解決事象です。再現は自己責任でお願いいたします。
:::

## レジストリ
GUIやポリシー、コマンドで対応できない設定はレジストリでなんとかするしかないという発想になりがちかと思うのですが、みなさんご存知の通りレジストリの扱いには細心の注意が必要です。

今回は私が実際に体験した恐怖のレジストリエピソードをご紹介します。


## ゾンビのようなレジストリ
とある設定をオフで固定したくて探し回っていたときのこと。Win11からの機能なのでインターネットの海にも情報が少なく困っていたのですが、海外サイトでようやくそれっぽいのがヒットしました。
（みんなも困ったら英訳で検索してみよう！）

「レジストリでいけると思ってたけど、こんなところにあったのか～」
と、言われるがまま検証環境でレジストリの値を追加。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/ce59f9c7-9c1c-95e1-6e1c-f3281d764695.png)

ご察しの通り、『Enabled』を[0]にしている値が今回追加したもの。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/0c664568-eed1-aef3-6314-be05380a5638.png)

設定はオフになりましたが、グレーアウト等はしていません。
トグルをクリックすると、オンになってしまいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/9eb2c599-b9dd-adfb-4958-ca172a7784e7.png)

残念ながら、目的のレジストリではありませんでしたね。
私が今回探していたものはオフで固定するものなので、オフ状態でグレーアウトやトグルを触っても設定不可となっていて欲しかったのです。

不要な値をレジストリに追加してしまったので忘れる前に削除しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/a2901cf1-82da-99a6-b3cd-8ee703bcf283.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/70aed1d5-be32-1f70-d24f-38eecf02a7d7.png)
削除できました
この設定どうしたものでしょうか。設定を触っているとき、ふと視線を感じました。
え？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/72f4c187-66e6-3185-b7d9-e103ad26241a.png)
復活してる！！！
Enabled、復活してる！！！

何度削除しても
先程の設定をオン→オフに切り替えると復活するようです。
オフのままやオンに切り替えても復活しません。
現時点で再現可能なのはオン→オフに切り替えた際です。

こちら検証環境なので業務上の問題はありませんが、この余分な値があってはこれ以後の検証に対して不適切なのでなんとしても削除したかったのですが
コマンドプロンプトからもPowerShellからもセーフモードにてGUI上から操作しても、設定をオン→オフに切り替えると不死鳥の如く復活してしまい、こんなことに工数割くのも馬鹿らしいので急がば回れで泣く泣く検証環境ごと上書きました。


## 初心者はレジストリに手を出すな
クライアントOS案件ではレジストリと戦う場面が多く、続けていくとレジストリに対して気が緩んでしまいます。
しかしやはりレジストリは危険な代物です。
上記の私の場合は、英語の記事を読み進めるのが億劫だったので削除方法等が特に記載されていないことに気づかずにすぐに検証してしまいました。それも反省点です。
レジストリは操作者の意図せぬ設定変更が行われてしまう危険性だけでなく、削除できない・復活する等の困った事態に陥ることがあります。

例えば上記とは違い、探し求めていた設定変更ができていた場合に、喜んで本番環境に適用してしまったとしましょう。
「このオフ固定の設定やっぱり不便だから、変更可能にして」と言われてから初めて削除できないことに気づいたら………

レジストリを扱うときは後片付けができるかまでじっくりと検証してからにしましょうね。
今回の件から私が得た教訓をみなさまにも共有です
【電脳少女プログラミング2088 ─壊レタ君を再構築─】SQL問題をやってみた。

paizaの新作プログラミングゲーム【電脳少女プログラミング2088 ─壊レタ君を再構築─】SQL問題をやってみました。
- - -
###### データセンター
https://ppg.paiza.jp/denno2088/challenges/denno2088_s_d_01

`person.id`と`person.name`を`person`テーブルからすべて取得するので
```sql
SELECT id, name FROM person;
```
となります。
- - -
:::note info
ここからは少しずつSQLを書いていきますので、最終形以外は
- シンタックスハイライト無し
- 文末のセミコロン無し

とさせていただきます。
:::

- - -
###### 二人が通った教室
https://ppg.paiza.jp/denno2088/challenges/denno2088_s_c_01

`memory.id`と`memory.talk`を`memory`テーブルから取得するので、まずは
```
SELECT id, talk FROM memory
```
`id`の小さい順に10件取得するので、`ORDER BY id LIMIT 10`を付けて
```sql
SELECT id, talk FROM memory ORDER BY id LIMIT 10;
```
となります。
- - -
###### 会員制ジム
https://ppg.paiza.jp/denno2088/challenges/denno2088_s_c_02

`memory.id`と`memory.talk`を取得するので、まずは
```
SELECT id, talk FROM memory
```
条件が
- `memory.importance`が3以上
- `category.name`が「悲しみ」

とあるので、一旦
```
SELECT
	id, talk
FROM
	memory
WHERE
	importance >= 3
    AND category.name = '悲しみ'
```
となりますが、`memory`テーブルと`category`テーブルを（内部）結合させなければなりません。
`memory`テーブルと`category`テーブルをカテゴリIDで結合させて
```sql
SELECT
	memory.id, memory.talk
FROM
	memory
	INNER JOIN category ON memory.category_id = category.id
WHERE
	memory.importance >= 3
	AND category.name = '悲しみ';
```
となります。
- - -
###### 打ち捨てられた図書館
https://ppg.paiza.jp/denno2088/challenges/denno2088_s_b_01

`memory.id`, `memory.talk`, `battle.result`を取得したいのですが、`memory`テーブルと`battle`テーブルを直接関係づける属性はありません。
そこで、中間テーブルに当たる`log`テーブルを使って、`memory`テーブルと`battle`テーブルのレコードを関連付けます。
```
SELECT
	memory.id, memory.talk, battle.result
FROM
	log
	INNER JOIN memory ON log.memory_id = memory.id
	INNER JOIN battle ON log.battle_id = battle.id
```
更に、`log.created_at`が`2085-08-01`〜`2087-10-20`の期間とありますので、`BETWEEN`を使って
```sql
SELECT
	memory.id,
	memory.talk,
	battle.result
FROM
	log
	INNER JOIN memory ON log.memory_id = memory.id
	INNER JOIN battle ON log.battle_id = battle.id
WHERE
	log.created_at BETWEEN '2085-08-01' AND '2087-10-20';
```
となります。
- - -
###### 巨大コーポの最上階
https://ppg.paiza.jp/denno2088/challenges/denno2088_s_a_01

`memory.id`, `memory.talk`, `person.name`, `battle.created_at`を取得したいので、まずは
```
SELECT
	memory.id,
	memory.talk,
	person.name,
	battle.created_at
```
`memory`, `person`, `battle`テーブルの各レコードを関連付けるため、`log`テーブルも使って4つのテーブルを
- 記憶のID（`memory.id`, `log.memory_id`）
- 人物のID（`person.id`, `log.person_id`, `battle.person_id`）

で（レイミの指摘を受けないような順番で）結合させます。
```
SELECT
	memory.id,
	memory.talk,
	person.name,
	battle.created_at
FROM
	memory
	INNER JOIN log ON memory.id = log.memory_id
	INNER JOIN person ON log.person_id = person.id
	INNER JOIN battle ON person.id = battle.person_id
```
更に、「重要度が5の人物の`person.deleted_at`と同じ`battle`の` battle.created_at`から」とありますので

```sql
SELECT
	memory.id,
	memory.talk,
	person.name,
	battle.created_at
FROM
	memory
	INNER JOIN log ON memory.id = log.memory_id
	INNER JOIN person ON log.person_id = person.id
	INNER JOIN battle ON person.id = battle.person_id
WHERE
	person.importance = 5
	AND battle.created_at = person.deleted_at;
```
となります。
個人的な備忘録：HTTPメソッドについて3時間語れなかったので、記事としてアウトプットして振り返ってみた

## はじめに
HTTPメソッドとは、Webブラウザやクライアントがサーバーに対してどのような操作を要求するかを指定するための方法です。

:::note info
***正しいメソッドを使用することで、API設計や通信の可読性が向上します。***
:::

本記事は個人的な備忘録としてまとめたものです。***その点をご理解いただければ幸いです。***

## 書こうと思ったきっかけ
ITスクールのハッカソンで、実際にAPIを構築する課題があり、HTTPメソッドの正しい使い分けが求められました。

:::note warn
***その中で、GETやPOSTはスムーズに理解できたものの、PUTやPATCHなどの違いを説明するのが難しいと感じました。***
:::

また、普段の開発では何となく使っているメソッドが多かったため、基礎から整理し直す必要性を実感しました。

***この記事を通じて、自分の理解を深めるとともに、同じ課題を持つ方への助けになれば幸いです。***

## HTTPメソッドの概要
HTTPメソッドは、クライアントとサーバー間で行われる通信の種類を指定するための仕組みです。

![スクリーンショット 2024-10-31 23.16.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/917249f5-0ddf-347f-5650-a2d3751f9b3d.png)
引用画像：https://www.japanitguide.com/html-reference/HTTP-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89:-GET-%E3%81%A8-POST.html

HTTPメソッドにはさまざまな種類がありますが、主要なメソッドについて以下に簡単にまとめます。詳しい説明は後述します。

:::note
**GET:** 
サーバーからデータを取得するために使用される。

**POST:** 
サーバーにデータを送信するために使用され、新しいリソースの作成や既存リソースの更新に適する。

**PUT:** 
指定したリソースを新しいデータで更新するために使用される。

**DELETE:** 
指定したリソースを削除するために使用される。

**PATCH:** 
リソースの一部を更新するために使用される。
:::

これらのメソッドは、サーバーに対するリクエスト内容の性質を明確に定義し、クライアントとサーバー間でのデータのやり取りを効率的に行うための重要な役割を担っています。

## 主なHTTPメソッド
HTTPメソッドの基本的な整理として、最もよく使われる「GET」と「POST」について、過去の記事で詳しくまとめていますので、ぜひ参考にしてください。

https://qiita.com/free-honda/items/afb45fd7036d17778ddb

### GET
**概要**: サーバーからデータを取得するために使用。  
**特徴**:
- リクエストパラメータはURLに付加される（例: `https://example.com/api/resource?id=123`）。
- データの取得専用であり、サーバー側の状態を変更しない。
- キャッシュされやすい。  
**例**: Webページを表示、検索結果を取得。

AWS LambdaとAPI Gatewayを使用したGETリクエスト対応のサーバーレスアーキテクチャ構築については、以下の記事を参考にしてください。

https://qiita.com/free-honda/items/f9489f39c90488e733f3

### POST
**概要**: サーバーにデータを送信し、新しいリソースを作成する際に使用。  
**特徴**:
- リクエストボディにデータを含む。
- サーバー側でデータの変更や追加が発生する。
- URLにはパラメータが含まれない（ボディに含める）。  
**例**: ユーザー登録、フォーム送信。

AWS LambdaとAPI Gatewayを使用したPOSTリクエスト対応のサーバーレスアーキテクチャ構築については、以下の記事をご参照ください。

https://qiita.com/free-honda/items/eef40d5c20acdc191550

### PUT
**概要**: 指定したリソースを作成または更新する際に使用。  
**特徴**:
- リソース全体を更新する（部分更新はできない）。
- 指定されたリソースが存在しない場合は新規作成されることもある。  
**例**: ユーザー情報の更新。

### PATCH
**概要**: リソースの一部を更新する際に使用。  
**特徴**:
- PUTと異なり、部分的な更新に対応。  
**例**: ユーザーのメールアドレスだけを更新。

PUTとPATCHの違いについては、以下の記事で簡単にまとめていますので参考にしてください。

https://qiita.com/free-honda/items/e6241e1d54419444c6e3

### DELETE
**概要**: 指定したリソースを削除する際に使用。  
**特徴**:
- サーバー上からデータを削除するためのメソッド。  
**例**: 投稿やユーザーアカウントの削除。

### HEAD
**概要**: GETメソッドと同じ動作をするが、レスポンスボディを返さない。  
**特徴**:
- リソースの存在確認やメタデータ取得に使用。  
**例**: ファイルのサイズや更新日時を確認。

### OPTIONS
**概要**: サーバーがサポートするHTTPメソッドや機能を確認する際に使用。  
**特徴**:
- 主にクロスオリジンリクエスト（CORS）時に利用される。  
**例**: ブラウザがサーバーの許可設定を確認。

### TRACE
**概要**: リクエストがサーバーにどのように届くかを確認するために使用。  
**特徴**:
- デバッグ目的で使用。  
**例**: ネットワーク経路の確認。

### CONNECT
**概要**: トンネル接続を確立するために使用。  
**特徴**:
- 主にHTTPS通信で使われる。  
**例**: プロキシサーバーを通じたSSL通信。

## まとめ

最後までお読みいただき、ありがとうございました。ITスクールのハッカソンに参加し、実際に手を動かしたことで、より実践的なスキルを獲得することができました。

:::note warn
***アプリケーションを設計する際は、これらのメソッドの特性を理解し、適切な使い分けを行うことが重要だと痛感しましｔ***
:::

***これからも、このような基本的な内容を丁寧にまとめ、知識を定着させていきたいと思います。***
［ServiceNow］アカウントを作成する

※この記事はServiceNow初心者が学習用のために記載した記事です。内容について誤っている場合がございます。不足点などございましたらコメントいただけますと幸いです。

# アカウントを作成とは
- 特定のユーザーがServiceNowにログインして機能を利用できるようにすることを意味する
- sys_userレコードを作成し、必要な設定を行うプロセスを含む
- Userテーブル（sys_user）でレコードを作成することとは違う
    - sys_userテーブルのレコード＝アカウントではない
    - Userテーブル（sys_user） に新たなレコードを作成する行為は、単にそのユーザーに関する情報をデータベースに追加することを指す

# アカウント作成の要件
- Activeフィールドを「true」に設定
    - ユーザーを有効化する必要がある
- User ID（ログインID）を設定
    - ログイン時に使用される一意のIDが必要
- パスワードの設定
    - パスワードが設定されていない場合、ログインできない
- ロールの付与
    - 権限（ロール）を割り当てないと、基本的な機能にアクセスできない場合がある
    - 例：itilロールを付与すると、インシデント管理を利用可能

# ServiceNowでアカウントを作成する手順
- User テーブルを開く
    - Filter navigatorで「sys_user.list」と検索して押下
- 新しいユーザーレコードを作成
    - Usersリストビューの右上にある「New」ボタンを押下
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/4d127e20-aa9f-f297-bb25-a20db58d149d.png)

- 必要なフィールドを入力します
   - User ID: ユーザーのログインID（例: account1_1）
   - First Name / Last Name: 名前（例: account1_2 / account1_3）
   - Email: メールアドレス（例: account1@example.com）
   - ※Password: パスワード（後でユーザーが変更可能）
   - Active: ユーザーを有効化するには「チェックを入れる」
   - ※Roles: ユーザーに必要な権限を割り当てる（例: itil や admin）
   - ※ Password、Rolesについては、一度レコードを作成してからフォームを開いて設定する
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/18c37466-5950-ebf4-456e-1f89d40ddd3b.png)
- 再度レコードのフォーム画面に入る
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/0833ce32-4ea6-cbdf-bdad-eac3b6541ce1.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/78f7840d-703d-a7b0-dbbc-276a7f20d3bd.png)
- Set Passwordを押下
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/69d86bd9-2bf6-8c87-4102-716a2d2c027d.png)
- 上記が初期ログインパスワード。コピーしてどこかに貼っておく

- ロールを割り当てる
    - 「Roles」セクションを探して、Edit（編集）ボタンを押下
    - 必要なロールを検索し、右側のリストに移動させる（ドラッグ＆ドロップか「Add」ボタンを使用）
   - 例: 
     - admin: 管理者権限
     - itil: インシデントやタスクを管理する基本権限
     - catalog: サービスカタログを利用できる権限
- Save（保存）を押下
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/d0b9a2f8-8f95-7226-1775-36c91cca06c6.png)

# 別のセッションでログインしてみる

- 作成したアカウントでServiceNowにログインして、正常に動作するか確認
    - 現在開いているURLをコピーして別のプロファイルで検索
    - プロファイルを作成して、「別のセッション」で試す
        - プロファイルの作成方法は別のページで記載
    - 先ほど作成したレコードのUserID、Passwordを記載してログイン
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/c11807e1-0a32-1df0-21f3-a089b54ceeff.png)
    - 新しいパスワードが求められるので設定する
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/06d6cfce-2de3-21cc-fbf6-dfc13bf6bb8d.png)
     - 作成されたアカウントで個人インスタンスにログインできていることを確認する
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624279/b5644bfd-0ecd-0d15-c15d-0786f90af7bb.png)
ファイルのフルパスを素早く検索する【Windows】

### 作成の経緯
元々は以下を作成した際に一意に絞れないものが出てきたことが作成の経緯です。

https://qiita.com/kokiengine/items/09545d4788af95ff5e42

怪我の功名で、「普通のExplorerからの検索より早くね？」となり、体裁を整えていった次第です。通常のExplorerの場合、ファイル内部の文字列まで検索しているので、かなり時間がかかるようで、環境にもよるかとは思いますが、自分が試した環境では5倍以上の速度で検索ができました。

## 検索スクリプト
PowerShellを用いた検索です。
検索を始めるパスを対話式にすると若干の手間があるので、デフォルト値を入れて必要に応じてデフォルト値を書き換える形で作成します。
コピペで実行できると思いますが、デフォルト部分は書き換え推奨です。

~~~
#検索を始めるディレクトリのデフォルト値の指定（書き換え可能）
$StartPath = "c:/"

#デフォルトの書き換えの有無チェック
$Check = Read-Host "「${StartPath}」配下を再帰的に検索します`n y or n"

#書き換える場合
if($Check -match "n"){
$StartPath = Read-Host "検索を始めるディレクトリのフルパスを記載"
}

#検索する文字列を対話式で入力
$SearchSTR = Read-Host "検索を始めるディレクトリのフルパスを記載"

#検索した結果を変数に格納
$Result = Get-ChildItem -Path ${StartPath} -Filter "*${SearchSTR}*" -Recurse 2>$null `
|Convert-Path

#変数にヘッダをつけて表示
echo $Result |% -b{$count = 1} -p{"[0] [1]" -f $count++,$_}

#複数パターンあるので、検索コマンドをfunction化する
function PSFileSearch{
Start-Process -FilePath "c:/windows/Explorer.exe" -ArgumentList "${Result}"
}

#検索結果による返答
switch($Result.Length){
0 {
 echo 検索はヒットしませんでした。
 pause
 exit
 }
1 {
 PSFileSearch
 ;exit
 }
}
$i = Read-Host "何行目を検索しますか"
$i = $i -1
$Result = $Result[$i]
PSFileSearch

~~~

検索時の`-Filter`の後ろは前後に`*`をつけることで完全一致ではなく部分一致での検索が可能になります。
`$i`の数字を引いているのは最初の行が0行目扱いであるためです。

### おわりに
今回はすぐに対象を選んでエクスプローラーで開く処理にしましたが、テキストに出力してゆっくり精査するような形にしても良いかと思います。
中間CA・ルートCA・SSL代理証明の整理

# 登場人物
- ブラウザ
    - クライアント側のWebブラウザ
    - ブラウザにはルート証明書がデフォルトでインストールされている
- サーバー
    - クライアントがアクセスしたいウェブサイト等
    - サーバーがHTTPS通信するためには、サーバーにSSL証明書をインストールする必要がある。/etc/conf.d/sslなどに配置する？
- 中間CA
    - サーバーのSSL証明書の正当性を保証する認証局
    - 例：AWSのACMを使って証明書を発行した場合サーバーと中間CAの間にACMが存在する。中間CAはAWSが管理する認証局となる。
- ルートCA
    - 中間CAの正当性を保証する。全てのCAの親。


# シーケンス
```mermaid
sequenceDiagram
    participant ブラウザ as ブラウザ
    participant サーバー as サーバー
    participant 中間CA as 中間証明書（Intermediate CA）
    participant ルートCA as ルート証明書（Root CA）

    ブラウザ->>サーバー: HTTPSリクエスト
    サーバー-->>ブラウザ: サーバー証明書と中間証明書を送信
    ブラウザ->>中間CA: サーバー証明書の署名を検証
    alt 中間証明書が信頼されている場合
        ブラウザ->>ルートCA: 中間証明書の署名を検証
        alt ルート証明書が信頼されている場合
            ブラウザ-->>ブラウザ: SSL証明書を信頼
        else ルート証明書が信頼されていない場合
            ブラウザ-->>ブラウザ: エラー（証明書が信頼できない）
        end
    else 中間証明書が信頼されていない場合
        ブラウザ-->>ブラウザ: エラー（証明書チェーンが不完全）
    end
```

# SSL代理証明
- 企業ネットワークなどで、社員の通信を監視したいニーズが有る。しかしクライアント（社員）とサーバーの通信はSSLで暗号化されているため監視できない。
- クライアントとサーバーの間にプロキシサーバーを割り込ませる
- プロキシサーバーとサーバー間では通常通りのSSL通信を行う
- 企業用の独自のSSL証明書を発行し、クライアントとプロキシ間では独自SSL証明書を使った通信をさせる。クライアントにはあらかじめ独自SSL証明書を配布しインストールさせておく。
```mermaid
sequenceDiagram
    participant クライアント as クライアント（社員PC）
    participant プロキシ as SSLプロキシサーバー
    participant サーバー as 外部サーバー（例: https://example.com）

    クライアント->>プロキシ: HTTPSリクエストを送信 (https://example.com)
    プロキシ-->>クライアント: 独自のSSL証明書を提示
    クライアント-->>クライアント: SSL証明書を検証（企業のルート証明書を信頼）
    クライアント->>プロキシ: 暗号化通信を確立

    プロキシ->>サーバー: HTTPSリクエストを送信 (https://example.com)
    サーバー-->>プロキシ: サーバー証明書を提示
    プロキシ-->>プロキシ: サーバー証明書を検証

    プロキシ-->>サーバー: 暗号化通信を確立
    サーバー-->>プロキシ: サーバーからのデータを受信

    プロキシ-->>プロキシ: 通信内容を復号・解析
    プロキシ-->>クライアント: データを再暗号化して送信
    クライアント-->>クライアント: 受信データを復号して処理
```

# オレオレ証明書
- SSL証明書を自分で作成してサーバーにUPする。ルートCA・中間CAを使わない。
- 公開鍵も秘密鍵も自分で作成する
- 接続時に安全な接続ではないことをブラウザから警告を受ける
- ローカル環境・検証環境でSSLの設定が面倒なときや明らかに不要なときに用いる手段。
- 本番環境での利用はもちろんNG

# TLS相互認証
- サーバー証明書だけでなく、クライアント側の持つクライアント証明書の検証も実施する
```mermaid
sequenceDiagram
    participant クライアント
    participant サーバー
    participant 認証局 as 認証局（CA）

    クライアント->>サーバー: Client Hello (対応可能な暗号スイートを送信)
    サーバー->>クライアント: Server Hello (選択した暗号スイート, サーバー証明書を送信)
    サーバー->>認証局: サーバー証明書の検証
    認証局-->>サーバー: 証明書有効
    サーバー->>クライアント: クライアント証明書の要求
    クライアント->>認証局: サーバー証明書の検証
    認証局-->>クライアント: 証明書有効
    クライアント->>サーバー: クライアント証明書の送信, 証明書署名
    サーバー->>認証局: クライアント証明書の検証
    認証局-->>サーバー: 証明書有効
    サーバー->>クライアント: 認証完了 (セキュア通信確立)
    クライアント->>サーバー: 暗号化されたデータ通信
```

# 参考
https://qiita.com/miyuki_samitani/items/b19aa5ac3b3c6e312bd5

https://speakerdeck.com/minorun365/zheng-ming-shu-tutehe-datuke-awsnozhong-jian-cayi-xing-nibei-eru

https://www.cloudflare.com/ja-jp/learning/access-management/what-is-mutual-tls/
DeepSeek Chatに数学検定1級の過去問を解かせたら全問正解だった

世の中、DeepSeek-R1の話題で持ち切りですね。[o1並みの推論性能がオープンソースで提供、かつ、API料金もo1の25分の1](https://notai.jp/deepseek-r1/)というのだから、すごい。[NVIDIAの株価も急落](https://www.newsweekjapan.jp/stories/business/2025/01/534519.php)する事態になっています。

DeepSeek V3ベースですが、[DeepSeek Chat](https://chat.deepseek.com/)で、簡単にその実力をお試ししてみました。

まずは、軽い質問から。「日本一高い山は？」に対する回答は下記の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666147/5f3beb6c-6789-f39d-9bb4-55b0a40f2f50.png)

[DeepSeekは数学的推論に強い](https://news.yahoo.co.jp/articles/80c04ecf16cbae02d59322c716b62df51ea2dd50)、とのことなので、[数学検定1級1次試験の過去問](https://www.su-gaku.net/suken/wp-content/themes/su-ken/pdf/support/past_question/pdfjs/web/2020/1q_que_1ji.pdf)の問題1～7を解かせてみます。

DeepSeek Chatは画像入力もOKなので、PDFの問題部分を切り取って、問題を画像として与え、「この問題を解いて」と指示しました。参考までに、[模範解答](https://www.su-gaku.net/suken/wp-content/themes/su-ken/pdf/support/past_question/pdfjs/web/2020/1q_ans_1ji.pdf)はこちらにあります。

結果はなんと、全問正解！DeepSeekが生成した回答の詳細は下記の通り。ちゃんとロジカルに考えて、かつ、正しい公式や考え方を使って正解を導き出せています。

問題1の回答：**正解**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666147/0e762cbd-dfe4-c78a-68af-3f737c99f1e9.png)

問題2の回答：**正解**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666147/6c26c886-e02f-4c02-715e-464f2996f05f.png)

問題3の回答：**正解**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666147/6a8b743e-e5c5-6efa-966f-a460ac99378d.png)

問題4の回答：**正解**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666147/621833ca-944a-8486-2855-8a5223a7bf34.png)

問題5の回答：**正解**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666147/e8a25cd2-e978-8108-6087-83f28f42d713.png)

問題6の回答：**正解**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666147/45e3ffbd-9dbb-11fe-03ba-d35c0d548b02.png)

問題7の回答：**正解**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666147/53bb245e-fd80-3aee-aaa3-36b94998239d.png)


お見事です。いや～、すごいなDeepSeek!
[AWS #37] Amazon Lightsail

<!--
 <font color="c00000"></font> 赤
-->
## はじめに
お疲れ様です。:computer:
今回はコンピューティングサービス分野にある<font color="c00000">**「Amazon Lightsail（ライトセール）」**</font>について見ていきたいと思います。


## Amazon Lightsail
**Amazon Lightsail**は、「仮想」の **プライベートサーバー（VPS:Virtual Private Server）** を<font color="c00000">**月額料金で提供するサービス**</font>です。
:upside_down: **[EC2](https://aws.amazon.com/jp/ec2/)と同じ仮想サーバー**なのですがLightsailは<font color="c00000">**「簡単かつシンプル」**</font>という特徴があります。細かいことは良いから **まずサーバーを立ち上げたいんだ！** という方におすすめかと思います。

サーバーの用途が決まっている場合や、分かりやすい料金でサーバーを使用したい場合などに有効になります。


Lightsailは **「簡単にすばやくWebサイトやサービスを作成」** できます。しかし<font color="c00000">**大規模のものには向いていません。**</font>

大規模でないのならば・・・
・**小規模**のサイトやサービスの構築
・テスト、検証用、開発の環境
などに適しています。

## おわりに
今回のちょっとしたまとめになります。

:::note info
Lightsailは**AWSに特別な知識が無くても利用しやすい**
:::

:::note info
**月額固定料金**なので、**予算を立てやすい**
:::

:::note info
**簡単かつシンプル**にサイトやサーバーを立ち上げることが可能である
:::

Amazon Lightsailは **「安くて使いやすい」「小規模のサービスを作成するのに有効である」** ということ、**「他のAWSサービスと料金体系等が異なる」** というのがわかりました。最後までお読みいただきありがとうございました！
>>**日頃より活用している参考書です。**
>> **「参考書」**
[**AWS認定クラウドプラクティショナー改定第3版（Amazon Lightsailは168ページ）**](https://x.gd/19i6N)
>

> **「AWS公式サイト」**
[**Amazon Lightsail**](https://aws.amazon.com/jp/lightsail/)

> **「Youtube」**
[**簡易サーバー・Amazon Lightsailの使い所を解説！AWSのコンピューティングサービス紹介 #2**](https://www.youtube.com/watch?v=LG41i0U9K14&ab_channel=%E3%82%AF%E3%83%A9%E3%82%B9%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%7CDevelopersIO%7CAWS%E3%82%84%E7%94%9F%E6%88%90AI%E3%81%AA%E3%81%A9%E6%9C%80%E6%96%B0%E6%8A%80%E8%A1%93%E3%81%AE%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F%E5%8B%95%E7%94%BB)
>
TypeScriptでSemaphoreを実装する

# Semaphoreとは
Semaphoreとは複数のタスクを同時に実行する際に、同時実行数を制限するための機能です。制限された実行数を超えたタスクは実行中のタスクが完了するまで待機します。

# Mutexとは違うもの？
概念的にはMutexはSemaphoreの同時実行数を1に設定したものと考えて良いです。

# Lockとは違うもの？
Mutexを意図してLockと書く場合もありますが、概念的にはLockは排他処理機構を指していて、SemaphoreもMutexもLockの一種と考えられます。

# TypeScriptでの実装

TypeScriptには基本的にスレッドが存在しないので、Semaphoreも非同期処理(Promise)として実装する必要があります。

基本的な考えは非常にシンプルで、タスクが投入されたらそれを即時処理(Do it now)するか、現在実行中の処理が終わってから順次処理(Do it later)するかを判断すれば良いです。

```ts
export class Semaphore {

    protected _running = 0
    protected readonly _pendingTaskQueue: (() => Promise<void>)[] = []

    constructor(readonly concurrentExecution: number) {
        if (!Number.isInteger(concurrentExecution)) {
            throw new SynchronizerInvalidError(`concurrentExecution should be integer value, concurrentExecution=${concurrentExecution}`)
        }
        if (concurrentExecution < 1) {
            throw new SynchronizerInvalidError(`concurrentExecution should be equal or greater than 1, concurrentExecution=${concurrentExecution}`)
        }
    }

    synchronized(cb: () => Promise<void>): Promise<void> {
        return new Promise<void>((resolve, reject) => {
            const task = () => {
                return cb().then(resolve).catch(reject)
            }
            if (this._running < this.concurrentExecution) {
                // Do it now!
                this.run(task)
            } else {
                // wait in the queue
                this._pendingTaskQueue.push(task)
            }
            return task
        })

    }

    protected run(cb: () => Promise<void>) {
        this._running++
        cb().finally(() => {
            this._running--
            if (this._pendingTaskQueue.length > 0) {
                // finally, it's my time!
                const task = this._pendingTaskQueue.shift()
                if (task !== undefined) {
                    this.run(task)
                }
            }
        })
    }

}
```

# 自作ライブラリ ya-syn
今回紹介した実装はya-synの実装の一部になっています。

https://github.com/tomohisaota/ya-syn
TypeScriptでDouble Checked Lockを使う

# Double Checked Lockとは？
Double-checked lockingとは、通常は複数スレッドから参照される変数を高速、かつ安全に初期化するために利用される手法です。

- 初期化処理は一回しか動かしたくない→ロックが必要
- 初期化中のインスタンスは利用できない→ロックが必要
- 初期化完了後はできるかぎり高速に動作させたい→ロックしたくない

ロックが必要だけど、ロックしたくない。この相反する要求を満たすために、ロックをせずにまずは確認を行い、初期化が必要なときにはロックを取得して再度確認を行う。２回確認するのでDouble Checkedと呼ぶわけです。

# TypeScriptなら不要では？
通常シングルスレッドで動作するTypeScript環境ですが、非同期処理が存在します。複数の非同期処理から参照される変数を高速、かつ安全に初期化するためにはこの手法が有効になります。

実際のコードは下記のようになります。

```typescript
export class LazyInitializer<T> {

    protected _target: T | undefined
    protected _synchronizer = new Semaphore(1)

    constructor(protected readonly _factory: () => Promise<T>) {
    }

    async get(): Promise<T> {
        if (this._target !== undefined) {
            return this._target
        }
        await this._synchronizer.synchronized(async () => {
            if (this._target === undefined) {
                this._target = await this._factory()
            }
        })
        // this._target cannot be undefined unless factory returns undefined
        if (this._target === undefined) {
            throw new SynchronizerInvalidError("factory returned undefined")
        }
        return this._target
    }
}
```

注：TypeScriptには標準でSemaphoreは存在しないので、Semaphoreは別途実装が必要です。
https://qiita.com/tomohisaota/items/88220c5812b1281e0985

# 自作ライブラリ ya-syn
今回紹介した実装はya-synの実装の一部になっています。

https://github.com/tomohisaota/ya-syn

もちろんSemaphoreもあります！
(注意)M5NanoC6 (RISC-V) のバイトオーダーを調べる(格納される時のバイトの並び)


参考

https://qiita.com/ryuichi1208/items/31442f9e8a7a7c94aeec

x 過去ログを見ょ!!!
x アルゴリズムは、あまり関係ないけど?
x 研究調査目的で非営利で引用しました。
x 「シリアルモニタ」は、なんどか開き直す
x 3.1.1
x unionは、共有体　(共用体)

いろいろ
今週中は、進捗が速すぎるのでジャブを何本か打つ予定!!!(何のこと)
したい事は、無線式のマイクロマウスの様な事をしたい。
事前調査のハマりポイントとは、コントローラーの感度調整かな?
そのまま、構造体を送っているのでチョット調査(なんのこと)
バイトオーダーは、基盤警察みたいな人が飛んでくるのかな?

目的
メモリー内でのバイトの並びを調べる


結果
----

![o_coq785.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3e8f1beb-1203-1862-90fb-1625eb7dce25.jpeg)



プログラム
----



```c++


//ser_byte_order_M5NanoC6

void setup() {
  // put your setup code here, to run once:

  //シリアルの初期化
  Serial.begin(9600);
  Serial.println("");
  //シリアルの待ちが0.5*9
  for (int i = 0; i < 9; i++) {
    delay(500);  //接続待ち
    Serial.print(".");
  }  //for
  Serial.println("");

    union {
        uint32_t b4;
        uint16_t b2[2];
        uint8_t  b1[4];
    } bytes ;

    bytes.b4 = 0x12345678 ;
    Serial.printf ("bytes.b4: %08X\n", bytes.b4) ;
    Serial.printf ("bytes.b2: %04X, %04X\n", bytes.b2[0], bytes.b2[1]) ;
    Serial.printf ("bytes.b1: %02X, %02X, %02X, %02X\n", bytes.b1[0], bytes.b1[1], bytes.b1[2], bytes.b1[3]) ;

}

void loop() {
  // put your main code here, to run repeatedly:

}



```
片手が塞がってるときにCtrl+Alt+Deleteを押したい

PCのロック画面を解除する際など、Ctrl+Alt+Deleteを片手で押せたらいいのにと思って調べてみました。

## 固定キー機能の活用
Windowsに備わっている「固定キー機能」を利用すると、複数のキーを同時に押す代わりに、キーを1つずつ押して操作できるようになります。

### 固定キー機能の有効化手順
1. **Shiftキーを連続で5回押す**
   - 「固定キー機能を有効にしますか？」というダイアログボックスが表示される
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1349988/cd2fe930-d5e2-ffdb-18b8-e5482b5c3179.png)
2. **「はい」を選択**すると、固定キー機能が有効になる

### 使用方法
有効状態では、キーを順番に押すことで同時押しの操作が可能になります。

例:
1. Ctrlを押す
2. Altを押す
3. Deleteを押す

これで、片手でもCtrl+Alt+Deleteを実行できます。

### 固定キー機能の解除方法
- 再度**Shiftキーを連続で5回押す**
- または、任意の2つのキーを同時に押す

## その他の方法
あくまで片手しか使えないときの代替手段としてはこの方法で十分かと思いますが、
効率化・省力化が目的であればショートカットデバイスの使用を検討してもいいかもしれません。
Pythonで競技プログラミング（atcoder）をやってみた


タイトル通り、Pythonを使って競技プログラミングを始めてみました。「atcoder」という超有名なサイトでbeginnerコンテストに3回ほど参加した感想を色々書いてみたいと思います。

## 始める前の偏見

・実行速度的にCとかコンパイラ言語が強くて、Pythonじゃダメなんでしょ？
・アルゴリズム知識の引き出しがないと解けないんだろうなあ。
・数学系のライブラリとか、言語差でかそう。

## 実際どうだったか

　実行速度はPyPyを使えばC++と大差ない（C++の方がわずかに早い？）。順位表を見ればわかるが、実はC++とPythonがユーザーの大半。
 
　アルゴリズム知識はあった方が良いが、なくてもbeginerコンテストならそこそこいける。慣れと考え方が大事で、そこは試行回数の問題だと感じた。つけるべき知識はそのうち、ゆっくりと収集すればいいと思う。
 
　ライブラリについて、問題を解くのにライブラリはほぼ使わない(Pythonの場合)。ビルトインで大体どうにかなる。というか原理的なコードで解こうとした方が、自分のコードの計算量がどれくらいなのかわかりやすい。

## システム面の話

　思ってたよりも緩い。qiitaとかネット上のドキュメントを参照してもいいらしい。ブラウザ上にエディタみたいなテキストエリアがあるが、公式がローカルのエディタで書くことを推奨している。

https://info.atcoder.jp/overview/contest/rules

　途中参加してもいいし途中放棄してもいい。ただ、レートが算出されるコンテストに参加するためには事前にまとまった時間の予定を作らないといけないため、生活習慣によっては難しいかもしれない。
　beginerコンテストでは7問くらいが出題されて、初心者は二、三問解ければ良さげ。プログラムの基本的な知識があればA問題は余裕、B問題も普通に解ける。
　C問題が曲者で、素直に解こうとすると解自体は出ても実行時間制限に引っかかってしまう。一度同じ内容をC言語で書き直しても数msしか変わらなかったため、本当に言語差はなさそう。これを解くために現在はコンテストの試行回数を稼いで、アルゴリズム改善のコツを掴もうとしている。
　なお、時間制限に引っかかるだけで解くこと自体はできるぜ！と調子に乗っていたらどうすれば解けるかはわかっても実装が難しいタイプのC問題に遭遇してへし折られた。なかなかやるじゃねえか。

## 将来的なあれこれ

　まずは灰色コーダーからの離脱やC問題を解くことを目標にとにかく試行回数を増やす感じで取り組んでいます。就活に役立つとか、アルゴリズム関係の能力がつくとかメリットはさまざまですが、そもそも単純にプログラムで問題を解くという体験が面白いですね。
　こういうアルゴリズムの改善的なやつは実際の制作、コーディングで都度影響するというほどではないですが、多分プログラミングをしていく中で視点がプロっぽくなっていくんだと思います。メモリ消費とか計算量とか。まだ3回しか参加してないのでアレですけど。
乗算機　機械語change

ハード的な乗算機の考察

x=0h0ff * y=0h0ff を考えた時
乗算命令語を　xyn1,xyn0 として
bit[0]=0,1  上のを下の最下位に持っていく
```
xyn[1],ffff　　　　　　 xyn[0],ffff裏レジ
 a|                  a|  
 d|                  d|
x0|     FE          x0|　　　FF             
 h|                  h|
 f|                  f|
 f|________________  f|________________
[1] A D y0 h 0 f f　　　[0] A D y0 h 0 f f
```
アキューム[1],[0]ffff= FEFF となるように
命令的には2命令。読み込み2回H,L

マシン語　00c3 009c 何かのジャンプの命令語にchangeとか。
マシン語　01c3 0099 機械1のジャンプの命令語にchange

に、使えないかな。
Raspberry Pi のホスト名変更した後に Chromium が起動しない

## 事象

Chromiumが起動しない。なにかエラーメッセージとか出てほしいけど、それも無い。
よく考えたらさっきホスト名変更したせいか……？

## 対処

`rm -rf ~/.config/chromium/Singleton*`

## 補足

せめてエラーメッセージが見たいと思う。
この状況でターミナルから `chromium-browser` を打ってみると、
```
The profile appears to be in use by another Chromium process (XXXXX) on another computer (XXXXXXXXXXXX).
Chromium has locked the profile so that it doesn't get corrupted. If you are sure that no other processes are using this profile, you can unlock the profile and relaunch Chromium.
```
と出るので、このエラーメッセージでググれば情報が出てくるのであった。

エラーメッセージが出なくてつまずいたので、ここにメモしておく
gitlab: rule if invalid expression syntax

gitlabのCIのrulesで守らないといけないルールがいくつかあり、それがわからずはまりました。

- rulesはgitlabサーバー上で実施され、Linuxコマンドなどは使えない
=> 使いたいコマンドがある場合、外部でLinuxコマンドを利用して、変数を作り渡す。(例: 別のプロジェクトのパイプラインからトリガーするときに、variablesとしてLinuxコマンドの結果を渡す）

- rulesのif文は==や!=は使うことができるが、<や<=は使えない!!??
数式をきれいに表示する方法2（統計）

# 目的
・この記事を使って、統計で使われる式をTeX「テフ」形式の書き方がわかります。
・ブログを書く際、コピー＆ペーストで使うことができます。
・TeX「テフ」形式の数式をすぐに使えるようにする目的のため、数式の詳細は
思い切って省くことにする。

# この記事を書いた理由
記事を書くとき、きれいな数式を簡単に書く方法はどうしたらよいか考えた結果、
コピー＆ペーストで使うほうが一番よいと考えた。

そして、数式を紹介しているページは存在するが、TeX「テフ」形式を紹介し、
コピー＆ペーストできるページがなかなか見つからないため、作ってみることにした。

# 数式
### 算術平均
$\bar{x} =  \dfrac{1}{n} \displaystyle \sum_{i = 1}^{n} x_{i}$

```
$\bar{x} =  \dfrac{1}{n} \displaystyle \sum_{i = 1}^{n} x_{i}$
```

### 分散
$　s^{2} =\dfrac{1}{n} \displaystyle \sum_{i = 1}^{n} \left(  x_{i} - \bar{x} \right)^{2} $

```
$　s^{2} =\dfrac{1}{n} \displaystyle \sum_{i = 1}^{n} \left(  x_{i} - \bar{x} \right)^{2} $
```
### 標準偏差
$　\sigma =　 \sqrt {s}$

```
$　\sigma =　 \sqrt {s}$
```

### 変動係数
$　C.V = \dfrac {\sigma}{\bar{x}} $
```
$　C.V = \dfrac {\sigma}{\bar{x}} $
```

### 相関係数
$ 
r = \dfrac{ \displaystyle 
\sum_{i = 1}^{n} \left(  x_{i} - \bar{x} \right) \left(  y_{i} - \bar{y} \right)} 
{\sqrt {\displaystyle \sum_{i = 1}^{n} \left(  x_{i} - \bar{x} \right)^{2} }
{\sqrt {\displaystyle \sum_{i = 1}^{n} \left(  y_{i} - \bar{y} \right)^{2} }
}}
$

```
$ 
r = \dfrac{ \displaystyle 
\sum_{i = 1}^{n} \left(  x_{i} - \bar{x} \right) \left(  y_{i} - \bar{y} \right)} 
{\sqrt {\displaystyle \sum_{i = 1}^{n} \left(  x_{i} - \bar{x} \right)^{2} }
{\sqrt {\displaystyle \sum_{i = 1}^{n} \left(  y_{i} - \bar{y} \right)^{2} }
}}
$

```

### 共分散
$ 
S_{xy} =   \dfrac{1}{n} \displaystyle 
\sum_{i = 1}^{n} \left(  x_{i} - \bar{x} \right) \left(  y_{i} - \bar{y} \right)
$ 
```
$ 
S_{xy} =   \dfrac{1}{n} \displaystyle 
\sum_{i = 1}^{n} \left(  x_{i} - \bar{x} \right) \left(  y_{i} - \bar{y} \right)
$ 
```

### 標準化
$ 
z = \dfrac{Z - \mu }{\sigma}
$ 

```
$ 
z = \dfrac{Z - \mu }{\sigma}
$ 
```
### 偏差値

$ 
T = 10 \times \dfrac{Z - \mu }{\sigma} + 50
$ 

```
$ 
T = 10 \times \dfrac{Z - \mu }{\sigma} + 50
$ 
```

# まとめ
ひとまず、よく利用しそうな統計量の数式を挙げてみました。
ブログなどで利用する場合、自由にコピペして使ってみてください。
要望や、修正・加筆等があれば適宜変更を加えていこうと思っています。

# 参照
■統計Web
<a href="https://bellcurve.jp/statistics/course/" target="_blank">https://bellcurve.jp/statistics/course/</a>

■これで完璧 Qiitaでの数式記法（統計学対応）
<a href="https://qiita.com/DeepTama/items/85470a66972432e14224" target="_blank">https://qiita.com/DeepTama/items/85470a66972432e14224</a>
TablePlusでSQLdumpをimportするときにprismaのenumでエラーになる解決方法

## はじめに

stg環境などで不具合が発生した場合、その原因をlocal環境で調査するために、該当環境のデータベース全体をダンプし、local環境へインポートすることが必要になるケースがあります。

しかし、Prismaで enum を使用している場合、TablePlusなどのGUIツールを使ったエクスポート → インポートでは正常に動作しないことがありました。

```ts
enum Weekday {
  MONDAY
  TUESDAY
  WEDNESDAY
  THURSDAY
  FRIDAY
  SATURDAY
  SUNDAY
}
```

```bash
ERROR:  type "_weekday" does not exist
LINE 75:     "business_days" _Weekday DEFAULT ARRAY[]::"Weekday"[],
```

この問題への対応策として、以下の2つの方法が考えられます：

- SQLを直接修正する
- PostgreSQLのコマンドを使用してダンプを取得する

今回は、 後者のPostgreSQLのコマンドを使用してデータをダンプし、それをlocal環境へインポートする方法を選択しました。
以下に、その具体的な手順を記載します。


## 環境

- macOS Sonoma 14.3.1
- PostgreSQL 15.10

## 手順

### 1. PostgreSQLのインストール

```bash
# PostgreSQLのインストール
$ brew install postgresql@15

# PATHの設定（M1/M2 Mac用）
$ echo 'export PATH="/opt/homebrew/opt/postgresql@15/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
```



### 2. データベースのfull dump取得

`password`にはデータベースのパスワードを入れてください。
また、実際のコマンドに`[]`は不要です。

```bash
PGPASSWORD="password" pg_dump \
  --clean \
  --if-exists \
  --no-owner \
  --inserts \
  --no-tablespaces \
  --no-acl 
  "postgresql://[username]@[hostname]/[database]?sslmode=require" > full_dump.sql
```

## オプションの説明（ref: [pg_dump](https://www.postgresql.jp/docs/9.4/app-pgdump.html)）

- `--clean`: データベースオブジェクトを作成するコマンドの前に、データベースオブジェクトを整理（削除）するコマンドを書き出します。 （--if-existsも指定されなければ、リストア先のデータベースの中に存在しないオブジェクトがある場合に、害がないエラーがいくつか発生するかもしれません。）
- `--if-exists`: データベースオブジェクトを初期化するときに、条件コマンドを使います(つまり、IF EXISTS句を追加します)。 
- `--no-owner`: オブジェクトの所有権を元のデータベースにマッチさせるためのコマンドを出力しません。 デフォルトでは、pg_dumpは、ALTER OWNER文またはSET SESSION AUTHORIZATION文を発行して、作成したデータベースオブジェクトの所有権を設定します。
- `--inserts`: データを（COPYではなく）INSERTコマンドの形式でダンプします。 これを行うとリストアに非常に時間がかかります。 主にPostgreSQL以外のデータベースへロード可能なダンプを作成する時に有用です。 しかし、このオプションは各行に対して別々のコマンドを生成しますので、一行を再ロードする時にエラーになったとしても、テーブルの内容まるごと失われることなく、一行のみが失われるだけですみます。 列の順序を変更した場合はリストアが失敗する可能性があることに注意してください。 --column-insertsはさらに処理が遅くなりますが、列の順序変更に対して安全です。
- `--no-tablespaces`: テーブル空間を選択するコマンドを出力しません。 このオプションを使用すると、すべてのオブジェクトはリストア時のデフォルトのテーブル空間の中に作成されます。
- `--no-acl`: アクセス権限（grant/revokeコマンド）のダンプを抑制します。（これがないとERROR: role "neon_superuser" does not existになります）

### 3. インポート

TablePlusなどでGUIから取得したfull_dump.sqlをインポートすれば完了です。

## まとめ

Neon.techのPostgreSQLからダンプを取得する際は

1. `pg_dump`を使用する
2. 必要なオプションを指定してダンプを実行

## 📚 参考リンク

- [pg_dump](https://www.postgresql.jp/docs/9.4/app-pgdump.html)
MLflowのモデル管理を学ぼう section2: Migrating from Stages

MLflowでは MLflow2.9.0 (December 6, 2023)から Stageを非推奨にしているようです。
Stageとは Modelの開発・テスト・本番かどうかを表すためのタグのようなものです。つまりはモデルのライフサイクル管理ですね。
https://mlflow.org/docs/latest/model-registry.html#migrating-from-stages
この件に関して全然知らなかったので、これを学んでいこうと思います。（1年以上前の変更ではありますが）
基本的に本記事は公式ドキュメントの読解と意訳的な立ち位置です。

# 今までのモデル管理とは
今まではモデルのライフサイクルを stageで管理してきました。
以下の画像通りですね。
![スクリーンショット 2025-01-28 23.44.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256764/c5e8e2f9-9089-ec99-e463-9d3103dd6536.png)

さらには Model version tagsと　Model version aliasesも実装されており、これらを活用してモデル管理をより柔軟にできますとのことです。

![スクリーンショット 2025-01-28 23.47.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256764/18ad4785-fbb1-235b-0ad0-ddbd5b96b439.png)


tagはモデル検索に利用できます。
例えば以下のコードを利用するとModel registoryに管理されているモデルのtags.validation_status = 'passed'だけ検索できます。
```python
model_name = "IrisLinearRegressionModel"
versions = client.search_model_versions(f"name='{model_name}' and tags.validation_status = 'passed'")
```
また、公式ドキュメントからの抜粋ですが、 aliasは指定のモデルを呼び出す時にも便利です。
`get_model_version_by_alias()` client API or the model URI `models:/<registered model name>@champion` で呼び出すことができるので、コードはchampionに固めておいて、モデル管理だけUIからの変更やモデル管理を実現したパイプラインで変えておけば良いのでとても便利です。

（個人的にはその上で使える機能が多すぎてどう使えば良いかまだ悩みますが）

# 今後のモデル管理とは(Migrating models away from stages
)
一つ目と二つ目は環境（dev,staging,prod)に関して如何にモデルを分けるかが書かれていましたが、それよりも三つ目のsection、「aliasを使ってバージョン管理を推奨する。」この点が一番大切だと思ったので、これを書きたいと思います。
一番のポイントは今まで
`models:/regression_model/Production` でproductionモデルを読み込んでいた箇所を `models:/prod.ml_team.regression_model@champion` に変えようということですね。
(models:<env>のenvは、開発環境と依存関係にあります。そして複数環境のモデルをcross environementで使う可能性があるので、自身でprefixとして prod.ml_teamとか付けてねってことみたいです。)

これは実際に触ってみてもう一つ嬉しいこともありました。今までstageは複数のモデルバージョンに対して productionを設定できてしまいました。しかしaliasは一つのモデルレジストリに対して一つのバージョンにしか設定できないようです。これは正しいより正しい管理が可能になりますね。
![スクリーンショット 2025-01-29 0.12.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256764/d40ff0f3-4fe9-95ab-0c26-cc4553ddc475.png)
![スクリーンショット 2025-01-29 0.13.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256764/7f41ffab-9390-622b-080e-b81461e58ba2.png)

> The "champion" alias is also being used on version 8. Adding it to this version will remove it from version 8.

# まとめ
- stageは無くなるのでaliasで管理しよう
- cross environmentsに備えて prod等自分でmodel名のprefixにしてね
Next.js + Vercelでサブドメインを設定してデプロイする方法

# はじめに
Next.jsで開発したwebアプリをVercelでデプロイしており、URLはVercelから付与される`xxxx.vercel.app`のようなデフォルトのURLだとします。

この`xxxx.vercel.app`で公開されているURLから、自分で持っている独自ドメインから作った**サブドメイン**を割り当てる方法を記録します。

なので、`moteasobu.jp`というドメインがあるとして
`indofullness.moteasobu.jp`というサブドメインを作りVercelでデプロイする、ということですね。

# 環境
ホスティング環境はSquarespace

https://support.squarespace.com/hc/ja-jp/articles/205812058-Squarespace%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AE%E3%82%B5%E3%83%96%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B?platform=v6&websiteId=6671a6569e521b54dffed302#toc---------------

☝️のサポートページを参考にやっていきます

## ドメインについて


# Vercelでサブドメインを設定
ではやっていきましょう。ホスティングサービスによって変わる部分もあるでしょうが、大体の流れは同じかと。
## Vercel側の設定
![Screenshot 2025-02-17 at 20.06.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/218af986-070d-4405-9b81-7f3e7f1b2d5f.png)
Settings→Domainsセクションに移動する。

使用したいサブドメインを入力して（例：app.example.com）、「Add Domain」ボタンをクリックする。

![Screenshot 2025-02-17 at 14.29.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/ed344d14-ff6a-43d8-b295-4c9a1424f88f.png)

これでVercel側の設定は終わり。

## ドメイン登録業者側のDNSの設定
Squarespaceを使っているので、いかに沿ってやっていきます。

https://support.squarespace.com/hc/ja-jp/articles/205812058-Squarespace%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AE%E3%82%B5%E3%83%96%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B?platform=v6&websiteId=6671a6569e521b54dffed302#toc---------------

>ドメイン ダ⁠ッシ⁠ュボ⁠ードを開きます⁠。
編集するドメインをクリ⁠ックします⁠。
[⁠DNS⁠] をクリ⁠ックします⁠。
[⁠カスタム レコ⁠ード⁠] まで下にスクロ⁠ールし⁠、[⁠レコ⁠ードを追加⁠] をクリ⁠ックします⁠。
[⁠ホスト⁠] フ⁠ィ⁠ールドにサブドメインを入力します⁠。たとえば⁠、完全なサブドメインが「⁠blog⁠.yourdomain⁠.com⁠」の場合⁠、「⁠blog⁠」と入力します⁠。
[⁠デ⁠ータ⁠] フ⁠ィ⁠ールドに「⁠ext-sq⁠.squarespace⁠.com⁠」と入力します⁠。
[⁠保存⁠] をクリ⁠ックします⁠。

カスタム レコ⁠ードを追加します。

![Screenshot 2025-02-17 at 21.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/09f19fa9-bcec-49ae-885e-a3fa39cfc116.png)
![Screenshot 2025-02-17 at 21.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/ff835d91-78d8-443a-9d00-67a0a633b8b1.png)

こんな感じで各値の名称は以下のようになってます。
左がSquarespaceの管理画面
右がVercelの管理画面

```
ホスト = Name
タイプ = CNAME
データ = VALUE
```
 ![Screenshot 2025-02-17 at 20.41.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/e7c7d5e6-c76d-4d16-a048-933aad66fe46.png)

これでカスタム レコ⁠ードを追加して保存します。
数分から数時間待てば完了です！


Next.js + Vercelでサブドメインを設定してデプロイすることができました！

https://indofullness.moteasobu.jp/
AtCoder ABC393 振り返り感想戦(緑コーダーがPythonでABCD問題)

## ABC 393感想まとめ

[AtCoder Beginner Contest 393 - AtCoder](https://atcoder.jp/contests/abc393)

ABCまで3問解答でした。Cまで20分を切っており(自分としては早いペース)、D問題は時間がたっぷりあったのだけどTLE解法しか思い浮かばず。

先週のABC392は用事のためお休みで、2週ぶりの参加となりました。14日間、問題を解いたりしていなかったのが良くなかったのかもしれません。

## [A - Poisonous Oyster](https://atcoder.jp/contests/abc393/tasks/abc393_a)

牡蠣にあたってしまう問題。この季節、切実な問題ですね。牡蠣は食べたいが、当たりたくはない...。

4パターンをifで場合分けしました。

``` python
S1, S2 = input().split()

if S1 == 'sick' and S2 == 'sick':
    print(1)
    exit()
if S1 == 'sick' and S2 == 'fine':
    print(2)
    exit()
if S1 == 'fine' and S2 == 'sick':
    print(3)
    exit()
if S1 == 'fine' and S2 == 'fine':
    print(4)
    exit()
```

## [B - A..B..C](https://atcoder.jp/contests/abc393/tasks/abc393_b)

文字列の中から、A..B..C が何個あるかを求める問題。
先頭から一文字ずつAを探していきます。もしAだったら文字間隔を[0, 1, 2...]と増やして[A..B..C]かどうかを探す、全探索です。

``` python 
S = list(input())

count = 0
for i in range(len(S)):
    # 文字が 'A' なら、B/Cを探索
    if S[i] == 'A':
        # 文字の間隔を d とする
        for d in range(1, 100):
            if i + d * 2 < len(S):
                # 'B' と 'C' が等間隔にあるか判定
                if S[i + d] == 'B' and S[i + d * 2] == 'C':
                    count += 1
            else:
                break

print(count)
```

## [C - Make it Simple](https://atcoder.jp/contests/abc393/tasks/abc393_c)

グラフの問題。
問題を要約すると、重複している経路、自己参照している経路の数を数えればokです。


``` python 
N, M = map(int, input().split())

line_dict = defaultdict(set) # a -> b の経路を保持する

same_count = 0 # 自己参照している経路の数
exist_count = 0 # 重複している経路の数
for i in range(M):
    a, b = map(int, input().split())

    # a == b のときは自己参照なので削除対象
    if a == b:
        same_count += 1
        continue

    # もし、a -> b への経路がすでにあれば、削除対象
    if a > b:
        a, b = b, a
    if b in line_dict[a]:
        exist_count += 1

    line_dict[a].add(b)

print(same_count + exist_count)
```

## [D - Swap to Gather](https://atcoder.jp/contests/abc393/tasks/abc393_d) [解説AC] 

これはコンテスト中には解けず、解説のYouTubeを見て復習しました。

https://www.youtube.com/live/RLCWqyDaZU4?si=aC5xS-vWfB1i3cI4


* 1の位置を記録する数列を求める
* 上記数列から、i番目の1の位置から i を引くことで、
    * [j, j+1 .... j+k] に1を集める という問題を、[j] に k 個の 1を集める に言い換えることができる
* 中央値の位置に 1 を集めるときが、最小になる

など、いろいろな考察テクニックが紹介されていました。

これは、アルゴリズムをそのまま使うというよりは、考察が必要な問題でしたね...。類似の過去問をやっていると、楽になったかもしれません。

::: note info
解説動画が大変参考になりました:bow_tone1:
:::

``` python
N = int(input())
S = list(input())

# 1の位置を取得
one_positions = []
for i, s in enumerate(S):
    if s == "1":
        one_positions.append(i)

# 1の位置をから0, -1, -2, ... を引く
# これにより、移動後の各点の位置を一点に集めることができる
for i in range(len(one_positions)):
    one_positions[i] -= i

# 1の位置の中央値
med = len(one_positions) // 2

# 中央値に集めるための移動回数を計算
answer = 0
for i in range(len(one_positions)):
    answer += abs(one_positions[i] - one_positions[med])

print(answer)
```
【LeetCode】11. Container With Most Water 解いてみた【Medium】

<!--quiita leet code テンプレ-->

<!--

## 技術記事のタイトル

【LeetCode】〇〇 解いてみた【Medium】

### 【 】(墨付き括弧)

タグ

LeetCode 競技プログラミング Python 

-->

## 問題の概要
![スクリーンショット 2025-02-12 21.11.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3913183/80f71a2c-28bd-4cef-89d7-14fb2698d2d7.png)
2つの棒で作れる最大の長方形の面積を求める
幅はインデックスの

Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49


## 最初に考えた解き方
・左右にポインターを配置
・値が小さい方を高さとして面積を計算。それをスタックと比較して大きいなら格納
・値が小さい方のポインターを内側へ。（それ以上大きい幅になることはないので）
・l>=rになったら終了

両方同じなら？？
＞どっちでもいのでは

わかりそうでわからない


## 何がよくなかったか？

面積を幅＊高さで考えようとしていたが、各インデックスごとに幅は考慮せずに高さだけ足していけば解決できたと思う


## 解き方

### 左右のマックスの低い方より低い分だけ水を入れれる

```
class Solution:
    def trap(self, height: List[int]) -> int:
        if not height:
            return 0

        l, r = 0, len(height) - 1
        leftMax, rightMax = height[l], height[r]
        res = 0
        while l < r:
            if leftMax < rightMax:
                l += 1
                leftMax = max(leftMax, height[l])
                res += leftMax - height[l]
            else:
                r -= 1
                rightMax = max(rightMax, height[r])
                res += rightMax - height[r]
        return res
```



#### 簡単に見えてしまうのが怖い

考え方がスマートすぎる
頭が上がらない


## 参考資料

https://leetcode.com/problems/trapping-rain-water/description/

## おわりに

すぐ近くに答えはあったりする。
今の考えを少し捻ったらどうなる？？
【C++】vectorへのアクセス「operator[]」と「at()」の違いついてChatGPTに聞いてみた

# 目的
C++においてstringやvector<T>などの要素へのアクセス方法「operator[]」と「at()」の違いについてChatGPTに聞いてみた。その備忘録として残す。

# 違い
主な違いは以下の3つである。
- 境界値チェック
- 実行速度
- 用法

詳しく見ていく。

| | operator[] | at() |
| :-: | --- | --- |
| 境界値チェック | インデックス範囲外は未定義動作<br>境界値チェックはしていない | インデックス範囲外アクセスの場合、"std::out_of_range"の例外をスローする。 |
| 実行速度 | at()より速い | operator[]より遅い |
| 用法 | パフォーマンス重視 | エラー処理が必要 |

ChatGPTさん曰く、実行速度に関してはエラーチェックの有無で変わるらしい。
また、用法に関してはoperator[]アクセスは競プロなどでよく見かける気がする。
ただ、どちらでアクセスするについても、事前にifで範囲確認行うのが無難であろう。
bashの配列

<h2>bashの配列</h2>

<h3>bashで配列ってすごく難しい。javaで配列のほうが全然簡単。いや、シェルで配列って文法的含めすごーくややこしい。</h3>


```
#!/bin/bash

while read line

do

if [[ -z $line ]]
then
  arr=$arr","
  continue

fi

arr=$arr$line

done < xyq.txt

echo ${arr[@]}

```

```
aaa
bbb
ccc

ddd
eee
fff

ggg
hhh
iii

```

<h3>日々向上と学習ですね</h3>
[AWS #38] AWS Trusted Advisor

<!--
 <font color="c00000"></font> 赤
-->
## はじめに
お疲れ様です。:computer:
今回は検出サービス分野にある<font color="c00000">**「AWS Trusted Advisor」**</font>について見ていきたいと思います。


## AWS Trusted Advisor
Trusted Advisorは**AWSの環境を検査**し、 <font color="c00000">**「AWSのベストプラクティス」**</font>に基づいてリアルタイムでレコメンデーションを提供してくれるWebサービスになります。

:upside_down: ユーザーの**AWSアカウント環境の状態を自動でチェック**してくれます。「ベストプラクティスに対してどうだったか」「どうすればより良くなる」と言った <font color="c00000">**アドバイスをレポート**</font>してくれます。

:::note info
レコメンデーション　➡　**「おすすめ」や、「推奨」** の意味をする単語です。
:::

## 5つの柱
Trusted Advisorには5つの柱に基づいてリソースを評価します。

・**コストの最適化**
・**パフォーマンス**
・**セキュリティ**
・**耐障害性（フォールトトレランス）**
・**サービスの制限**
この上記５つが柱となります。

### コストの最適化
コストの最適化では、 <font color="c00000">**「ここを見直せばコストを最適化できる」**</font>という視点でチェックしたアドバイスがレポートされます。具体的に**月額のコストがどのくらい下がるか**という金額も計算されて表示されます。**「無駄なコストが発生していないか」** がチェックされるということですね。

### パフォーマンス
システム内で**パフォーマンスを低下させてしまう原因**はいくつかあり、その原因となる <font color="c00000">**設定や選択がされていないかがチェック**</font>されます。コスト最適化とは逆に、使用率の高いインスタンスを確認します。例えばEC2に実装している処理に対してリソースが不足しているという可能性があります。そう言った場合は対象の処理が最も早く完了するインスタンスタイプに変更することがAdvisorから推奨されます。

### セキュリティ
この柱は <font color="c00000">**セキュリティのある状態になっていないか**</font>を確認します。例えばバックアップのスナップショットではEBSやRDSのスナップショットは他の特定のアカウントへの共有もできます。さらに、アカウントを特定せずに公開共有することも可能です（パブリック状態）。**必要なアカウント間のみで共有**することもが大切です。

:keyboard: AWS環境に**リスクのある設定が無いか**がチェックされるということですね。

### 耐障害性（フォールトトレランス）
こちらは**耐障害性が低い状態でないかどうか**をチェック、 <font color="c00000">**耐障害性を高めるためのアドバイスを提供**</font>します。

主な項目として、**「EBSのスナップショット」** や **「RDSのマルチAZ配置」** があります。「EBSのスナップショット」ではスナップショットが作成されていない、または最後に作成されてから時間が経過していることがチェックされます。「RDSのマルチAZ配置」は「マルチAZ配置」になっていないデータベースインスタンスがチェックされ、ユーザーに通知が行きます。

### サービスの制限
**「サービスクォータ」** とも言います。
AWSアカウントに作成できる**リソースの最大数**のことになります。このサービスクォータの約80%以上を使用するとユーザーに対して**アラートが来る**ように設定されています。

:upside_down: 誤ってしまい過剰な操作による意図しない請求や、不正アクセスによる意図しない請求なども回避ができます

## おわりに
今回のちょっとしたまとめになります。

:::note info
**Trusted AdvisorはAWS環境を自動でチェック**し、 <font color="c00000">**ベストプラクティスに沿ったアドバイスをレポート**</font>してくれます
:::

:::note info
**「コスト最適」** では**無駄なコストが発生していないか**がチェックされます
:::

:::note info
**「パフォーマンス」** では**最適なサービス、サイズが選択されているか**がチェックされます
:::

:::note info
**「セキュリティ」** では、**環境にリスクのある設定がないか**がチェックされます
:::

:::note info
**「耐障害性」** では、**耐障害性の低い状態が無いか**がチェックされます
:::

:::note info
**「サービスの制限」** では、**制限に近づいてきたサービスが警告（アラート）としてユーザーに通知**されます
:::

最後までお読みいただきありがとうございました！
>>**日頃より活用している参考書です。**
>> **「参考書」**
[**AWS認定クラウドプラクティショナー改定第3版（AWS Trusted Advisorは332ページ）**](https://x.gd/19i6N)
>

> **「AWS公式サイト」**
[**AWS Trusted Advisor**](https://aws.amazon.com/jp/premiumsupport/technology/trusted-advisor/)

> **「Youtube」**
[**【AWS Trusted Advisor】ソリューションアーキテクト アソシエイト(SAA) 第38回講座**](https://www.youtube.com/watch?v=hadye-MNxWo)
>
[Nestjs × Docker] prisma ORM で migration するときに躓いた話

**「それでも、と言い続けろ」**
マリーダクルスの言い付けを守り続けています。

1. 朝起きたけどクソ寒いとき
2. ベンチプレスで潰れそうなとき
3. 有酸素運動が憂鬱なとき
4. エラーが全く直らないとき
6. エヴァの時短駆け抜けたとき
7. タバコ、エナジードリンクの誘惑に負けそうなとき

自分に負けそうなときでも、マリーダさんの言い付けを思い出し、自分を奮い立たせています。
そう、僕はユニコーンガンダムのパイロットなのです。

## Docker × NestJSでデータベース環境(postgres)を作りたい！
いろいろ省きますが、僕は現在docker上でNestJS環境を構築し、開発を進めています。
僕は普段Laravelを利用しているので、NestJSを使うのはワクワクしています。
また、データベースも普段はMySQLを利用していたので、勉強の意味も兼ねてpostgres環境でやろうと思いました。

セットアップやパッケージのインストール等は省きます。
ちなみにパッケージはprismaを利用しています。
以下の公式ドキュメントを参考にしてください。(マイグレーションのNestJS公式ドキュメント)
https://docs.nestjs.com/recipes/prisma#create-two-database-tables-with-prisma-migrate

NestJS、データベースの環境は以下です。
docker.compose.yml
```
db:
    image: postgres:latest
    environment:
      POSTGRES_USER: jony_newtype
      POSTGRES_PASSWORD: password
      POSTGRES_DB: app_database
    volumes:
      - postgres_volume:/var/lib/postgresql/data
      - ./docker/postgres/script:/docker-entrypoint-initdb.d
      - ./docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf
    ports:
      - '5432:5432'
    networks:
      - app-networks

nestjs:
    build:
      context: ./api
      dockerfile: Dockerfile
    volumes:
      - ./api/nest-api:/app
    ports:
      - '3000:3000'
    networks:
      - app-networks

networks:
  app-networks:
    driver: bridge

volumes:
  postgres_volume:
```

他にもコンテナはありますが、省いています。
まずここで注目してほしいのが同じnetworkに乗せているということです。

:::note alert
バックエンドのコンテナとデータベースのコンテナが同じnetworkに乗っていないと、データベースのホスト名を識別できず、直接通信ができない
:::

次にバックエンド側のマイグレーション関連のファイルです。
主に以下のファイルが重要です。
・schema.prisma
・.env

最初にschema.prisma
```
generator client {
  	provider = "prisma-client-js"
}

datasource db {
  	provider = "postgresql"
  	url      = env("DATABASE_URL")
}

----これより下にテーブル仕様
```

次に.env
```
DATABASE_URL="postgresql://jony_newtype:password@db:5432/app_database?schema=newtype"
DATABASE_USER=jony_newtype
DATABASE_PASSWORD=password
DB_HOST=db
```
.env側からユーザやパスワードを環境変数に代入する必要があるのは言うまでもありませんが、ここで注目してほしいのはschemaとDB_HOSTという変数です。

僕はこれまでデータベースのschemaという概念を理解できていませんでした。
これはデータベースとテーブルの間にあるレイヤーです。
これを間違っていたため、マイグレーションが許されませんでした。

またDB_HOSTの環境変数についてですが、

:::note warn
これを代入しないと、URL上でコンテナ名であるデータベースホストを識別してくれません。
:::
僕の場合はこの"db"はコンテナのサービス名です。
データベースのエンドポイントを示すために必要な記述ですが、DB_HOSTに代入しないとただのよくわからん文字列と判別されてしまうようです。

## 終わり
NestJSで開発を進めていますが、結構楽しいです。
僕はNestJSのロゴと色が大好きです。
zipに圧縮してダウンロード

# はじめに
複数のファイルをzipでダウンロードしたいという要望がありました。
C#で開発していたこともあり、「ZipArchive」を使ってみました。

# 導入
参照に「System.IO.Compression」を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/838220d6-c83b-4ccf-8c95-1b839b89f6ba.png)

# コード
### usingディレクティブ
```c#
using System.IO.Compression;
```
を追加します。

### zip圧縮
MemoryStream内で処理（ClosedXmlを使ったサンプル）
```c#
byte[] ret;
using (var ms = new MemoryStream())
{
    using (var zip = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        for (int i = 0; i < 5; i++)
        {
            // テンプレートファイルを読み込み
            using (var workbook = new XLWorkbook(@".\template\テンプレート.xlsx"))
            {
                // ブックを加工
                // …
                // ブックをstream変換
                using (var msBook = new MemoryStream())
                {
                    workbook.SaveAs(msBook);
                    byte[] retBook = msBook.ToArray();

                    using (Stream stream = zip.CreateEntry(i.ToString("0000") + ".xlsx", CompressionLevel.Optimal).Open())
                    {
                        stream.Write(retBook, 0, retBook.Length);
                    }
                }
            }
        }
    }
    ret = ms.ToArray();
}
```

上記の「ret」を送信してダウンロードさせる
```c#
public ActionResult DownloadExcel3()
{
    // 上記の「ret」を返却
    return File(ret, "application/octet-stream", "XXX.zip");
}
```