diff --git a/package-lock.json b/package-lock.json index 03988dc46..e29944e5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35722,6 +35722,21 @@ "engines": { "node": ">=6" } + }, + "packages/trpc/node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.6.tgz", + "integrity": "sha512-hNukAxq7hu4o5/UjPp5jqoBEtrpCbOmnUqZSKNJG8GrUVzfq0ucdhQFVrHcLRMvQcwqqDh1a5AJN9ORnNDpgBQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/packages/lib/server-only/admin/get-users-stats.ts b/packages/lib/server-only/admin/get-users-stats.ts index 1cf18e23f..f80997107 100644 --- a/packages/lib/server-only/admin/get-users-stats.ts +++ b/packages/lib/server-only/admin/get-users-stats.ts @@ -1,7 +1,11 @@ import { DateTime } from 'luxon'; -import { prisma } from '@documenso/prisma'; -import { DocumentStatus, SubscriptionStatus } from '@documenso/prisma/client'; +import { kyselyPrisma, prisma, sql } from '@documenso/prisma'; +import { + DocumentStatus, + SubscriptionStatus, + UserSecurityAuditLogType, +} from '@documenso/prisma/client'; export const getUsersCount = async () => { return await prisma.user.count(); @@ -94,17 +98,26 @@ type GetMonthlyActiveUsersQueryResult = Array<{ }>; export const getMonthlyActiveUsers = async () => { - const result = await prisma.$queryRaw` - SELECT - DATE_TRUNC('month', "lastSignedIn") AS "month", - COUNT(DISTINCT "id") as "count", - SUM(COUNT(DISTINCT "id")) OVER (ORDER BY DATE_TRUNC('month', "lastSignedIn")) as "cume_count" - FROM "User" - WHERE "lastSignedIn" >= NOW() - INTERVAL '1 year' AND "disabled" = false - GROUP BY DATE_TRUNC('month', "lastSignedIn") - ORDER BY "month" DESC - LIMIT 12 - `; + const qb = kyselyPrisma.$kysely + .selectFrom('UserSecurityAuditLog') + .select(({ fn }) => [ + fn('DATE_TRUNC', [sql.lit('MONTH'), 'UserSecurityAuditLog.createdAt']).as('month'), + fn.count('userId').distinct().as('count'), + fn + .sum(fn.count('userId').distinct()) + .over((ob) => + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ob.orderBy(fn('DATE_TRUNC', [sql.lit('MONTH'), 'UserSecurityAuditLog.createdAt']) as any), + ) + .as('cume_count'), + ]) + // @ts-expect-error - Raw SQL enum casting not properly typed by Kysely + .where(sql`type = ${UserSecurityAuditLogType.SIGN_IN}::"UserSecurityAuditLogType"`) + .groupBy(({ fn }) => fn('DATE_TRUNC', [sql.lit('MONTH'), 'UserSecurityAuditLog.createdAt'])) + .orderBy('month', 'desc') + .limit(12); + + const result = await qb.execute(); return result.map((row) => ({ month: DateTime.fromJSDate(row.month).toFormat('yyyy-MM'), diff --git a/packages/ui/primitives/document-flow/add-settings.tsx b/packages/ui/primitives/document-flow/add-settings.tsx index 0cc37d5a5..5eddcfd25 100644 --- a/packages/ui/primitives/document-flow/add-settings.tsx +++ b/packages/ui/primitives/document-flow/add-settings.tsx @@ -13,8 +13,14 @@ import { SUPPORTED_LANGUAGES } from '@documenso/lib/constants/i18n'; import { DEFAULT_DOCUMENT_TIME_ZONE, TIME_ZONES } from '@documenso/lib/constants/time-zones'; import type { TDocument } from '@documenso/lib/types/document'; import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth'; -import { DocumentVisibility, TeamMemberRole } from '@documenso/prisma/client'; -import { DocumentStatus, type Field, type Recipient, SendStatus } from '@documenso/prisma/client'; +import { + DocumentStatus, + DocumentVisibility, + type Field, + type Recipient, + SendStatus, + TeamMemberRole, +} from '@documenso/prisma/client'; import { DocumentGlobalAuthAccessSelect, DocumentGlobalAuthAccessTooltip,