-
-
Notifications
You must be signed in to change notification settings - Fork 18
feat: add GetConnectionsInfoByIds use case and corresponding API endpoint #1703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import { ApiProperty } from '@nestjs/swagger'; | ||
| import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; | ||
|
|
||
| export class FoundConnectionInfoRO { | ||
| @ApiProperty() | ||
| id: string; | ||
|
|
||
| @ApiProperty() | ||
| title: string; | ||
|
|
||
| @ApiProperty({ enum: ConnectionTypesEnum }) | ||
| type: ConnectionTypesEnum; | ||
|
|
||
| @ApiProperty() | ||
| host: string; | ||
|
|
||
| @ApiProperty() | ||
| port: number; | ||
|
|
||
| @ApiProperty() | ||
| database: string; | ||
|
|
||
| @ApiProperty() | ||
| schema: string; | ||
|
|
||
| @ApiProperty() | ||
| sid: string; | ||
|
|
||
| @ApiProperty() | ||
| ssh: boolean; | ||
|
|
||
| @ApiProperty() | ||
| ssl: boolean; | ||
|
|
||
| @ApiProperty() | ||
| createdAt: Date; | ||
|
|
||
| @ApiProperty() | ||
| updatedAt: Date; | ||
|
|
||
| @ApiProperty() | ||
| isTestConnection: boolean; | ||
|
|
||
| @ApiProperty() | ||
| is_frozen: boolean; | ||
|
|
||
| @ApiProperty() | ||
| masterEncryption: boolean; | ||
|
|
||
| @ApiProperty() | ||
| azure_encryption: boolean; | ||
|
|
||
| @ApiProperty() | ||
| authSource: string; | ||
|
|
||
| @ApiProperty() | ||
| dataCenter: string | null; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import { ApiProperty } from '@nestjs/swagger'; | ||
| import { IsArray, IsNotEmpty, IsString } from 'class-validator'; | ||
|
|
||
| export class GetConnectionsInfoByIdsDS { | ||
| @ApiProperty({ type: [String] }) | ||
| @IsArray() | ||
| @IsNotEmpty() | ||
| @IsString({ each: true }) | ||
| connectionIds: Array<string>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,8 +25,10 @@ import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; | |
| import { Messages } from '../../exceptions/text/messages.js'; | ||
| import { SentryInterceptor } from '../../interceptors/sentry.interceptor.js'; | ||
| import { CreatedConnectionResponse, SuccessResponse } from './data-structures/common-responce.ds.js'; | ||
| import { FoundConnectionInfoRO } from './data-structures/found-connection-info.ro.js'; | ||
| import { CreateConnectionForHostedDbDto } from './data-structures/create-connecttion-for-selfhosted-db.dto.js'; | ||
| import { DeleteConnectionForHostedDbDto } from './data-structures/delete-connection-for-hosted-db.dto.js'; | ||
| import { GetConnectionsInfoByIdsDS } from './data-structures/get-connections-info-by-ids.ds.js'; | ||
| import { RegisterCompanyWebhookDS } from './data-structures/register-company.ds.js'; | ||
| import { RegisteredCompanyDS } from './data-structures/registered-company.ds.js'; | ||
| import { SaasRegisterUserWithGithub } from './data-structures/saas-register-user-with-github.js'; | ||
|
|
@@ -38,6 +40,7 @@ import { | |
| ICreateConnectionForHostedDb, | ||
| IDeleteConnectionForHostedDb, | ||
| IFreezeConnectionsInCompany, | ||
| IGetConnectionsInfoByIds, | ||
| IGetUserInfo, | ||
| ILoginUserWithGitHub, | ||
| ILoginUserWithGoogle, | ||
|
|
@@ -95,6 +98,8 @@ export class SaasController { | |
| private readonly deleteConnectionForHostedDbUseCase: IDeleteConnectionForHostedDb, | ||
| @Inject(UseCaseType.SAAS_UPDATE_HOSTED_CONNECTION_PASSWORD) | ||
| private readonly updateHostedConnectionPasswordUseCase: IUpdateHostedConnectionPassword, | ||
| @Inject(UseCaseType.SAAS_GET_CONNECTIONS_INFO_BY_IDS) | ||
| private readonly getConnectionsInfoByIdsUseCase: IGetConnectionsInfoByIds, | ||
| ) {} | ||
|
|
||
| @ApiOperation({ summary: 'Company registered webhook' }) | ||
|
|
@@ -326,4 +331,17 @@ export class SaasController { | |
| ): Promise<SuccessResponse> { | ||
| return await this.updateHostedConnectionPasswordUseCase.execute(updatePasswordData); | ||
| } | ||
|
|
||
| @ApiOperation({ summary: 'Get connections info by ids' }) | ||
| @ApiBody({ type: GetConnectionsInfoByIdsDS }) | ||
| @ApiResponse({ | ||
| status: 200, | ||
| type: [FoundConnectionInfoRO], | ||
| }) | ||
| @Post('/connections/info') | ||
| async getConnectionsInfoByIds( | ||
|
Comment on lines
+335
to
+342
|
||
| @Body() connectionsData: GetConnectionsInfoByIdsDS, | ||
| ): Promise<Array<FoundConnectionInfoRO>> { | ||
| return await this.getConnectionsInfoByIdsUseCase.execute(connectionsData); | ||
|
Comment on lines
+335
to
+345
|
||
| } | ||
|
Comment on lines
+335
to
+346
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; | ||
| import { In } from 'typeorm'; | ||
| 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 { Messages } from '../../../exceptions/text/messages.js'; | ||
| import { FoundConnectionInfoRO } from '../data-structures/found-connection-info.ro.js'; | ||
| import { GetConnectionsInfoByIdsDS } from '../data-structures/get-connections-info-by-ids.ds.js'; | ||
| import { IGetConnectionsInfoByIds } from './saas-use-cases.interface.js'; | ||
|
|
||
| @Injectable() | ||
| export class GetConnectionsInfoByIdsUseCase | ||
| extends AbstractUseCase<GetConnectionsInfoByIdsDS, Array<FoundConnectionInfoRO>> | ||
| implements IGetConnectionsInfoByIds | ||
| { | ||
| constructor( | ||
| @Inject(BaseType.GLOBAL_DB_CONTEXT) | ||
| protected _dbContext: IGlobalDatabaseContext, | ||
| ) { | ||
|
Comment on lines
+12
to
+20
|
||
| super(); | ||
| } | ||
|
|
||
| protected async implementation(inputData: GetConnectionsInfoByIdsDS): Promise<Array<FoundConnectionInfoRO>> { | ||
| const { connectionIds } = inputData; | ||
| if (!connectionIds || connectionIds.length === 0) { | ||
| throw new HttpException( | ||
| { | ||
| message: Messages.CONNECTION_ID_MISSING, | ||
| }, | ||
| HttpStatus.BAD_REQUEST, | ||
| ); | ||
| } | ||
|
|
||
| const connections = await this._dbContext.connectionRepository.findBy({ | ||
| id: In(connectionIds), | ||
| }); | ||
|
Comment on lines
+35
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add authorization scoping before fetching by arbitrary IDs. The current query returns any matching 🤖 Prompt for AI Agents |
||
|
|
||
| return connections.map((connection) => this.buildConnectionInfoRO(connection)); | ||
| } | ||
|
|
||
| private buildConnectionInfoRO(connection: ConnectionEntity): FoundConnectionInfoRO { | ||
| return { | ||
| id: connection.id, | ||
| title: connection.title, | ||
| type: connection.type, | ||
| host: connection.host, | ||
| port: connection.port, | ||
| database: connection.database, | ||
| schema: connection.schema, | ||
| sid: connection.sid, | ||
| ssh: connection.ssh, | ||
| ssl: connection.ssl, | ||
| createdAt: connection.createdAt, | ||
| updatedAt: connection.updatedAt, | ||
| isTestConnection: connection.isTestConnection, | ||
| is_frozen: connection.is_frozen, | ||
| masterEncryption: connection.masterEncryption, | ||
| azure_encryption: connection.azure_encryption, | ||
| authSource: connection.authSource, | ||
| dataCenter: connection.dataCenter, | ||
| }; | ||
| } | ||
|
Comment on lines
+35
to
+63
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import { CompanyInfoEntity } from '../../../entities/company-info/company-info.entity.js'; | ||
| import { CreatedConnectionDTO } from '../../../entities/connection/application/dto/created-connection.dto.js'; | ||
| import { FoundConnectionInfoRO } from '../data-structures/found-connection-info.ro.js'; | ||
| import { SaaSRegisterDemoUserAccountDS } from '../../../entities/user/application/data-structures/demo-user-account-register.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'; | ||
|
|
@@ -9,6 +10,7 @@ import { CreatedConnectionResponse, SuccessResponse } from '../data-structures/c | |
| import { CreateConnectionForHostedDbDto } from '../data-structures/create-connecttion-for-selfhosted-db.dto.js'; | ||
| import { DeleteConnectionForHostedDbDto } from '../data-structures/delete-connection-for-hosted-db.dto.js'; | ||
| import { FreezeConnectionsInCompanyDS } from '../data-structures/freeze-connections-in-company.ds.js'; | ||
| import { GetConnectionsInfoByIdsDS } from '../data-structures/get-connections-info-by-ids.ds.js'; | ||
| import { GetUserInfoByIdDS } from '../data-structures/get-user-info.ds.js'; | ||
| import { GetUsersInfosByEmailDS } from '../data-structures/get-users-infos-by-email.ds.js'; | ||
| import { RegisterCompanyWebhookDS } from '../data-structures/register-company.ds.js'; | ||
|
|
@@ -82,3 +84,7 @@ export interface IDeleteConnectionForHostedDb { | |
| export interface IUpdateHostedConnectionPassword { | ||
| execute(inputData: UpdateHostedConnectionPasswordDto): Promise<SuccessResponse>; | ||
| } | ||
|
|
||
| export interface IGetConnectionsInfoByIds { | ||
| execute(inputData: GetConnectionsInfoByIdsDS): Promise<Array<FoundConnectionInfoRO>>; | ||
| } | ||
|
Comment on lines
+88
to
+90
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: rocket-admin/rocketadmin
Length of output: 525
🏁 Script executed:
Repository: rocket-admin/rocketadmin
Length of output: 5285
🏁 Script executed:
# Read the complete FoundConnectionInfoRO file to verify current state cat -n backend/src/microservices/saas-microservice/data-structures/found-connection-info.ro.tsRepository: rocket-admin/rocketadmin
Length of output: 1362
🏁 Script executed:
Repository: rocket-admin/rocketadmin
Length of output: 4298
🏁 Script executed:
Repository: rocket-admin/rocketadmin
Length of output: 772
Fix DTO nullability to match nullable entity fields returned by mapper.
The
FoundConnectionInfoROdeclares several fields as required/non-null, butConnectionEntitydefines them as nullable/optional, and thebuildConnectionInfoROmapper passes these values through unchanged. This creates an inaccurate API contract where the Swagger schema doesn't reflect that these fields can benullorundefined.Fields requiring updates (currently required, should be optional/nullable):
type,host,database,schema,sid,ssl,authSource— are explicitly nullable in the entity (| null)port— has@Column({ default: null }), allowing null values in the databaseProposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents