テナント管理画面に変更履歴を付ける(改修案)
本体の標準機能ではありません
テナントの編集画面には「変更履歴の一覧」タブがありません。このページは、それを足す場合の設計メモです。
前提にした現行実装
テナントの履歴の仕組みは、画面と URL の部分だけが欠けています。
| 項目 | 1.5.8.1 |
|---|---|
Tenants_history テーブル | ある(CodeDefiner が作る。データベースのテーブル構成) |
| 更新時の履歴のコピー | 動いている。verUp のとき TenantsCopyToStatement で更新前の行を Tenants_history に入れ、Ver を増やす(TenantModel.cs#L979-L986) |
Tenants_history の主キー | (TenantId, Ver)(Tenants_TenantId.json) |
| 履歴の一覧・1 件の表示 | TenantUtilities.Histories() / History() はある(TenantUtilities.cs#L1632、L1729) |
| 履歴タブの中身 | FieldSetHistories の領域は作られる(TenantUtilities.cs#L560) |
| タブの見出し | 無い。EditorTabs は「全般」「SCIM トークン」「サーバースクリプト」だけ(TenantUtilities.cs#L617-L640) |
| コントローラー | 無い。TenantsController に Histories・History・RestoreFromHistory・DeleteHistory のアクションが無い(TenantsController.cs) |
| 復元・削除のメソッド | 無い |
主キーは 1.5.8.1 で直っている
調査した 1.5.1.0 の定義では Tenants_TenantId.json に PkHistory が無く、Tenants_history の主キーは (Ver) だけでした。複数テナントの同じバージョンの履歴が衝突するため、履歴機能を足す前に直す必要がありました。1.5.8.1 の定義には "PkHistory": "1" があり、この前提作業は不要です。
ほかの管理画面との比較です。
| モデル | 履歴の一覧 | タブ | 復元 | 削除 |
|---|---|---|---|---|
Issues / Results / Wikis(items) | あり | あり | あり | あり |
| Users / Depts / Groups | あり | あり | なし | なし |
| Tenants | メソッドだけ | なし | なし | なし |
Users・Depts・Groups の一覧は、UsersController などの Histories(int id) / History(int id) から呼ばれます(UsersController.cs#L155-L180)。復元・削除のボタンを出す HistoryCommands は context.Controller == "items" のときだけ表示されるので(HtmlHistoryCommands.cs#L41-L46)、管理画面には復元・削除のボタンが出ません。表示条件の全体は 変更履歴タブと復元・削除ボタンの表示条件 にあります。
第 1 段階:履歴を見られるようにする
変更は 2 ファイルです。
タブの見出しを足す
TenantUtilities.EditorTabs() の最後に、Users・Depts・Groups と同じ条件(新規作成でないとき)で履歴タブを足します。
.Li(
_using: tenantModel.MethodType != BaseModel.MethodTypes.New,
action: () => hb
.A(
href: "#FieldSetHistories",
text: Displays.ChangeHistoryList(context: context)))コントローラーにアクションを足す
テナントの編集画面は URL に ID を持たないので、他の管理画面と違い context.TenantId を使います。自分のテナント以外の履歴を指定できないようにする意味もあります。
[HttpPost]
public string Histories()
{
var context = new Context();
var log = new SysLogModel(context: context);
var json = TenantUtilities.Histories(
context: context,
ss: SiteSettingsUtilities.TenantsSiteSettings(context: context),
tenantId: context.TenantId);
log.Finish(context: context, responseSize: json.Length);
return json;
}
[HttpPost]
public string History()
{
var context = new Context();
var log = new SysLogModel(context: context);
var json = TenantUtilities.History(
context: context,
ss: SiteSettingsUtilities.TenantsSiteSettings(context: context),
tenantId: context.TenantId);
log.Finish(context: context, responseSize: json.Length);
return json;
}第 2 段階:復元・削除を足す
| 箇所 | 追加するもの |
|---|---|
TenantUtilities.cs | RestoreFromHistory()、DeleteHistory() |
TenantsController.cs | RestoreFromHistory(POST)、DeleteHistory(DELETE)のアクション |
TenantValidators.cs | 履歴の削除の検証(History.json の PhysicalDelete とテナント管理の権限) |
HtmlHistoryCommands.cs | ボタンを出す条件に tenants を足す |
復元
ResultUtilities.RestoreFromHistory() と同じ流れにします。
図を読み込み中…
tenantModel.SetByModel(new TenantModel().Get(
context: context,
ss: ss,
tableType: Sqls.TableTypes.History,
where: Rds.TenantsWhere()
.TenantId(tenantId)
.Ver(ver.First().ToInt())));
tenantModel.VerUp = true;
var errorData = tenantModel.Update(
context: context,
ss: ss,
otherInitValue: true);削除
History.json の PhysicalDelete を確かめ、選んだバージョン(またはすべて選択時はそれ以外)を Tenants_history から物理削除して、履歴の一覧を返し直します。
ボタンを出す条件
_using: (Parameters.History.Restore || Parameters.History.PhysicalDelete)
&& (context.Controller == "items" || context.Controller == "tenants")
&& (context.CanUpdate(ss: ss) || context.CanManageSite(ss: ss))
&& (ss.AllowRestoreHistories != false || ss.AllowPhysicalDeleteHistories != false)
&& !ss.Locked());CanUpdate と CanManageSite はサイトの権限を見る判定なので、テナントでは Permissions.CanManageTenant(context) で判定するように分ける必要があります。
注意点
| 項目 | 内容 |
|---|---|
| 自動生成コード | TenantsController.cs・TenantValidators.cs などは CodeDefiner の生成対象です。手で足したコードが再生成で消えないよう、テンプレート(App_Data/Definitions/Definition_Code/)側を直すか、再生成のたびに当て直します |
| 権限 | テナント管理の権限(Permissions.CanManageTenant(context)。テナント管理者か特権ユーザー)を必須にします |
| キャッシュ | テナントの設定はキャッシュされているので、復元後にキャッシュを作り直します |
| バックグラウンドサーバースクリプト | テナントの設定を復元すると、そのスケジュールも戻ります |
Tenants_deleted | 主キーは (TenantId) だけで、削除した状態は 1 件しか持てません。ほかのテーブルの _deleted も同じ設計です |