diff --git a/apps/web/src/app/(dashboard)/admin/site-settings/page.tsx b/apps/web/src/app/(dashboard)/admin/site-settings/page.tsx
index bffb72ff0..52ab1431a 100644
--- a/apps/web/src/app/(dashboard)/admin/site-settings/page.tsx
+++ b/apps/web/src/app/(dashboard)/admin/site-settings/page.tsx
@@ -1,12 +1,13 @@
import { getSiteSettings } from '@documenso/lib/server-only/site-settings/get-site-settings';
-import { SITE_SETTINGS_BANNER_ID } from '@documenso/lib/server-only/site-settings/schemas/banner';
+import {
+ SITE_SETTINGS_BANNER_ID,
+ ZSiteSettingsBannerSchema,
+} from '@documenso/lib/server-only/site-settings/schemas/banner';
import { SettingsHeader } from '~/components/(dashboard)/settings/layout/header';
import { BannerForm } from './banner-form';
-// import { BannerForm } from './banner-form';
-
export default async function AdminBannerPage() {
const banner = await getSiteSettings().then((settings) =>
settings.find((setting) => setting.id === SITE_SETTINGS_BANNER_ID),
@@ -17,7 +18,7 @@ export default async function AdminBannerPage() {
-
+
);
diff --git a/apps/web/src/components/(dashboard)/settings/webhooks/trigger-multiselect-combobox.tsx b/apps/web/src/components/(dashboard)/settings/webhooks/trigger-multiselect-combobox.tsx
index 5636f1931..badbdc3bf 100644
--- a/apps/web/src/components/(dashboard)/settings/webhooks/trigger-multiselect-combobox.tsx
+++ b/apps/web/src/components/(dashboard)/settings/webhooks/trigger-multiselect-combobox.tsx
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
-import { WebhookTriggerEvents } from '@prisma/client/';
+import { WebhookTriggerEvents } from '@prisma/client';
import { Check, ChevronsUpDown } from 'lucide-react';
import { toFriendlyWebhookEventName } from '@documenso/lib/universal/webhook/to-friendly-webhook-event-name';
diff --git a/apps/web/src/instrumentation.ts b/apps/web/src/instrumentation.ts
index c52d2da15..f4ad8bbe2 100644
--- a/apps/web/src/instrumentation.ts
+++ b/apps/web/src/instrumentation.ts
@@ -1,9 +1,7 @@
-import { sendInstanceInfo } from '@documenso/lib/server-only/telemetry/send-instance-info';
+import { registerInstance } from '@documenso/lib/server-only/telemetry/register-instance';
-export async function register() {
- await sendInstanceInfo({
- uniqueId: '1',
- timestamp: new Date(),
- version: '1.2.3',
- });
-}
+export const register = async () => {
+ if (process.env.NEXT_RUNTIME === 'nodejs') {
+ await registerInstance();
+ }
+};
diff --git a/packages/lib/server-only/site-settings/schema.ts b/packages/lib/server-only/site-settings/schema.ts
index ff6194219..1a4f78f3b 100644
--- a/packages/lib/server-only/site-settings/schema.ts
+++ b/packages/lib/server-only/site-settings/schema.ts
@@ -1,9 +1,12 @@
import { z } from 'zod';
import { ZSiteSettingsBannerSchema } from './schemas/banner';
+import { ZSiteSettingsTelemetrySchema } from './schemas/telemetry';
-// TODO: Use `z.union([...])` once we have more than one setting
-export const ZSiteSettingSchema = ZSiteSettingsBannerSchema;
+export const ZSiteSettingSchema = z.union([
+ ZSiteSettingsBannerSchema,
+ ZSiteSettingsTelemetrySchema,
+]);
export type TSiteSettingSchema = z.infer;
diff --git a/packages/lib/server-only/site-settings/schemas/telemetry.ts b/packages/lib/server-only/site-settings/schemas/telemetry.ts
new file mode 100644
index 000000000..2c783c243
--- /dev/null
+++ b/packages/lib/server-only/site-settings/schemas/telemetry.ts
@@ -0,0 +1,20 @@
+import { nanoid } from 'nanoid';
+import { z } from 'zod';
+
+import { ZSiteSettingsBaseSchema } from './_base';
+
+export const SITE_SETTINGS_TELEMETRY_ID = 'site.instance-id';
+
+export const ZSiteSettingsTelemetrySchema = ZSiteSettingsBaseSchema.extend({
+ id: z.literal(SITE_SETTINGS_TELEMETRY_ID),
+ data: z
+ .object({
+ instanceId: z.string(),
+ })
+ .optional()
+ .default({
+ instanceId: nanoid(),
+ }),
+});
+
+export type TSiteSettingsTelemetrySchema = z.infer;
diff --git a/packages/lib/server-only/site-settings/upsert-site-setting.ts b/packages/lib/server-only/site-settings/upsert-site-setting.ts
index 6fc59b1d1..52c77b390 100644
--- a/packages/lib/server-only/site-settings/upsert-site-setting.ts
+++ b/packages/lib/server-only/site-settings/upsert-site-setting.ts
@@ -3,7 +3,7 @@ import { prisma } from '@documenso/prisma';
import type { TSiteSettingSchema } from './schema';
export type UpsertSiteSettingOptions = TSiteSettingSchema & {
- userId: number;
+ userId: number | null;
};
export const upsertSiteSetting = async ({
diff --git a/packages/lib/server-only/telemetry/register-instance.ts b/packages/lib/server-only/telemetry/register-instance.ts
new file mode 100644
index 000000000..ffb082058
--- /dev/null
+++ b/packages/lib/server-only/telemetry/register-instance.ts
@@ -0,0 +1,42 @@
+import { nanoid } from 'nanoid';
+
+import { getSiteSettings } from '../site-settings/get-site-settings';
+import {
+ SITE_SETTINGS_TELEMETRY_ID,
+ ZSiteSettingsTelemetrySchema,
+} from '../site-settings/schemas/telemetry';
+import { upsertSiteSetting } from '../site-settings/upsert-site-setting';
+import { sendInstance } from './send-instance';
+
+export const registerInstance = async () => {
+ const instanceResponse = await getSiteSettings().then((settings) =>
+ settings.find((setting) => setting.id === SITE_SETTINGS_TELEMETRY_ID),
+ );
+
+ const instance = ZSiteSettingsTelemetrySchema.parse(instanceResponse);
+
+ if (!instance) {
+ const upsert = await upsertSiteSetting({
+ data: {
+ instanceId: nanoid(),
+ },
+ enabled: true,
+ id: SITE_SETTINGS_TELEMETRY_ID,
+ userId: null,
+ });
+
+ const instance = ZSiteSettingsTelemetrySchema.parse(upsert);
+
+ return await sendInstance({
+ uniqueId: instance.data?.instanceId,
+ timestamp: new Date(),
+ version: '1.2.3',
+ });
+ }
+
+ return await sendInstance({
+ uniqueId: instance.data.instanceId,
+ timestamp: new Date(),
+ version: '1.2.3',
+ });
+};
diff --git a/packages/lib/server-only/telemetry/send-instance-info.ts b/packages/lib/server-only/telemetry/send-instance.ts
similarity index 86%
rename from packages/lib/server-only/telemetry/send-instance-info.ts
rename to packages/lib/server-only/telemetry/send-instance.ts
index f9934bbcd..bc4fd9766 100644
--- a/packages/lib/server-only/telemetry/send-instance-info.ts
+++ b/packages/lib/server-only/telemetry/send-instance.ts
@@ -1,10 +1,10 @@
-export type SendInstanceInfo = {
+export type SendInstance = {
uniqueId: string;
timestamp: Date;
version: string;
};
-export const sendInstanceInfo = async ({ uniqueId, timestamp, version }: SendInstanceInfo) => {
+export const sendInstance = async ({ uniqueId, timestamp, version }: SendInstance) => {
const isProduction = process.env.NODE_ENV === 'production';
const isTelemetryDisabled = process.env.DISABLE_TELEMETRY === 'true';
diff --git a/packages/trpc/server/admin-router/schema.ts b/packages/trpc/server/admin-router/schema.ts
index 6bb567dbd..cf3c36060 100644
--- a/packages/trpc/server/admin-router/schema.ts
+++ b/packages/trpc/server/admin-router/schema.ts
@@ -1,7 +1,7 @@
import { Role } from '@prisma/client';
import z from 'zod';
-import { ZSiteSettingSchema } from '@documenso/lib/server-only/site-settings/schema';
+import { ZSiteSettingsBannerSchema } from '@documenso/lib/server-only/site-settings/schemas/banner';
export const ZAdminFindDocumentsQuerySchema = z.object({
term: z.string().optional(),
@@ -30,7 +30,7 @@ export type TAdminUpdateRecipientMutationSchema = z.infer<
typeof ZAdminUpdateRecipientMutationSchema
>;
-export const ZAdminUpdateSiteSettingMutationSchema = ZSiteSettingSchema;
+export const ZAdminUpdateSiteSettingMutationSchema = ZSiteSettingsBannerSchema;
export type TAdminUpdateSiteSettingMutationSchema = z.infer<
typeof ZAdminUpdateSiteSettingMutationSchema
diff --git a/packages/tsconfig/process-env.d.ts b/packages/tsconfig/process-env.d.ts
index 80498f415..6c0761c72 100644
--- a/packages/tsconfig/process-env.d.ts
+++ b/packages/tsconfig/process-env.d.ts
@@ -70,6 +70,7 @@ declare namespace NodeJS {
VERCEL?: string;
VERCEL_ENV?: 'production' | 'development' | 'preview';
VERCEL_URL?: string;
+ NEXT_RUNTIME?: 'nodejs' | 'edge';
DEPLOYMENT_TARGET?: 'webapp' | 'marketing';
FONT_CAVEAT_URI: string;
diff --git a/turbo.json b/turbo.json
index 783e3ece9..ce5a3d525 100644
--- a/turbo.json
+++ b/turbo.json
@@ -111,6 +111,7 @@
"E2E_TEST_AUTHENTICATE_USERNAME",
"E2E_TEST_AUTHENTICATE_USER_EMAIL",
"E2E_TEST_AUTHENTICATE_USER_PASSWORD",
- "DISABLE_TELEMETRY"
+ "DISABLE_TELEMETRY",
+ "NEXT_RUNTIME"
]
}