mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-04 01:18:20 +02:00
## About the changes - `getActiveUsers` is using multiple stores, so it is refactored into read-model - Refactored Instance stats service into `features` to co-locate related code Closes https://linear.app/unleash/issue/UNL-230/active-users-prometheus ### Important files `src/lib/features/instance-stats/getActiveUsers.ts` ## Discussion points `getActiveUsers` is coded less _class-based_ then previous similar read-models. In one file instead of 3 (read-model interface, fake read model, sql read model). I find types and functions way more readable, but I'm ready to refactor it to interfaces and classes if consistency is more important.
57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
import { type Db } from 'lib/server-impl';
|
|
|
|
export type GetActiveUsers = () => Promise<{
|
|
last7: number;
|
|
last30: number;
|
|
last60: number;
|
|
last90: number;
|
|
}>;
|
|
|
|
export const createGetActiveUsers =
|
|
(db: Db): GetActiveUsers =>
|
|
async () => {
|
|
const combinedQuery = db
|
|
.select('id as user_id', 'seen_at')
|
|
.from('users')
|
|
.unionAll(
|
|
db.select('user_id', 'seen_at').from('personal_access_tokens'),
|
|
);
|
|
|
|
const result = await db
|
|
.with('Combined', combinedQuery)
|
|
.select({
|
|
last_week: db.raw(
|
|
"COUNT(DISTINCT CASE WHEN seen_at > NOW() - INTERVAL '1 week' THEN user_id END)",
|
|
),
|
|
last_month: db.raw(
|
|
"COUNT(DISTINCT CASE WHEN seen_at > NOW() - INTERVAL '1 month' THEN user_id END)",
|
|
),
|
|
last_two_months: db.raw(
|
|
"COUNT(DISTINCT CASE WHEN seen_at > NOW() - INTERVAL '2 months' THEN user_id END)",
|
|
),
|
|
last_quarter: db.raw(
|
|
"COUNT(DISTINCT CASE WHEN seen_at > NOW() - INTERVAL '3 months' THEN user_id END)",
|
|
),
|
|
})
|
|
.from('Combined');
|
|
|
|
return {
|
|
last7: parseInt(result?.[0]?.last_week || '0', 10),
|
|
last30: parseInt(result?.[0]?.last_month || '0', 10),
|
|
last60: parseInt(result?.[0]?.last_two_months || '0', 10),
|
|
last90: parseInt(result?.[0]?.last_quarter || '0', 10),
|
|
};
|
|
};
|
|
|
|
export const createFakeGetActiveUsers =
|
|
(
|
|
activeUsers: Awaited<ReturnType<GetActiveUsers>> = {
|
|
last7: 0,
|
|
last30: 0,
|
|
last60: 0,
|
|
last90: 0,
|
|
},
|
|
): GetActiveUsers =>
|
|
() =>
|
|
Promise.resolve(activeUsers);
|