Skip to content

Commit 13b5fb5

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 13b5fb5

File tree

2 files changed

+94
-38
lines changed

2 files changed

+94
-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: 89 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,113 @@
1+
import { ajv, validateUnauthorizedErrorResponse } from '@rocket.chat/rest-typings';
2+
13
import { getStatistics, getLastStatistics } from '../../../statistics/server';
24
import telemetryEvent from '../../../statistics/server/lib/telemetryEvents';
35
import { API } from '../api';
46
import { getPaginationItems } from '../helpers/getPaginationItems';
57

6-
API.v1.addRoute(
8+
API.v1.get(
79
'statistics',
8-
{ authRequired: true },
910
{
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-
);
11+
authRequired: true,
12+
response: {
13+
200: ajv.compile<Record<string, unknown>>({
14+
type: 'object',
15+
properties: {
16+
success: {
17+
type: 'boolean',
18+
enum: [true],
19+
},
20+
},
21+
required: ['success'],
22+
}),
23+
401: validateUnauthorizedErrorResponse,
1924
},
2025
},
26+
async function action() {
27+
const { refresh = 'false' } = this.queryParams;
28+
29+
return API.v1.success(
30+
await getLastStatistics({
31+
userId: this.userId,
32+
refresh: refresh === 'true',
33+
}),
34+
);
35+
},
2136
);
2237

23-
API.v1.addRoute(
38+
API.v1.get(
2439
'statistics.list',
25-
{ authRequired: true },
2640
{
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,
41+
authRequired: true,
42+
response: {
43+
200: ajv.compile<{
44+
statistics: unknown[];
45+
count: number;
46+
offset: number;
47+
total: number;
48+
}>({
49+
type: 'object',
50+
properties: {
51+
statistics: { type: 'array' },
52+
count: { type: 'number' },
53+
offset: { type: 'number' },
54+
total: { type: 'number' },
55+
success: {
56+
type: 'boolean',
57+
enum: [true],
4058
},
41-
}),
42-
);
59+
},
60+
required: ['statistics', 'count', 'offset', 'total', 'success'],
61+
}),
62+
401: validateUnauthorizedErrorResponse,
4363
},
4464
},
65+
async function action() {
66+
const { offset, count } = await getPaginationItems(this.queryParams);
67+
const { sort, fields, query } = await this.parseJsonQuery();
68+
69+
return API.v1.success(
70+
await getStatistics({
71+
userId: this.userId,
72+
query,
73+
pagination: {
74+
offset,
75+
count,
76+
sort,
77+
fields,
78+
},
79+
}),
80+
);
81+
},
4582
);
4683

47-
API.v1.addRoute(
84+
API.v1.post(
4885
'statistics.telemetry',
49-
{ authRequired: true },
5086
{
51-
post() {
52-
const events = this.bodyParams;
87+
authRequired: true,
88+
response: {
89+
200: ajv.compile<void>({
90+
type: 'object',
91+
properties: {
92+
success: {
93+
type: 'boolean',
94+
enum: [true],
95+
},
96+
},
97+
required: ['success'],
98+
additionalProperties: false,
99+
}),
100+
401: validateUnauthorizedErrorResponse,
101+
},
102+
},
103+
function action() {
104+
const events = this.bodyParams;
53105

54-
events?.params?.forEach((event) => {
55-
const { eventName, ...params } = event;
56-
void telemetryEvent.call(eventName, params);
57-
});
106+
events?.params?.forEach((event: { eventName: string; [key: string]: unknown }) => {
107+
const { eventName, ...params } = event;
108+
void telemetryEvent.call(eventName, params);
109+
});
58110

59-
return API.v1.success();
60-
},
111+
return API.v1.success();
61112
},
62113
);

0 commit comments

Comments
 (0)