diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 52f5676c5..f8fc496d5 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -34,6 +34,7 @@ import { CompanyLogoModule } from './entities/company-logo/company-logo.module.j import { CompanyFaviconModule } from './entities/company-favicon/company-favicon.module.js'; import { CompanyTabTitleModule } from './entities/company-tab-title/company-tab-title.module.js'; import { TableFiltersModule } from './entities/table-filters/table-filters.module.js'; +import { DemoDataModule } from './entities/demo-data/demo-deta.module.js'; @Module({ imports: [ @@ -64,6 +65,7 @@ import { TableFiltersModule } from './entities/table-filters/table-filters.modul CompanyFaviconModule, CompanyTabTitleModule, TableFiltersModule, + DemoDataModule, ], controllers: [AppController], providers: [ diff --git a/backend/src/common/application/global-database-context.interface.ts b/backend/src/common/application/global-database-context.interface.ts index 8d684b891..4ce617d94 100644 --- a/backend/src/common/application/global-database-context.interface.ts +++ b/backend/src/common/application/global-database-context.interface.ts @@ -45,13 +45,15 @@ import { CompanyFaviconEntity } from '../../entities/company-favicon/company-fav import { CompanyTabTitleEntity } from '../../entities/company-tab-title/company-tab-title.entity.js'; import { TableFiltersEntity } from '../../entities/table-filters/table-filters.entity.js'; import { ITableFiltersCustomRepository } from '../../entities/table-filters/repository/table-filters-custom-repository.interface.js'; +import { TableSettingsEntity } from '../../entities/table-settings/table-settings.entity.js'; +import { TableWidgetEntity } from '../../entities/widget/table-widget.entity.js'; export interface IGlobalDatabaseContext extends IDatabaseContext { userRepository: Repository & IUserRepository; connectionRepository: Repository & IConnectionRepository; groupRepository: IGroupRepository; permissionRepository: IPermissionRepository; - tableSettingsRepository: ITableSettingsRepository; + tableSettingsRepository: Repository & ITableSettingsRepository; userAccessRepository: IUserAccessRepository; agentRepository: IAgentRepository; emailVerificationRepository: IEmailVerificationRepository; @@ -63,7 +65,7 @@ export interface IGlobalDatabaseContext extends IDatabaseContext { tableLogsRepository: ITableLogsRepository; userActionRepository: IUserActionRepository; logOutRepository: ILogOutRepository; - tableWidgetsRepository: ITableWidgetsRepository; + tableWidgetsRepository: Repository & ITableWidgetsRepository; tableInfoRepository: Repository; tableFieldInfoRepository: Repository; tableActionRepository: Repository & ITableActionRepository; diff --git a/backend/src/common/application/global-database-context.ts b/backend/src/common/application/global-database-context.ts index b685f9486..387138587 100644 --- a/backend/src/common/application/global-database-context.ts +++ b/backend/src/common/application/global-database-context.ts @@ -99,7 +99,7 @@ export class GlobalDatabaseContext implements IGlobalDatabaseContext { private _connectionRepository: Repository & IConnectionRepository; private _groupRepository: IGroupRepository; private _permissionRepository: IPermissionRepository; - private _tableSettingsRepository: ITableSettingsRepository; + private _tableSettingsRepository: Repository & ITableSettingsRepository; private _userAccessRepository: IUserAccessRepository; private _agentRepository: IAgentRepository; private _emailVerificationRepository: IEmailVerificationRepository; @@ -111,7 +111,7 @@ export class GlobalDatabaseContext implements IGlobalDatabaseContext { private _tableLogsRepository: ITableLogsRepository; private _userActionRepository: IUserActionRepository; private _logOutRepository: ILogOutRepository; - private _tableWidgetsRepository: ITableWidgetsRepository; + private _tableWidgetsRepository: Repository & ITableWidgetsRepository; private _tableFieldInfoRepository: Repository; private _tableInfoReposioty: Repository; private _tableActionRepository: Repository & ITableActionRepository; @@ -234,7 +234,7 @@ export class GlobalDatabaseContext implements IGlobalDatabaseContext { return this._permissionRepository; } - public get tableSettingsRepository(): ITableSettingsRepository { + public get tableSettingsRepository(): Repository & ITableSettingsRepository { return this._tableSettingsRepository; } @@ -282,7 +282,7 @@ export class GlobalDatabaseContext implements IGlobalDatabaseContext { return this._logOutRepository; } - public get tableWidgetsRepository(): ITableWidgetsRepository { + public get tableWidgetsRepository(): Repository & ITableWidgetsRepository { return this._tableWidgetsRepository; } diff --git a/backend/src/entities/demo-data/demo-data.service.ts b/backend/src/entities/demo-data/demo-data.service.ts new file mode 100644 index 000000000..f94c112ef --- /dev/null +++ b/backend/src/entities/demo-data/demo-data.service.ts @@ -0,0 +1,1125 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/enums/connection-types-enum.js'; +import { IGlobalDatabaseContext } from '../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../common/data-injection.tokens.js'; +import { QueryOrderingEnum } from '../../enums/query-ordering.enum.js'; +import { isTest } from '../../helpers/app/is-test.js'; +import { Constants } from '../../helpers/constants/constants.js'; +import { CreateConnectionPropertiesDs } from '../connection-properties/application/data-structures/create-connection-properties.ds.js'; +import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; +import { buildConnectionPropertiesEntity } from '../connection-properties/utils/build-connection-properties-entity.js'; +import { ConnectionEntity } from '../connection/connection.entity.js'; +import { GroupEntity } from '../group/group.entity.js'; +import { PermissionEntity } from '../permission/permission.entity.js'; +import { CreateTableSettingsDs } from '../table-settings/application/data-structures/create-table-settings.ds.js'; +import { TableSettingsEntity } from '../table-settings/table-settings.entity.js'; +import { buildNewTableSettingsEntity } from '../table-settings/utils/build-new-table-settings-entity.js'; +import { buildConnectionEntitiesFromTestDtos } from '../user/utils/build-connection-entities-from-test-dtos.js'; +import { buildDefaultAdminGroups } from '../user/utils/build-default-admin-groups.js'; +import { buildDefaultAdminPermissions } from '../user/utils/build-default-admin-permissions.js'; +import { CreateTableWidgetDs } from '../widget/application/data-sctructures/create-table-widgets.ds.js'; +import { WidgetTypeEnum } from '../../enums/widget-type.enum.js'; +import { buildNewTableWidgetEntity } from '../widget/utils/build-new-table-widget-entity.js'; +import { buildEmptyActionRule } from '../table-actions/table-action-rules-module/utils/build-empty-action-rule.util.js'; +import { + CreateRuleDataDs, + CreateTableActionEventDS, +} from '../table-actions/table-action-rules-module/application/data-structures/create-action-rules.ds.js'; +import { TableActionEventEnum } from '../../enums/table-action-event-enum.js'; +import { TableActionTypeEnum } from '../../enums/table-action-type.enum.js'; +import { buildActionEventWithRule } from '../table-actions/table-action-events-module/utils/build-action-event-with-rule.util.js'; +import { slackPostMessage } from '../../helpers/index.js'; + +@Injectable() +export class DemoDataService { + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} + + public async createDemoDataForUser(userId: string): Promise> { + try { + return await this.createDemoData(userId); + } catch (error) { + console.error(`Error during demo data creation for user with ID ${userId}:`, error); + await slackPostMessage(`Error during demo data creation for user with ID ${userId}: ${error.message}`); + } + } + + private async createDemoData(userId: string): Promise> { + const foundUser = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + }); + + if (!foundUser) { + throw new Error(`Unexpected error in demo data creation: User with ID ${userId} not found.`); + } + + const testConnections = Constants.getTestConnectionsArr(); + const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(testConnections); + const createdTestConnections = await Promise.all( + testConnectionsEntities.map(async (connection): Promise => { + connection.author = foundUser; + return await this._dbContext.connectionRepository.saveNewConnection(connection); + }), + ); + const testGroupsEntities = buildDefaultAdminGroups(foundUser, createdTestConnections); + const createdTestGroups = await Promise.all( + testGroupsEntities.map(async (group: GroupEntity) => { + return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); + }), + ); + const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); + await Promise.all( + testPermissionsEntities.map(async (permission: PermissionEntity) => { + await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); + }), + ); + + if (!isTest()) { + const createdPostgresConnection = createdTestConnections.find( + (connection) => connection.type === ConnectionTypesEnum.postgres, + ); + if (createdPostgresConnection) { + await this.createTestTableSettingsPostgres(createdPostgresConnection); + await this.createConnectionPropertiesForPostgresDemoData(createdPostgresConnection); + await this.createPostgresDemoTableActions(createdPostgresConnection); + } + const createdMySQLConnection = createdTestConnections.find( + (connection) => connection.type === ConnectionTypesEnum.mysql || connection.type === ConnectionTypesEnum.mysql2, + ); + if (createdMySQLConnection) { + await this.createTestTableSettingsMySQL(createdMySQLConnection); + await this.createMySQLDemoTableActions(createdMySQLConnection); + } + } + + return createdTestConnections; + } + + private async createTestTableSettingsMySQL(connection: ConnectionEntity): Promise> { + const tableSettingsDtos: Array = [ + { + table_name: 'event', + display_name: '', + search_fields: [], + excluded_fields: [], + list_fields: ['title', 'start_time', 'end_time', 'space_id', 'image_url', 'organizer_id', 'description', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['title', 'description'], + identification_fields: [], + columns_view: ['organizer_id', 'space_id', 'title', 'description', 'start_time', 'end_time'], + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'celebration', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'event_attendee', + display_name: '', + search_fields: ['event_id', 'user_id', 'guest_name', 'guest_email', 'status'], + excluded_fields: [], + list_fields: ['user_id', 'guest_name', 'status', 'guest_email', 'event_id', 'created_at', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['event_id', 'user_id', 'guest_name', 'guest_email'], + identification_fields: [], + columns_view: [], + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'groups', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'events', + display_name: null, + search_fields: [], + excluded_fields: [], + list_fields: [], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: null, + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: null, + identity_column: null, + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: null, + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'location', + display_name: '', + search_fields: ['name', 'address', 'city', 'country'], + excluded_fields: [], + list_fields: [], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['name', 'address', 'city', 'country'], + identification_fields: [], + columns_view: ['name', 'address', 'city', 'country'], + identity_column: 'name', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'domain', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'membership', + display_name: '', + search_fields: ['user_id', 'space_id', 'membership_type'], + excluded_fields: [], + list_fields: ['user_id', 'start_date', 'end_date', 'space_id', 'membership_type', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['user_id', 'space_id'], + identification_fields: [], + columns_view: ['user_id', 'space_id', 'start_date', 'end_date', 'membership_type'], + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'diamond', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'space', + display_name: '', + search_fields: ['location_id', 'name', 'type', 'description'], + excluded_fields: [], + list_fields: ['name', 'type', 'price_per_hour', 'capacity', 'location_id', 'description', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['location_id', 'name', 'description'], + identification_fields: [], + columns_view: [], + identity_column: 'name', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'desk', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'table-1', + display_name: '', + search_fields: [], + excluded_fields: [], + list_fields: [], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: [], + identity_column: '', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: '', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'user', + display_name: '', + search_fields: ['name', 'email', 'phone'], + excluded_fields: [], + list_fields: [], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['name', 'email', 'phone'], + identification_fields: [], + columns_view: [], + identity_column: 'name', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: ['email', 'phone'], + icon: 'person', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + ]; + const tableSettingEntities = tableSettingsDtos.map((dto) => { + return buildNewTableSettingsEntity(dto, connection); + }); + const savedTableSettings = await this._dbContext.tableSettingsRepository.save(tableSettingEntities); + await this.createDemoMySQLTablesWidgets(savedTableSettings); + return savedTableSettings; + } + + private async createDemoMySQLTablesWidgets(tableSettings: Array): Promise { + const foundEventTableSettings = tableSettings.find((settings) => settings.table_name === 'event'); + if (foundEventTableSettings) { + const createEventWidgetsData: Array = [ + { + field_name: 'organizer_id', + widget_type: '' as any, + name: 'Organizer', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'space_id', + widget_type: '' as any, + name: 'Space', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'start_time', + widget_type: '' as any, + name: 'Starts at', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'end_time', + widget_type: '' as any, + name: 'Ends at', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'image_url', + widget_type: 'Image' as any, + name: 'Poster', + description: '', + widget_params: '// provide image height in px to dispaly in table\n// example:\n{\n "height": 100\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createEventWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundEventTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + const foundEventAttendeeTableSettings = tableSettings.find((settings) => settings.table_name === 'event_attendee'); + if (foundEventAttendeeTableSettings) { + const createEventAttendeeWidgetsData: Array = [ + { + field_name: 'event_id', + widget_type: '' as any, + name: 'Event', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'status', + widget_type: 'Select' as any, + name: '', + description: '', + widget_params: + '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": true,\n "options": [\n {\n "value": "confirmed",\n "label": "⭐ Confirmed"\n },\n {\n "value": "checked_in",\n "label": "✅ Checked in"\n },\n {\n "value": "cancelled",\n "label": "❌ Cancelled"\n }\n ]\n}', + widget_options: null, + }, + ]; + const newWidgets = createEventAttendeeWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundEventAttendeeTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundMembershipTableSettings = tableSettings.find((settings) => settings.table_name === 'membership'); + if (foundMembershipTableSettings) { + const createMembershipWidgetsData: Array = [ + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: '', + widget_options: null, + }, + { + field_name: 'space_id', + widget_type: '' as any, + name: 'Space', + description: '', + widget_params: '', + widget_options: null, + }, + ]; + const newWidgets = createMembershipWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundMembershipTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundSpaceTableSettings = tableSettings.find((settings) => settings.table_name === 'space'); + if (foundSpaceTableSettings) { + const createSpaceWidgetsData: Array = [ + { + field_name: 'price_per_hour', + widget_type: 'Money' as any, + name: '', + description: '', + widget_params: + '// Configure money widget settings\n// example:\n{\n "default_currency": "USD",\n "show_currency_selector": false,\n "decimal_places": 2,\n "allow_negative": false\n}\n', + widget_options: null, + }, + { + field_name: 'type', + widget_type: 'Select' as any, + name: '', + description: '', + widget_params: + '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": false,\n "options": [\n {\n "value": "private_office",\n "label": "Private office"\n },\n {\n "value": "meeting_room",\n "label": "Meeting room"\n },\n {\n "value": "conference_room",\n "label": "Conference room"\n },\n {\n "value": "event_stage",\n "label": "Event stage"\n },\n {\n "value": "hot_desk",\n "label": "Hot desk"\n }\n ]\n}', + widget_options: null, + }, + ]; + const newWidgets = createSpaceWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundSpaceTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + const foundUserTableSettings = tableSettings.find((settings) => settings.table_name === 'user'); + if (foundUserTableSettings) { + const createUserWidgetsData: Array = [ + { + field_name: 'phone', + widget_type: 'Phone' as any, + name: '', + description: '', + widget_params: + '// Configure international phone number widget\n// example:\n{\n "preferred_countries": ["US", "GB", "CA"],\n "enable_placeholder": true,\n "enable_auto_country_select": true,\n "phone_validation": true,\n "format": "international"\n}\n', + widget_options: null, + }, + { + field_name: 'role', + widget_type: 'Select' as any, + name: '', + description: '', + widget_params: + '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": false,\n "options": [\n {\n "value": "admin",\n "label": "👑 Admin"\n },\n {\n "value": "organizer",\n "label": "👩‍💻 Organizer"\n },\n {\n "value": "member",\n "label": "🙍🏻‍♂️ Member"\n }\n ]\n}', + widget_options: null, + }, + ]; + const newWidgets = createUserWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundUserTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + } + + private async createMySQLDemoTableActions(connection: ConnectionEntity): Promise { + const actionRulesData: Array = [ + { + table_name: 'user', + rule_title: 'Blacklist', + }, + { + table_name: 'user', + rule_title: 'Notification on new user', + }, + ]; + const savedEmptyActionRules = []; + for (const rule_data of actionRulesData) { + const newActionRule = buildEmptyActionRule(rule_data, connection); + const savedActionRule = await this._dbContext.actionRulesRepository.saveNewOrUpdatedActionRule(newActionRule); + savedEmptyActionRules.push(savedActionRule); + } + const foundSavedUserBlacklistActionRule = savedEmptyActionRules.find( + (rule) => rule.table_name === 'user' && rule.rule_title === 'Blacklist', + ); + if (foundSavedUserBlacklistActionRule) { + const createActionEventData: CreateTableActionEventDS = { + event: TableActionEventEnum.CUSTOM, + event_title: 'Blacklist', + icon: 'do_not_disturb_on_total_silence', + require_confirmation: true, + type: TableActionTypeEnum.single, + }; + const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedUserBlacklistActionRule); + await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); + } + const foundSavedUserNotificationActionRule = savedEmptyActionRules.find( + (rule) => rule.table_name === 'user' && rule.rule_title === 'Notification on new user', + ); + if (foundSavedUserNotificationActionRule) { + const createActionEventData: Array = [ + { + event: TableActionEventEnum.ADD_ROW, + event_title: null, + icon: null, + require_confirmation: false, + type: TableActionTypeEnum.single, + }, + { + event: TableActionEventEnum.UPDATE_ROW, + event_title: null, + icon: null, + require_confirmation: false, + type: TableActionTypeEnum.single, + }, + { + event: TableActionEventEnum.DELETE_ROW, + event_title: null, + icon: null, + require_confirmation: false, + type: TableActionTypeEnum.single, + }, + ]; + for (const actionEventData of createActionEventData) { + const newActionEvent = buildActionEventWithRule(actionEventData, foundSavedUserNotificationActionRule); + await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); + } + } + } + + private async createPostgresDemoTableActions(connection: ConnectionEntity): Promise { + const actionRulesData: Array = [ + { + table_name: 'certificates', + rule_title: 'download ', + }, + { + table_name: 'courses', + rule_title: 'Publish', + }, + ]; + + const savedEmptyActionRules = []; + for (const rule_data of actionRulesData) { + const newActionRule = buildEmptyActionRule(rule_data, connection); + const savedActionRule = await this._dbContext.actionRulesRepository.saveNewOrUpdatedActionRule(newActionRule); + savedEmptyActionRules.push(savedActionRule); + } + + const foundSavedCertificatesActionRule = savedEmptyActionRules.find((rule) => rule.table_name === 'certificates'); + if (foundSavedCertificatesActionRule) { + const createActionEventData: CreateTableActionEventDS = { + event: TableActionEventEnum.CUSTOM, + event_title: 'Download PDF', + icon: 'download', + require_confirmation: false, + type: TableActionTypeEnum.single, + }; + const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedCertificatesActionRule); + await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); + } + + const foundSavedCoursesActionRule = savedEmptyActionRules.find((rule) => rule.table_name === 'courses'); + if (foundSavedCoursesActionRule) { + const createActionEventData: CreateTableActionEventDS = { + event: TableActionEventEnum.CUSTOM, + event_title: 'Update course data', + icon: 'send', + require_confirmation: true, + type: TableActionTypeEnum.single, + }; + const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedCoursesActionRule); + await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); + } + } + + private async createConnectionPropertiesForPostgresDemoData( + connection: ConnectionEntity, + ): Promise { + const createPropertiesData: CreateConnectionPropertiesDs = { + hidden_tables: [], + logo_url: + 'https://demo-data.rocketadmin.com/postgres-demo-images/assets_task_01k04ftq4ce4dtg0td6g3d8x6f_1752497601_img_1-1.webp', + primary_color: '#8CBF77', + secondary_color: '#FB8837', + hostname: null, + company_name: 'School of Fish', + tables_audit: true, + connectionId: 'JeVyEzZY', + human_readable_table_names: true, + allow_ai_requests: true, + default_showing_table: 'users', + userId: connection?.author?.id || null, + master_password: null, + }; + const connectionProperties = buildConnectionPropertiesEntity(createPropertiesData, connection); + return await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(connectionProperties); + } + + private async createTestTableSettingsPostgres(connection: ConnectionEntity): Promise> { + const tableSettingsDtos: Array = [ + { + table_name: 'certificates', + display_name: null, + search_fields: [], + excluded_fields: [], + list_fields: ['user_id', 'course_id', 'certificate_url', 'issued_at', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: ['user_id', 'course_id', 'issued_at', 'certificate_url'], + identity_column: 'course_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'workspace_premium', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'course_mentors', + display_name: null, + search_fields: [], + excluded_fields: [], + list_fields: [], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: null, + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: null, + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: 'co_present', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'course_modules', + display_name: null, + search_fields: [], + excluded_fields: [], + list_fields: ['position', 'title', 'course_id', 'description', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: [], + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'dashboard_2', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'courses', + display_name: null, + search_fields: [], + excluded_fields: [], + list_fields: ['title', 'description', 'language', 'level', 'price', 'is_published', 'created_at', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: [], + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'book_ribbon', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'enrollments', + display_name: '', + search_fields: [], + excluded_fields: [], + list_fields: ['user_id', 'course_id', 'progress', 'completed', 'enrolled_at', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: [], + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'how_to_reg', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'lessons', + display_name: null, + search_fields: [], + excluded_fields: [], + list_fields: ['title', 'module_id', 'content', 'video_url', 'duration', 'position', 'content_url', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: null, + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: null, + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: 'local_library', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'quiz_attempts', + display_name: null, + search_fields: [], + excluded_fields: [], + list_fields: ['user_id', 'quiz_id', 'score', 'started_at', 'completed_at', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: null, + readonly_fields: ['completed_at'], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + columns_view: null, + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: 'add_task', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'quizzes', + display_name: null, + search_fields: ['lesson_id', 'title'], + excluded_fields: [], + list_fields: ['title', 'lesson_id', 'max_score', 'questions', 'id'], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: null, + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['title'], + identification_fields: [], + columns_view: null, + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: 'edit_document', + allow_csv_export: false, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'users', + display_name: '', + search_fields: ['role', 'full_name', 'email', 'bio'], + excluded_fields: [], + list_fields: [ + 'full_name', + 'role', + 'email', + 'bio', + 'date_of_birth', + 'created_at', + 'last_login', + 'password_hash', + 'id', + ], + list_per_page: null, + ordering: QueryOrderingEnum.ASC, + ordering_field: '', + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['role', 'full_name', 'email', 'bio'], + identification_fields: [], + columns_view: ['role', 'full_name', 'email', 'date_of_birth'], + identity_column: 'full_name', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: ['email', 'date_of_birth'], + icon: 'groups_3', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + ]; + + const tableSettingEntities = tableSettingsDtos.map((dto) => { + return buildNewTableSettingsEntity(dto, connection); + }); + const savedTableSettings = await this._dbContext.tableSettingsRepository.save(tableSettingEntities); + await this.createDemoPostgresTablesWidgets(savedTableSettings); + return savedTableSettings; + } + + private async createDemoPostgresTablesWidgets(tableSettings: Array): Promise { + const foundCertificatesTableSettings = tableSettings.find((settings) => settings.table_name === 'certificates'); + if (foundCertificatesTableSettings) { + const createCertificatesWidgetsData: Array = [ + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'course_id', + widget_type: '' as any, + name: 'Course', + description: "hi i'm a description", + widget_params: '', + widget_options: null, + }, + { + field_name: 'certificate_url', + widget_type: WidgetTypeEnum.URL, + name: '', + description: '', + widget_params: '// No settings required', + widget_options: null, + }, + ]; + const newWidgets = createCertificatesWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundCertificatesTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + const foundCourseMentorsTableSettings = tableSettings.find((settings) => settings.table_name === 'course_mentors'); + if (foundCourseMentorsTableSettings) { + const createCourseMentorsWidgetsData: Array = [ + { + field_name: 'course_id', + widget_type: '' as any, + name: 'Course', + description: '', + widget_params: '', + widget_options: null, + }, + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + ]; + const newWidgets = createCourseMentorsWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundCourseMentorsTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundCourseModulesTableSettings = tableSettings.find((settings) => settings.table_name === 'course_modules'); + if (foundCourseModulesTableSettings) { + const createCourseModulesWidgetsData: Array = [ + { + field_name: 'course_id', + widget_type: '' as any, + name: 'Course', + description: '', + widget_params: '', + widget_options: null, + }, + ]; + const newWidgets = createCourseModulesWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundCourseModulesTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundCoursesTableSettings = tableSettings.find((settings) => settings.table_name === 'courses'); + if (foundCoursesTableSettings) { + const createCoursesWidgetsData: Array = [ + { + field_name: 'price', + widget_type: 'Money' as any, + name: '', + description: '', + widget_params: + '// Configure money widget settings\n// example:\n{\n "default_currency": "USD",\n "show_currency_selector": false,\n "decimal_places": 2,\n "allow_negative": false\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createCoursesWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundCoursesTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundEnrollmentsTableSettings = tableSettings.find((settings) => settings.table_name === 'enrollments'); + if (foundEnrollmentsTableSettings) { + const createEnrollmentsWidgetsData: Array = [ + { + field_name: 'course_id', + widget_type: '' as any, + name: 'Course', + description: '', + widget_params: '', + widget_options: null, + }, + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + ]; + const newWidgets = createEnrollmentsWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundEnrollmentsTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundLessonsTableSettings = tableSettings.find((settings) => settings.table_name === 'lessons'); + if (foundLessonsTableSettings) { + const createLessonsWidgetsData: Array = [ + { + field_name: 'video_url', + widget_type: WidgetTypeEnum.URL, + name: '', + description: '', + widget_params: '// No settings required', + widget_options: null, + }, + { + field_name: 'module_id', + widget_type: '' as any, + name: 'Module', + description: '', + widget_params: null, + widget_options: null, + }, + ]; + const newWidgets = createLessonsWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundLessonsTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundQuizAttemptsTableSettings = tableSettings.find((settings) => settings.table_name === 'quiz_attempts'); + if (foundQuizAttemptsTableSettings) { + const createQuizAttemptsWidgetsData: Array = [ + { + field_name: 'quiz_id', + widget_type: '' as any, + name: 'Quiz', + description: '', + widget_params: '', + widget_options: null, + }, + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + ]; + const newWidgets = createQuizAttemptsWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundQuizAttemptsTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundQuizzesTableSettings = tableSettings.find((settings) => settings.table_name === 'quizzes'); + if (foundQuizzesTableSettings) { + const createQuizzesWidgetsData: Array = [ + { + field_name: 'lesson_id', + widget_type: '' as any, + name: 'Lesson', + description: '', + widget_params: '', + widget_options: null, + }, + ]; + const newWidgets = createQuizzesWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundQuizzesTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + + const foundUsersTableSettings = tableSettings.find((settings) => settings.table_name === 'users'); + if (foundUsersTableSettings) { + const createUsersWidgetsData: Array = [ + { + field_name: 'role', + widget_type: 'Select' as any, + name: '', + description: '', + widget_params: + '{\n "allow_null": false,\n "options": [\n {\n "value": "admin",\n "label": "🥷 Admin"\n },\n {\n "value": "mentor",\n "label": "🧑‍🏫 Mentor"\n },\n {\n "value": "student",\n "label": "🧑‍🎓 Student"\n }\n ]\n}', + widget_options: null, + }, + { + field_name: 'password_hash', + widget_type: WidgetTypeEnum.Password, + name: 'Password', + description: '', + widget_params: + '// provide algorithm to encrypt your password, one of:\n//sha1, sha3, sha224, sha256, sha512, sha384, bcrypt, scrypt, argon2, pbkdf2.\n// example:\n\n{\n "algorithm": "sha224"\n}\n\n', + widget_options: null, + }, + ]; + const newWidgets = createUsersWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundUsersTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + } +} diff --git a/backend/src/entities/demo-data/demo-deta.module.ts b/backend/src/entities/demo-data/demo-deta.module.ts new file mode 100644 index 000000000..b3d0e63b9 --- /dev/null +++ b/backend/src/entities/demo-data/demo-deta.module.ts @@ -0,0 +1,23 @@ +import { Global, MiddlewareConsumer, Module } from '@nestjs/common'; +import { DemoDataService } from './demo-data.service.js'; +import { BaseType } from '../../common/data-injection.tokens.js'; +import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +@Global() +@Module({ + imports: [TypeOrmModule.forFeature([])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + + DemoDataService, + ], + controllers: [], + exports: [DemoDataService], +}) +export class DemoDataModule { + public configure(_consumer: MiddlewareConsumer): any {} +} diff --git a/backend/src/microservices/saas-microservice/use-cases/login-with-github.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/login-with-github.use.case.ts index 2cb9e03c8..26c718f68 100644 --- a/backend/src/microservices/saas-microservice/use-cases/login-with-github.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/login-with-github.use.case.ts @@ -2,19 +2,13 @@ import { Inject, Injectable, InternalServerErrorException } from '@nestjs/common import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { ConnectionEntity } from '../../../entities/connection/connection.entity.js'; -import { GroupEntity } from '../../../entities/group/group.entity.js'; -import { PermissionEntity } from '../../../entities/permission/permission.entity.js'; +import { DemoDataService } from '../../../entities/demo-data/demo-data.service.js'; import { RegisterUserDs } from '../../../entities/user/application/data-structures/register-user-ds.js'; import { ExternalRegistrationProviderEnum } from '../../../entities/user/enums/external-registration-provider.enum.js'; import { UserRoleEnum } from '../../../entities/user/enums/user-role.enum.js'; import { UserEntity } from '../../../entities/user/user.entity.js'; -import { buildConnectionEntitiesFromTestDtos } from '../../../entities/user/utils/build-connection-entities-from-test-dtos.js'; -import { buildDefaultAdminGroups } from '../../../entities/user/utils/build-default-admin-groups.js'; -import { buildDefaultAdminPermissions } from '../../../entities/user/utils/build-default-admin-permissions.js'; import { buildUserGitHubIdentifierEntity } from '../../../entities/user/utils/build-github-identifier-entity.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { Constants } from '../../../helpers/constants/constants.js'; import { SaasRegisterUserWithGithub } from '../data-structures/saas-register-user-with-github.js'; import { ILoginUserWithGitHub } from './saas-use-cases.interface.js'; @@ -26,6 +20,7 @@ export class LoginUserWithGithubUseCase constructor( @Inject(BaseType.GLOBAL_DB_CONTEXT) protected _dbContext: IGlobalDatabaseContext, + private readonly demoDataService: DemoDataService, ) { super(); } @@ -61,27 +56,8 @@ export class LoginUserWithGithubUseCase const newUserGitHubIdentifier = buildUserGitHubIdentifierEntity(savedUser, Number(githubId)); await this._dbContext.userGitHubIdentifierRepository.saveGitHubIdentifierEntity(newUserGitHubIdentifier); - const testConnections = Constants.getTestConnectionsArr(); - const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(testConnections); - const createdTestConnections = await Promise.all( - testConnectionsEntities.map(async (connection): Promise => { - connection.author = savedUser; - return await this._dbContext.connectionRepository.saveNewConnection(connection); - }), - ); - const testGroupsEntities = buildDefaultAdminGroups(savedUser, createdTestConnections); - const createdTestGroups = await Promise.all( - testGroupsEntities.map(async (group: GroupEntity) => { - return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); - }), - ); - const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); - await Promise.all( - testPermissionsEntities.map(async (permission: PermissionEntity) => { - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); - }), - ); - + await this.demoDataService.createDemoDataForUser(savedUser.id); + return savedUser; } catch (_e) { throw new InternalServerErrorException(Messages.GITHUB_REGISTRATION_FAILED); diff --git a/backend/src/microservices/saas-microservice/use-cases/login-with-google.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/login-with-google.use.case.ts index 4e2760683..c0afdd6de 100644 --- a/backend/src/microservices/saas-microservice/use-cases/login-with-google.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/login-with-google.use.case.ts @@ -2,16 +2,10 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { ConnectionEntity } from '../../../entities/connection/connection.entity.js'; -import { GroupEntity } from '../../../entities/group/group.entity.js'; -import { PermissionEntity } from '../../../entities/permission/permission.entity.js'; +import { DemoDataService } from '../../../entities/demo-data/demo-data.service.js'; import { RegisterUserDs } from '../../../entities/user/application/data-structures/register-user-ds.js'; import { ExternalRegistrationProviderEnum } from '../../../entities/user/enums/external-registration-provider.enum.js'; import { UserEntity } from '../../../entities/user/user.entity.js'; -import { buildConnectionEntitiesFromTestDtos } from '../../../entities/user/utils/build-connection-entities-from-test-dtos.js'; -import { buildDefaultAdminGroups } from '../../../entities/user/utils/build-default-admin-groups.js'; -import { buildDefaultAdminPermissions } from '../../../entities/user/utils/build-default-admin-permissions.js'; -import { Constants } from '../../../helpers/constants/constants.js'; import { SaasRegisterUserWithGoogleDS } from '../data-structures/sass-register-user-with-google.js'; import { ILoginUserWithGoogle } from './saas-use-cases.interface.js'; @@ -23,6 +17,7 @@ export class LoginWithGoogleUseCase constructor( @Inject(BaseType.GLOBAL_DB_CONTEXT) protected _dbContext: IGlobalDatabaseContext, + private readonly demoDataService: DemoDataService, ) { super(); } @@ -52,26 +47,7 @@ export class LoginWithGoogleUseCase userData, ExternalRegistrationProviderEnum.GOOGLE, ); - const testConnections = Constants.getTestConnectionsArr(); - const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(testConnections); - const createdTestConnections = await Promise.all( - testConnectionsEntities.map(async (connection): Promise => { - connection.author = savedUser; - return await this._dbContext.connectionRepository.saveNewConnection(connection); - }), - ); - const testGroupsEntities = buildDefaultAdminGroups(savedUser, createdTestConnections); - const createdTestGroups = await Promise.all( - testGroupsEntities.map(async (group: GroupEntity) => { - return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); - }), - ); - const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); - await Promise.all( - testPermissionsEntities.map(async (permission: PermissionEntity) => { - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); - }), - ); + await this.demoDataService.createDemoDataForUser(savedUser.id); return savedUser; } } diff --git a/backend/src/microservices/saas-microservice/use-cases/register-demo-user-account.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/register-demo-user-account.use.case.ts index 6939444fb..b9e1593e1 100644 --- a/backend/src/microservices/saas-microservice/use-cases/register-demo-user-account.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/register-demo-user-account.use.case.ts @@ -4,16 +4,11 @@ import { IGlobalDatabaseContext } from '../../../common/application/global-datab import { BaseType } from '../../../common/data-injection.tokens.js'; import { CompanyInfoEntity } from '../../../entities/company-info/company-info.entity.js'; import { ConnectionEntity } from '../../../entities/connection/connection.entity.js'; -import { GroupEntity } from '../../../entities/group/group.entity.js'; -import { PermissionEntity } from '../../../entities/permission/permission.entity.js'; +import { DemoDataService } from '../../../entities/demo-data/demo-data.service.js'; import { SaaSRegisterDemoUserAccountDS } from '../../../entities/user/application/data-structures/demo-user-account-register.ds.js'; import { FoundUserDto } from '../../../entities/user/dto/found-user.dto.js'; import { UserRoleEnum } from '../../../entities/user/enums/user-role.enum.js'; import { UserEntity } from '../../../entities/user/user.entity.js'; -import { buildConnectionEntitiesFromTestDtos } from '../../../entities/user/utils/build-connection-entities-from-test-dtos.js'; -import { buildDefaultAdminGroups } from '../../../entities/user/utils/build-default-admin-groups.js'; -import { buildDefaultAdminPermissions } from '../../../entities/user/utils/build-default-admin-permissions.js'; -import { Constants } from '../../../helpers/constants/constants.js'; import { ISaasDemoRegisterUser } from './saas-use-cases.interface.js'; @Injectable() @@ -24,15 +19,16 @@ export class SaasRegisterDemoUserAccountUseCase constructor( @Inject(BaseType.GLOBAL_DB_CONTEXT) protected _dbContext: IGlobalDatabaseContext, + private readonly demoDataService: DemoDataService, ) { super(); } protected async implementation(userData: SaaSRegisterDemoUserAccountDS): Promise { const savedUser = await this.createDemoUser(userData); - const createdTestConnections = await this.createTestConnections(savedUser); - const createdTestGroups = await this.createTestGroups(savedUser, createdTestConnections); - await this.createTestPermissions(createdTestGroups); + + const createdTestConnections = await this.demoDataService.createDemoDataForUser(savedUser.id); + const savedCompanyInfo = await this.createCompanyInfo(userData, createdTestConnections); savedUser.company = savedCompanyInfo; @@ -54,41 +50,6 @@ export class SaasRegisterDemoUserAccountUseCase return await this._dbContext.userRepository.save(demoUser); } - private async createTestConnections(savedUser: UserEntity): Promise { - const testConnections = Constants.getTestConnectionsArr(); - const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(testConnections); - - return await Promise.all( - testConnectionsEntities.map(async (connection): Promise => { - connection.author = savedUser; - return await this._dbContext.connectionRepository.saveNewConnection(connection); - }), - ); - } - - private async createTestGroups( - savedUser: UserEntity, - createdTestConnections: ConnectionEntity[], - ): Promise { - const testGroupsEntities = buildDefaultAdminGroups(savedUser, createdTestConnections); - - return await Promise.all( - testGroupsEntities.map(async (group: GroupEntity) => { - return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); - }), - ); - } - - private async createTestPermissions(createdTestGroups: GroupEntity[]): Promise { - const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); - - await Promise.all( - testPermissionsEntities.map(async (permission: PermissionEntity) => { - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); - }), - ); - } - private async createCompanyInfo( userData: SaaSRegisterDemoUserAccountDS, createdTestConnections: ConnectionEntity[], diff --git a/backend/src/microservices/saas-microservice/use-cases/saas-usual-register-user.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/saas-usual-register-user.use.case.ts index 86b8c1c15..71c4e1a55 100644 --- a/backend/src/microservices/saas-microservice/use-cases/saas-usual-register-user.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/saas-usual-register-user.use.case.ts @@ -1,23 +1,17 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; -import assert from 'assert'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { CompanyInfoEntity } from '../../../entities/company-info/company-info.entity.js'; import { ConnectionEntity } from '../../../entities/connection/connection.entity.js'; +import { DemoDataService } from '../../../entities/demo-data/demo-data.service.js'; import { EmailService } from '../../../entities/email/email/email.service.js'; -import { GroupEntity } from '../../../entities/group/group.entity.js'; -import { PermissionEntity } from '../../../entities/permission/permission.entity.js'; import { RegisterUserDs } from '../../../entities/user/application/data-structures/register-user-ds.js'; import { SaasUsualUserRegisterDS } from '../../../entities/user/application/data-structures/usual-register-user.ds.js'; import { FoundUserDto } from '../../../entities/user/dto/found-user.dto.js'; import { UserRoleEnum } from '../../../entities/user/enums/user-role.enum.js'; import { UserEntity } from '../../../entities/user/user.entity.js'; -import { buildConnectionEntitiesFromTestDtos } from '../../../entities/user/utils/build-connection-entities-from-test-dtos.js'; -import { buildDefaultAdminGroups } from '../../../entities/user/utils/build-default-admin-groups.js'; -import { buildDefaultAdminPermissions } from '../../../entities/user/utils/build-default-admin-permissions.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { Constants } from '../../../helpers/constants/constants.js'; import { SaasCompanyGatewayService } from '../../gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { ISaasRegisterUser } from './saas-use-cases.interface.js'; @@ -31,6 +25,7 @@ export class SaasUsualRegisterUseCase protected _dbContext: IGlobalDatabaseContext, private readonly saasCompanyGatewayService: SaasCompanyGatewayService, private readonly emailService: EmailService, + private readonly demoDataService: DemoDataService, ) { super(); } @@ -59,27 +54,7 @@ export class SaasUsualRegisterUseCase const savedUser = await this._dbContext.userRepository.saveRegisteringUser(registerUserData); - const testConnections = Constants.getTestConnectionsArr(); - const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(testConnections); - const createdTestConnections = await Promise.all( - testConnectionsEntities.map(async (connection): Promise => { - assert(savedUser.id, 'User should be saved before creating connections'); - connection.author = savedUser; - return await this._dbContext.connectionRepository.saveNewConnection(connection); - }), - ); - const testGroupsEntities = buildDefaultAdminGroups(savedUser, createdTestConnections); - const createdTestGroups = await Promise.all( - testGroupsEntities.map(async (group: GroupEntity) => { - return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); - }), - ); - const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); - await Promise.all( - testPermissionsEntities.map(async (permission: PermissionEntity) => { - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); - }), - ); + const createdTestConnections = await this.demoDataService.createDemoDataForUser(savedUser.id); if (userCompany) { userCompany.users.push(savedUser);