modified: backend/src/config/dynamicSwagger.ts

modified:   backend/src/controllers/endpointController.ts
	new file:   backend/src/migrations/009_add_response_schema.sql
	modified:   backend/src/types/index.ts
	modified:   frontend/src/pages/EndpointEditor.tsx
	modified:   frontend/src/types/index.ts
This commit is contained in:
2026-03-13 15:22:32 +03:00
parent b6b7064a41
commit 727c6765f8
6 changed files with 94 additions and 15 deletions

View File

@@ -44,6 +44,7 @@ export async function generateDynamicSwagger(): Promise<SwaggerSpec> {
e.path,
e.parameters,
e.is_public,
e.response_schema,
fp.full_path as folder_name
FROM endpoints e
LEFT JOIN folder_path fp ON e.folder_id = fp.id
@@ -136,15 +137,17 @@ export async function generateDynamicSwagger(): Promise<SwaggerSpec> {
description: 'Успешный ответ',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
success: { type: 'boolean' },
data: { type: 'array', items: { type: 'object' } },
rowCount: { type: 'number' },
executionTime: { type: 'number' },
},
},
schema: endpoint.response_schema
? endpoint.response_schema
: {
type: 'object',
properties: {
success: { type: 'boolean' },
data: { type: 'array', items: { type: 'object' } },
rowCount: { type: 'number' },
executionTime: { type: 'number' },
},
},
},
},
},

View File

@@ -88,6 +88,7 @@ export const createEndpoint = async (req: AuthRequest, res: Response) => {
aql_body,
aql_query_params,
detailed_response,
response_schema,
} = req.body;
if (!name || !method || !path) {
@@ -122,9 +123,9 @@ export const createEndpoint = async (req: AuthRequest, res: Response) => {
name, description, method, path, database_id, sql_query, parameters,
folder_id, user_id, is_public, enable_logging,
execution_type, script_language, script_code, script_queries,
aql_method, aql_endpoint, aql_body, aql_query_params, detailed_response
aql_method, aql_endpoint, aql_body, aql_query_params, detailed_response, response_schema
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21)
RETURNING *`,
[
name,
@@ -147,6 +148,7 @@ export const createEndpoint = async (req: AuthRequest, res: Response) => {
aql_body || null,
JSON.stringify(aql_query_params || {}),
detailed_response || false,
response_schema ? JSON.stringify(response_schema) : null,
]
);
@@ -183,6 +185,7 @@ export const updateEndpoint = async (req: AuthRequest, res: Response) => {
aql_body,
aql_query_params,
detailed_response,
response_schema,
} = req.body;
const result = await mainPool.query(
@@ -206,8 +209,9 @@ export const updateEndpoint = async (req: AuthRequest, res: Response) => {
aql_body = $17,
aql_query_params = $18,
detailed_response = $19,
response_schema = $20,
updated_at = CURRENT_TIMESTAMP
WHERE id = $20
WHERE id = $21
RETURNING *`,
[
name,
@@ -229,6 +233,7 @@ export const updateEndpoint = async (req: AuthRequest, res: Response) => {
aql_body || null,
aql_query_params ? JSON.stringify(aql_query_params) : null,
detailed_response || false,
response_schema ? JSON.stringify(response_schema) : null,
id,
]
);
@@ -488,6 +493,7 @@ export const exportEndpoint = async (req: AuthRequest, res: Response) => {
is_public: endpoint.is_public || false,
enable_logging: endpoint.enable_logging || false,
detailed_response: endpoint.detailed_response || false,
response_schema: endpoint.response_schema || null,
folder_name: folderName,
};
@@ -700,9 +706,9 @@ export const importEndpoint = async (req: AuthRequest, res: Response) => {
name, description, method, path, database_id, sql_query, parameters,
folder_id, user_id, is_public, enable_logging,
execution_type, script_language, script_code, script_queries,
aql_method, aql_endpoint, aql_body, aql_query_params, detailed_response
aql_method, aql_endpoint, aql_body, aql_query_params, detailed_response, response_schema
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21)
RETURNING *`,
[
exportData.name,
@@ -725,6 +731,7 @@ export const importEndpoint = async (req: AuthRequest, res: Response) => {
exportData.aql_body || null,
JSON.stringify(exportData.aql_query_params || {}),
exportData.detailed_response || false,
exportData.response_schema ? JSON.stringify(exportData.response_schema) : null,
]
);

View File

@@ -0,0 +1,7 @@
-- Add response_schema to endpoints for Swagger documentation
-- Stores an OpenAPI-compatible JSON schema describing the 200 response
ALTER TABLE endpoints
ADD COLUMN IF NOT EXISTS response_schema JSONB DEFAULT NULL;
COMMENT ON COLUMN endpoints.response_schema IS 'Optional OpenAPI JSON schema for the 200 response, displayed in Swagger documentation.';

View File

@@ -71,6 +71,8 @@ export interface Endpoint {
aql_endpoint?: string;
aql_body?: string;
aql_query_params?: Record<string, string>;
// Response schema for Swagger docs
response_schema?: object | null;
created_at: Date;
updated_at: Date;
}
@@ -176,5 +178,7 @@ export interface ExportedEndpoint {
is_public: boolean;
enable_logging: boolean;
detailed_response: boolean;
response_schema: object | null;
folder_name: string | null;
}