mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-11 00:08:30 +01:00
refactor: add schemas to feedback controller (#1698)
* refactor: remove previous getProjects route * refactor: add schemas to feedback controller
This commit is contained in:
parent
e64d5a1f97
commit
28ecb158a9
@ -12,6 +12,7 @@ import { featureTypeSchema } from './spec/feature-type-schema';
|
||||
import { featureTypesSchema } from './spec/feature-types-schema';
|
||||
import { featureVariantsSchema } from './spec/feature-variants-schema';
|
||||
import { featuresSchema } from './spec/features-schema';
|
||||
import { feedbackSchema } from './spec/feedback-schema';
|
||||
import { healthOverviewSchema } from './spec/health-overview-schema';
|
||||
import { healthReportSchema } from './spec/health-report-schema';
|
||||
import { mapValues } from '../util/map-values';
|
||||
@ -54,6 +55,7 @@ export const schemas = {
|
||||
featureTypesSchema,
|
||||
featureVariantsSchema,
|
||||
featuresSchema,
|
||||
feedbackSchema,
|
||||
healthOverviewSchema,
|
||||
healthReportSchema,
|
||||
overrideSchema,
|
||||
|
27
src/lib/openapi/spec/feedback-schema.ts
Normal file
27
src/lib/openapi/spec/feedback-schema.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
|
||||
export const feedbackSchema = {
|
||||
$id: '#/components/schemas/feedbackSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: [],
|
||||
properties: {
|
||||
userId: {
|
||||
type: 'number',
|
||||
},
|
||||
feedbackId: {
|
||||
type: 'string',
|
||||
},
|
||||
neverShow: {
|
||||
type: 'boolean',
|
||||
},
|
||||
given: {
|
||||
type: 'string',
|
||||
format: 'date-time',
|
||||
nullable: true,
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
} as const;
|
||||
|
||||
export type FeedbackSchema = FromSchema<typeof feedbackSchema>;
|
@ -26,8 +26,6 @@ export default class ProjectApi extends Controller {
|
||||
this.projectService = services.projectService;
|
||||
this.openApiService = services.openApiService;
|
||||
|
||||
this.get('/', this.getProjects);
|
||||
|
||||
this.route({
|
||||
path: '',
|
||||
method: 'get',
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Response } from 'express';
|
||||
|
||||
import Controller from '../controller';
|
||||
import { Logger } from '../../logger';
|
||||
import { IUnleashConfig } from '../../types/option';
|
||||
@ -7,73 +6,106 @@ import { IUnleashServices } from '../../types/services';
|
||||
import UserFeedbackService from '../../services/user-feedback-service';
|
||||
import { IAuthRequest } from '../unleash-types';
|
||||
import { NONE } from '../../types/permissions';
|
||||
|
||||
interface IFeedbackBody {
|
||||
neverShow?: boolean;
|
||||
feedbackId: string;
|
||||
given?: Date;
|
||||
}
|
||||
import { OpenApiService } from '../../services/openapi-service';
|
||||
import {
|
||||
feedbackSchema,
|
||||
FeedbackSchema,
|
||||
} from '../../openapi/spec/feedback-schema';
|
||||
import { serializeDates } from '../../types/serialize-dates';
|
||||
import { parseISO } from 'date-fns';
|
||||
import { createRequestSchema, createResponseSchema } from '../../openapi';
|
||||
import BadDataError from '../../error/bad-data-error';
|
||||
|
||||
class UserFeedbackController extends Controller {
|
||||
private logger: Logger;
|
||||
|
||||
private userFeedbackService: UserFeedbackService;
|
||||
|
||||
private openApiService: OpenApiService;
|
||||
|
||||
constructor(
|
||||
config: IUnleashConfig,
|
||||
{ userFeedbackService }: Pick<IUnleashServices, 'userFeedbackService'>,
|
||||
{
|
||||
userFeedbackService,
|
||||
openApiService,
|
||||
}: Pick<IUnleashServices, 'userFeedbackService' | 'openApiService'>,
|
||||
) {
|
||||
super(config);
|
||||
this.logger = config.getLogger('feedback-controller.ts');
|
||||
this.userFeedbackService = userFeedbackService;
|
||||
this.openApiService = openApiService;
|
||||
|
||||
this.post('/', this.recordFeedback, NONE);
|
||||
this.put('/:id', this.updateFeedbackSettings, NONE);
|
||||
this.route({
|
||||
method: 'post',
|
||||
path: '',
|
||||
handler: this.createFeedback,
|
||||
permission: NONE,
|
||||
middleware: [
|
||||
openApiService.validPath({
|
||||
tags: ['admin'],
|
||||
operationId: 'createFeedback',
|
||||
requestBody: createRequestSchema('feedbackSchema'),
|
||||
responses: { 200: createResponseSchema('feedbackSchema') },
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
this.route({
|
||||
method: 'put',
|
||||
path: '/:id',
|
||||
handler: this.updateFeedback,
|
||||
permission: NONE,
|
||||
middleware: [
|
||||
openApiService.validPath({
|
||||
tags: ['admin'],
|
||||
operationId: 'updateFeedback',
|
||||
requestBody: createRequestSchema('feedbackSchema'),
|
||||
responses: { 200: createResponseSchema('feedbackSchema') },
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private async recordFeedback(
|
||||
req: IAuthRequest<any, any, IFeedbackBody, any>,
|
||||
res: Response,
|
||||
private async createFeedback(
|
||||
req: IAuthRequest<unknown, unknown, FeedbackSchema>,
|
||||
res: Response<FeedbackSchema>,
|
||||
): Promise<void> {
|
||||
const BAD_REQUEST = 400;
|
||||
const { user } = req;
|
||||
|
||||
const { feedbackId } = req.body;
|
||||
|
||||
if (!feedbackId) {
|
||||
res.status(BAD_REQUEST).json({
|
||||
error: 'feedbackId must be present.',
|
||||
});
|
||||
return;
|
||||
if (!req.body.feedbackId) {
|
||||
throw new BadDataError('Missing feedbackId');
|
||||
}
|
||||
|
||||
const feedback = {
|
||||
...req.body,
|
||||
userId: user.id,
|
||||
const updated = await this.userFeedbackService.updateFeedback({
|
||||
feedbackId: req.body.feedbackId,
|
||||
userId: req.user.id,
|
||||
given: new Date(),
|
||||
neverShow: req.body.neverShow || false,
|
||||
};
|
||||
});
|
||||
|
||||
const updated = await this.userFeedbackService.updateFeedback(feedback);
|
||||
res.json(updated);
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
feedbackSchema.$id,
|
||||
serializeDates(updated),
|
||||
);
|
||||
}
|
||||
|
||||
private async updateFeedbackSettings(
|
||||
req: IAuthRequest<any, any, IFeedbackBody, any>,
|
||||
res: Response,
|
||||
private async updateFeedback(
|
||||
req: IAuthRequest<{ id: string }, unknown, FeedbackSchema>,
|
||||
res: Response<FeedbackSchema>,
|
||||
): Promise<void> {
|
||||
const { user } = req;
|
||||
const { id } = req.params;
|
||||
|
||||
const feedback = {
|
||||
...req.body,
|
||||
feedbackId: id,
|
||||
userId: user.id,
|
||||
const updated = await this.userFeedbackService.updateFeedback({
|
||||
feedbackId: req.params.id,
|
||||
userId: req.user.id,
|
||||
neverShow: req.body.neverShow || false,
|
||||
};
|
||||
given: req.body.given && parseISO(req.body.given),
|
||||
});
|
||||
|
||||
const updated = await this.userFeedbackService.updateFeedback(feedback);
|
||||
res.json(updated);
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
feedbackSchema.$id,
|
||||
serializeDates(updated),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ test('it gives 400 when feedback is not present', async () => {
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(400)
|
||||
.expect((res) => {
|
||||
expect(res.body.error).toBeTruthy();
|
||||
expect(res.body.name).toEqual('BadDataError');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -435,8 +435,5 @@ test(`should clean apitokens for not existing environment after import with drop
|
||||
.expect(202);
|
||||
|
||||
const apiTokens = await app.services.apiTokenService.getAllTokens();
|
||||
|
||||
console.log(apiTokens);
|
||||
|
||||
expect(apiTokens.length).toEqual(0);
|
||||
});
|
||||
|
@ -422,6 +422,27 @@ Object {
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"feedbackSchema": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
"feedbackId": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"given": Object {
|
||||
"format": "date-time",
|
||||
"nullable": true,
|
||||
"type": "string",
|
||||
},
|
||||
"neverShow": Object {
|
||||
"type": "boolean",
|
||||
},
|
||||
"userId": Object {
|
||||
"type": "number",
|
||||
},
|
||||
},
|
||||
"required": Array [],
|
||||
"type": "object",
|
||||
},
|
||||
"healthOverviewSchema": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
@ -1429,6 +1450,78 @@ Object {
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/feedback": Object {
|
||||
"post": Object {
|
||||
"operationId": "createFeedback",
|
||||
"requestBody": Object {
|
||||
"content": Object {
|
||||
"application/json": Object {
|
||||
"schema": Object {
|
||||
"$ref": "#/components/schemas/feedbackSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "feedbackSchema",
|
||||
"required": true,
|
||||
},
|
||||
"responses": Object {
|
||||
"200": Object {
|
||||
"content": Object {
|
||||
"application/json": Object {
|
||||
"schema": Object {
|
||||
"$ref": "#/components/schemas/feedbackSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "feedbackSchema",
|
||||
},
|
||||
},
|
||||
"tags": Array [
|
||||
"admin",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/feedback/{id}": Object {
|
||||
"put": Object {
|
||||
"operationId": "updateFeedback",
|
||||
"parameters": Array [
|
||||
Object {
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"schema": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
"requestBody": Object {
|
||||
"content": Object {
|
||||
"application/json": Object {
|
||||
"schema": Object {
|
||||
"$ref": "#/components/schemas/feedbackSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "feedbackSchema",
|
||||
"required": true,
|
||||
},
|
||||
"responses": Object {
|
||||
"200": Object {
|
||||
"content": Object {
|
||||
"application/json": Object {
|
||||
"schema": Object {
|
||||
"$ref": "#/components/schemas/feedbackSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "feedbackSchema",
|
||||
},
|
||||
},
|
||||
"tags": Array [
|
||||
"admin",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/projects": Object {
|
||||
"get": Object {
|
||||
"operationId": "getProjects",
|
||||
|
Loading…
Reference in New Issue
Block a user