Skip to content

Commit b210f09

Browse files
Merge branch 'main' into feature/guard-null-primary-key
2 parents 768a9d6 + bf9ae3c commit b210f09

72 files changed

Lines changed: 2520 additions & 478 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/src/common/data-injection.tokens.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export enum UseCaseType {
119119
SAAS_DELETE_CONNECTION_FOR_HOSTED_DB = 'SAAS_DELETE_CONNECTION_FOR_HOSTED_DB',
120120
SAAS_UPDATE_HOSTED_CONNECTION_PASSWORD = 'SAAS_UPDATE_HOSTED_CONNECTION_PASSWORD',
121121
SAAS_GET_CONNECTIONS_INFO_BY_IDS = 'SAAS_GET_CONNECTIONS_INFO_BY_IDS',
122+
SAAS_GET_HOSTED_CONNECTION_CREDENTIALS = 'SAAS_GET_HOSTED_CONNECTION_CREDENTIALS',
122123

123124
INVITE_USER_IN_COMPANY_AND_CONNECTION_GROUP = 'INVITE_USER_IN_COMPANY_AND_CONNECTION_GROUP',
124125
VERIFY_INVITE_USER_IN_COMPANY_AND_CONNECTION_GROUP = 'VERIFY_INVITE_USER_IN_COMPANY_AND_CONNECTION_GROUP',

backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,8 @@ export class RequestInfoFromTableWithAIUseCaseV7
171171

172172
for await (const chunk of stream) {
173173
if (chunk.type === 'text' && chunk.content) {
174-
response.write(chunk.content);
175174
accumulatedContent += chunk.content;
176-
totalAccumulatedResponse += chunk.content;
175+
this.writeChunk(response, { type: 'thinking', content: chunk.content });
177176
}
178177

179178
if (chunk.type === 'tool_call' && chunk.toolCall) {
@@ -191,13 +190,15 @@ export class RequestInfoFromTableWithAIUseCaseV7
191190
);
192191

193192
if (pendingToolCalls.length === 0) {
193+
this.writeChunk(response, { type: 'thinking_commit' });
194+
totalAccumulatedResponse += accumulatedContent;
194195
break;
195196
}
196197

198+
this.writeChunk(response, { type: 'thinking_reset' });
199+
197200
for (const toolCall of pendingToolCalls) {
198-
this.logger.log(
199-
`Tool call: ${toolCall.name}, arguments=${JSON.stringify(toolCall.arguments)}`,
200-
);
201+
this.logger.log(`Tool call: ${toolCall.name}, arguments=${JSON.stringify(toolCall.arguments)}`);
201202
}
202203

203204
const toolResults = await this.executeToolCalls(
@@ -209,9 +210,7 @@ export class RequestInfoFromTableWithAIUseCaseV7
209210
);
210211

211212
for (const toolResult of toolResults) {
212-
this.logger.log(
213-
`Tool result for ${toolResult.toolCallId}: resultLength=${toolResult.result.length}`,
214-
);
213+
this.logger.log(`Tool result for ${toolResult.toolCallId}: resultLength=${toolResult.result.length}`);
215214
}
216215

217216
if (this.aiProvider === AIProviderType.OPENAI && lastResponseId) {
@@ -227,9 +226,7 @@ export class RequestInfoFromTableWithAIUseCaseV7
227226

228227
depth++;
229228
} catch (loopError) {
230-
this.logger.error(
231-
`Error in tool loop at depth ${depth + 1}: ${loopError.message}`,
232-
);
229+
this.logger.error(`Error in tool loop at depth ${depth + 1}: ${loopError.message}`);
233230
throw loopError;
234231
}
235232
}
@@ -238,13 +235,24 @@ export class RequestInfoFromTableWithAIUseCaseV7
238235
this.logger.warn(`Tool loop reached max depth (${this.maxDepth})`);
239236
const maxDepthMessage =
240237
'\n\nYour question is too complex to process at this time. Please try simplifying it or breaking it down into smaller parts.';
241-
response.write(maxDepthMessage);
238+
this.writeChunk(response, { type: 'text', content: maxDepthMessage });
242239
totalAccumulatedResponse += maxDepthMessage;
243240
}
244241

245242
return { lastResponseId, accumulatedResponse: totalAccumulatedResponse };
246243
}
247244

245+
private writeChunk(
246+
response: Response,
247+
chunk:
248+
| { type: 'thinking'; content: string }
249+
| { type: 'thinking_reset' }
250+
| { type: 'thinking_commit' }
251+
| { type: 'text'; content: string },
252+
): void {
253+
response.write(JSON.stringify(chunk) + '\n');
254+
}
255+
248256
private async executeToolCalls(
249257
toolCalls: AIToolCall[],
250258
dataAccessObject: IDataAccessObject | IDataAccessObjectAgent,
@@ -306,9 +314,7 @@ export class RequestInfoFromTableWithAIUseCaseV7
306314
result = encodeError({ error: `Unknown tool: ${toolCall.name}` });
307315
}
308316
} catch (error) {
309-
this.logger.error(
310-
`Tool call ${toolCall.name} (${toolCall.id}) failed: ${error.message}`,
311-
);
317+
this.logger.error(`Tool call ${toolCall.name} (${toolCall.id}) failed: ${error.message}`);
312318
result = encodeError({ error: error.message });
313319
}
314320

backend/src/entities/table/use-cases/add-row-in-table.use.case.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,33 @@ import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/help
55
import AbstractUseCase from '../../../common/abstract-use.case.js';
66
import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js';
77
import { BaseType } from '../../../common/data-injection.tokens.js';
8-
import {
9-
AmplitudeEventTypeEnum,
10-
LogOperationTypeEnum,
11-
OperationResultStatusEnum,
12-
} from '../../../enums/index.js';
8+
import { AmplitudeEventTypeEnum, LogOperationTypeEnum, OperationResultStatusEnum } from '../../../enums/index.js';
139
import { TableActionEventEnum } from '../../../enums/table-action-event-enum.js';
1410
import { Messages } from '../../../exceptions/text/messages.js';
1511
import { isObjectEmpty, toPrettyErrorsMsg } from '../../../helpers/index.js';
1612
import { AmplitudeService } from '../../amplitude/amplitude.service.js';
13+
import { CedarPermissionsService } from '../../cedar-authorization/cedar-permissions.service.js';
1714
import { isTestConnectionUtil } from '../../connection/utils/is-test-connection-util.js';
1815
import { TableActionActivationService } from '../../table-actions/table-actions-module/table-action-activation.service.js';
1916
import { TableLogsService } from '../../table-logs/table-logs.service.js';
2017
import { AddRowInTableDs } from '../application/data-structures/add-row-in-table.ds.js';
2118
import { ReferencedTableNamesAndColumnsDs, TableRowRODs } from '../table-datastructures.js';
22-
import { convertBinaryDataInRowUtil } from '../utils/convert-binary-data-in-row.util.js';
19+
import { attachForeignColumnNames } from '../utils/attach-foreign-column-names.util.js';
20+
import { buildTableSettingsForResponse } from '../utils/build-table-settings-for-response.util.js';
2321
import { convertHexDataInRowUtil } from '../utils/convert-hex-data-in-row.util.js';
22+
import { extractForeignKeysFromWidgets } from '../utils/extract-foreign-keys-from-widgets.util.js';
23+
import { filterForeignKeysByReadPermission } from '../utils/filter-foreign-keys-by-permission.util.js';
2424
import { formFullTableStructure } from '../utils/form-full-table-structure.js';
2525
import { hashPasswordsInRowUtil } from '../utils/hash-passwords-in-row.util.js';
26+
import {
27+
enrichReferencedTablesWithDisplayNames,
28+
filterReferencedTablesByPermission,
29+
} from '../utils/process-referenced-tables.util.js';
2630
import { processUuidsInRowUtil } from '../utils/process-uuids-in-row-util.js';
2731
import { removePasswordsFromRowsUtil } from '../utils/remove-password-from-row.util.js';
32+
import { getUserEmailForAgent, validateConnection } from '../utils/validate-connection.util.js';
2833
import { validateTableRowUtil } from '../utils/validate-table-row.util.js';
29-
import { CedarPermissionsService } from '../../cedar-authorization/cedar-permissions.service.js';
3034
import { IAddRowInTable } from './table-use-cases.interface.js';
31-
import { validateConnection, getUserEmailForAgent } from '../utils/validate-connection.util.js';
32-
import { extractForeignKeysFromWidgets } from '../utils/extract-foreign-keys-from-widgets.util.js';
33-
import { filterForeignKeysByReadPermission } from '../utils/filter-foreign-keys-by-permission.util.js';
34-
import { attachForeignColumnNames } from '../utils/attach-foreign-column-names.util.js';
35-
import { filterReferencedTablesByPermission, enrichReferencedTablesWithDisplayNames } from '../utils/process-referenced-tables.util.js';
36-
import { buildTableSettingsForResponse } from '../utils/build-table-settings-for-response.util.js';
3735

3836
@Injectable()
3937
export class AddRowInTableUseCase extends AbstractUseCase<AddRowInTableDs, TableRowRODs> implements IAddRowInTable {
@@ -98,7 +96,13 @@ export class AddRowInTableUseCase extends AbstractUseCase<AddRowInTableDs, Table
9896
dao.getReferencedTableNamesAndColumns(tableName, userEmail),
9997
]);
10098

101-
await filterReferencedTablesByPermission(referencedTableNamesAndColumns, userId, connectionId, masterPwd, this.cedarPermissions);
99+
await filterReferencedTablesByPermission(
100+
referencedTableNamesAndColumns,
101+
userId,
102+
connectionId,
103+
masterPwd,
104+
this.cedarPermissions,
105+
);
102106
const referencedTableNamesAndColumnsWithTablesDisplayNames = await enrichReferencedTablesWithDisplayNames(
103107
referencedTableNamesAndColumns,
104108
connectionId,
@@ -121,14 +125,21 @@ export class AddRowInTableUseCase extends AbstractUseCase<AddRowInTableDs, Table
121125
let foreignKeysWithAutocompleteColumns: Array<ForeignKeyWithAutocompleteColumnsDS> = [];
122126

123127
foreignKeysWithKeysFromWidgets = await filterForeignKeysByReadPermission(
124-
foreignKeysWithKeysFromWidgets, userId, connectionId, masterPwd, this.cedarPermissions,
128+
foreignKeysWithKeysFromWidgets,
129+
userId,
130+
connectionId,
131+
masterPwd,
132+
this.cedarPermissions,
125133
);
126134

127135
if (foreignKeysWithKeysFromWidgets?.length > 0) {
128136
foreignKeysWithAutocompleteColumns = await Promise.all(
129137
foreignKeysWithKeysFromWidgets.map((el) =>
130138
attachForeignColumnNames(
131-
el, userEmail, connectionId, dao,
139+
el,
140+
userEmail,
141+
connectionId,
142+
dao,
132143
this._dbContext.tableSettingsRepository.findTableSettings.bind(this._dbContext.tableSettingsRepository),
133144
).catch(() => el as ForeignKeyWithAutocompleteColumnsDS),
134145
),
@@ -158,7 +169,6 @@ export class AddRowInTableUseCase extends AbstractUseCase<AddRowInTableDs, Table
158169
operationResult = OperationResultStatusEnum.successfully;
159170
addedRow = await dao.getRowByPrimaryKey(tableName, addedRowPrimaryKey, builtDAOsTableSettings, userEmail);
160171
addedRow = removePasswordsFromRowsUtil(addedRow, tableWidgets);
161-
addedRow = convertBinaryDataInRowUtil(addedRow, tableStructure);
162172
return {
163173
row: addedRow,
164174
foreignKeys: foreignKeysWithAutocompleteColumns,

backend/src/entities/table/use-cases/bulk-update-rows-in-table.use.case.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ import { OperationResultStatusEnum } from '../../../enums/operation-result-statu
99
import { ExceptionOperations } from '../../../exceptions/custom-exceptions/exception-operation.js';
1010
import { UnknownSQLException } from '../../../exceptions/custom-exceptions/unknown-sql-exception.js';
1111
import { Messages } from '../../../exceptions/text/messages.js';
12-
import { validateConnection, getUserEmailForAgent } from '../utils/validate-connection.util.js';
1312
import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js';
1413
import { TableLogsService } from '../../table-logs/table-logs.service.js';
1514
import { UpdateRowsInTableDs } from '../application/data-structures/update-rows-in-table.ds.js';
1615
import { convertHexDataInPrimaryKeyUtil } from '../utils/convert-hex-data-in-primary-key.util.js';
16+
import { convertHexDataInRowUtil } from '../utils/convert-hex-data-in-row.util.js';
1717
import { hashPasswordsInRowUtil } from '../utils/hash-passwords-in-row.util.js';
1818
import { processUuidsInRowUtil } from '../utils/process-uuids-in-row-util.js';
19+
import { getUserEmailForAgent, validateConnection } from '../utils/validate-connection.util.js';
1920
import { IBulkUpdateRowsInTable } from './table-use-cases.interface.js';
2021

2122
@Injectable()
@@ -94,6 +95,7 @@ export class BulkUpdateRowsInTableUseCase
9495
try {
9596
let processedNewValues = await hashPasswordsInRowUtil(newValues, tableWidgets);
9697
processedNewValues = processUuidsInRowUtil(processedNewValues, tableWidgets);
98+
processedNewValues = convertHexDataInRowUtil(processedNewValues, tableStructure);
9799
await dao.bulkUpdateRowsInTable(tableName, processedNewValues, primaryKeys, userEmail);
98100
operationResult = OperationResultStatusEnum.successfully;
99101
return {

backend/src/entities/table/use-cases/get-row-by-primary-key.use.case.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,24 @@ import { ExceptionOperations } from '../../../exceptions/custom-exceptions/excep
1111
import { UnknownSQLException } from '../../../exceptions/custom-exceptions/unknown-sql-exception.js';
1212
import { Messages } from '../../../exceptions/text/messages.js';
1313
import { compareArrayElements } from '../../../helpers/index.js';
14+
import { CedarPermissionsService } from '../../cedar-authorization/cedar-permissions.service.js';
1415
import { buildActionEventDto } from '../../table-actions/table-action-rules-module/utils/build-found-action-event-dto.util.js';
1516
import { GetRowByPrimaryKeyDs } from '../application/data-structures/get-row-by-primary-key.ds.js';
1617
import { ReferencedTableNamesAndColumnsDs, TableRowRODs } from '../table-datastructures.js';
17-
import { convertBinaryDataInRowUtil } from '../utils/convert-binary-data-in-row.util.js';
18+
import { attachForeignColumnNames } from '../utils/attach-foreign-column-names.util.js';
19+
import { buildTableSettingsForResponse } from '../utils/build-table-settings-for-response.util.js';
1820
import { convertHexDataInPrimaryKeyUtil } from '../utils/convert-hex-data-in-primary-key.util.js';
21+
import { extractForeignKeysFromWidgets } from '../utils/extract-foreign-keys-from-widgets.util.js';
22+
import { filterForeignKeysByReadPermission } from '../utils/filter-foreign-keys-by-permission.util.js';
1923
import { findAvailableFields } from '../utils/find-available-fields.utils.js';
2024
import { formFullTableStructure } from '../utils/form-full-table-structure.js';
25+
import {
26+
enrichReferencedTablesWithDisplayNames,
27+
filterReferencedTablesByPermission,
28+
} from '../utils/process-referenced-tables.util.js';
2129
import { removePasswordsFromRowsUtil } from '../utils/remove-password-from-row.util.js';
22-
import { CedarPermissionsService } from '../../cedar-authorization/cedar-permissions.service.js';
30+
import { getUserEmailForAgent, validateConnection } from '../utils/validate-connection.util.js';
2331
import { IGetRowByPrimaryKey } from './table-use-cases.interface.js';
24-
import { validateConnection, getUserEmailForAgent } from '../utils/validate-connection.util.js';
25-
import { extractForeignKeysFromWidgets } from '../utils/extract-foreign-keys-from-widgets.util.js';
26-
import { filterForeignKeysByReadPermission } from '../utils/filter-foreign-keys-by-permission.util.js';
27-
import { attachForeignColumnNames } from '../utils/attach-foreign-column-names.util.js';
28-
import { filterReferencedTablesByPermission, enrichReferencedTablesWithDisplayNames } from '../utils/process-referenced-tables.util.js';
29-
import { buildTableSettingsForResponse } from '../utils/build-table-settings-for-response.util.js';
3032

3133
@Injectable()
3234
export class GetRowByPrimaryKeyUseCase
@@ -102,15 +104,22 @@ export class GetRowByPrimaryKeyUseCase
102104

103105
tableForeignKeys = tableForeignKeys.concat(foreignKeysFromWidgets);
104106
tableForeignKeys = await filterForeignKeysByReadPermission(
105-
tableForeignKeys, userId, connectionId, masterPwd, this.cedarPermissions,
107+
tableForeignKeys,
108+
userId,
109+
connectionId,
110+
masterPwd,
111+
this.cedarPermissions,
106112
);
107113

108114
let foreignKeysWithAutocompleteColumns: Array<ForeignKeyWithAutocompleteColumnsDS> = [];
109115
if (tableForeignKeys && tableForeignKeys.length > 0) {
110116
foreignKeysWithAutocompleteColumns = await Promise.all(
111117
tableForeignKeys.map((el) =>
112118
attachForeignColumnNames(
113-
el, userEmail, connectionId, dao,
119+
el,
120+
userEmail,
121+
connectionId,
122+
dao,
114123
this._dbContext.tableSettingsRepository.findTableSettings.bind(this._dbContext.tableSettingsRepository),
115124
).catch(() => el as ForeignKeyWithAutocompleteColumnsDS),
116125
),
@@ -133,10 +142,15 @@ export class GetRowByPrimaryKeyUseCase
133142
);
134143
}
135144
rowData = removePasswordsFromRowsUtil(rowData, tableWidgets);
136-
rowData = convertBinaryDataInRowUtil(rowData, tableStructure);
137145
const formedTableStructure = formFullTableStructure(tableStructure, tableSettings);
138146

139-
await filterReferencedTablesByPermission(referencedTableNamesAndColumns, userId, connectionId, masterPwd, this.cedarPermissions);
147+
await filterReferencedTablesByPermission(
148+
referencedTableNamesAndColumns,
149+
userId,
150+
connectionId,
151+
masterPwd,
152+
this.cedarPermissions,
153+
);
140154
const referencedTableNamesAndColumnsWithTablesDisplayNames = await enrichReferencedTablesWithDisplayNames(
141155
referencedTableNamesAndColumns,
142156
connectionId,

0 commit comments

Comments
 (0)