OmniAICreator/Qiita-1.07M huggingface dataset:
【生成AI】Youtubeの動画を視聴せずにAIに要約させる。

# Step1 拡張機能のDL
https://chromewebstore.google.com/detail/youtube-transcriber-and-s/dhjiababgkcfbglanikgepmmdelngfon

# Step2 Youtubeの動画見たら自動的に追加される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575047/83c055f9-d955-4d52-9a4d-83f1c80c2903.png)

# Step3 Transcribe videoをクリックしてコピーボタンを押す！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575047/6afebc43-cca2-4047-9257-c568be0d7118.png)

# chagptに投げて要約してもらう！

https://chatgpt.com/
Spring Boot 3 + JPA + PostgreSQLでjsonb型のカラムにinsertする方法

# 前提条件
前提とする環境のデータベースのテーブルを確認していきます。
## 環境
Spring Boot ver 3.3.1
gradle
kotlin
jdk 21
psql (PostgreSQL) 14.16

## データベース
```sql
CREATE TABLE IF NOT EXISTS SAMPLE_TABLE (
    id SERIAL PRIMARY KEY,
    json_data JSONB NOT NULL
);
```
Spring BootとPostgreSQLサーバーが接続されていることは`psql`等を用いてデータベースにデータを入れた状態で JPA の`.findeAll()`等を用いて事前に確認してください。
# サンプルコード

## build.gradle.kts

必要なdependenciesを追加

```kotlin name=build.gradle.kts
dependencies {
    // jsonb型を設定するために必要
    // hypersistence-utils-hibernateを60にするかどうかは自身の環境に合わせる
	implementation "io.hypersistence:hypersistence-utils-hibernate-60:3.5.2"
}
```

## SampleEntity.kt

```kotlin name=SampleEntity.kt
import io.hypersistence.utils.hibernate.type.json.JsonType
import jakarta.persistence.*
import org.hibernate.annotations.Type

@Entity
@Table(name = "SAMPLE_TABLE")
data class SampleEntity(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    val id: Long?,

    // @Typeを宣言することでStringをJsonに変換してくれる
    @Type(JsonType::class)
    // columnDefinition で jsonb を指定
    @Column(name = "json_data", columnDefinition = "jsonb")
    val jsonData: String
){
    // 引数なしのコンストラクタを追加
    constructor() : this(null,  "")
}
```

## SampleRepository.kt

```kotlin name=SampleRepository.kt
import com.sample.SampleEntity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface SampleRepository : JpaRepository<SampleEntity, Long>
```

## SampleService.kt

```kotlin name=SampleService.kt
            val entity = SampleEntity(
                //jsonをstringに直してから渡す
                jsonData = "{\"name\":\"dummyName\"}"
            )
            val savedEntity = sampleEntityRepository.save(entity)
```
ollamaが見えない時、どうするか

# この文書の目的
## 想定する読者
 この文書は次のような人向けのメモです。
1. 手持ちのパソコンにLinuxをインストールして、生成AIを試してみようと思っている人。
2. 生成AIサービスはどけだけ課金されるかわからないので、手持ちのLinuxマシンにollamaを入れてみた人。
3. Linuxはインストールして使ってみているぐらいで、初心者。
　私はネットワークにはあまり興味が無く誤り・誤解があるかも知りません。間違いがあれば教えて頂けると幸いです。
## 何を解決するか
　Linuxマシンにollamaとdiffyを入れてみたけど、difyにollamaを登録できない問題を解決するヒントです。
# ollamaの動作環境など
## OSなどの概略
　今回は次のようなマシンです。
1. Dell Precision 3420らしいワークステーション（Xeonに主記憶40ギガバイト、Quadro P400）
1. OSはkubutnu 22.04LTS（最新パッチまで適用）
　要するにサブマシンで生成AI実験機を組み立てたわけですね。
　このマシンは自宅内LANに接続され、インターネットとは隔離されています。 
## ollamaのどのようにインストールしたか
　[公式サイトの手順]( https://github.com/ollama/ollama/blob/main/docs/linux.md )どおりにインストールしています。
  次のコマンドでインストールですね。
```
curl -fsSL https://ollama.com/install.sh | sh
```
 　インストールしたらコマンドプロンプトで動作確認します。
 　最初はphi4など準備されているLLMを動かして動作することを確認したほうがよいです。
 　私はphi4を動かした後、chromiumで`http://localhost:11434` にアクセスし`Ollama is running`と表示されネットワーク経由で通信できることを確認しました（これが落とし穴）。
## difyのインストール
　こちらは事前にdockerとdosker-composeをパッケージからインストールしてから、[公式サイトの手順](  https://docs.dify.ai/getting-started/install-self-hosted/docker-compose )どおりにインストールしています。
```
git clone https://github.com/langgenius/dify.git --branch 0.15.3
```
　次にマニュアルに従いローカルマシンにWebブラウザでアクセスし、インストールプログラムを実行すると難なくdifyが動きます。
## ollamaが登録できない
　さて、ここまで来たらdifyでチャットポットを作ろうか、と設定からモデルプロバイダーをクリックし、マニュアルを参考にモデルプロバイダーのアドレス（次の図の赤枠にdockerから見えるネットワークなど）を指定したのですが、どうしてもサービスが見つからず登録ボタンが有効にならないのでした。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347462/15cfe219-0150-4fee-b6af-dc0228ce3919.png)
# チェックポイントと対策
　IPアドレスとポート番号を指定してアクセスできているので、最初、ファイアーウォールを疑いました。
　kubuntuはufwがインストールされていますが、状態を確認すると、そもそもファイアーウォールが有効になっていない。
  何か他のセキュリティソフトで通信が遮断されている可能性も疑い、30分ほどネットワーク関係の設定を確認したのですが・・。
  ふと、ollama自体が外部からの接続を待っているのか、と思い調べたところlocalhostからの通信のみ待っている状態でした。

## ollamaの設定変更
　設定ファイルは`/etc/systemd/system/ollama.service`です。
　こちらの記事(ollamaセットアップのメモランダム)
 
 https://qiita.com/hanaya/items/e55de1e80a04469484fd
 
 を参考に次のように通信を行うネットワークを指定します。　
```
Environment="OLLAMA_HOST=0.0.0.0"
Environment="OLLAMA_ORIGINS=192.168.*,172.*"
```
　サービスを再起動するか、システムを再起動すると無事にollamaのサービスが見えるようになり追加できるようになります。
　[ollamaのFAQ]( https://github.com/ollama/ollama/blob/main/docs/faq.md )では以下の部分に記述されています。
> Ollama binds 127.0.0.1 port 11434 by default. 
> Change the bind address with the OLLAMA_HOST environment variable.
> Refer to the section above for how to set environment variables on your platform.

 意味としてはOLLAMA_HOSTで「全てのネットワークインターフェースからのアクセスを受け付ける」、OLLAMA_ORIGINSでアクセスするネットワークを制限するという意味のようです。ちなみに自宅LNAは192.168.*はクラスCのネットワークとして構成しているため、172.*はdockerのために指定しています。
## 原因
　同じマシン上にあっても、直接インストールしたプログラムとdocker環境にあるdifyは環境が分けられるため、異なるマシンのようになります。
　このためLinuxマシンの環境からlocalhostでアクセスできても、docker環境からは別のマシンとして指定する必要があるのでした。

# まとめ
　これでdocker環境上のdifyからollamaにアクセスできるようになりました。
　さらに同じネットワーク上のマシンからもアクセスできます。
　サーバー構築のためのネットワーク構成の知識が必要だと思い知りました。
AlreadyRunningエラーでUbuntuにログインできないときの対処法


## Google Chrome Remote Desktop の削除方法と GUI の復旧手順
### 1. セッションの停止

まず、Ctr+Alt+F2キーでCUI環境に変更し、エラーが発生しているユーザーでログインします。
その後、エラーを発生しているユーザーが実行しているセッションをすべて停止します。
```
sudo pkill -KILL -u <username>
```

### 2. リモートデスクトップ の削除

次に、リモートデスクトップアプリ を完全に削除します。

```bash
sudo apt-get remove --purge chrome-remote-desktop
```

### 3. 関連ファイルの削除

以下のコマンドで関連ファイルも削除してください。

```bash
sudo rm -rf ~/.config/chrome-remote-desktop
```

### 4. 再起動

コンピュータを再起動して、正常にログインできることを確認します。

```bash
sudo shutdown -r now
```

### まとめ

1. CUI環境でセッションを停止する
2. アプリケーションを削除する
3. 関連ファイルを消去する
4. 再起動する
【2025年最新版】誰でも簡単にOSSコントリビュートをする方法！

### そもそもOSSコントリビュートって何？
<details><summary>OSSコミットメントに関する説明（トグルになってます。）</summary>
オープンソースソフトウェア（OSS）プロジェクトに対して、コードの追加や修正、ドキュメントの改善などの貢献をすること。

- コードの貢献（新機能の追加や既存コードの最適化など）
- ドキュメントの改善（誤字脱字、ユーザーが理解しやすい説明文の提案など）
- バグ報告や提案（バグや問題点をレポートするなど）
</details>



### 今回お世話になるリポジトリ

https://github.com/first-contributions-ja/first-contributions-ja.github.io

### 早速やっていきます。(無駄を省いたシンプルな説明です。詳しくは本家様のREADNMEでご確認ください。)

### 1.リポジトリをフォーク！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575047/6cbf1164-c164-4b8f-a800-1f6a90ae2f83.png)

**初期設定のままで大丈夫**

### 2.リポジトリをクローン！
`git clone 自分のフォークしたgithubURL`
### 3.作業用ブランチを作成！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575047/a40f9ff2-4f39-4ca2-91ed-31f8d3d8e41e.png)

### 4.変更！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575047/31f0dbe7-063d-40a8-8488-a0de74d52c72.png)


### 5.変更をコミット→プッシュ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575047/c94872b1-3a98-4c80-9f43-639cbc669df8.png)

### 6.プルリクエストを作成！!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575047/6aeab459-c391-4d06-a68f-9f48ac530f23.png)

### 8.レビューとフィードバックに対応！
通った！
この絵文字がwebページのアニメーションに追加されるらしい！
オンラインMTGにおける心理的安全性の向上

### **はじめに**

スクラムマスターの資格を取得する際の研修で、**心理的安全性の重要性**を学びました。チーム内でお互いに自由に意見を言い合える環境を作ることは、スクラムの成功には欠かせません。

その中でも、私が特に課題だと感じたのは**オンラインMTG**でした。リモートワークが主流となった今、会議のやり方一つでチームの心理的安全性が大きく変わると実感しました。

本記事では、オンラインMTGにおける心理的安全性の課題と、それに対して私が実践した改善策を紹介します。

### **1. オンラインMTGの心理的安全性の課題**

近年、多くの会議がオンラインで実施されています。その際、よく見られる光景として、**発言者以外がミュート＆カメラOFF**の状態が挙げられます。

もちろん、音声トラブルやプライバシーの問題などの理由があり、この運用をしているチームも多いでしょう。しかし、この状況には大きなデメリットがあります。

**発言後の「沈黙」**

- 発言者が話した後、シーンとした時間が生まれる
- ベテランメンバーは気にならないかもしれないが、新人や普段発言しないメンバーには心理的負担が大きい
- 「数秒間の沈黙の地獄」を経験したら、次に発言しようと思わなくなる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2015150/313e6dbf-2764-4532-adc1-2d8ac72805c5.png)

さらに、「もっと質問しろ」と強要する文化があると、**ますます発言しづらい環境**になってしまいます。

この課題を解決するために、私はある策を講じました。

### **2. 実践した改善策**

私が実践したのは、**「リアクション機能の活用」** です。

リアクション機能とは、オンライン会議ツールに備わっている、**👍（いいね）や👏（拍手）、😊（笑顔）などのアイコンを押せる機能**です。

#### **リアクション機能の活用ルール**
1. **誰かが発言したら、必ずリアクションをする**
   - 「👍（いいね）」や「👏（拍手）」を押して、話を聞いていることを伝える
   - 大したコメントをする必要はなく、「聞いているよ」の意思表示が重要

2. **発言に対して、短いフィードバックを送る**
   - 「いい視点ですね！」や「なるほど」といった簡単なコメントをチャットで送る
   - これにより、発言者が「ちゃんと聞いてもらえている」と実感しやすくなる

これを導入したことで、発言者が**シーンとした空間を感じることなく、安心して話せる**ようになりました。
![024.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2015150/de483581-2747-4277-99a7-bb70b8e53a39.png)


### **3. 取り組みの効果**

このリアクション文化を導入した結果、以下のような効果を実感しました。

1. **発言のハードルが下がる**
   - 「聞いてもらえている」という安心感が生まれ、新人や発言しづらいメンバーも積極的に話せるようになった。

2. **チームの一体感が向上する**
   - ミュート＆カメラOFFでも、リアクションによって「ちゃんと会話が成立している」と感じられる。

3. **文化として徐々に広がる**
   - 最初は自分のチームだけで実践していたが、次第にグループ事業所や部署全体にも広がっていった。

オンラインMTGでは、「心理的安全性を確保するためには、発言者に寄り添うリアクションが大事」だと強く実感しました。

### **4. おわりに**

心理的安全性を確保するには、チーム全員が「発言しやすい環境づくり」を意識することが大切です。

オンラインMTGでは、リアクション機能を活用することで、**発言しやすい空気を作る**ことができます。これは決して強制するものではなく、**数人が実践するだけで自然と広がっていく文化**だと感じました。

もし、オンライン会議で発言の少なさや沈黙が気になる場合は、ぜひ試してみてください！
俺の.gitconfig

こういった記事は世にあふれていますが、新しく環境構築する際、都度何らかの方法でテキストを送信するのも面倒なので、自分用のメモとしてalias部分だけ残しておきます。
とはいえ「こうした方がいい」などのご指摘は歓迎なので、何かありましたらコメントください。

```.gitconfig
[alias]
    co = checkout
    cob = checkout -b
    b = branch
    unst = reset HEAD
    cancel = reset --soft HEAD^
    s = status
    cm = commit -m
    radd = remote add origin
    cp = cherry-pick
    rv = revert
    rvn = revert -n
    rb = rebase
    rbc = rebase --continue
    ps = push
    pl = pull
```
Postgresコンテナのデータを別のPostgresコンテナに移行する

# はじめに
DB ContainerにPostgresを利用してDocker開発を行っている場合に，別のPostgresコンテナにデータ移行を行う方法をまとめます．

# 環境
- Ubuntu 22.04
- Postgres version：15
- Docker version：26.0.0

# 基本コマンド
※ sudo コマンドが必要かも
### Dockerコンテナの状態確認

```
docker ps -a
```

### Dockerコンテナ内に入る

```
docker exec -it ContainerID bash
```

### Dockerコンテナ → ホストマシンへ のファイル転送

```
docker cp ContainerID:/file/path /host/file/path
```

### ホストマシン → Dockerコンテナ のファイル転送

```
docker cp /host/file/path ContainerID:/file/path
```

# DB全てを移行する場合

### 1. データのエクスポート（移行元サーバ）

```
# ダンプを作成
pg_dump -U postgres -F c -f database_backup.dump postgres
```

### 2. データのリストア（新サーバ）

```
# データベースの作成(作成済みの場合はスキップ)
createdb -U postgres postgres

# dump形式のリストア
pg_restore -U postgres -d postgres -c database_backup.dump

# マイグレーション等を実行してテーブルを作成してしまった時に重複するテーブルを削除してリストア
pg_restore -U postgres -d postgres --clean --if-exists --no-owner --no-privileges database_backup.dump
```

# 特定のテーブルのみ移行

### 1. 特定テーブルのエクスポート

```
# 単一テーブルのダンプ(table1)
pg_dump -U postgres -F c -t table1 -f table_backup.dump postgres

# 複数テーブルのダンプ(table1, table2)
pg_dump -U postgres -F c -t table1 -t table2 -f tables_backup.dump postgres
```

### 2. 特定テーブルのリストア

```
# テーブルのリストア
pg_restore -U postgres -d postgres -c database_backup.dump

# マイグレーション等を実行してテーブルを作成してしまった時に重複するテーブルを削除してリストア
pg_restore -U postgres -d postgres -t table_name --clean --if-exists table_backup.dump
```

# 一般的なエラーと対処法

### 1. 依存関係エラー

```
ERROR: cannot drop table because other objects depend on it
DETAIL: constraint fk_constraint on table dependent_table depends on table target_table
```

**対処法**:

- `-clean --if-exists`オプションを使用
- 依存関係のあるテーブルも含めてダンプを作成

### 2. 権限エラー

**エラー例**:

```
ERROR: permission denied for database "postgres"
```

**対処法**:

- PostgreSQLのスーパーユーザー権限で実行
- `-no-owner --no-privileges`オプションを使用

### 3. 重複キーエラー

**エラー例**:

```
ERROR: duplicate key value violates unique constraint
```

**対処法**:

- データベースを完全に再作成してからリストア
- `-clean`オプションを使用
SRP & CCP の適用

## **1. 単一責任の原則 (SRP: Single Responsibility Principle)**  
「クラスは一つの変更理由だけを持つべきである」

### ✅ **適用ポイント**  
- 変更の理由が異なるものは、別のドメインやサービスとして分離する。  
- **異なるユースケース** や **異なるビジネスロジック** を一緒にすると、不要な結合が発生し、変更時の影響範囲が広がる。  
- 例）**注文作成**と**注文履歴管理**は異なる責務を持つため、分離が適切。   

---

## **2. 共通閉鎖の原則 (CCP: Common Closure Principle)**  
**「パッケージのクラスは同じ種類の変更に対して閉じているべきである」**  
**「ある変更が影響する範囲は、そのパッケージ内に閉じ込めるべきである」**  

### ✅ **適用ポイント**  
- 変更が発生する際に、影響を受けるコンポーネントが同じなら、同じコンテキスト内で統合する。  
- 逆に、変更の影響を受けないものは、独立して分離するのが適切。  
- 例）決済のロジックが変わると影響を受けるのは決済関連の機能のみ → **決済ドメイン内で統合**。  

---

## **3. まとめ：SRP & CCP を考慮した分離基準**  
| 判断基準 | 分離のポイント |  
|----------|----------------|  
| **SRP（単一責任の原則）** | **変更理由が異なる場合、分離**する。 |  
| **CCP（共通閉鎖の原則）** | **同じ変更の影響を受ける場合、統合**する。 |  
| **イベント駆動アーキテクチャ** | SRP で分離しつつ、CCP で統合すべき部分は **イベントベースで疎結合にする**。 |  

💡 **基本的には注文と決済を分離し、イベント駆動アーキテクチャ（SAGA など）を活用するのが最適！**

### **注文・決済ドメインを例えした場合**  

#### **1. Bounded Context を基準にした分離**  
注文（Order）と決済（Payment）は異なる Bounded Context を持っています。  

- **注文（Order）Bounded Context**  
  - ユーザーが商品をカートに追加し、注文を作成するプロセス  
  - 注文状態の管理（未決済、決済完了、配送中、キャンセルなど）  
  - 在庫管理や注文履歴の管理  

- **決済（Payment）Bounded Context**  
  - 決済処理（クレジットカード、銀行振込、電子決済など）  
  - 決済承認・精算処理  
  - 決済失敗・返金処理  

これらのドメインは異なる責務を持つため、分離するのが適切です。  

---

#### **2. 単一責任の原則 (SRP: Single Responsibility Principle) による追加分離**  
各ドメイン内でも、変更の理由ごとにさらに細かく分離できます。  

##### **(1) 注文ドメイン（Order Domain）の内部分離**  
✅ **異なる変更理由を持つ場合、分離する**  
- **Order Command Service** → 注文の作成・キャンセル  
- **Order Query Service** → 注文情報の取得  
- **Order History Service** → 注文履歴の管理  

💡 **注文の作成と取得は異なる責務を持つため、分離が適切**  

##### **(2) 決済ドメイン（Payment Domain）の内部分離**  
✅ **異なる変更理由を持つ場合、分離する**  
- **Payment Processing Service** → 決済の承認・キャンセル  
- **Payment Gateway Adapter** → 外部決済システムとの連携  
- **Refund Service** → 決済キャンセル・返金処理  

💡 **決済承認と返金処理は異なるビジネスプロセスを持つため、分離が適切**  

---

#### **3. 共通閉鎖の原則 (CCP: Common Closure Principle) による統合の検討**  
- **「注文が変更されるたびに決済も変更されるべきか？」**  
  - 例えば、注文が作成されるたびに決済情報も必ず作成される場合、統合する方が適切な場合もある。  
- **「決済が失敗した場合、注文状態も変更されるべきか？」**  
  - 決済失敗時に注文状態を変更する必要がある場合、注文と決済が密接に関連するが、  
    **イベント駆動アーキテクチャ** を活用して疎結合にするのが理想的。  

 **統合すべきケース**  
- **注文と決済のトランザクションが強く結びついている場合**（SAGA パターンの適用）  
- **変更の影響範囲がほぼ同じで、別々に管理すると複雑になる場合**  

 **分離すべきケース**  
- **注文と決済の変更理由が異なる場合**  
- **決済ロジックが外部決済システムと密接に関係する場合**  
- **スケーラビリティや独立したデプロイが必要な場合**  

---

### 最適なアーキテクチャ（分離されたサービス構造）
**1) 注文サービス（Order Service）**  
- 注文作成 (`Order Command Service`)  
- 注文情報取得 (`Order Query Service`)  
- 注文履歴 (`Order History Service`)  
- 注文イベント (`Order Event Publisher`)  

**2) 決済サービス（Payment Service）**  
- 決済承認 (`Payment Processing Service`)  
- 決済ゲートウェイ連携 (`Payment Gateway Adapter`)  
- 返金処理 (`Refund Service`)  
- 決済イベント (`Payment Event Publisher`)  

---

### 結論：どこまで分離し、どこで統合すべきか？
1️⃣ **Bounded Context を基準に分離**  
2️⃣ **SRP に基づいて、異なる変更理由を持つコンポーネントを分離**  
3️⃣ **CCP に基づいて、変更の影響範囲が同じなら統合を検討**  
4️⃣ **イベント駆動アーキテクチャ（SAGA パターンなど）を活用し、適切に連携**  

**基本的には注文と決済を分離し、イベント駆動アーキテクチャで疎結合にするのが理想的！**
バージョン管理システム Jujutsuのチートシートを翻訳した

[Jujutsu](https://github.com/jj-vcs/jj)(コマンド名 jj)はかなり新しいバージョン管理システムで、以下のような特長を備えています。

* Gitとの相互運用性
* シンプルで合理的なコマンドライン
* 強力なブランチ操作と衝突解決

総合すると強力な機能とシンプルなUIをすでにGitで運用されているプロジェクトにも持ち込めるわけで、筆者にとってはとっくに手放せないツールとなっています。

そんなJujutsuですが、Justin Pombrio氏とLark氏により作成された[リファレンスとチートシート](https://justinpombrio.net/2025/02/11/jj-cheat-sheet.html)を見つけたので、今回日本語訳を作成しました。

* [PDFファイル](https://github.com/ygohko/jj-notes/blob/main/combined.pdf)
* [リポジトリ](https://github.com/ygohko/jj-notes)

![combined_page-0002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100666/71a6a9f1-3f4a-403b-a4b3-53287dccd243.jpeg)

リファレンスは短いながらも密度が高く、翻訳しながらもよくわからないまま使っている機能の詳細について理解を深めることができました。また、チートシートは基本的なコマンドの動作を一覧でき、これから触ってみるという方のよい手助けになるのではないかと思います。

お気づきの点がありましたら、GitHubからお知らせいただければ助かります。Jujutsuは気になるけど情報が少なくて... という方が実際に触ってみるきっかけになりましたら幸いです!
atcoder_水色精進記録5_ABC073d

# Atcoder水色精進記録
ABC073
D - joisino's travel
https://atcoder.jp/contests/abc073/tasks/abc073_d

# アルゴリズム・データ構造
ワーシャルフロイド・順列全探索

# 考察
最初と最後を自由に決められるサラリーマン循環問題？
N＝200
R =max(8)

R=max(8)のため、順列全探索が可能？
8!=40,320 → Yes

全探索中に各都市の距離を求めるのは計算量が大きくなるため事前に距離を求めておく。
ワーシャルフロイドで全ての頂点間の最短経路を求める。
N**3 = 200*200*200=8,000,000なので可能。

ワーシャルフロイドでの最短経路で既に通った街を経由する場合がある？
その場合、順列全探索で最小にならないため気にしなくてOK

# 提出
https://atcoder.jp/contests/abc073/submissions/63114082

# 感想
ワーシャルフロイドを自分で実装出来た。
Tips: Auth.jsのv5でLINEプロバイダーを使う時は「checks: ["state"]」を明示しないとエラーになる

## この記事は何
Auth.jsにはLINEプロバイダーが用意されているのですが、ガイド通りにやってもうまくいかなかったので記事としてまとめておきます。

## 起こっていた事
Auth.jsとは、JavaScript系の各フレームワークで簡単に認証の仕組みを実装できるライブラリです。
詳しくは以下をご覧ください。

https://authjs.dev/

このAuth.jsには各サービスのOAuthのプロバイダ用のテンプレートも用意されており、簡単に認証を導入できるようになっています。

https://authjs.dev/getting-started/authentication/oauth

LINEもプロバイダの一つと提供されており、ガイドも用意されています。

https://authjs.dev/getting-started/authentication/oauth?framework=next-js

しかし、このガイド通りに実装を行なってもエラーが発生してしまい、正しく動作しませんでした。

## 原因

https://github.com/nextauthjs/next-auth/issues/9596

にあるとおり、`checks: ["state"]`というパラメータがデフォルトでは設定されておらず、これを明示しないと正しく認証が通らないようでした。

```typescript:./auth.ts（誤）

import NextAuth from "next-auth"
import LINE from "next-auth/providers/line"
 
export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [LINE],
})
```

```typescript:./auth.ts（正）

import NextAuth from "next-auth"
import LINE from "next-auth/providers/line"
 
export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [
    Line({
      clientId: process.env.AUTH_LINE_ID,
      clientSecret: process.env.AUTH_LINE_SECRET,
      checks: ["state"],
   }),
  ],
})
```

今の所ガイド通りに実装してもLINEの認証は正しく動作しないため、ご注意ください。
【ChatGPTに限らず】ブレイン・ロット（脳腐れ）をなんとかしましょう。


　どうも、カーブミラーです。

　今回は、ブレイン・ロット（脳腐れ）をなんとかしましょう、という内容です。

:::note info
本記事は、生成AIに限らない
記事です。　　　あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　こちらも載せますね。
　　[ChatGPTが使えない？ログインできない・反応しない原因やエラー時の対処法を解説](https://aismiley.co.jp/ai_news/chatgpt-error-resolution-explanation/)
***
　まずは、ニュースです。

　AIが研究者たちが
　　10年掛かった問題を
　　　二日で解明して、
　　　　研究者たちと同じ結論に。

　[AIが「スーパー耐性菌」の難題を2日で解明　科学者が10年かけたのと同じ結論に](https://www.bbc.com/japanese/articles/ceqjndj9dy4o)

　耐性菌云々は置いておくとして、
　　その問題を、Googleが開発した
　　　AIツール「co-scientist」に
　　　　指示を出したところ、
　　　　　48時間以内に同じ結論を
　　　　　　導き出したという。

　質問した時点で
　　研究結果は公表されておらず、
　　　AIが事前に情報を知ることは
　　　　不可能だった。

　さらに、AIは
　　4つの追加の仮説も提示。
　　　そのうちのひとつは
　　　　研究者たちが考えもしなかった
　　　　　もので、現在研究に
　　　　　　取り掛かっているとのこと｡

　研究者たちは
　　驚いているが、
　　　AIを優れたツールだと
　　　　受け取っているらしい。

　ちなみに
　　別記事では、
　　　co-scientistは、
　　　　Gemini 2.0をベースに
　　　　　作られたとのこと。
***
　では、【本題】です。

　今回は、
　　ブレイン・ロット（脳腐れ）を
　　　なんとかしましょう。

　こちらの記事を参考にしました。
　　[世界でバズった「ブレイン・ロット（脳腐れ）」になりやすい人の特徴は？AIを使って脱出する方法](https://www.lifehacker.jp/article/2501-trendbuzz-brainrot-use-ai/?page=2)

　　[ブレインロットを知っていますか？ ─ 無限スクロールがもたらす影響](https://note.com/tanotin/n/n689c63f601c4?utm_source=chatgpt.com)
***
　ブレイン・ロット（脳腐れ）とは？

　オンライン上の
　　低品質なコンテンツを
　　　過剰に消費することで、
　　　　精神的・知的能力が
　　　　　低下する現象です。

　低品質なコンテンツとは、
　　情報の価値が乏しく、
　　　視聴者にとって有益ではない
　　　　コンテンツのことを指します。

　　誤情報やフェイクニュース
　　クリックベイト（釣りタイトル）
　　極端な意見・炎上狙いの投稿
　　無意味な短尺動画
　　ミーム文化の過剰消費
　　無限スクロール系のコンテンツなど｡

　なぜ、これが問題なのか？

　　視聴後に何も残らないので、
　　　時間の無駄。

　　正しい知識が身につかないどころか
　　　誤情報を信じてしまう。

　　深い思考を必要としない
　　　コンテンツに慣れてしまうため、
　　　　短絡的な思考になる。

　結論として、
　　**「短時間で強い刺激を与えるが、
　　　知的価値のないもの」**が
　　　　低品質なコンテンツの
　　　　　典型例と言えます。
***
　解決策は？

　記事内では、
　　以下の方法が有効とされています。

　- **視聴時間の制限**：
　　デジタルデバイスの使用時間を
　　　意識的に制限し、
　　　　過度なコンテンツ消費を防ぐ。

　- **質の高いコンテンツの選択**：
　　娯楽性だけでなく、
　　　教育的価値のあるコンテンツを
　　　　積極的に選ぶ。

　- **デジタルデトックスの実施**：
　　定期的にデジタルデバイスから離れ､
　　　自然の中で過ごす時間を設ける。

　- **趣味や運動の取り入れ**：
　　オンライン以外の活動を
　　　生活に取り入れ、
　　　　バランスの取れた生活を
　　　　　心がける。

　また、
　　コンテンツを
　　　受動的に消費するのではなく、
　　　　自ら創造する側に回ることで、
　　　　　脳を活性化させることも
　　　　　　効果的です。
***
　例えば、

　視聴時間の制限
　・1日あたりの
　　　SNS使用時間を制限する。
　・1回のSNS利用時間を
　　　15分や30分など明確に設定し、
　　　　それ以上は使用しない。
　・寝る前1時間はデバイスをオフ


　質の高いコンテンツを選択
　・エンタメ系の動画だけでなく、
　　　教育系・ドキュメンタリー
　　　　・自己啓発のコンテンツを
　　　　　バランスよく組み込む。
　・役立たないアカウントは
　　　フォローを外し、
　　　　質の高い情報を発信している
　　　　　アカウントを選ぶ。


　デジタルデトックスを実施
　・週に1日、
　　　スマホやPCを触らない日を作る。
　・朝起きて1時間、寝る前1時間は
　　　デバイスを使わない。
　・SNSの通知をオフにし、
　　　必要なときだけアプリを開く。


　趣味や運動を取り入れる
　・手を動かす趣味を習慣化する。
　・自然と触れ合う時間を増やす。
　・友人や家族とリアルな時間を過ごす｡


　受動的な視聴ではなく、
　　能動的な発信をする。
　・発信をすることで創造性を高める。
　・動画編集やライティング、
　　　イラスト制作に挑戦する。
***
　これらを参考にして、
　　ブレイン・ロット（脳腐れ）を
　　　払拭しましょう。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
paroleのクラッシュ

### 以下を吐いてparoleがクラッシュする

libva info: VA-API version 1.14.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_14
libva error: /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so init failed
libva info: va_openDriver() returns 1
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_1_10
libva info: va_openDriver() returns 0

(parole:197927): GStreamer-CRITICAL **: 13:49:06.355: gst_caps_from_string: assertion 'string' failed

(parole:197927): GStreamer-CRITICAL **: 13:49:06.355: gst_pad_template_new: assertion 'caps != NULL' failed

(parole:197927): GStreamer-CRITICAL **: 13:49:06.355: gst_mini_object_unref: assertion 'mini_object != NULL' failed

(parole:197927): GStreamer-CRITICAL **: 13:49:06.356: gst_element_class_add_pad_template: assertion 'GST_IS_PAD_TEMPLATE (templ)' failed

(parole:197927): GStreamer-Video-CRITICAL **: 13:49:06.356: gst_video_decoder_init: assertion 'pad_template != NULL' failed

(parole:197927): GStreamer-WARNING **: 13:49:06.356: Element vaapidecode0 has an ALWAYS template src, but no pad of the same name
Segmentation fault (コアダンプ)

### 解決
sudo apt purge gstreamer1.0-vaapi
ConoHaVPSのUbuntuサーバーからDBサーバーに接続するためのネットワーク設定


基本は公式サイトの以下ドキュメントに従う。

『[ご利用ガイド DBサーバー接続用ネットワークを使う](https://support.conoha.jp/v/dbnetwork/)』

上記工程のうち「VPSの設定を行う」の項目はCentOSベースで解説されており、Ubuntuの場合はnetplanで設定することになる。

自分はネットワーク知識が無いため読み替えるのに苦戦したが、以下のように設定すればつながった。

```
$ sudo vi /etc/netplan/50-cloud-init.yaml 
```

```yaml
network:
  version: 2
  ethernets:
    ens4: # `$ ip a`で確認
      addresses:
        - 172.21.xx.xx/23 # ConoHa管理画面の対象Webサーバー「ネットワーク情報」の「shared〜」の「IPアドレス」
      gateway4: 172.21.yy.yy # ConoHa管理画面の対象Webサーバー「ネットワーク情報」の「shared〜」の「ゲートウェイ」
      routes:
        - to: 172.21.74.0/23 # ドキュメントに記載の該当リージョンの固定値
          via: 172.21.yy.yy # gateway4と同様
          metric: 100
      dhcp4: no
```

```bash
# 反映
$ sudo netplan --debug apply
```

```bash
# 確認
$ ping private.xxxx.tyo1.database-hosting.conoha.io
```
【初学者向け】Bootstrapの特徴について調べてみた

## 背景

bootstrapを実務で使うことになったので勉強しようと思い、よく利用しているサービス内で検索したのですが、Bootstrapの講座はハンズオン形式だったため、
- なぜこのタグを使うんだろう？
- どういう仕組みなんだろう？

と思うことが多かったです。なので、一度しっかり基礎に立ち帰り、一つずつ基礎から着実に力を入れようと思い、勉強を始めました。

## Bootstrapの特徴

### レスポンシブデザインに対応

フルードグリッド、フルードイメージ、メディアクエリなどの技術で構成されている。

#### フルードグリッド（可変グリッド）とは？
グリッドシステムとリキッドデザインを組み合わせた手法。

**◽️グリッドシステムとは？**

>グリッドシステムとは、ページのレイアウトを均等な列（カラム）や行（ロー）に分割し、要素を配置する方法。
>出典: ChatGPT（2025年2月11日）

Bootstrapでは、レイアウトを1行あたり12列まで分割することができる。


**◽️リキッドシステムとは？**
>リキッドシステムとは、コンテンツが画面サイズに応じて流動的（リキッド）に伸縮するレイアウト のこと。
固定幅ではなく、比率（％）で指定する ことで、どの画面サイズでもコンテンツが自動的に調整される。
>出典: ChatGPT（2025年2月11日）

つまり、フルードグリッドは**ページのレイアウトを行や列でデザインし、画面サイズに合わせてレイアウトを自在に伸縮することができるレイアウト**のこと。

#### フルードイメージとは？

画面サイズに応じて画像を拡大縮小すること。
フルードグリッドと組み合わせてグリッドのサイズに応じて画像サイズを変更する。

#### メディアクエリとは？
デバイスの種類や解像度やデバイスの向きなどの条件をあらかじめ指定しておくことでデザインを切り替える。
上記のフルードグリッドを組み合わせるとPCで見た時は4列で構成されているが、スマホだと8列で構成されるというような使い方が可能。

### デザインされたコンポーネント

入力フォームやボタンのデザインを予めBootstrapで用意されているため、対応したクラスをHTMLに追加するだけで簡単にデザイン性のあるWebサイトやWebアプリを作ることができる。カタログで使いたいボタンデザインを探し、そのボタンを作るために使用するクラス名を要素に追加するイメージ。
Bootstrapの公式サイトにはさまざまなコンポーネントの使い方が記載されているので、困った時は公式ドキュメントを確認する。今回はボタンを例に出したので、ボタンのリンクを貼っておきます。

https://getbootstrap.jp/docs/5.3/components/buttons/

### Bootstrap Iconsというアイコン集がある

Webアプリ開発をしていると検索ボタンに虫眼鏡マークをつけたりとアイコンを使いたいと感じる場面は多い。
Bootstrapを使えばそのようなアイコンをサイト内で検索するだけで簡単に実装することができる。

https://icons.getbootstrap.jp/

## 今日はここまで

今日学んだことは以上です。
あまりイメージがついていないところもありますが、なんとなく概要が掴めた気がします。
今までグリッドデザインというキモのところをあまり理解せずに使っていたのが混乱の原因だったんだというのがわかってきました。
次は実際に導入してみる方法と簡単にデザインを作ってみようと思います。

## 参考書籍
本記事の内容は以下の書籍を参考にして学習したものをまとめたものです。
説明がわかりやすく、図解もしているのでかなりわかりやすいのでおすすめです。

https://gihyo.jp/book/2022/978-4-297-12490-8
ProxmoxのLXCコンテナにPostgreSQLのサーバーを建てるまで

# 筆者について

```
name → Koki Teramoto
age → 18
language → ja_JP, en_US
```

# 本編

題名の通りなのですが、少してこずったので備忘録程度に書いておきます。参考記事は以下の2つです。ありがとうございます。

https://qiita.com/nanbuwks/items/846cf3536a82a2798555#%E3%83%A6%E3%83%BC%E3%82%B6%E3%82%92%E4%BD%9C%E3%82%8B

https://qiita.com/natyosu/items/f8fe7aeff7e9e815bb90

コンテナの情報は以下のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/1bddf869-d12c-4021-b793-b4bec1ef6f34.png)

## PostgreSQLのインストール

インストールはとても簡単です。

```
sudo apt install postgresql postgresql-contrib
```

## アクセス許可の設定

ローカル以外からのアクセスを有効化する必要がありますのでそちらの設定を加えていきます。ちなみに、以下の設定ファイルは`/etc/postgresql/{version}/main`にあります。

### `postgresql.conf`の設定

リッスンポートを変更します。以下のように書き換えてください。

```conf:postgresql.conf
listen_addresses = '*'
```

### `pg_hba.conf`の設定

ここは気をつけましょう。`pg_hba.conf`の下の方まで行きます。きっとこんな記述箇所があるはずです。

```conf:pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     all             ::1/128                 scram-sha-256
```

変更するのはここのIPv4のところです。CIDER表記でアクセスできるIPを変更してください。また、`METHOD`は`md5`に変更しましょう。僕は、以下のように設定を変更しました。

```conf:pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             192.168.0.0/16          md5
host    all             all             100.0.0.0/8             md5
# IPv6 local connections:
#host    all             all             ::1/128                scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     all             ::1/128                 scram-sha-256
```

IPv6を設定しようかと思いましたがめんどくさかったので、とりあえずオフにしてIPv4の設定だけにしました。そして、TailscaleとLANからのアクセスを許可するためにそれぞれ設定を変更しています。

## ユーザー（ロール）の作成

まずはデフォルトユーザーでログインします。

```zsh
sudo -u postgres psql
```

次に、ユーザーを作成します。

```sql
CREATE USER username WITH PASSWORD 'password';
```

データベースを作成します。

```sql
CREATE DATABASE database_name;
```

ローカルの検証用なので、スーパーユーザー権限を付与しちゃいます。ここは適宜必要に応じて必ず変更してください。

```sql
ALTER ROLE username WITH SUPERUSER
```

あとは、ログインするだけです！試してみましょう。

```zsh
psql -h 192.168.101.100 -U test -d test_db
```

見事にログインできました！

# 最後に

これ、Javaの勉強用に作ったSQLサーバー、適用にパーって作ったんですけども、Javaの方が難しくて驚いてます。データベースの勉強も進めていかねば、、、。
（ブラウザ版）ディープラーニングの画像認識による結晶粒度の評価アプリ

# はじめに
前回の記事で、TeachableMachineを利用した結晶粒度の評価についてご紹介しました。記事の内容は次のようなものです。
1. 種々の粒度番号に相当する金属組織の画像（組織画像）をデータセットとして作成
1. データセットをTeachableMachineで学習
1. 学習後のモデルをダウンロード
1. Python言語のプログラムにモデルを読み込ませて、組織画像の粒度番号を推論

https://qiita.com/_Moony/items/36e35a46215cb5efc332

今回は、ウェブ上で組織画像の粒度番号を推定するため、次のような内容にしました。
1. TeachableMachineで学習したモデルをウェブ上にアップロード
1. html言語（javascript含む）のプログラムにモデルを読み込ませて、組織画像の粒度番号を推論

ここで、前回の記事では、画像の倍率などの情報を画像ファイルと同じフォルダに格納している「cond.ini」から取得しましたが、今回はアプリ上で情報を直接入力することにしました。

# 使い方
1. はじめに、粒度番号を評価したい組織画像を用意します。以下URLのimgフォルダ内にサンプル画像があるので、それらを使うこともできます。
https://github.com/repositoryfiles/EvaluationGrainSizeUsingDeepLearning_BrowserVersion
imgフォルダ内の画像ファイル名は、材料名_熱処理_倍率_画像の幅 になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/af4d266c-6eab-4414-bf66-8f10cd625158.png)

2. 次のサイトにアクセスします。自動的にウェブアプリが立ち上がります。
https://repositoryfiles.github.io/EvaluationGrainSizeUsingDeepLearning_BrowserVersion/

3. 組織画像の「倍率」と**その倍率で表示させたときの**「画像の幅（mm）」を設定します。デフォルトでは500倍、142mmとなっています。サンプル画像の粒度番号を評価する場合、ファイル名の「mag」と「size」に続く数値を「倍率」と「画像の幅（mm）」にそれぞれ入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/64fe434d-48fa-4513-89e0-2582c3bd9513.png)

4. ファイルを選択して画像ファイルを読み込みむと、TeachableMachineのモデルでの粒度番号の推論値が表示されます。粒度番号の表示には少し時間がかかる場合があります。粒度番号に続くカッコ内の数値は、推論結果の確率を表示したものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/0c67f6d2-86b8-4ef8-aab2-08510524cd5c.png)

5. 別の画像を評価する場合など、ページをリロードする場合は「ページをリロードする」をクリックします。

# このプログラムについて
imgが格納されているURLにある「index.html」がプログラムです。
TeachableMachineからindex.htmlへのモデルの読み込みは、次のように行っています。

1. TeachableMachineで作成されるモデルを「Tensorflow.js」の形式でクラウド上にアップロードします（「モデルをアップロード」をクリックします）。
![モデルをアップロード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/b3b3389a-45b0-4c7f-88bf-9a0d47f79fcc.jpeg)

2. アップロード後に「共有可能なリンク」が表示されます。
![共有可能なリンク.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/7dd99485-1e25-4f3e-a816-b3168a496be4.jpeg)

3. このURLをindex.htmlで指定します（28行目）。

# おわりに
- 当サイトの利用結果について、当方は責任を負いません。
- インターネットが使える環境でしたら、index.htmlはローカルパソコン上で実行できると思います。お使いの環境に合うように改良・活用していただけたら幸いです。
Github複数アカウント管理方法

# はじめに
Web上でGithubのアカウントを切り替え可能になったが、それぞれのアカウントに対して１台のPCから作業を行う際に必要となる設定の忘備録として残しておく。
# 秘密鍵・公開鍵を生成する
```terminal
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/ユーザー名/.ssh/id_rsa): <--鍵の保存先 
Enter passphrase (empty for no passphrase):  <-- パスフレーズを入力（任意）
Enter same passphrase again:  <-- もう一度、パスフレーズを入力（任意）
```

サブの場合はわかりやすいようにsubを名前に入れておく。
Githubへのsshキーの登録方法は割愛。

# 設定ファイルの変更
ssh経由でのリモートサーバーの接続する際に利用される設定ファイルの変更を行う。
```~/.ssh/config
Host github-sub
  HostName github.com
  IdentityFile ~/.ssh/github_sub
  User git
  Port 22
  TCPKeepAlive yes
  IdentitiesOnly yes
```

# zshの設定ファイルの変更
ターミナル上でGithubのアカウントを切り替えられるようにしておく
```~/.zshrc
function gitmain() {
  git config --global user.name <githubのユーザー名>
  git config --global user.email <メールアドレス>
  source ~/.zshrc
}

function gitsub() {
  git config --global user.name <githubのユーザー名>
  git config --global user.email <メールアドレス>
  source ~/.zshrc
}

export PROMPT="
%F{green}[%~]%f <`git config user.name`>
=> %# "
RPROMPT='%*'
```

それぞれ、`gitmain`, `gitsub` コマンドの実行でアカウントを切り替える。
切り替える際に `source ~/.zshrc` (反映)も自動で行うようにしておく。

export PROMPT は現在のアカウントを常に表示しておくためのカスタマイズ設定で、以下のように表示される。
```terminal
[~/path/hoge] <user.name>
```

# ssh-agentに鍵追加
以下のように表示された場合追加が必要。(権限不足でgit pushできない)
```terminal
$ ssh-add -l 
The agent has no identities.
```

毎回手動で秘密鍵を登録するのは面倒なので、起動のたびに自動で登録まで行われるようにzshの設定ファイルを変更する。

```~/.zshrc
# 既存の ssh-agent プロセスをチェック
if ! pgrep -u "$USER" ssh-agent > /dev/null; then
    eval "$(ssh-agent -s)"
fi

# ssh-add の前に鍵がすでに登録されているか確認
if ! ssh-add -l | grep -q "github_sub"; then
    ssh-add ~/.ssh/github_sub
fi
```

これでターミナルを起動するたびに登録されていなければ自動で鍵を登録してくれる。

# おわり
以上でGithub上のそれぞれのアカウントに１台のPCからGit操作を行うことができる。
CUIでタグを付けるソフトを自作して使っているので紹介

# この記事はなに？
僕の作った便利ツールである、これの紹介。身も蓋もない。

https://github.com/uesseu/ntag

下記でインストールできます。
```sh
pip install git+https://github.com/uesseu/ntag
```

# タグは便利である
みなさん、タグ使ってますか？使ってますよね。なにしろ、このqiitaの記事にすらタグが付いています。パッと思いつく限り

- gmail
- qiita
- iTunes

などなど、挙げればきりがないです。メール、記事、音楽などを皆さんはタグで管理しています。2025年2月現在、僕は婚活していますが、婚活アプリもタグ管理です。人間すらタグで管理されるのです。

# ファイルをタグで管理しよう
WindowsにもMacOSにもタグが標準でついています。皆さん、使っていますか？僕は…使っていません!何故か？僕はTerminalの中に引きこもってvimを弄るキモオタだからです!
GUIにあれだけタグがありますが、CUIの世界にはどうでしょうか？実はあるんですよ。調べれば、あります。詳しくはググれ。でも、僕が満足できるものはなかったのです。
僕が欲しかったのは以下のような性能です。

- ディレクトリ単位で管理
- inode/file indexベース
- CUIやvimで使いやすい
- いろどりが豊かである
- マルチプラットホーム
- pythonとか軽量言語で作ってあとで改造できる

というわけで作ったのです。inode/file indexベースなので、例えファイルやディレクトリを移動してもちゃんと追跡できます。

# 使い方
gitみたいに特定のディレクトリをリポジトリにします。

```sh
ntag init
```

で、タグを作ります。

```sh
echo hoge | ntag make
```

標準入出力かよ!と思われるでしょうが、このソフトは基本標準入出力で動きます。理由は大量のファイルとタグを管理するためにはコマンドライン引数では苦しいからです。大量のファイルを捌くために、非同期的にファイル名をパイプに渡すように作っていますし。

ここで、タグを確認します。

```sh
ntag list
```

色もつけましょうね。この機能は現時点ではwindowsでは動きません。

```sh
ntag color
```
対話的に設定できます。

では、タグを付けましょう。
```sh
echo filename.md | ntag add hoge
```

あとは

```sh
ntag filter red
```
こんな感じになります。

> filename.md \[ <font color=red>red</font> \]

これでfilename.mdにredが付いているのが確認できるはずです。ちなみに、タグを指定せずにfilterコマンドを打つと全てのファイルを絞りこまずに表示します。

```sh
ntag filter
```

これはパイプで繋いでいけます。下記はredが付いていてかつblueとyellowのいずれかが付いているのを絞りこみます。

```sh
ntag filter red | ntag filter blue yellow
```

パイプに流す時にはタグは流しません。ttyの上だけでタグを表示します。
例えばこんな感じにすると、currentというタグが付いていて、かつ'.py'という文字列が付いているファイルのみをvimで編集することになります。

```sh
vim $(ntag filter current | grep .py)
```

# inode上書き対策
ファイルを上書きする時にinodeを変更されたら追跡できなくなります。vimの場合このようにすればinodeを上書きしなくなるので大丈夫です。

```vim
set backupcopy=yes
```

vscodeやemacsでどうすればいいのかは僕にはわかりませんが、できるでしょう、多分。

# 他の機能
コメントを付けられます。

# 現時点での不備
僕自身は割と便利に使っているのですが、僕がlinuxユーザーなのであまりwindowsに配慮していないです。というか、自分しか使わねーだろという発想がある…。
誰か興味あればちゃんと整備します。既知の問題は下記の通りです。

- Windowsでの検証が不十分
    - 特に色関連はなにもしていない
- インポート/エクスポートのテストが不十分
- MacOSを持っていないのでそこはわからん

# おわりに
本当に僕以外あまり使う人がいないなら、ゆっくりと整備をつづけていくことになろうかと思いますが、興味がある人がいればモチベーションはあがるかも。
自己紹介みたいなやつ

## 初めに
Qiita界隈のみなさん、はじめまして。ギリギリZ世代の中学3年生です。
今までQiitaは見るだけで使ってきましたが、自分でも記録をしていきたいと思い投稿を始めようと思います。参考にしてもいらいたいというよりは、自分用の記録として積み重ねていきます。

## プロフィール
学年：中学三年生（春から高校生 / 2025.02現在）
趣味：スポーツ観戦

IT業界を専門ではなく、趣味程度に楽しんでます。
田舎でスポーツチームを応援してる人生を楽しみながら、AIを活用して効率化システムを作ってみたり、WEBサイトを作ってみたりしています。

いろいろ間違ったことばっか発信していくと思うので信用はしない方がいいと思います。
よろしくお願いします。
APIテストツールはPostmanだけでいいの？オンライン版の活用術と最適な代替サービス選び

Postmanは開発者必携のAPIテストツールです。リクエスト作成からスクリプト記述、結果分析まで、多機能なサポートが特徴。今や開発プロセスに欠かせない存在となっています。

デスクトップ版だけでなく、ブラウザで使えるオンライン版も提供中。実際の使い方を見ていきましょう。

:::note info
開発チームのAPIテスト効率を劇的に向上させる「[Apidog](http://www.apidog.com/jp/?utm_source=opr&utm_medium=a2qiita2)」。Postman互換の無料オンラインツールながら、リアルタイム共同編集や自動ドキュメント生成機能が特徴。モックサーバー構築も数クリックで完了し、フロント/バックエンドの並行開発が可能に。直感的なUIと豊富なテンプレートで、初心者でもプロ級のAPIテストを実現。チームメンバーとの権限管理機能も充実、セキュアな共同作業環境を無料で提供中。今すぐGoogleアカウントでログインして、次世代API開発体験を始めましょう！
:::

## Postman Web版の便利機能
オンライン版Postmanなら、面倒なインストール不要でAPIテストが可能。リクエスト管理からワークフロー改善まで、効率的な機能が満載です。

主な特徴：
- **パラメータ設定**：エンドポイントやヘッダーを動的に変更可能。複数シナリオのテストに最適
- **環境変数**：複数リクエストで使い回せる値の管理が簡単。テスト作業が格段に楽になります
- **スクリプト機能**：JavaScriptで事前スクリプトやテストコードを記述可能。自動化処理や複雑な検証もお任せ
- **多形式対応**：JSON/XML/HTMLなど主要データ形式を網羅。正確なテスト結果が得られます


![postman-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/3ff42653-1126-4586-b8c3-8745c106b4a6.png)

## PostmanオンラインでAPIテストする手順（日本語に設定可能）

### 1. アカウントにログイン
「Sign in」ボタンでログイン。未登録の方は「Sign up for free」から簡単登録可能です。
![log-in-postman-online-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/9bdb20ac-3bec-42a1-90f3-7217853870c8.png)

### 2. 新規エンドポイント作成
「新規」ボタン→HTTPメソッド（GET/POSTなど）を選択。これで新規リクエストが作成できます。

### 3. 基本パラメータ入力
テスト対象のAPIエンドポイントURLを入力(例: DeepSeek API)。必要に応じてヘッダーやパラメータも設定しましょう。 
![postman-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/2b1ee153-8c82-4665-bd4a-99cd91e8847d.png)

### 4. リクエスト送信
「送信」ボタンをクリック。これでAPIテストが開始されます。

### 5. レスポンス確認
ステータスコードやヘッダー、本文が表示されます。結果分析はこの画面で行いましょう。

## コレクション作成方法
1. 左上「新規」→「コレクション」選択
![postman-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/4e701f86-b698-466e-91ed-13ab13428798.png)

2. サイドバーに新規グループが表示されます
![postman-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/67aebbe4-0b86-4873-8309-1404fe1b3738.png)

3. 右上「インポート」で既存コレクションの取り込みも可能
![postman-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/60726287-c6c4-4316-8cd2-457beb5fbf86.png)

4. 「リクエストを追加」ボタンをクリックでリクエストを追加
![postman-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/4a425d5e-103f-4d4f-9d12-83f6b15f71b4.png)


## Postman代替ツール：Apidog オンライン
[Apidog](http://www.apidog.com/jp/?utm_source=opr&utm_medium=a2qiita2)はPostman互換の無料APIツール。視覚的な操作画面と充実機能が魅力です。

主な特徴：
1. **APIテスト**：リアルタイムでレスポンス確認可能
2. **ドキュメント自動作成**：エンドポイント情報から詳細仕様書を生成
3. **モックサーバー**：実際のAPIが未完成でもテスト可能
4. **チーム連携**：権限管理機能付きの共同作業環境
5. **カスタムワークフロー**：複雑なテストシナリオも自在に構築

## ApidogでAPIテストする方法
簡単4ステップ：
1. Google/GitHubアカウントでログイン
![log-in-apidog-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/e08766c7-6275-4963-97f1-77d13b3c4f3c.png)

2. 「+」タブ→「新しいリクエスト」で新規作成
![apidog-新しいリクエストを作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/43386b02-a6a4-4c33-a320-831455113228.png)

3. メソッド・URL・パラメータを設定→「保存」
![apidog-HTTPメソッドをget選択-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968588/236e7dee-0687-476f-b7df-2a9c4ae31fc2.png)

4. 「送信」クリックで即時テスト→結果レポートを確認

[Apidog](http://www.apidog.com/jp/?utm_source=opr&utm_medium=a2qiita2)にはデスクトップ版も用意されています。用途に合わせて最適なツールを選びましょう。
LibreChatでAzureのDeepSeek R1を使う

# はじめに
- 2025年1月29日にAzureでDeepSeek R1が利用できるようになりました
    - 参考: [DeepSeek R1 が Azure AI Foundry および GitHub で利用可能に](https://news.microsoft.com/ja-jp/features/250130-deepseek-r1-is-now-available-on-azure-ai-foundry-and-github/)
- 本記事ではLibreChatでAzureのDeepSeek R1を利用するまでの手順を記録します

## 注意事項
- 本記事は2025年2月24日現在の情報で記載しています
- 閲覧時期によっては変更となっていることがありますので、ご注意ください

## 前提
- 下記2点を前提とします
    - [LibreChat](https://www.librechat.ai/)がインストールされていること
    - Azure AI FoundryにDeepSeek R1がデプロイされていること
- 必要に応じて下記記事を参照してください
    - [LibreChatでAzure OpenAIを使う](https://qiita.com/ackyv7/items/9386e9295f528a23ed02)
    - [AzureのDeepSeekを試す](https://qiita.com/ackyv7/items/531e74ff73e1d2532898)

:::note warn
LibreChatは上記記事ではv0.7.5ですが、本記事では[v0.7.7-rc1](https://github.com/danny-avila/LibreChat/releases/tag/v0.7.7-rc1)を利用していますので、ご注意ください。
:::

# 手順
## DeepSeek R1の設定取得
- Azure AI Foundryにアクセスし、DeepSeek-R1をデプロイしているプロジェクトを開きます
- 下記設定値を控えます
![Azure_AI_Project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402149/37275db6-6da9-4e0e-a5e1-4024c63e462c.png)

## LibreChatの設定変更
- `librechat.yaml`に下記設定を追加し、LibreChatを起動します
```yaml:librechat.yaml
endpoints:
  azureOpenAI:
    groups:
    - group: "Azure DeepSeek"
      name: "DeepSeek R1"
      apiKey: "（1）"
      baseURL: "（2）"
      serverless: true
      models:
        DeepSeek-R1: true
```

## LibreChatの動作確認
- LibreChatにアクセスし、DeepSeek-R1を選択し動作するか確認します
![LibreChat_DeepSeek.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402149/32ecc1fb-2dff-446f-bfd0-4083accf921b.png)

以上です。おつかれさまでした。
Go言語で書くgRPC テクニック：初級編

## はじめに

gRPCは、高速・軽量なRPCフレームワークで、Go言語との相性が良く、マイクロサービス間の通信や API サーバーの実装に最適です。  

**対象読者**
- gRPCの基本を理解し、実際に使ってみたい方
- Go言語を使ったシンプルなgRPCサーバー・クライアントを構築したい方

**目次**
1. シンプルなUnary RPCの実装
2. gRPCの接続管理（コネクションプーリング）
3. リトライとタイムアウトの設定

---

### 1. シンプルなUnary RPCの実装

Unary RPCは、1つのリクエストに対して 1つのレスポンスを返す最もシンプルな通信方式です。

**1.1 .proto ファイルの定義**
.protoファイルで、リクエストとレスポンスの形式を定義します。

**example.proto**
```proto
syntax = "proto3";
package example;

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

message HelloRequest {
    string name = 1;
}

message HelloResponse {
    string message = 1;
}
```

- `syntax = "proto3";`：Protocol Buffersのバージョン指定
- `service`：gRPCのサービスを定義
- `rpc`：gRPCメソッドの定義（リクエスト・レスポンス）
- `message`：リクエスト・レスポンスのデータ構造

----

**1.2 gRPC コードの生成**
以下のコマンドを実行して、Go用のgRPCコードを生成します。
```sh
protoc --go_out=. --go-grpc_out=. example.proto
```

- **`example.pb.go`**：Protocol Buffersのコード
- **`example_grpc.pb.go`**：gRPCのコード

----

**1.3 Server の実装**
example.protoで定義したメソッドを実装します。

**server.go**
```go
package main

import (
    "context"
    "fmt"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "example"
)

type server struct {
    pb.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {
    message := "Hello, " + req.Name
    return &pb.HelloResponse{Message: message}, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    fmt.Println("Server is running on port 50051")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}
```

- `SayHello` メソッド：リクエストを受け取り、メッセージを返す
- `grpc.NewServer()`：gRPC サーバーを作成
- `RegisterGreeterServer()`：生成したコードをサーバーに登録

**1.4 Client の実装**
SayHelloメソッドを呼び出すクライアントを実装します。

**client.go**
```go
package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "google.golang.org/grpc"
    pb "example"
)

func main() {
    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()

    c := pb.NewGreeterClient(conn)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "Gopher"})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    fmt.Println("Greeting: ", r.Message)
}
```

- `grpc.Dial()`：サーバーに接続
- `NewGreeterClient()`：gRPCクライアントを作成
- `SayHello()`：`example.proto` で定義したRPCメソッドを呼び出す

---

## まとめ

| 項目 | 説明 |
|------|------|
| **Unary RPC** | 1つのリクエストに対して1つのレスポンスを返すシンプルな通信方式 |
| **Server 実装** | `SayHello()` メソッドを定義して、リクエストに応答 |
| **Client 実装** | `SayHello()` メソッドを呼び出して、レスポンスを受け取る |

今回は最もシンプルなUnary RPCを使ったgRPCの基本を解説しました。  
次は中級編として、**ストリーミング RPC** や **インターセプター** の使い方をまとめていこうと思います。
[AWS]Amazon S3 セキュリティプラクティス「送信時のデータ暗号化」メモ

Amazon S3のセキュリティベストプラクティスにおける「送信時のデータ暗号化」についてメモする。

## 用語・概念
- **TLS (Transport Layer Security):**  
    ネットワーク通信の暗号化プロトコル。
- **HTTPS (HyperText Transfer Protocol Secure):**  
    TLSにより暗号化されたHTTPプロトコル。これにより、通信経路上でのデータの盗聴や改竄を防止する。
- **aws:SecureTransport:**  
    AWSのIAM条件キーの1つ。リクエストが暗号化（HTTPS/TLS）されているかどうかを判定し、暗号化されていないリクエストを拒否するために使用される。
    
## 設定が必要な理由 (設定しない場合のリスク)
- **中間者攻撃の防止:**  
    HTTPS (TLS) により、ネットワーク上での通信が暗号化されるため、攻撃者が通信を盗聴したり改竄するリスクを大幅に低減できる。
- **データの完全性と信頼性:**  
    暗号化された接続では、データが転送中に改ざんされるリスクが少なく、受信側が正しいデータを確実に受け取ることができる。
- **規制やコンプライアンスの遵守:**  
    業界によっては、送信時のデータ暗号化が必須とされる場合があり、これにより法令や内部ポリシーに準拠した運用が可能になる。
    
**中間者攻撃例**
```mermaid
sequenceDiagram
    participant C as クライアント
    participant A as 攻撃者 (Man-in-the-Middle)
    participant S as Amazon S3

    C->>A: HTTPリクエスト (暗号化なし)
    A->>A: リクエスト内容を盗聴/改竄
    A->>S: 改竄済みHTTPリクエストを中継
    S-->>A: レスポンス (オリジナル)
    A->>C: 改竄または盗聴されたレスポンス
```

## AWS CLIによる設定方法

### バケットポリシー

- S3バケットポリシーにおいて、**aws:SecureTransport** 条件を利用し、暗号化されていないリクエスト（`aws:SecureTransport=false`）を拒否する設定を適用する。
- 以下のJSONポリシー例は、指定されたS3バケットへの全リクエストのうち、HTTPS (TLS) 経由でのアクセスのみを許可し、暗号化されていないリクエストは拒否する。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyUnencryptedConnections",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::your-bucket-name",
        "arn:aws:s3:::your-bucket-name/*"
      ],
      "Condition": {
        "Bool": {"aws:SecureTransport": "false"}
      }
    }
  ]
}
```
### AWS CLIでの設定手順

1. 既存のバケットに対して、上記のポリシーを適用する場合は、`put-bucket-policy` コマンドを使用する。

```bash
aws s3api put-bucket-policy \
    --bucket your-bucket-name \
    --policy '{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "DenyUnencryptedConnections",
          "Effect": "Deny",
          "Principal": "*",
          "Action": "s3:*",
          "Resource": [
            "arn:aws:s3:::your-bucket-name",
            "arn:aws:s3:::your-bucket-name/*"
          ],
          "Condition": {
            "Bool": {"aws:SecureTransport": "false"}
          }
        }
      ]
    }'
```


## 参考文献

- [Amazon S3 セキュリティベストプラクティス (公式ドキュメント)](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/security-best-practices.html) 
- [AWS CLI: put-bucket-policy (公式ドキュメント)](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-policy.html)
個人的備忘録：Djangoのマイグレーションが適用されないときの解決策を自分なりにまとめてみた

## はじめに
Djangoで開発を進めていると、データベースの変更を反映するためのマイグレーションが正しく適用されないことがあります。

:::note warn
**特に、`No migrations to apply.` というメッセージが表示されたときは、どこで問題が起きているのか確認する必要があります。**
:::

本記事では、マイグレーションが適用されない場合の確認方法と解決策を解説します。

## 書こうと思ったきっかけ
Djangoを使った開発の中で、マイグレーションに関する問題に何度も遭遇しました。

:::note info
***特に、モデルを変更したはずなのに適用するべきマイグレーションが見つからないといった状況が発生すると、原因を特定するのに時間がかかることがあります。***
:::

そこで、よくある原因と解決策をまとめることで、同じ問題に直面した人の助けになればと思い、この記事を書くことにしました。

## Djangoのマイグレーションが適用されないときの解決策
Djangoでマイグレーションを適用しようとした際に、以下のようなメッセージが表示されることがあります。

```css
Operations to perform:
  Apply all migrations: accounts, admin, auth, contenttypes, sessions, xxx
Running migrations:
  No migrations to apply.
```

このメッセージは、適用すべき新しいマイグレーションがないことを意味しています。

とはいえ、実際にはモデルを変更したのにマイグレーションが適用されていない場合もあります。

そのようなときに確認すべきポイントを解説します。

### 1. 既存のマイグレーションを確認する
まず、データベースに適用済みのマイグレーションを確認します。

```bash
python manage.py showmigrations
```

このコマンドを実行すると、各アプリのマイグレーション一覧が表示され、適用済みのものには `[X]` がついています。

### 2. 新しいマイグレーションが必要か確認する
モデル (`models.py`) に変更を加えたのにマイグレーションが作成されていない場合、以下のコマンドを実行してください。

```bash
python manage.py makemigrations
```

もし `No changes detected` と表示される場合、以下の点を確認してください。

- **モデル (`models.py`) に本当に変更を加えたか？**
- **アプリが `INSTALLED_APPS` に含まれているか？** (`settings.py` で確認)
- **マイグレーションフォルダ (`migrations/`) が正しく生成されているか？**

### 3. マイグレーションを適用する
`makemigrations` によって新しいマイグレーションが作成されたら、次のコマンドで適用します。

```bash
python manage.py migrate
```

この時点でエラーが出る場合、エラーメッセージを確認して適切に対処してください。

### 4. マイグレーションのリセット（必要な場合）
データベースの状態が不整合になっている場合、マイグレーションをリセットして再適用できます。

```bash
python manage.py migrate --fake xxx zero
python manage.py migrate xxx
```

**注意**: `--fake` オプションを使うと、Django はマイグレーションが適用されたと「見なす」だけで、実際のデータベース変更は行いません。データの消失には注意しましょう。

### 5. データベースの状態を確認する
もし `migrate` を実行しても変更が反映されない場合、データベースの状態を直接確認します。

```bash
python manage.py dbshell
```

または、手動でデータベースに接続し、`django_migrations` テーブルを確認します。

```sql
SELECT * FROM django_migrations WHERE app = 'xxx';
```

このテーブルに `xxx` アプリのマイグレーション履歴がない場合、適用が正しく行われていない可能性があります。

## まとめ
1. `showmigrations` でマイグレーションが適用されているか確認
2. `makemigrations` で新しいマイグレーションを作成
3. `migrate` で適用
4. 必要なら `migrate --fake` でリセット
5. データベースの状態をチェック

Djangoのマイグレーションは、プロジェクトのデータベース管理において重要な作業の一つです。

適用されない場合は焦らずに、上記の手順を順番に試して、問題を特定して解決していきましょう！
[AWS]Amazon S3 バージョニング・オブジェクトロック 概要


Amazon S3の「バージョニング」と「オブジェクトロック」機能についてまとめる。

## 用語
- **S3バージョニング**  
    同一バケット内で同じキー名のオブジェクトに対して複数のバージョンを保持できる機能。これにより、オブジェクトが更新・削除された際にも、以前の状態に戻すことが可能となる。
- **オブジェクトロック**  
    オブジェクトに対し、指定した期間または無期限に変更（削除や上書き）を防止する機能。
    - **Governanceモード**：一定の管理者権限があれば、ロック解除や上書きが可能。
    - **Complianceモード**：設定された期間は強制的に不変状態となり、いかなる権限をもってしても変更できない（WORM: Write Once Read Many）。
## 用途
- **S3バージョニング**
    - **誤操作対策**：誤ってオブジェクトを削除または上書きしてしまった場合に、以前のバージョンから復元できる。
    - **変更履歴の保持**：オブジェクトの更新履歴を保存し、変更内容の追跡や監査に利用可能。
    - **バックアップ・災害復旧**：データ損失時の復旧手段として機能する。
- **オブジェクトロック**
    - **法令遵守**：金融や医療など、規制に基づくデータ保持要件を満たすために、データの不変性を保証する。
    - **セキュリティ対策**：内部・外部からの不正な削除や改ざんを防止し、重要データを保護する。
    - **コンプライアンス遵守**：企業ポリシーに則ったデータ管理を実現する。
## メリット
- **S3バージョニング**
    - **データ保全**：誤削除・上書きによるデータ損失リスクを大幅に低減。
    - **迅速な復元**：以前のバージョンに迅速にロールバックでき、システムの可用性を向上。
    - **監査対応**：変更履歴の追跡が可能なため、内部監査やセキュリティ対策に有効。
- **オブジェクトロック**
    - **不変性の保証**：設定された期間中、データが意図せず変更されるリスクを排除。
    - **コンプライアンス強化**：規制に応じたデータ保存ポリシーを実装することで、法的リスクを低減。
    - **セキュリティ向上**：内部・外部の悪意ある操作からデータを保護。

## 未設定時に生じるリスク
- **S3バージョニング未設定の場合**
    - 誤ってオブジェクトを削除または上書きすると、元に戻す手段がなくなり、データ損失のリスクが増大する。
    - 変更履歴が残らないため、監査対応やトラブルシューティングが困難になる。
- **オブジェクトロック未設定の場合**
    - 内部または外部からの不正な削除や改ざんに対して脆弱となり、データの信頼性や不変性が確保できない。
    - 法令や規制によるデータ保持要件を満たさず、コンプライアンス違反のリスクが発生する。

## AWS CLIによる設定方法
### S3バージョニングの有効化
```bash
aws s3api put-bucket-versioning --bucket <bucket-name> --versioning-configuration Status=Enabled
```
### オブジェクトロックの有効化
#### バケット新規作成
1.**バケット作成時にオブジェクトロックを有効化**  
```bash
aws s3api create-bucket \
    --bucket my-new-bucket \
    --object-lock-enabled-for-bucket
```
2.**オブジェクトロックの構成設定**  
- 既存バケットに対して、ロックルール（デフォルト保持ポリシー）を設定する。
- 例として、**GOVERNANCE** モードで30日間の保持を設定する場合を示す。
```bash
aws s3api put-object-lock-configuration \
    --bucket my-new-bucket \
    --object-lock-configuration '{
         "ObjectLockEnabled": "Enabled",
         "Rule": {
             "DefaultRetention": {
                 "Mode": "GOVERNANCE",
                 "Days": 30
             }
         }
     }'
```
        
#### 作成済みバケット変更
- 既存バケットに対して **put-object-lock-configuration** コマンドを用い、オブジェクトロックを有効化し、デフォルト保持ポリシーを設定する。
- 以下は例として、**GOVERNANCE** モードで30日間の保持を設定するケース。
```shell
aws s3api put-object-lock-configuration \
    --bucket my-existing-bucket \
    --object-lock-configuration '{
         "ObjectLockEnabled": "Enabled",
         "Rule": {
             "DefaultRetention": {
                 "Mode": "GOVERNANCE",
                 "Days": 30
             }
         }
     }'
```

## 参考文献

- [Amazon S3 バージョニング (公式ドキュメント)](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/Versioning.html)
- [Amazon S3 オブジェクトロック (公式ドキュメント)](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/object-lock.html) 
- [AWS CLI: put-bucket-versioning](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-versioning.html) 
- [AWS CLI: put-object-lock-configuration](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object-lock-configuration.html) 
- [Amazon S3 で既存のバケットでの S3 オブジェクトロックの有効化のサポートが開始](https://aws.amazon.com/jp/about-aws/whats-new/2023/11/amazon-s3-enabling-object-lock-buckets/)