# キュー、Vault、GraphQL、接続制限

いずれも**専用データベース**（`p_<ref>`）にあるプロジェクトで使います。新しいプロジェクトは最初から専用データベースです。

## キュー（pgmq）

pgmqと同じSQL関数です。最初の`create_queue`が`pgmq`スキーマをインストールします。

```sql
select pgmq.create('jobs');
select * from pgmq.send('jobs', '{"to": "a@example.com"}');
select * from pgmq.read('jobs', 30, 10);
select pgmq.archive('jobs', 1);
select pgmq.delete('jobs', 2);
select * from pgmq.pop('jobs');
select * from pgmq.metrics('jobs');
```

ツール: `list_queues`、`create_queue`、`send_queue_message`、`peek_queue`（取り出さずに見る）、`purge_queue`、
`delete_queue`、`set_queues_api`。キューのテーブル`pgmq.q_<名前>`はサービスロールのもので、アクセスルールが有効です。
`set_queues_api { exposed: true }`にすると、データAPIから呼べます。

```js
await supabase.schema('pgmq_public').rpc('send', { queue_name: 'jobs', message: { hello: 'world' } })
await supabase.schema('pgmq_public').rpc('read', { queue_name: 'jobs', sleep_seconds: 30, n: 5 })
```

公開キーやログインユーザーが使うには、SQLで権限とルールを与えます。

```sql
grant insert, select, update on pgmq.q_jobs to authenticated;
create policy "own jobs" on pgmq.q_jobs for all to authenticated using (true) with check (true);
```

## Vault

シークレットを暗号化し、プロジェクトのデータベースの`vault.secrets`に保存します。鍵はプラットフォームが持ち、データベースには
保存されないため、ダンプ、バックアップ、ブランチには暗号文だけが残ります。シークレットキー（サービスロール）で読むときだけ復号されます。

```sql
select vault.create_secret('sk_live_...', 'stripe_key', 'Stripe');
select decrypted_secret from vault.decrypted_secrets where name = 'stripe_key';
select vault.update_secret('<id>', 'sk_live_new');
```

ツール: `list_vault_secrets`（名前のみ）、`create_vault_secret`、`update_vault_secret`、`delete_vault_secret`。
公開キーとログインユーザーは`vault`スキーマを見られず、直接接続（`<ref>_db`）では`decrypted_secret`はnullです。

## 専用データベースへの移行

Vaultと大きなデータベースには専用データベースが必要です（Proプランから）。`get_database_move`で今どこにあるかと移行の状態を確認し、
`move_to_dedicated_database`でコンソールの「今すぐ移行」と同じように移行を依頼します（オーナーと管理者）。
順番が来ると移行し、移行中は書き込みが止まり、読み取りは続きます。REST: `GET`と`POST /projects/<ref>/database/move`、
CLI: `oneend db move`、`oneend db move now`。

## 専用ディスク

データベースが大きくなった有料プロジェクトは、ほかのプロジェクトと共有するディスクから、このプロジェクトだけのディスクと Postgres に移ります
（Supabase がプロジェクトごとにインスタンスとボリュームを持つのと同じです）。20GB を超えると自動で移し（支出上限がオフの組織または
Enterprise）、Enterprise はサイズに関係なく依頼できます。ディスクは `max(1.2 × データベース, 20GB)` から始まり、75% を超えると 1.5 倍に
増え（4時間に1回まで）、作成したサイズに対して1GBあたり月 ₩1,200（75セント）で請求します。移している間は書き込みが失敗し、読み取りは
できます（`expected_downtime_seconds`）。接続文字列とパスワードは変わりません。移した後は特定時点ではなく毎日のバックアップから復元します。

`get_dedicated_disk` でディスクのサイズ、使用量、月額、30日間の履歴、縮小の提案を確認し、`request_dedicated_disk` で移行を、
`shrink_dedicated_disk` で縮小を依頼します（オーナーと管理者）。自動で縮小することはありません。7日間 25% 未満の使用が続くと縮小を
提案し、確認するとより小さいディスクを作って移し、元のディスクを削除します。プロジェクトを削除すると、30日後にディスクも削除され費用は0になります。
REST: `GET`と`POST /projects/<ref>/database/dedicated-disk`、`POST /projects/<ref>/database/dedicated-disk/shrink`、
CLI: `oneend db disk`、`oneend db disk request`、`oneend db disk shrink`。

## 専用サーバー

Pro から、プロジェクトだけが使うサーバーを借りられます(アプリとデータベースが共有し、データベースはメモリの 25%)。サイズと場所ごとの
月額は `list_server_sizes` が示し、ここには書きません。`get_server` がサーバー・待機サーバー・作業を表示し、`request_server`(tier, region)
が借り、`resize_server`(tier, when=now|tonight)がサイズを変え(待機サーバーがなければ 3〜5 分応答なし)、`set_standby`(standby,
auto_failover)が待機サーバーと自動切り替え(60 秒応答なし)を、`move_server`(region)が場所の移動を(無料、月に 1 回、古いサーバーは 7 日保管)、
`release_server`(confirm=ref)が返却を、`set_restore_days`(7|28)が復元できる期間を設定します。支払いが失敗すると 7 日間読み取り専用になり、
その後最後のバックアップを取ってサーバーを削除します。
REST: `GET`・`POST`・`PATCH`・`DELETE /projects/<ref>/server`、`PUT /projects/<ref>/server/standby`、`POST /projects/<ref>/server/move`、
`PUT /projects/<ref>/server/restore-days`。CLI: `oneend server`、`oneend server request|resize|standby|move|release|restore-days`。

## GraphQL

`enable_extension { ref, name: "pg_graphql" }`で有効にすると`/graphql/v1`が開きます。キーとアクセスルールは`/rest/v1`と同じです。

```
POST https://<ref>.<zone>/graphql/v1
apikey: <publishable key>
{"query": "{ todosCollection { edges { node { id title } } } }"}
```

## 直接接続の接続制限とTLS

`get_network_restrictions`、`update_network_restrictions { ref, allowed_cidrs: ["203.0.113.0/24"], enforce_ssl: true }`。
既定ではすべてのアドレスを許可し、TLSが必須です。リクエストを送ったアドレスが一覧にないと、`confirm: true`なしでは保存されません。
コンソール、API、`run_sql`は接続プーラーを通らないため、制限を誤ってかけてもそこから元に戻せます。

## 読み取り専用レプリカ

まだありません。本番の待機サーバー（ステージ3）は障害対策用で、お客様の接続は受け付けません。

HTTPでは`GET /queues`、`POST /queues`、`POST /queues/<名前>/messages`、`GET /queues/<名前>/messages`、
`POST /queues/<名前>/purge`、`DELETE /queues/<名前>`、`PUT /queues/api`、`GET /vault`、`POST /vault`、
`PATCH /vault/<名前>`、`DELETE /vault/<名前>`、`GET /network-restrictions`、`PUT /network-restrictions`です。

---

https://end.blackall.ai/docs/database-features?lang=ja
