Skip to content

Commit 80c7f9d

Browse files
chore: migrate apps engine logs API endpoint to new format (RocketChat#40225)
Co-authored-by: Douglas Gubert <douglas.gubert@gmail.com>
1 parent 543b6c8 commit 80c7f9d

4 files changed

Lines changed: 387 additions & 47 deletions

File tree

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,72 @@
1-
import { isAppLogsProps } from '@rocket.chat/rest-typings';
1+
import { isAppLogsProps, ajv } from '@rocket.chat/rest-typings';
22

33
import { getPaginationItems } from '../../../../../app/api/server/helpers/getPaginationItems';
44
import type { AppsRestApi } from '../rest';
55
import { makeAppLogsQuery } from './lib/makeAppLogsQuery';
66

7+
// TODO: this is a very common error response schema. We should find a way to standardize it.
8+
const errorResponse = ajv.compile<{
9+
success: false;
10+
error: string;
11+
}>({
12+
additionalProperties: false,
13+
type: 'object',
14+
properties: {
15+
error: { type: 'string' },
16+
status: { type: 'string', nullable: true },
17+
message: { type: 'string', nullable: true },
18+
success: { type: 'boolean', description: 'Indicates if the request was successful.' },
19+
},
20+
required: ['success', 'error'],
21+
});
22+
723
export const registerAppGeneralLogsHandler = ({ api, _orch }: AppsRestApi) =>
8-
void api.addRoute(
24+
void api.get(
925
'logs',
10-
{ authRequired: true, permissionsRequired: ['manage-apps'], validateParams: isAppLogsProps },
1126
{
12-
async get() {
13-
const { offset, count } = await getPaginationItems(this.queryParams);
14-
const { sort } = await this.parseJsonQuery();
27+
authRequired: true,
28+
permissionsRequired: ['manage-apps'],
29+
query: isAppLogsProps,
30+
response: {
31+
200: ajv.compile({
32+
type: 'object',
33+
properties: {
34+
offset: { type: 'number' },
35+
// TODO: reference a schema for the array items
36+
logs: { type: 'array' },
37+
count: { type: 'number' },
38+
total: { type: 'number' },
39+
success: { type: 'boolean' },
40+
},
41+
required: ['offset', 'logs', 'count', 'total', 'success'],
42+
additionalProperties: false,
43+
}),
44+
400: errorResponse,
45+
401: errorResponse,
46+
403: errorResponse,
47+
404: errorResponse,
48+
},
49+
},
50+
async function action() {
51+
const { offset, count } = await getPaginationItems(this.queryParams);
52+
const { sort } = await this.parseJsonQuery();
1553

16-
const options = {
17-
sort: sort || { _updatedAt: -1 },
18-
skip: offset,
19-
limit: count,
20-
};
54+
const options = {
55+
sort: sort || { _updatedAt: -1 },
56+
skip: offset,
57+
limit: count,
58+
};
2159

22-
let query: Record<string, any>;
60+
let query: Record<string, any>;
2361

24-
try {
25-
query = makeAppLogsQuery(this.queryParams);
26-
} catch (error) {
27-
return api.failure({ error: error instanceof Error ? error.message : 'Unknown error' });
28-
}
62+
try {
63+
query = makeAppLogsQuery(this.queryParams);
64+
} catch (error) {
65+
return api.failure({ error: error instanceof Error ? error.message : 'Unknown error' });
66+
}
2967

30-
const result = await _orch.getLogStorage().findPaginated(query, options);
68+
const result = await _orch.getLogStorage().findPaginated(query, options);
3169

32-
return api.success({ offset, logs: result.logs, count: result.logs.length, total: result.total });
33-
},
70+
return api.success({ offset, logs: result.logs, count: result.logs.length, total: result.total });
3471
},
3572
);
Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,80 @@
1-
import { isAppLogsProps } from '@rocket.chat/rest-typings';
1+
import { isAppLogsProps, ajv } from '@rocket.chat/rest-typings';
22

33
import { getPaginationItems } from '../../../../../app/api/server/helpers/getPaginationItems';
44
import type { AppsRestApi } from '../rest';
55
import { makeAppLogsQuery } from './lib/makeAppLogsQuery';
66

7+
const errorResponse = ajv.compile<{
8+
success: false;
9+
error: string;
10+
}>({
11+
additionalProperties: false,
12+
type: 'object',
13+
properties: {
14+
error: { type: 'string' },
15+
status: { type: 'string', nullable: true },
16+
message: { type: 'string', nullable: true },
17+
success: { type: 'boolean', description: 'Indicates if the request was successful.' },
18+
},
19+
required: ['success', 'error'],
20+
});
21+
722
export const registerAppLogsHandler = ({ api, _manager, _orch }: AppsRestApi) =>
8-
void api.addRoute(
23+
void api.get(
924
':id/logs',
10-
{ authRequired: true, permissionsRequired: ['manage-apps'], validateParams: isAppLogsProps },
1125
{
12-
async get() {
13-
const proxiedApp = _manager.getOneById(this.urlParams.id);
26+
authRequired: true,
27+
permissionsRequired: ['manage-apps'],
28+
query: isAppLogsProps,
29+
response: {
30+
200: ajv.compile({
31+
type: 'object',
32+
properties: {
33+
offset: { type: 'number' },
34+
logs: { type: 'array' },
35+
count: { type: 'number' },
36+
total: { type: 'number' },
37+
success: { type: 'boolean' },
38+
},
39+
required: ['offset', 'logs', 'count', 'total', 'success'],
40+
additionalProperties: false,
41+
}),
42+
400: errorResponse,
43+
401: errorResponse,
44+
403: errorResponse,
45+
404: errorResponse,
46+
},
47+
},
48+
async function action() {
49+
const proxiedApp = _manager.getOneById(this.urlParams.id);
1450

15-
if (!proxiedApp) {
16-
return api.notFound(`No App found by the id of: ${this.urlParams.id}`);
17-
}
51+
if (!proxiedApp) {
52+
return api.notFound(`No App found by the id of: ${this.urlParams.id}`);
53+
}
1854

19-
if (this.queryParams.appId && this.queryParams.appId !== this.urlParams.id) {
20-
return api.notFound(`Invalid query parameter "appId": ${this.queryParams.appId}`);
21-
}
55+
if (this.queryParams.appId && this.queryParams.appId !== this.urlParams.id) {
56+
return api.notFound(`Invalid query parameter "appId": ${this.queryParams.appId}`);
57+
}
2258

23-
const { offset, count } = await getPaginationItems(this.queryParams);
24-
const { sort } = await this.parseJsonQuery();
59+
const { offset, count } = await getPaginationItems(this.queryParams);
60+
const { sort } = await this.parseJsonQuery();
2561

26-
const options = {
27-
sort: sort || { _updatedAt: -1 },
28-
skip: offset,
29-
limit: count,
30-
};
62+
const options = {
63+
sort: sort || { _updatedAt: -1 },
64+
skip: offset,
65+
limit: count,
66+
};
3167

32-
let query: Record<string, any>;
68+
let query: Record<string, any>;
3369

34-
try {
35-
query = makeAppLogsQuery({ appId: this.urlParams.id, ...this.queryParams });
36-
} catch (error) {
37-
return api.failure({ error: error instanceof Error ? error.message : 'Unknown error' });
38-
}
70+
try {
71+
query = makeAppLogsQuery({ appId: this.urlParams.id, ...this.queryParams });
72+
} catch (error) {
73+
return api.failure({ error: error instanceof Error ? error.message : 'Unknown error' });
74+
}
3975

40-
const result = await _orch.getLogStorage().findPaginated(query, options);
76+
const result = await _orch.getLogStorage().findPaginated(query, options);
4177

42-
return api.success({ offset, logs: result.logs, count: result.logs.length, total: result.total });
43-
},
78+
return api.success({ offset, logs: result.logs, count: result.logs.length, total: result.total });
4479
},
4580
);

0 commit comments

Comments
 (0)