feat(settings): store Khanegi keys in settings tables instead of tenant JSON
Template defaults seed from deploy_settings_const; new tenants copy them, import decides per key, and /get_settings reads the per-tenant rows. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,15 @@
|
||||
import { IsString, MaxLength, MinLength } from 'class-validator';
|
||||
import { Allow, IsArray, IsIn, IsOptional, IsString, MaxLength, MinLength, ValidateNested } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
|
||||
export class ImportDecisionDto {
|
||||
@IsString()
|
||||
@MinLength(1)
|
||||
@MaxLength(50)
|
||||
key!: string;
|
||||
|
||||
@IsIn(['none', 'this', 'all'])
|
||||
scope!: 'none' | 'this' | 'all';
|
||||
}
|
||||
|
||||
export class ImportProgramSettingsDto {
|
||||
@IsString()
|
||||
@@ -10,4 +21,15 @@ export class ImportProgramSettingsDto {
|
||||
@MinLength(1)
|
||||
@MaxLength(120)
|
||||
password!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => ImportDecisionDto)
|
||||
decisions?: ImportDecisionDto[];
|
||||
|
||||
/** اگر true فقط پیشنمایش برگردد */
|
||||
@IsOptional()
|
||||
@Allow()
|
||||
preview?: boolean;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Allow, IsArray, IsOptional, IsString, MaxLength, MinLength } from 'class-validator';
|
||||
|
||||
export class AddSettingKeysDto {
|
||||
@IsArray()
|
||||
@Allow()
|
||||
items!: Array<Record<string, unknown>>;
|
||||
}
|
||||
|
||||
export class DeleteSettingKeyDto {
|
||||
@IsString()
|
||||
@MinLength(1)
|
||||
@MaxLength(50)
|
||||
key!: string;
|
||||
}
|
||||
@@ -35,10 +35,14 @@ export class ProgramSettingsController {
|
||||
@Body() body: ImportProgramSettingsDto,
|
||||
@CurrentUser() user: { id: string },
|
||||
) {
|
||||
return this.programSettings.importFromKhanegi(
|
||||
if (body.preview) {
|
||||
return this.programSettings.previewImport(tenantId, body.mobile, body.password);
|
||||
}
|
||||
return this.programSettings.applyImport(
|
||||
tenantId,
|
||||
body.mobile,
|
||||
body.password,
|
||||
body.decisions || [],
|
||||
user.id,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ProgramSettingsController } from './program-settings.controller';
|
||||
import { PublicProgramSettingsController } from './public-program-settings.controller';
|
||||
import { ApiPublicProgramSettingsController } from './api-public-program-settings.controller';
|
||||
import { RemoteProgramSettingsController } from './remote-program-settings.controller';
|
||||
import { SettingTemplatesController } from './setting-templates.controller';
|
||||
import { ProgramSettingsService } from './program-settings.service';
|
||||
|
||||
@Module({
|
||||
@@ -14,6 +15,7 @@ import { ProgramSettingsService } from './program-settings.service';
|
||||
PublicProgramSettingsController,
|
||||
ApiPublicProgramSettingsController,
|
||||
RemoteProgramSettingsController,
|
||||
SettingTemplatesController,
|
||||
],
|
||||
providers: [ProgramSettingsService],
|
||||
exports: [ProgramSettingsService],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
import { Body, Controller, Delete, Get, Post, Query, UseGuards } from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
||||
import { PermissionsGuard } from '../auth/permissions.guard';
|
||||
import { RequirePermissions } from '../auth/permissions.decorator';
|
||||
import { CurrentUser } from '../auth/current-user.decorator';
|
||||
import { AddSettingKeysDto, DeleteSettingKeyDto } from './dto/setting-keys.dto';
|
||||
import { ProgramSettingsService } from './program-settings.service';
|
||||
|
||||
@Controller('setting-templates')
|
||||
@UseGuards(JwtAuthGuard, PermissionsGuard)
|
||||
export class SettingTemplatesController {
|
||||
constructor(private readonly programSettings: ProgramSettingsService) {}
|
||||
|
||||
@Get()
|
||||
@RequirePermissions('khanegi:read')
|
||||
list() {
|
||||
return this.programSettings.listTemplates();
|
||||
}
|
||||
|
||||
@Post('keys')
|
||||
@RequirePermissions('khanegi:write')
|
||||
addKeys(@Body() body: AddSettingKeysDto, @CurrentUser() user: { id: string }) {
|
||||
return this.programSettings.addKeys(body.items || [], user.id);
|
||||
}
|
||||
|
||||
@Delete('keys')
|
||||
@RequirePermissions('khanegi:write')
|
||||
removeKey(
|
||||
@Query('key') keyQuery: string | undefined,
|
||||
@Body() body: DeleteSettingKeyDto | undefined,
|
||||
@CurrentUser() user: { id: string },
|
||||
) {
|
||||
const key = body?.key || keyQuery || '';
|
||||
return this.programSettings.deleteKey(key, user.id);
|
||||
}
|
||||
|
||||
@Post('seed')
|
||||
@RequirePermissions('khanegi:write')
|
||||
seed() {
|
||||
return this.programSettings.ensureTemplatesSeeded();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user