1- import { Injectable } from "@nestjs/common" ;
2- import { QueryOrderingEnum } from "../../enums/query-ordering.enum.js" ;
3- import { WidgetTypeEnum } from "../../enums/widget-type.enum.js" ;
4- import { checkFieldAutoincrement } from "../../helpers/check-field-autoincrement.js" ;
5- import { TableSettingsEntity } from "../table-settings/table-settings.entity.js" ;
6- import { TableWidgetEntity } from "../widget/table-widget.entity.js" ;
7- import { TableInformation } from "./ai-data-entities/types/ai-module-types.js" ;
8- import { AmazonBedrockAiProvider } from "./amazon-bedrock/amazon-bedrock.ai.provider.js" ;
1+ import { Injectable } from '@nestjs/common' ;
2+ import { WidgetTypeEnum } from '../../enums/widget-type.enum.js' ;
3+ import { checkFieldAutoincrement } from '../../helpers/check-field-autoincrement.js' ;
4+ import { TableWidgetEntity } from '../widget/table-widget.entity.js' ;
5+ import { TableInformation } from './ai-data-entities/types/ai-module-types.js' ;
6+ import { AmazonBedrockAiProvider } from './amazon-bedrock/amazon-bedrock.ai.provider.js' ;
7+ import { TableSettingsEntity } from '../table-settings/common-table-settings/table-settings.entity.js' ;
98
109interface AIGeneratedTableSettings {
1110 table_name : string ;
1211 display_name : string ;
13- list_fields : string [ ] ;
14- ordering_field : string | null ;
15- ordering : "ASC" | "DESC" ;
1612 search_fields : string [ ] ;
1713 readonly_fields : string [ ] ;
1814 columns_view : string [ ] ;
@@ -42,47 +38,39 @@ export class AiService {
4238 }
4339
4440 private buildPrompt ( tablesInformation : Array < TableInformation > ) : string {
45- const widgetTypes = Object . values ( WidgetTypeEnum ) . join ( ", " ) ;
41+ const widgetTypes = Object . values ( WidgetTypeEnum ) . join ( ', ' ) ;
4642
4743 const tablesDescription = tablesInformation
4844 . map ( ( table ) => {
4945 const columns = table . structure
5046 . map (
5147 ( col ) =>
52- ` - ${ col . column_name } : ${ col . data_type } ${ col . allow_null ? " (nullable)" : "" } ${ checkFieldAutoincrement ( col . column_default , col . extra ) ? " (auto_increment)" : "" } ` ,
48+ ` - ${ col . column_name } : ${ col . data_type } ${ col . allow_null ? ' (nullable)' : '' } ${ checkFieldAutoincrement ( col . column_default , col . extra ) ? ' (auto_increment)' : '' } ` ,
5349 )
54- . join ( "\n" ) ;
55- const primaryKeys = table . primaryColumns
56- . map ( ( pk ) => pk . column_name )
57- . join ( ", " ) ;
50+ . join ( '\n' ) ;
51+ const primaryKeys = table . primaryColumns . map ( ( pk ) => pk . column_name ) . join ( ', ' ) ;
5852 const foreignKeys = table . foreignKeys
59- . map (
60- ( fk ) =>
61- ` - ${ fk . column_name } -> ${ fk . referenced_table_name } .${ fk . referenced_column_name } ` ,
62- )
63- . join ( "\n" ) ;
53+ . map ( ( fk ) => ` - ${ fk . column_name } -> ${ fk . referenced_table_name } .${ fk . referenced_column_name } ` )
54+ . join ( '\n' ) ;
6455
6556 return `
6657Table: ${ table . table_name }
67- Primary Keys: ${ primaryKeys || " none" }
58+ Primary Keys: ${ primaryKeys || ' none' }
6859 Columns:
6960${ columns }
7061 Foreign Keys:
71- ${ foreignKeys || " none" } `;
62+ ${ foreignKeys || ' none' } `;
7263 } )
73- . join ( " \n\n" ) ;
64+ . join ( ' \n\n' ) ;
7465
7566 return `You are a database administration assistant. Analyze the following database tables and generate optimal settings for displaying and managing them in a web admin panel.
7667
7768For each table, provide:
78691. display_name: A human-readable name for the table
79- 2. list_fields: Columns to display in the table list view (most important columns first, max 5-7 columns)
80- 3. ordering_field: The best column to sort by default (usually created_at, id, or a timestamp)
81- 4. ordering: ASC or DESC
82- 5. search_fields: Columns that should be searchable
83- 6. readonly_fields: Columns that should not be editable (like auto_increment, timestamps)
84- 7. columns_view: All columns in preferred display order
85- 8. widgets: For each column, suggest the best widget type from: ${ widgetTypes }
70+ 2. search_fields: Columns that should be searchable (text fields like name, email, title)
71+ 3. readonly_fields: Columns that should not be editable (like auto_increment, timestamps)
72+ 4. columns_view: All columns in preferred display order
73+ 5. widgets: For each column, suggest the best widget type from: ${ widgetTypes }
8674
8775Available widget types and when to use them:
8876- Password: for password fields
@@ -118,9 +106,6 @@ Respond ONLY with valid JSON in this exact format (no markdown, no explanations)
118106 {
119107 "table_name": "table_name",
120108 "display_name": "Human Readable Name",
121- "list_fields": ["col1", "col2"],
122- "ordering_field": "created_at",
123- "ordering": "DESC",
124109 "search_fields": ["name", "email"],
125110 "readonly_fields": ["id", "created_at"],
126111 "columns_view": ["id", "name", "email", "created_at"],
@@ -139,12 +124,12 @@ Respond ONLY with valid JSON in this exact format (no markdown, no explanations)
139124
140125 private parseAIResponse ( aiResponse : string ) : AIResponse {
141126 let cleanedResponse = aiResponse . trim ( ) ;
142- if ( cleanedResponse . startsWith ( " ```json" ) ) {
127+ if ( cleanedResponse . startsWith ( ' ```json' ) ) {
143128 cleanedResponse = cleanedResponse . slice ( 7 ) ;
144- } else if ( cleanedResponse . startsWith ( " ```" ) ) {
129+ } else if ( cleanedResponse . startsWith ( ' ```' ) ) {
145130 cleanedResponse = cleanedResponse . slice ( 3 ) ;
146131 }
147- if ( cleanedResponse . endsWith ( " ```" ) ) {
132+ if ( cleanedResponse . endsWith ( ' ```' ) ) {
148133 cleanedResponse = cleanedResponse . slice ( 0 , - 3 ) ;
149134 }
150135 cleanedResponse = cleanedResponse . trim ( ) ;
@@ -161,36 +146,15 @@ Respond ONLY with valid JSON in this exact format (no markdown, no explanations)
161146 tablesInformation : Array < TableInformation > ,
162147 ) : Array < TableSettingsEntity > {
163148 return aiResponse . tables . map ( ( tableSettings ) => {
164- const tableInfo = tablesInformation . find (
165- ( t ) => t . table_name === tableSettings . table_name ,
166- ) ;
167- const validColumnNames =
168- tableInfo ?. structure . map ( ( col ) => col . column_name ) || [ ] ;
149+ const tableInfo = tablesInformation . find ( ( t ) => t . table_name === tableSettings . table_name ) ;
150+ const validColumnNames = tableInfo ?. structure . map ( ( col ) => col . column_name ) || [ ] ;
169151
170152 const settings = new TableSettingsEntity ( ) ;
171153 settings . table_name = tableSettings . table_name ;
172154 settings . display_name = tableSettings . display_name ;
173- settings . list_fields = this . filterValidColumns (
174- tableSettings . list_fields ,
175- validColumnNames ,
176- ) ;
177- settings . ordering_field = tableSettings . ordering_field ;
178- settings . ordering =
179- tableSettings . ordering === "DESC"
180- ? QueryOrderingEnum . DESC
181- : QueryOrderingEnum . ASC ;
182- settings . search_fields = this . filterValidColumns (
183- tableSettings . search_fields ,
184- validColumnNames ,
185- ) ;
186- settings . readonly_fields = this . filterValidColumns (
187- tableSettings . readonly_fields ,
188- validColumnNames ,
189- ) ;
190- settings . columns_view = this . filterValidColumns (
191- tableSettings . columns_view ,
192- validColumnNames ,
193- ) ;
155+ settings . search_fields = this . filterValidColumns ( tableSettings . search_fields , validColumnNames ) ;
156+ settings . readonly_fields = this . filterValidColumns ( tableSettings . readonly_fields , validColumnNames ) ;
157+ settings . columns_view = this . filterValidColumns ( tableSettings . columns_view , validColumnNames ) ;
194158 settings . table_widgets = tableSettings . widgets
195159 . filter ( ( w ) => validColumnNames . includes ( w . field_name ) )
196160 . map ( ( widgetData ) => {
@@ -206,38 +170,35 @@ Respond ONLY with valid JSON in this exact format (no markdown, no explanations)
206170 } ) ;
207171 }
208172
209- private filterValidColumns (
210- columns : string [ ] ,
211- validColumnNames : string [ ] ,
212- ) : string [ ] {
173+ private filterValidColumns ( columns : string [ ] , validColumnNames : string [ ] ) : string [ ] {
213174 return columns ?. filter ( ( col ) => validColumnNames . includes ( col ) ) || [ ] ;
214175 }
215176
216177 private mapWidgetType ( widgetType : string ) : WidgetTypeEnum | undefined {
217178 const widgetTypeMap = new Map < string , WidgetTypeEnum > ( [
218- [ " Password" , WidgetTypeEnum . Password ] ,
219- [ " Boolean" , WidgetTypeEnum . Boolean ] ,
220- [ " Date" , WidgetTypeEnum . Date ] ,
221- [ " Time" , WidgetTypeEnum . Time ] ,
222- [ " DateTime" , WidgetTypeEnum . DateTime ] ,
223- [ " JSON" , WidgetTypeEnum . JSON ] ,
224- [ " Textarea" , WidgetTypeEnum . Textarea ] ,
225- [ " String" , WidgetTypeEnum . String ] ,
226- [ " Readonly" , WidgetTypeEnum . Readonly ] ,
227- [ " Number" , WidgetTypeEnum . Number ] ,
228- [ " Select" , WidgetTypeEnum . Select ] ,
229- [ " UUID" , WidgetTypeEnum . UUID ] ,
230- [ " Enum" , WidgetTypeEnum . Enum ] ,
231- [ " Foreign_key" , WidgetTypeEnum . Foreign_key ] ,
232- [ " File" , WidgetTypeEnum . File ] ,
233- [ " Image" , WidgetTypeEnum . Image ] ,
234- [ " URL" , WidgetTypeEnum . URL ] ,
235- [ " Code" , WidgetTypeEnum . Code ] ,
236- [ " Phone" , WidgetTypeEnum . Phone ] ,
237- [ " Country" , WidgetTypeEnum . Country ] ,
238- [ " Color" , WidgetTypeEnum . Color ] ,
239- [ " Range" , WidgetTypeEnum . Range ] ,
240- [ " Timezone" , WidgetTypeEnum . Timezone ] ,
179+ [ ' Password' , WidgetTypeEnum . Password ] ,
180+ [ ' Boolean' , WidgetTypeEnum . Boolean ] ,
181+ [ ' Date' , WidgetTypeEnum . Date ] ,
182+ [ ' Time' , WidgetTypeEnum . Time ] ,
183+ [ ' DateTime' , WidgetTypeEnum . DateTime ] ,
184+ [ ' JSON' , WidgetTypeEnum . JSON ] ,
185+ [ ' Textarea' , WidgetTypeEnum . Textarea ] ,
186+ [ ' String' , WidgetTypeEnum . String ] ,
187+ [ ' Readonly' , WidgetTypeEnum . Readonly ] ,
188+ [ ' Number' , WidgetTypeEnum . Number ] ,
189+ [ ' Select' , WidgetTypeEnum . Select ] ,
190+ [ ' UUID' , WidgetTypeEnum . UUID ] ,
191+ [ ' Enum' , WidgetTypeEnum . Enum ] ,
192+ [ ' Foreign_key' , WidgetTypeEnum . Foreign_key ] ,
193+ [ ' File' , WidgetTypeEnum . File ] ,
194+ [ ' Image' , WidgetTypeEnum . Image ] ,
195+ [ ' URL' , WidgetTypeEnum . URL ] ,
196+ [ ' Code' , WidgetTypeEnum . Code ] ,
197+ [ ' Phone' , WidgetTypeEnum . Phone ] ,
198+ [ ' Country' , WidgetTypeEnum . Country ] ,
199+ [ ' Color' , WidgetTypeEnum . Color ] ,
200+ [ ' Range' , WidgetTypeEnum . Range ] ,
201+ [ ' Timezone' , WidgetTypeEnum . Timezone ] ,
241202 ] ) ;
242203 return widgetTypeMap . get ( widgetType ) ;
243204 }
0 commit comments