mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	openapi: document operations for admin ui feedback (#4226)
This PR updates the endpoint documentation and schemas related to Admin UI feedback.
This commit is contained in:
		
							parent
							
								
									3da1cbba47
								
							
						
					
					
						commit
						8f5bda6b8a
					
				@ -54,7 +54,9 @@ import {
 | 
			
		||||
    featureTypesSchema,
 | 
			
		||||
    featureUsageSchema,
 | 
			
		||||
    featureVariantsSchema,
 | 
			
		||||
    feedbackSchema,
 | 
			
		||||
    feedbackCreateSchema,
 | 
			
		||||
    feedbackUpdateSchema,
 | 
			
		||||
    feedbackResponseSchema,
 | 
			
		||||
    groupSchema,
 | 
			
		||||
    groupsSchema,
 | 
			
		||||
    groupUserModelSchema,
 | 
			
		||||
@ -254,7 +256,9 @@ export const schemas: UnleashSchemas = {
 | 
			
		||||
    featureTypesSchema,
 | 
			
		||||
    featureUsageSchema,
 | 
			
		||||
    featureVariantsSchema,
 | 
			
		||||
    feedbackSchema,
 | 
			
		||||
    feedbackCreateSchema,
 | 
			
		||||
    feedbackUpdateSchema,
 | 
			
		||||
    feedbackResponseSchema,
 | 
			
		||||
    groupSchema,
 | 
			
		||||
    groupsSchema,
 | 
			
		||||
    groupUserModelSchema,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								src/lib/openapi/spec/feedback-create-schema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/lib/openapi/spec/feedback-create-schema.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
import { FromSchema } from 'json-schema-to-ts';
 | 
			
		||||
 | 
			
		||||
export const feedbackCreateSchema = {
 | 
			
		||||
    $id: '#/components/schemas/feedbackCreateSchema',
 | 
			
		||||
    required: ['feedbackId'],
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    description: 'User feedback information to be created.',
 | 
			
		||||
    properties: {
 | 
			
		||||
        neverShow: {
 | 
			
		||||
            description:
 | 
			
		||||
                '`true` if the user has asked never to see this feedback questionnaire again. Defaults to `false`.',
 | 
			
		||||
            type: 'boolean',
 | 
			
		||||
            example: false,
 | 
			
		||||
        },
 | 
			
		||||
        feedbackId: {
 | 
			
		||||
            description: 'The name of the feedback session',
 | 
			
		||||
            type: 'string',
 | 
			
		||||
            example: 'pnps',
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    components: {},
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
export type FeedbackCreateSchema = FromSchema<typeof feedbackCreateSchema>;
 | 
			
		||||
@ -1,24 +1,19 @@
 | 
			
		||||
import { FromSchema } from 'json-schema-to-ts';
 | 
			
		||||
 | 
			
		||||
export const feedbackSchema = {
 | 
			
		||||
    $id: '#/components/schemas/feedbackSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
export const feedbackResponseSchema = {
 | 
			
		||||
    $id: '#/components/schemas/feedbackResponseSchema',
 | 
			
		||||
    additionalProperties: false,
 | 
			
		||||
    description: 'User feedback information',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    description: 'User feedback information about a particular feedback item.',
 | 
			
		||||
    properties: {
 | 
			
		||||
        userId: {
 | 
			
		||||
            description: 'Identifier of the current user giving feedback',
 | 
			
		||||
            description: 'The ID of the user that gave the feedback.',
 | 
			
		||||
            type: 'integer',
 | 
			
		||||
            example: 2,
 | 
			
		||||
        },
 | 
			
		||||
        feedbackId: {
 | 
			
		||||
            description: 'The name of the feedback session',
 | 
			
		||||
            type: 'string',
 | 
			
		||||
            example: 'pnps',
 | 
			
		||||
        },
 | 
			
		||||
        neverShow: {
 | 
			
		||||
            description:
 | 
			
		||||
                '`true` when user opts-in to never show the feedback again.',
 | 
			
		||||
                '`true` if the user has asked never to see this feedback questionnaire again.',
 | 
			
		||||
            type: 'boolean',
 | 
			
		||||
            example: false,
 | 
			
		||||
        },
 | 
			
		||||
@ -29,8 +24,13 @@ export const feedbackSchema = {
 | 
			
		||||
            nullable: true,
 | 
			
		||||
            example: '2023-07-06T08:29:21.282Z',
 | 
			
		||||
        },
 | 
			
		||||
        feedbackId: {
 | 
			
		||||
            description: 'The name of the feedback session',
 | 
			
		||||
            type: 'string',
 | 
			
		||||
            example: 'pnps',
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    components: {},
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
export type FeedbackSchema = FromSchema<typeof feedbackSchema>;
 | 
			
		||||
export type FeedbackResponseSchema = FromSchema<typeof feedbackResponseSchema>;
 | 
			
		||||
							
								
								
									
										30
									
								
								src/lib/openapi/spec/feedback-update-schema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/lib/openapi/spec/feedback-update-schema.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
import { FromSchema } from 'json-schema-to-ts';
 | 
			
		||||
 | 
			
		||||
export const feedbackUpdateSchema = {
 | 
			
		||||
    $id: '#/components/schemas/feedbackUpdateSchema',
 | 
			
		||||
    type: 'object',
 | 
			
		||||
    description: 'User feedback information to be updated.',
 | 
			
		||||
    properties: {
 | 
			
		||||
        userId: {
 | 
			
		||||
            description: 'The ID of the user that gave the feedback.',
 | 
			
		||||
            type: 'integer',
 | 
			
		||||
            example: 2,
 | 
			
		||||
        },
 | 
			
		||||
        neverShow: {
 | 
			
		||||
            description:
 | 
			
		||||
                '`true` if the user has asked never to see this feedback questionnaire again.',
 | 
			
		||||
            type: 'boolean',
 | 
			
		||||
            example: false,
 | 
			
		||||
        },
 | 
			
		||||
        given: {
 | 
			
		||||
            description: 'When this feedback was given',
 | 
			
		||||
            type: 'string',
 | 
			
		||||
            format: 'date-time',
 | 
			
		||||
            nullable: true,
 | 
			
		||||
            example: '2023-07-06T08:29:21.282Z',
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    components: {},
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
export type FeedbackUpdateSchema = FromSchema<typeof feedbackUpdateSchema>;
 | 
			
		||||
@ -32,7 +32,9 @@ export * from './variant-schema';
 | 
			
		||||
export * from './variant-flag-schema';
 | 
			
		||||
export * from './version-schema';
 | 
			
		||||
export * from './features-schema';
 | 
			
		||||
export * from './feedback-schema';
 | 
			
		||||
export * from './feedback-create-schema';
 | 
			
		||||
export * from './feedback-update-schema';
 | 
			
		||||
export * from './feedback-response-schema';
 | 
			
		||||
export * from './override-schema';
 | 
			
		||||
export * from './password-schema';
 | 
			
		||||
export * from './projects-schema';
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { FromSchema } from 'json-schema-to-ts';
 | 
			
		||||
import { userSchema } from './user-schema';
 | 
			
		||||
import { permissionSchema } from './permission-schema';
 | 
			
		||||
import { feedbackSchema } from './feedback-schema';
 | 
			
		||||
import { feedbackResponseSchema } from './feedback-response-schema';
 | 
			
		||||
 | 
			
		||||
export const meSchema = {
 | 
			
		||||
    $id: '#/components/schemas/meSchema',
 | 
			
		||||
@ -24,7 +24,7 @@ export const meSchema = {
 | 
			
		||||
            description: 'User feedback information',
 | 
			
		||||
            type: 'array',
 | 
			
		||||
            items: {
 | 
			
		||||
                $ref: '#/components/schemas/feedbackSchema',
 | 
			
		||||
                $ref: '#/components/schemas/feedbackResponseSchema',
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
        splash: {
 | 
			
		||||
@ -39,7 +39,7 @@ export const meSchema = {
 | 
			
		||||
        schemas: {
 | 
			
		||||
            userSchema,
 | 
			
		||||
            permissionSchema,
 | 
			
		||||
            feedbackSchema,
 | 
			
		||||
            feedbackResponseSchema,
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
@ -7,15 +7,15 @@ import UserFeedbackService from '../../services/user-feedback-service';
 | 
			
		||||
import { IAuthRequest } from '../unleash-types';
 | 
			
		||||
import { NONE } from '../../types/permissions';
 | 
			
		||||
import { OpenApiService } from '../../services/openapi-service';
 | 
			
		||||
import {
 | 
			
		||||
    feedbackSchema,
 | 
			
		||||
    FeedbackSchema,
 | 
			
		||||
} from '../../openapi/spec/feedback-schema';
 | 
			
		||||
import { FeedbackCreateSchema } from '../../openapi/spec/feedback-create-schema';
 | 
			
		||||
import { FeedbackUpdateSchema } from '../../openapi/spec/feedback-update-schema';
 | 
			
		||||
import { FeedbackResponseSchema } from '../../openapi/spec/feedback-response-schema';
 | 
			
		||||
import { serializeDates } from '../../types/serialize-dates';
 | 
			
		||||
import { parseISO } from 'date-fns';
 | 
			
		||||
import { createRequestSchema } from '../../openapi/util/create-request-schema';
 | 
			
		||||
import { createResponseSchema } from '../../openapi/util/create-response-schema';
 | 
			
		||||
import BadDataError from '../../error/bad-data-error';
 | 
			
		||||
import { feedbackResponseSchema, getStandardResponses } from '../../openapi';
 | 
			
		||||
 | 
			
		||||
class UserFeedbackController extends Controller {
 | 
			
		||||
    private logger: Logger;
 | 
			
		||||
@ -45,8 +45,14 @@ class UserFeedbackController extends Controller {
 | 
			
		||||
                openApiService.validPath({
 | 
			
		||||
                    tags: ['Admin UI'],
 | 
			
		||||
                    operationId: 'createFeedback',
 | 
			
		||||
                    requestBody: createRequestSchema('feedbackSchema'),
 | 
			
		||||
                    responses: { 200: createResponseSchema('feedbackSchema') },
 | 
			
		||||
                    summary: 'Send Unleash feedback',
 | 
			
		||||
                    description:
 | 
			
		||||
                        'Sends feedback gathered from the Unleash UI to the Unleash server. Must be called with a token with an identifiable user (either from being sent from the UI or from using a [PAT](https://docs.getunleash.io/reference/api-tokens-and-client-keys#personal-access-tokens)).',
 | 
			
		||||
                    requestBody: createRequestSchema('feedbackCreateSchema'),
 | 
			
		||||
                    responses: {
 | 
			
		||||
                        200: createResponseSchema('feedbackResponseSchema'),
 | 
			
		||||
                        ...getStandardResponses(400, 401, 415),
 | 
			
		||||
                    },
 | 
			
		||||
                }),
 | 
			
		||||
            ],
 | 
			
		||||
        });
 | 
			
		||||
@ -60,16 +66,22 @@ class UserFeedbackController extends Controller {
 | 
			
		||||
                openApiService.validPath({
 | 
			
		||||
                    tags: ['Admin UI'],
 | 
			
		||||
                    operationId: 'updateFeedback',
 | 
			
		||||
                    requestBody: createRequestSchema('feedbackSchema'),
 | 
			
		||||
                    responses: { 200: createResponseSchema('feedbackSchema') },
 | 
			
		||||
                    summary: 'Update Unleash feedback',
 | 
			
		||||
                    description:
 | 
			
		||||
                        'Updates the feedback with the provided ID. Only provided fields are updated. Fields left out are left untouched. Must be called with a token with an identifiable user (either from being sent from the UI or from using a [PAT](https://docs.getunleash.io/reference/api-tokens-and-client-keys#personal-access-tokens)).',
 | 
			
		||||
                    requestBody: createRequestSchema('feedbackUpdateSchema'),
 | 
			
		||||
                    responses: {
 | 
			
		||||
                        200: createResponseSchema('feedbackResponseSchema'),
 | 
			
		||||
                        ...getStandardResponses(400, 401, 415),
 | 
			
		||||
                    },
 | 
			
		||||
                }),
 | 
			
		||||
            ],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private async createFeedback(
 | 
			
		||||
        req: IAuthRequest<unknown, unknown, FeedbackSchema>,
 | 
			
		||||
        res: Response<FeedbackSchema>,
 | 
			
		||||
        req: IAuthRequest<unknown, unknown, FeedbackCreateSchema>,
 | 
			
		||||
        res: Response<FeedbackResponseSchema>,
 | 
			
		||||
    ): Promise<void> {
 | 
			
		||||
        if (!req.body.feedbackId) {
 | 
			
		||||
            throw new BadDataError('Missing feedbackId');
 | 
			
		||||
@ -85,14 +97,14 @@ class UserFeedbackController extends Controller {
 | 
			
		||||
        this.openApiService.respondWithValidation(
 | 
			
		||||
            200,
 | 
			
		||||
            res,
 | 
			
		||||
            feedbackSchema.$id,
 | 
			
		||||
            feedbackResponseSchema.$id,
 | 
			
		||||
            serializeDates(updated),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private async updateFeedback(
 | 
			
		||||
        req: IAuthRequest<{ id: string }, unknown, FeedbackSchema>,
 | 
			
		||||
        res: Response<FeedbackSchema>,
 | 
			
		||||
        req: IAuthRequest<{ id: string }, unknown, FeedbackUpdateSchema>,
 | 
			
		||||
        res: Response<FeedbackResponseSchema>,
 | 
			
		||||
    ): Promise<void> {
 | 
			
		||||
        const updated = await this.userFeedbackService.updateFeedback({
 | 
			
		||||
            feedbackId: req.params.id,
 | 
			
		||||
@ -104,7 +116,7 @@ class UserFeedbackController extends Controller {
 | 
			
		||||
        this.openApiService.respondWithValidation(
 | 
			
		||||
            200,
 | 
			
		||||
            res,
 | 
			
		||||
            feedbackSchema.$id,
 | 
			
		||||
            feedbackResponseSchema.$id,
 | 
			
		||||
            serializeDates(updated),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,13 @@ beforeAll(async () => {
 | 
			
		||||
        );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    app = await setupAppWithCustomAuth(stores, preHook);
 | 
			
		||||
    app = await setupAppWithCustomAuth(stores, preHook, {
 | 
			
		||||
        experimental: {
 | 
			
		||||
            flags: {
 | 
			
		||||
                strictSchemaValidation: true,
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
afterAll(async () => {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user