メインコンテンツまでスキップ

UI設定

UI Settingパッケージは、コード変更なしで動的なアプリケーション設定を管理するための柔軟なフレームワークを提供します。管理者がカスタムフィールドを定義し、ユーザーがそのスキーマに準拠したデータを保存できるようにします。

このパッケージを使用するタイミング

以下の場合にこのパッケージを使用します:

  • 開発者の介入なしに管理者がカスタムフォームを定義できるようにする
  • テナント固有の設定(テーマ、プリファレンス、制限)を保存する
  • ユーザーが編集可能な通知やメールテンプレート設定を作成する
  • 設定可能なドロップダウンリストやマスターデータテーブルを構築する

このパッケージが解決する問題

問題解決策
新しい設定ごとにコードのデプロイが必要APIを通じてスキーマを動的に定義
テナント間で設定構造が異なるマルチテナントスキーマサポート
ユーザー入力設定のバリデーションがないフィールド定義でデータ型と制約を強制
設定用の管理UIを構築するのが困難スキーマイントロスペクション付きREST API

コアコンセプト

このモジュールは2つの主要コンポーネントで動作します:

  1. 設定: データエントリのスキーマ/構造を定義します。各設定にはコード、名前、およびデータ構造を記述するフィールドのリストがあります。

  2. データ設定: 設定のスキーマに準拠する実際のデータエントリ。各データ設定は特定の設定コードに属します。

インストール

npm install @mbc-cqrs-serverless/ui-setting

コアコンセプト

このモジュールは2つの主要コンポーネントで動作します:

  1. 設定: データエントリのスキーマ/構造を定義します。各設定にはコード、名前、およびデータ構造を記述するフィールドのリストがあります。

  2. データ設定: 設定のスキーマに準拠する実際のデータエントリ。各データ設定は特定の設定コードに属します。

モジュール設定

アプリケーションにSettingModuleを登録します:

import { Module } from '@nestjs/common';
import { SettingModule } from '@mbc-cqrs-serverless/ui-setting';

@Module({
imports: [
SettingModule.register({
enableSettingController: true, // Enable REST API for settings
enableDataController: true, // Enable REST API for data settings
}),
],
})
export class AppModule {}

設定オプション

オプション説明
enableSettingControllerboolean設定REST APIコントローラーを有効化
enableDataControllerbooleanデータ設定REST APIコントローラーを有効化

Settingサービス

SettingServiceは設定定義を管理します。

利用可能なメソッド

import { SettingService } from '@mbc-cqrs-serverless/ui-setting';

@Injectable()
export class MyService {
constructor(private readonly settingService: SettingService) {}

async example() {
// List all settings for a tenant
const settings = await this.settingService.list(tenantCode);

// Get a specific setting
const setting = await this.settingService.get({ pk, sk });

// Create a new setting
const newSetting = await this.settingService.create(
tenantCode,
createDto,
{ invokeContext }
);

// Update a setting
const updated = await this.settingService.update(
{ pk, sk },
updateDto,
{ invokeContext }
);

// Delete a setting
const deleted = await this.settingService.delete(
{ pk, sk },
{ invokeContext }
);

// Check if a setting code exists
const exists = await this.settingService.checkExistSettingCode(
tenantCode,
code
);
}
}

設定の作成

const createDto: CreateSettingDto = {
code: 'user-preferences',
name: 'User Preferences',
attributes: {
description: 'User preference settings',
fields: [
{
physicalName: 'theme',
name: 'Theme',
dataType: 'string',
isRequired: true,
isShowedOnList: true,
defaultValue: 'light',
},
{
physicalName: 'language',
name: 'Language',
dataType: 'string',
isRequired: true,
isShowedOnList: true,
defaultValue: 'en',
},
{
physicalName: 'pageSize',
name: 'Page Size',
dataType: 'number',
isRequired: false,
isShowedOnList: false,
min: '10',
max: '100',
defaultValue: '20',
},
],
},
};

フィールド定義

設定内の各フィールドには以下のプロパティを設定できます:

プロパティ必須説明
physicalNamestringはいフィールドの一意識別子
namestringはい表示名
descriptionstringいいえフィールドの説明
dataTypestringはいデータ型(string、number、booleanなど)
minstringいいえ数値フィールドの最小値
maxstringいいえ数値フィールドの最大値
lengthstringいいえ文字列フィールドの最大長
maxRownumberいいえ複数行テキストの最大行数
defaultValuestringいいえフィールドのデフォルト値
isRequiredbooleanはいフィールドが必須かどうか
isShowedOnListbooleanはいリストビューに表示するかどうか
dataFormatstringいいえデータのフォーマット指定

DataSettingサービス

DataSettingServiceは定義された設定のデータエントリを管理します。

利用可能なメソッド

import { DataSettingService } from '@mbc-cqrs-serverless/ui-setting';

@Injectable()
export class MyService {
constructor(private readonly dataSettingService: DataSettingService) {}

async example() {
// List data settings (optionally filter by setting code)
const dataList = await this.dataSettingService.list(
tenantCode,
{ settingCode: 'user-preferences' }
);

// Get a specific data setting
const data = await this.dataSettingService.get({ pk, sk });

// Create a new data setting
const newData = await this.dataSettingService.create(
tenantCode,
createDto,
{ invokeContext }
);

// Update a data setting
const updated = await this.dataSettingService.update(
{ pk, sk },
updateDto,
{ invokeContext }
);

// Delete a data setting
const deleted = await this.dataSettingService.delete(
{ pk, sk },
{ invokeContext }
);

// Check if a data code exists
const exists = await this.dataSettingService.checkExistCode(
tenantCode,
settingCode,
code
);
}
}

データ設定の作成

const createDto: CreateDataSettingDto = {
settingCode: 'user-preferences',
code: 'user-001',
name: 'User 001 Preferences',
attributes: {
theme: 'dark',
language: 'ja',
pageSize: 50,
},
};

REST APIエンドポイント

コントローラーが有効な場合、以下のエンドポイントが利用可能です:

設定エンドポイント

メソッドエンドポイント説明
GET/settingsすべての設定を一覧表示
GET/settings/:pk/:sk特定の設定を取得
POST/settings新しい設定を作成
PUT/settings/:pk/:sk設定を更新
DELETE/settings/:pk/:sk設定を削除

データ設定エンドポイント

メソッドエンドポイント説明
GET/data-settingsすべてのデータ設定を一覧表示
GET/data-settings/:pk/:sk特定のデータ設定を取得
POST/data-settings新しいデータ設定を作成
PUT/data-settings/:pk/:skデータ設定を更新
DELETE/data-settings/:pk/:skデータ設定を削除

マルチテナントサポート

このモジュールはマルチテナントのデータ分離を自動的に処理します。各テナントの設定とデータはテナント固有のキーで保存されます:

// Settings are stored with tenant-prefixed keys
// pk: MASTER#<tenantCode>
// sk: SETTING#<code>

// Data settings are stored with setting-prefixed keys
// pk: MASTER#<tenantCode>
// sk: <settingCode>#<code>

Example Use Cases

Use Case 1: User Notification Preferences

Scenario: Each user can configure their notification preferences (email on/off, SMS on/off).

Implementation: Create a "notification-settings" schema, then store each user's preferences as data entries.

@Injectable()
export class AppConfigService {
constructor(
private readonly settingService: SettingService,
private readonly dataSettingService: DataSettingService,
) {}

async initializeDefaultSettings(tenantCode: string, invokeContext: IInvoke) {
// Create a setting schema for notification preferences
const settingDto: CreateSettingDto = {
code: 'notification-settings',
name: 'Notification Settings',
attributes: {
description: 'Configure notification preferences',
fields: [
{
physicalName: 'emailEnabled',
name: 'Email Notifications',
dataType: 'boolean',
isRequired: true,
isShowedOnList: true,
defaultValue: 'true',
},
{
physicalName: 'smsEnabled',
name: 'SMS Notifications',
dataType: 'boolean',
isRequired: true,
isShowedOnList: true,
defaultValue: 'false',
},
],
},
};

await this.settingService.create(tenantCode, settingDto, { invokeContext });
}

async getUserNotificationSettings(
tenantCode: string,
userId: string,
) {
const { items } = await this.dataSettingService.list(tenantCode, {
settingCode: 'notification-settings',
});

return items.find(item => item.code === userId);
}
}