# アプリの登録と運用

検証用の利用環境で、アプリを1つ登録し、データを操作し、止めて再開するまでを通しで行う手順です。既存の顧客データには、そのまま適用しないでください。

先に、[利用者として接続する](authentication.md)と、[HTTP・実行例](examples.md)を確認してください。

## 登場人物

この手順には、次の人と処理が登場します。用語は[用語集](glossary.md)にもあります。

| 登場するもの | この手順での役割 | 必要な権限 |
| --- | --- | --- |
| 利用者 | 基盤にログインして、アプリのデータを作成・更新・削除する人 | 対象の表の読み取り・書き込み・削除の範囲 |
| 組織の管理者 | あなたの組織で、利用者に表を使う権限を与え、アプリ定義を登録し、serviceを承認する人 | 管理権限（`manage_access`と`service_administrator`の両方）と、MFA |
| 表の設計者 | アプリの表の設計を担う人。表の設計の権限を、持つ必要がある | 対象の表の`can_design` |
| あなた（開発者） | 手順を実行し、アプリを登録して、結果を確認する | 手順ごとの実施者の権限 |
| service | 人の操作を介さずに動く処理。最後に設定する | 組織の管理者の承認 |

## 管理権限について

管理権限（`manage_access`と`service_administrator`）は、利用環境で事前に登録された権限です。誰が初期設定を行うかは、利用環境の取り決めによります。表の権限の`role`として、付与することはできません。自分で権限を上げるAPIもありません。

`GET /v1/me`の`permissions`と`capabilities`には、これらが出るとは限りません。持っているかどうかを、自分で確かめる方法は、現在ありません。権限の付与は、環境管理者に依頼してください。権限がないのに、管理のAPIへ試しに書き込む方法で、確認しないでください。

## 全体の流れ

| 手順 | 実施者 | 目的 |
| --- | --- | --- |
| 1. 利用者に権限を与える | 組織の管理者 | 利用者が、表を使えるようにする |
| 2. アプリを計画して登録する | 組織の管理者（対象の表の`can_design`も必要） | アプリが使う表と依存先を、基盤に登録する |
| 3. データを作成・取得・更新する | 利用者 | 登録した表を、利用者の権限で使う |
| 4. 関連を設定する | 表の設計者（`can_design`を持つ利用者） | 表どうしの親子の関係を設定する |
| 5. 削除と復元 | 利用者 | 行を削除し、ごみ箱から戻す |
| 6. 停止と再開 | 組織の管理者 | アプリを止め、再開する |
| 7. serviceを設定する | 組織の管理者と開発者 | 人の操作を介さない処理に、限られた権限を与える |
| 8. 記録して終了する | あなた | 結果を記録する |

## 1. 利用者に権限を与える

実施者: 組織の管理者

アプリのデータを使う利用者に、対象の表を使う権限を与えます。権限は、表ごと、利用者ごとに設定します。

1. `GET /v2/access/subjects`で利用者の一覧を、`GET /v2/access/tables`で表の一覧を確認します。
2. `GET /v2/access/grants/{subjectId}/{collection}`で、現在の権限と`version`を取得します。
3. `PUT`で、最新の`version`、`enabled`、`role`、`read_scope`、`write_scope`、`can_design`、`can_close`、`can_import`、`expires_at`を送ります。

- 初回の`version=0`は、現在の権限がないことを取得して確認した場合だけ使います。
- `expires_at`は、実施する時点より未来の、承認の期限にします。
- 権限の変更では、`Idempotency-Key`と`If-Match`を使いません。本文の`version`を使います。
- 削除の範囲は、別の契約です。`write_scope`だけで削除できるとは限りません。削除の範囲（`none`・`own`・`all`）は、`GET /v2/access/deletions/{subjectId}/{collection}`で確かめ、同じパスの`PUT`で設定します（利用環境で有効な場合）。この`PUT`は、上の権限の変更と違い、本文の`version`・`scope`・`expires_at`・`reason`に加えて、ヘッダーの`Idempotency-Key`が必要です。利用者の今の削除の範囲は、表の定義の応答の`delete_scope`で確かめられます。
- 設定した後、利用者の新しいリクエストで、許可と拒否を確認します。
- まだ作っていない表の識別子にも、期限付きの権限を設定できます。先に、表の設計の権限（`can_design`）を付けてから、アプリを計画して登録します。権限を設定する相手の利用者は、登録済みである必要があります。
- `role`は、`^[a-z][a-z0-9_-]{0,47}$`の名前です。`owner`は予約されていて、使えません。`role`の名前は、列の`read`・`write`と、表の`export_roles`にある、同じ名前と照合されます。列の`write`は、`read`に含まれる必要があります。
- `GET /v2/access/subjects`は、`id`、`active`、`actor_type`だけを返し、表示名は返しません。どの`id`が誰かは、環境管理者から受け取る対応表などで、確認します。

## 2. アプリを計画して登録する

実施者: 組織の管理者。登録する表については、実施する利用者に、`can_design`（表の設計の権限）が必要です。

登録の前に「計画」を作り、変更の内容を確認してから、同じ内容で「適用」します。

1. `POST /v2/apps/plan`に、`id`、`version`、`name`、`datasets`、`dependencies`を持つmanifestを送ります。`owned`はアプリが所有する表、`shared`は既存の共有表です。新しい表を作るにも、事前に設計の権限が必要です。
2. 返った`changes`を確認します。
3. 同じmanifestと、返された`fingerprint`で、`POST /v2/apps/apply`を実行します。`Idempotency-Key`が必須です。例にある`aaaa…`の`fingerprint`を、実際には送らないでください。
4. `GET /v2/apps/{appId}`と、各表のdefinitionで、登録の結果を確認します。

manifestの`version`は、新しいアプリでは1、更新では、現在の版に1を足した値です。更新するときは、現在の状態を読み、更新したmanifestで計画を作り、同じmanifestと`fingerprint`で適用します。競合したときは、計画を取り直して、差分を確認します。`revision`は、停止・再開などの状態の変更を含めた、競合を防ぐための版です。`manifest.version`とは別の値で、揃える必要はありません。停止と再開では、取得した`revision`を、そのまま送ります。

計画と適用の間に前提が変わったときは、競合として、再計画と再確認を行います。アプリの登録は、画面のプログラムのアップロードや、サーバーへの配置を行いません。

## 3. データを作成・取得・更新する

実施者: 利用者

ここからは、利用者の資格で操作します。

1. definitionの`schema_version`と、書ける列を確認します。
2. `POST /v2/tables/{collection}/batch`の`create`に`values`を送ります。`id`と所有者は、基盤が決めます。返った`id`と`version`を保存します。
3. 検索（`query`）で取得します。
4. `update`には、保存した`id`と`version`を指定します。

作成と更新は、別の`Idempotency-Key`を使います。412が返ったときは、[競合・再送・復帰](reliability.md)に従い、再取得、比較、利用者への確認へ進みます。結果が不明なだけのときは、同じキーと本文を保持します。

## 4. 関連を設定する

実施者: 表の設計者（`can_design`を持つ利用者）

子の表に、関連用の列を定義します。親と子の関係を、基盤に伝えます。

- `PUT /v2/tables/{collection}/access`に、`mode`、`parent_collection`、`field`、`cardinality`を送ります。`If-Match`には関連設定の現在の`version`を、`Idempotency-Key`も指定します。
- 親に所属する方式では、親と子の、現在の権限を確認します。
- 複数の表を一括で変更する`POST /v2/transactions`は、最大8表、合計100行の操作です。既存の親の`id`を使い、各表の`schema_version`を指定します。

## 5. 削除と復元

実施者: 利用者

1. ごみ箱の保持期間が設定されていることと、利用者の削除の範囲を、先に確認します。
2. `delete`に、行の`id`と`version`、必要なら`reason`を送ります。
3. `GET /v2/tables/{collection}/trash`で、`trash_id`と現在の`version`を取得します。
4. `POST /v2/tables/{collection}/trash/{trashId}/restore`に、その`version`、`reason`、`Idempotency-Key`を渡します。

`rowId`と`trashId`を取り違えないでください。定義の変更、期限切れ、現在の権限による拒否は、自動では回避しません。

## 6. 停止と再開

実施者: 組織の管理者

停止と再開は、行の操作とは別の、アプリの状態の操作です。

1. `GET /v2/apps/{appId}`で、`revision`を取得します。
2. `POST /v2/apps/{appId}/state`に、`Idempotency-Key`を付けて、`action=stop`、`revision`、`reason`を送ります。
3. 再開は、別の`Idempotency-Key`と、現在の`revision`で、`action=resume`を送ります。停止と再開の、どちらも`reason`が必須です。

`trash`、`restore`、`detach`も同じ状態のAPIですが、保持期間、依存先、現在の状態に従います。復元した直後は`stopped`になります。必要な確認の後に、明示的に再開します。

## 7. serviceを設定する

実施者: 組織の管理者と開発者

[serviceとして接続する](service-access.md)の手順で、申請、承認、provision、`private_key_jwt`、activateを行います。

確認すること:

- serviceの検索（query）が成功する。
- 許可されていない列、表、操作が、拒否される。
- 人向けの`GET /v1/me`が、拒否される。
- 書き込みを許可するときは、serviceのbatch（最大50操作）を使い、本文の現在の版と`Idempotency-Key`を確認する。
- suspendまたはrevokeの後に、古い資格が拒否される。

## 8. 記録して終了する

対象のAPI版、利用環境、実施した時刻、操作ID、HTTPとcodeと`request_id`、許可と拒否、再試行したときの同じ操作の識別子を記録します。資格と原本のデータは、記録しません。
