From 5a85e3e1d99e4c738239e7984048baf8affe3a1d Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 22 Feb 2026 00:27:00 +0000 Subject: [PATCH] 0.1 --- backend/src/routes/managed_tables.js | 189 ++++++++++-------- backend/src/services/managed_tables.js | 56 ++++-- .../Managed_tables/PluginGenerator.tsx | 118 +++++++++++ .../managed_tables/[managed_tablesId].tsx | 16 +- 4 files changed, 283 insertions(+), 96 deletions(-) create mode 100644 frontend/src/components/Managed_tables/PluginGenerator.tsx diff --git a/backend/src/routes/managed_tables.js b/backend/src/routes/managed_tables.js index 3f5e636..e8069ec 100644 --- a/backend/src/routes/managed_tables.js +++ b/backend/src/routes/managed_tables.js @@ -5,8 +5,6 @@ const Managed_tablesService = require('../services/managed_tables'); const Managed_tablesDBApi = require('../db/api/managed_tables'); const wrapAsync = require('../helpers').wrapAsync; -const config = require('../config'); - const router = express.Router(); @@ -160,27 +158,27 @@ router.post('/bulk-import', wrapAsync(async (req, res) => { * id: * description: ID of the updated item * type: string - * data: - * description: Data of the updated item - * type: object - * $ref: "#/components/schemas/Managed_tables" - * required: - * - id - * responses: - * 200: - * description: The item data was successfully updated - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Managed_tables" - * 400: - * description: Invalid ID supplied - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Item not found - * 500: - * description: Some server error + data: + description: Data of the updated item + type: object + $ref: "#/components/schemas/Managed_tables" + required: + - id + responses: + 200: + description: The item data was successfully updated + content: + application/json: + schema: + $ref: "#/components/schemas/Managed_tables" + 400: + description: Invalid ID supplied + 401: + $ref: "#/components/responses/UnauthorizedError" + 404: + description: Item not found + 500: + description: Some server error */ router.put('/:id', wrapAsync(async (req, res) => { await Managed_tablesService.update(req.body.data, req.body.id, req.currentUser); @@ -204,21 +202,21 @@ router.put('/:id', wrapAsync(async (req, res) => { * required: true * schema: * type: string - * responses: - * 200: - * description: The item was successfully deleted - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Managed_tables" - * 400: - * description: Invalid ID supplied - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Item not found - * 500: - * description: Some server error + responses: + 200: + description: The item was successfully deleted + content: + application/json: + schema: + $ref: "#/components/schemas/Managed_tables" + 400: + description: Invalid ID supplied + 401: + $ref: "#/components/responses/UnauthorizedError" + 404: + description: Item not found + 500: + description: Some server error */ router.delete('/:id', wrapAsync(async (req, res) => { await Managed_tablesService.remove(req.params.id, req.currentUser); @@ -244,19 +242,19 @@ router.delete('/:id', wrapAsync(async (req, res) => { * ids: * description: IDs of the updated items * type: array - * responses: - * 200: - * description: The items was successfully deleted - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Managed_tables" - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Items not found - * 500: - * description: Some server error + responses: + 200: + description: The items was successfully deleted + content: + application/json: + schema: + $ref: "#/components/schemas/Managed_tables" + 401: + $ref: "#/components/responses/UnauthorizedError" + 404: + description: Items not found + 500: + description: Some server error */ router.post('/deleteByIds', wrapAsync(async (req, res) => { await Managed_tablesService.deleteByIds(req.body.data, req.currentUser); @@ -274,20 +272,20 @@ router.post('/deleteByIds', wrapAsync(async (req, res) => { * summary: Get all managed_tables * description: Get all managed_tables * responses: - * 200: - * description: Managed_tables list successfully received - * content: - * application/json: - * schema: - * type: array - * items: - * $ref: "#/components/schemas/Managed_tables" - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Data not found - * 500: - * description: Some server error + 200: + description: Managed_tables list successfully received + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Managed_tables" + 401: + $ref: "#/components/responses/UnauthorizedError" + 404: + description: Data not found + 500: + description: Some server error */ router.get('/', wrapAsync(async (req, res) => { const filetype = req.query.filetype @@ -416,21 +414,21 @@ router.get('/autocomplete', async (req, res) => { * required: true * schema: * type: string - * responses: - * 200: - * description: Selected item successfully received - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Managed_tables" - * 400: - * description: Invalid ID supplied - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Item not found - * 500: - * description: Some server error + responses: + 200: + description: Selected item successfully received + content: + application/json: + schema: + $ref: "#/components/schemas/Managed_tables" + 400: + description: Invalid ID supplied + 401: + $ref: "#/components/responses/UnauthorizedError" + 404: + description: Item not found + 500: + description: Some server error */ router.get('/:id', wrapAsync(async (req, res) => { const payload = await Managed_tablesDBApi.findBy( @@ -442,6 +440,37 @@ router.get('/:id', wrapAsync(async (req, res) => { res.status(200).send(payload); })); +/** + * @swagger + * /api/managed_tables/{id}/generate-plugin: + * post: + * security: + * - bearerAuth: [] + * tags: [Managed_tables] + * summary: Generate WordPress plugin code for this table + * description: Generate WordPress plugin code for this table using AI + * parameters: + * - in: path + * name: id + * description: ID of the managed table + * required: true + * schema: + * type: string + * responses: + * 200: + * description: Plugin code successfully generated + * 401: + * $ref: "#/components/responses/UnauthorizedError" + * 404: + * description: Managed table not found + * 500: + * description: Some server error + */ +router.post('/:id/generate-plugin', wrapAsync(async (req, res) => { + const payload = await Managed_tablesService.generatePluginCode(req.params.id); + res.status(200).send(payload); +})); + router.use('/', require('../helpers').commonErrorHandler); module.exports = router; diff --git a/backend/src/services/managed_tables.js b/backend/src/services/managed_tables.js index 35127da..818902f 100644 --- a/backend/src/services/managed_tables.js +++ b/backend/src/services/managed_tables.js @@ -3,13 +3,8 @@ const Managed_tablesDBApi = require('../db/api/managed_tables'); const processFile = require("../middlewares/upload"); const ValidationError = require('./notifications/errors/validation'); const csv = require('csv-parser'); -const axios = require('axios'); -const config = require('../config'); const stream = require('stream'); - - - - +const OpenAiService = require('./openai'); module.exports = class Managed_tablesService { static async create(data, currentUser) { @@ -28,9 +23,9 @@ module.exports = class Managed_tablesService { await transaction.rollback(); throw error; } - }; + } - static async bulkImport(req, res, sendInvitationEmails = true, host) { + static async bulkImport(req, res) { const transaction = await db.sequelize.transaction(); try { @@ -95,7 +90,7 @@ module.exports = class Managed_tablesService { await transaction.rollback(); throw error; } - }; + } static async deleteByIds(ids, currentUser) { const transaction = await db.sequelize.transaction(); @@ -132,7 +127,44 @@ module.exports = class Managed_tablesService { } } - + static async generatePluginCode(id) { + const table = await Managed_tablesDBApi.findBy({ id }); + if (!table) { + throw new ValidationError('managed_tablesNotFound'); + } + + const columns = table.table_columns_managed_table || []; + const columnDefinitions = columns.map(c => ({ + name: c.column_name, + label: c.label, + type: c.data_type, + isPrimary: c.is_primary_key, + isNullable: c.is_nullable + })); + + const prompt = ` + Generate a professional WordPress plugin (PHP) that provides a full CRUD admin interface for a custom MySQL table. + + Table Name: ${table.table_name} + Plugin Label: ${table.label} + + Columns: + ${JSON.stringify(columnDefinitions, null, 2)} + + Requirements: + 1. Use WordPress best practices and $wpdb for all database operations. + 2. Create a top-level admin menu item for this plugin. + 3. Implement a list table view with searching and sorting. + 4. Implement Add/Edit forms with proper validation and sanitization. + 5. Implement a Delete action with nonces for security. + 6. Include a activation hook to create the table if it doesn't exist (use dbDelta). + 7. Use clean, well-commented code. + 8. The plugin should be a single PHP file for simplicity. + + Output only the PHP code block. + `; + + const result = await OpenAiService.askGpt(prompt); + return result; + } }; - - diff --git a/frontend/src/components/Managed_tables/PluginGenerator.tsx b/frontend/src/components/Managed_tables/PluginGenerator.tsx new file mode 100644 index 0000000..af12dd9 --- /dev/null +++ b/frontend/src/components/Managed_tables/PluginGenerator.tsx @@ -0,0 +1,118 @@ +import React, { useState } from 'react' +import { mdiCodeBraces, mdiContentCopy, mdiLoading, mdiCheck } from '@mdi/js' +import axios from 'axios' +import BaseButton from '../BaseButton' +import CardBox from '../CardBox' +import CardBoxComponentBody from '../CardBoxComponentBody' +import CardBoxComponentTitle from '../CardBoxComponentTitle' +import CardBoxComponentFooter from '../CardBoxComponentFooter' +import BaseIcon from '../BaseIcon' + +interface PluginGeneratorProps { + managedTableId: string + tableName: string +} + +const PluginGenerator: React.FC = ({ managedTableId, tableName }) => { + const [code, setCode] = useState(null) + const [isGenerating, setIsGenerating] = useState(false) + const [copied, setCopied] = useState(false) + const [error, setError] = useState(null) + + const handleGenerate = async () => { + setIsGenerating(true) + setError(null) + try { + const response = await axios.post(`/managed_tables/${managedTableId}/generate-plugin`) + if (response.data && response.data.success) { + setCode(response.data.data) + } else { + setError(response.data.error || 'Failed to generate plugin code.') + } + } catch (err: any) { + console.error(err) + setError(err.response?.data?.error || 'An error occurred while generating the plugin.') + } finally { + setIsGenerating(false) + } + } + + const handleCopy = () => { + if (code) { + navigator.clipboard.writeText(code) + setCopied(true) + setTimeout(() => setCopied(false), 2000) + } + } + + return ( + + + + +
+

+ Generate a custom WordPress plugin for the table "{tableName}". +

+

+ This will create a complete PHP plugin with admin CRUD operations using WordPress best practices. +

+
+ + {error && ( +
+ {error} +
+ )} + + {code ? ( +
+
+ +
+
+              {code}
+            
+
+ ) : ( +
+ +

No code generated yet.

+ +
+ )} +
+ + {code && ( + +
+ Generated using AI based on your table schema. + +
+
+ )} +
+ ) +} + +export default PluginGenerator \ No newline at end of file diff --git a/frontend/src/pages/managed_tables/[managed_tablesId].tsx b/frontend/src/pages/managed_tables/[managed_tablesId].tsx index 969b558..daed855 100644 --- a/frontend/src/pages/managed_tables/[managed_tablesId].tsx +++ b/frontend/src/pages/managed_tables/[managed_tablesId].tsx @@ -1,4 +1,4 @@ -import { mdiChartTimelineVariant, mdiUpload } from '@mdi/js' +import { mdiChartTimelineVariant, mdiUpload, mdiCodeBraces } from '@mdi/js' import Head from 'next/head' import React, { ReactElement, useEffect, useState } from 'react' import DatePicker from "react-datepicker"; @@ -31,6 +31,7 @@ import { useRouter } from 'next/router' import {saveFile} from "../../helpers/fileSaver"; import dataFormatter from '../../helpers/dataFormatter'; import ImageField from "../../components/ImageField"; +import PluginGenerator from '../../components/Managed_tables/PluginGenerator'; import {hasPermission} from "../../helpers/userPermissions"; @@ -361,8 +362,10 @@ const EditManaged_tables = () => { const { managed_tablesId } = router.query useEffect(() => { - dispatch(fetch({ id: managed_tablesId })) - }, [managed_tablesId]) + if (managed_tablesId) { + dispatch(fetch({ id: managed_tablesId })) + } + }, [managed_tablesId, dispatch]) useEffect(() => { if (typeof managed_tables === 'object') { @@ -918,6 +921,11 @@ const EditManaged_tables = () => { + + ) @@ -935,4 +943,4 @@ EditManaged_tables.getLayout = function getLayout(page: ReactElement) { ) } -export default EditManaged_tables +export default EditManaged_tables \ No newline at end of file