Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions backend/src/entities/ai/ai.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,26 @@ IMPORTANT:
const tableInfo = tablesInformation.find((t) => t.table_name === tableSettings.table_name);
const validColumnNames = tableInfo?.structure.map((col) => col.column_name) || [];

const requiredFieldsWithoutDefault = new Set(
tableInfo?.structure
.filter((col) => !col.allow_null && col.column_default === null && !checkFieldAutoincrement(col.column_default, col.extra))

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requiredFieldsWithoutDefault calls checkFieldAutoincrement(col.column_default, col.extra) in a branch where col.column_default is guaranteed to be null. The helper is typed as checkFieldAutoincrement(defaultValue: string, ...), so this is type-inconsistent and can break compilation under strictNullChecks (and makes the intent unclear). Consider updating the helper signature to accept string | null (and extra?: string | null) or coalescing the argument at the call site.

Suggested change
.filter((col) => !col.allow_null && col.column_default === null && !checkFieldAutoincrement(col.column_default, col.extra))
.filter(
(col) =>
!col.allow_null &&
col.column_default === null &&
!checkFieldAutoincrement(col.column_default ?? '', col.extra),
)

Copilot uses AI. Check for mistakes.
.map((col) => col.column_name) || [],
);

const settings = new TableSettingsEntity();
settings.table_name = tableSettings.table_name;
settings.display_name = tableSettings.display_name;
settings.search_fields = this.filterValidColumns(tableSettings.search_fields, validColumnNames);
settings.readonly_fields = this.filterValidColumns(tableSettings.readonly_fields, validColumnNames);
settings.columns_view = this.filterValidColumns(tableSettings.columns_view, validColumnNames);
settings.readonly_fields = this.filterValidColumns(tableSettings.readonly_fields, validColumnNames).filter(
(field) => !requiredFieldsWithoutDefault.has(field),
);
const filteredColumnsView = this.filterValidColumns(tableSettings.columns_view, validColumnNames);
for (const requiredField of requiredFieldsWithoutDefault) {
if (!filteredColumnsView.includes(requiredField)) {
filteredColumnsView.push(requiredField);
Comment on lines +318 to +320

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop that appends requiredFieldsWithoutDefault to filteredColumnsView does an includes check for each required field, resulting in O(n*m) behavior for wide tables. Converting filteredColumnsView to a Set for membership checks (and back to an array at the end) would make this linear and simpler to reason about.

Suggested change
for (const requiredField of requiredFieldsWithoutDefault) {
if (!filteredColumnsView.includes(requiredField)) {
filteredColumnsView.push(requiredField);
const filteredColumnsViewSet = new Set(filteredColumnsView);
for (const requiredField of requiredFieldsWithoutDefault) {
if (!filteredColumnsViewSet.has(requiredField)) {
filteredColumnsView.push(requiredField);
filteredColumnsViewSet.add(requiredField);

Copilot uses AI. Check for mistakes.
}
}
settings.columns_view = filteredColumnsView;
settings.ordering = this.mapOrdering(tableSettings.ordering);
settings.ordering_field = validColumnNames.includes(tableSettings.ordering_field)
? tableSettings.ordering_field
Expand Down
Loading