Skip to content

Commit bb2c550

Browse files
committed
refactor: migrate statistics endpoints to new chained API pattern
Migrates statistics (GET), statistics.list (GET), and statistics.telemetry (POST) from the legacy addRoute() pattern to the new chained .get()/.post() API pattern with typed AJV response schemas and query parameter validation using existing isStatisticsProps and isStatisticsListProps validators. Part of #38876
1 parent 3145c41 commit bb2c550

File tree

2 files changed

+101
-38
lines changed

2 files changed

+101
-38
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@rocket.chat/meteor': patch
3+
---
4+
5+
Migrated `statistics`, `statistics.list`, and `statistics.telemetry` REST API endpoints from legacy `addRoute` pattern to the new chained `.get()`/`.post()` API pattern with typed response schemas and AJV query parameter validation.
Lines changed: 96 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,120 @@
1+
import {
2+
ajv,
3+
isStatisticsProps,
4+
isStatisticsListProps,
5+
validateUnauthorizedErrorResponse,
6+
} from '@rocket.chat/rest-typings';
7+
18
import { getStatistics, getLastStatistics } from '../../../statistics/server';
29
import telemetryEvent from '../../../statistics/server/lib/telemetryEvents';
310
import { API } from '../api';
411
import { getPaginationItems } from '../helpers/getPaginationItems';
512

6-
API.v1.addRoute(
13+
API.v1.get(
714
'statistics',
8-
{ authRequired: true },
915
{
10-
async get() {
11-
const { refresh = 'false' } = this.queryParams;
12-
13-
return API.v1.success(
14-
await getLastStatistics({
15-
userId: this.userId,
16-
refresh: refresh === 'true',
17-
}),
18-
);
16+
authRequired: true,
17+
validateParams: isStatisticsProps,
18+
response: {
19+
200: ajv.compile<Record<string, unknown>>({
20+
type: 'object',
21+
properties: {
22+
success: {
23+
type: 'boolean',
24+
enum: [true],
25+
},
26+
},
27+
required: ['success'],
28+
}),
29+
401: validateUnauthorizedErrorResponse,
1930
},
2031
},
32+
async function action() {
33+
const { refresh = 'false' } = this.queryParams;
34+
35+
return API.v1.success(
36+
await getLastStatistics({
37+
userId: this.userId,
38+
refresh: refresh === 'true',
39+
}),
40+
);
41+
},
2142
);
2243

23-
API.v1.addRoute(
44+
API.v1.get(
2445
'statistics.list',
25-
{ authRequired: true },
2646
{
27-
async get() {
28-
const { offset, count } = await getPaginationItems(this.queryParams);
29-
const { sort, fields, query } = await this.parseJsonQuery();
30-
31-
return API.v1.success(
32-
await getStatistics({
33-
userId: this.userId,
34-
query,
35-
pagination: {
36-
offset,
37-
count,
38-
sort,
39-
fields,
47+
authRequired: true,
48+
validateParams: isStatisticsListProps,
49+
response: {
50+
200: ajv.compile<{
51+
statistics: unknown[];
52+
count: number;
53+
offset: number;
54+
total: number;
55+
}>({
56+
type: 'object',
57+
properties: {
58+
statistics: { type: 'array' },
59+
count: { type: 'number' },
60+
offset: { type: 'number' },
61+
total: { type: 'number' },
62+
success: {
63+
type: 'boolean',
64+
enum: [true],
4065
},
41-
}),
42-
);
66+
},
67+
required: ['statistics', 'count', 'offset', 'total', 'success'],
68+
}),
69+
401: validateUnauthorizedErrorResponse,
4370
},
4471
},
72+
async function action() {
73+
const { offset, count } = await getPaginationItems(this.queryParams);
74+
const { sort, fields, query } = await this.parseJsonQuery();
75+
76+
return API.v1.success(
77+
await getStatistics({
78+
userId: this.userId,
79+
query,
80+
pagination: {
81+
offset,
82+
count,
83+
sort,
84+
fields,
85+
},
86+
}),
87+
);
88+
},
4589
);
4690

47-
API.v1.addRoute(
91+
API.v1.post(
4892
'statistics.telemetry',
49-
{ authRequired: true },
5093
{
51-
post() {
52-
const events = this.bodyParams;
94+
authRequired: true,
95+
response: {
96+
200: ajv.compile<void>({
97+
type: 'object',
98+
properties: {
99+
success: {
100+
type: 'boolean',
101+
enum: [true],
102+
},
103+
},
104+
required: ['success'],
105+
additionalProperties: false,
106+
}),
107+
401: validateUnauthorizedErrorResponse,
108+
},
109+
},
110+
function action() {
111+
const events = this.bodyParams;
53112

54-
events?.params?.forEach((event) => {
55-
const { eventName, ...params } = event;
56-
void telemetryEvent.call(eventName, params);
57-
});
113+
events?.params?.forEach((event: { eventName: string; [key: string]: unknown }) => {
114+
const { eventName, ...params } = event;
115+
void telemetryEvent.call(eventName, params);
116+
});
58117

59-
return API.v1.success();
60-
},
118+
return API.v1.success();
61119
},
62120
);

0 commit comments

Comments
 (0)