From de1d611e4b0d46b8a872a3b42bc41301cec3346e Mon Sep 17 00:00:00 2001 From: Yuta Hiroto Date: Wed, 17 Sep 2025 14:34:53 +0900 Subject: [PATCH] refactor: clean up --- .env.sample | 5 + .internal/setup/db.mjs | 2 +- .internal/setup/questions/otel.mjs | 5 +- .internal/tests/common.test.mjs.snapshot | 72 +- .internal/tests/no-docker.test.mjs.snapshot | 1 - .internal/tests/no-e2e.test.mjs.snapshot | 3 +- .internal/tests/no-otel.test.mjs.snapshot | 34 +- .../tests/no-sample-code.test.mjs.snapshot | 30 +- .internal/tests/no-stripe.test.mjs.snapshot | 20 +- compose.yml | 26 - env.ts | 5 + next.config.ts | 24 +- otel-collector-config.yml | 30 - package.json | 2 + pnpm-lock.yaml | 1814 ++++++++++++++++- pnpm-workspace.yaml | 2 + .../(private)/me/_components/UpdateMyInfo.tsx | 6 +- src/app/_actions/users.ts | 72 +- src/app/_clients/sentry.ts | 22 + src/app/_providers/Sentry.tsx | 20 + src/app/_utils/auth.ts | 3 + src/app/_utils/sentry.ts | 10 + src/app/global-error.tsx | 8 +- src/app/layout.tsx | 9 +- src/instrumentation-client.ts | 21 + src/instrumentation.ts | 10 +- src/otel/instrumentations.ts | 7 + src/otel/node.ts | 8 +- src/sentry.edge.config.ts | 6 + src/sentry.server.config.ts | 13 + 30 files changed, 2121 insertions(+), 169 deletions(-) delete mode 100644 otel-collector-config.yml create mode 100644 src/app/_clients/sentry.ts create mode 100644 src/app/_providers/Sentry.tsx create mode 100644 src/app/_utils/sentry.ts create mode 100644 src/instrumentation-client.ts create mode 100644 src/otel/instrumentations.ts create mode 100644 src/sentry.edge.config.ts create mode 100644 src/sentry.server.config.ts diff --git a/.env.sample b/.env.sample index 25113b4d..d4a3bb88 100644 --- a/.env.sample +++ b/.env.sample @@ -38,3 +38,8 @@ STRIPE_SECRET_KEY=xxxx STRIPE_WEBHOOK_SECRET=xxxx STRIPE_PRICE_ID=xxxx # end: stripe # + +SENTRY_ORG= +SENTRY_PROJECT= +SENTRY_AUTH_TOKEN= +NEXT_PUBLIC_SENTRY_DSN= diff --git a/.internal/setup/db.mjs b/.internal/setup/db.mjs index ceb22ec5..02173946 100644 --- a/.internal/setup/db.mjs +++ b/.internal/setup/db.mjs @@ -3,7 +3,7 @@ import { spawn } from "node:child_process"; export async function generateMigrationFiles() { const commands = [ "pnpm db:up", - "pnpm db:migrate --name initial-migration", + "pnpm db:migrate --name initial", "pnpm generate:client", "docker compose down", ]; diff --git a/.internal/setup/questions/otel.mjs b/.internal/setup/questions/otel.mjs index 7d4cdd89..0834d079 100644 --- a/.internal/setup/questions/otel.mjs +++ b/.internal/setup/questions/otel.mjs @@ -7,10 +7,7 @@ import { removeWords, } from "../utils.mjs"; -export const removedFiles = /** @type {const} */ ([ - "otel-collector-config.yml", - "./src/instrumentation.ts", -]); +export const removedFiles = /** @type {const} */ (["./src/instrumentation.ts"]); export const removedDirs = /** @type {const} */ (["./src/otel"]); diff --git a/.internal/tests/common.test.mjs.snapshot b/.internal/tests/common.test.mjs.snapshot index 30a8f231..8792ba9d 100644 --- a/.internal/tests/common.test.mjs.snapshot +++ b/.internal/tests/common.test.mjs.snapshot @@ -22,7 +22,6 @@ exports[`common > should put files 1`] = ` "internal-tests-output-common/knip.config.ts", "internal-tests-output-common/lefthook.yml", "internal-tests-output-common/next.config.ts", - "internal-tests-output-common/otel-collector-config.yml", "internal-tests-output-common/package.json", "internal-tests-output-common/playwright.config.ts", "internal-tests-output-common/pnpm-lock.yaml", @@ -82,6 +81,11 @@ exports[`common > should update .env.sample 1`] = ` "STRIPE_SECRET_KEY=xxxx", "STRIPE_WEBHOOK_SECRET=xxxx", "STRIPE_PRICE_ID=xxxx", + "", + "SENTRY_ORG=", + "SENTRY_PROJECT=", + "SENTRY_AUTH_TOKEN=", + "NEXT_PUBLIC_SENTRY_DSN=", "" ] `; @@ -429,30 +433,6 @@ exports[`common > should update compose.yml 1`] = ` " interval: 1s", " timeout: 5s", " retries: 10", - " jaeger:", - " image: jaegertracing/all-in-one", - " ports:", - " # https://www.jaegertracing.io/docs/1.6/getting-started/#all-in-one-docker-image", - " # frontend", - " - 16686:16686", - " - 14268", - " - 14250", - " environment:", - " - METRICS_STORAGE_TYPE=prometheus", - " - PROMETHEUS_QUERY_SUPPORT_SPANMETRICS_CONNECTOR=true", - " - COLLECTOR_OTLP_ENABLED=true", - " # don't use contrib on prod", - " # https://opentelemetry.io/blog/2024/otel-collector-anti-patterns/#3--not-using-the-right-collector-distribution-or-not-building-your-own-distribution", - " otel-collector:", - " image: otel/opentelemetry-collector-contrib", - " command: [\\"--config=/conf/otel-collector-config.yml\\"]", - " volumes:", - " - ./otel-collector-config.yml:/conf/otel-collector-config.yml", - " ports:", - " - 13133:13133 # health_check extension", - " - 4317:4317 # OTLP gRPC receiver", - " depends_on:", - " - jaeger", "" ] `; @@ -473,6 +453,8 @@ exports[`common > should update dependencies 1`] = ` "@opentelemetry/semantic-conventions", "@prisma/client", "@prisma/instrumentation", + "@sentry/nextjs", + "@sentry/profiling-node", "clsx", "next", "next-auth", @@ -798,6 +780,11 @@ exports[`common > should update env.ts 1`] = ` " STRIPE_PRICE_ID: z.string().min(1),", " STRIPE_SECRET_KEY: z.string().min(1),", " STRIPE_WEBHOOK_SECRET: z.string().min(1),", + "", + " SENTRY_ORG: z.string().min(1).optional().or(z.literal(\\"\\")),", + " SENTRY_PROJECT: z.string().min(1).optional().or(z.literal(\\"\\")),", + " SENTRY_AUTH_TOKEN: z.string().min(1).optional().or(z.literal(\\"\\")),", + " NEXT_PUBLIC_SENTRY_DSN: z.string().min(1).optional().or(z.literal(\\"\\")),", "});", "", "const runtimeEnv = z.object({});", @@ -847,6 +834,7 @@ exports[`common > should update knip.config.ts 1`] = ` exports[`common > should update next.config.ts 1`] = ` [ + "import { withSentryConfig } from \\"@sentry/nextjs\\";", "import type { NextConfig } from \\"next\\";", "import { config } from \\"./env\\";", "", @@ -880,6 +868,15 @@ exports[`common > should update next.config.ts 1`] = ` " },", " ],", " },", + " {", + " source: \\"/:path*\\",", + " headers: [", + " {", + " key: \\"Document-Policy\\",", + " value: \\"js-profiling\\",", + " },", + " ],", + " },", " ];", " },", " images: {", @@ -910,7 +907,17 @@ exports[`common > should update next.config.ts 1`] = ` " ],", "};", "", - "export default nextConfig;", + "export default withSentryConfig(nextConfig, {", + " org: process.env.SENTRY_ORG,", + " project: process.env.SENTRY_PROJECT,", + " silent: !process.env.CI,", + " widenClientFileUpload: true,", + " authToken: process.env.SENTRY_AUTH_TOKEN,", + " disableLogger: true,", + " reactComponentAnnotation: {", + " enabled: true,", + " },", + "});", "" ] `; @@ -1068,6 +1075,7 @@ exports[`common > should update src/app/layout.tsx 1`] = ` "import { Inter } from \\"next/font/google\\";", "import { Footer } from \\"./_components/Footer\\";", "import { Header } from \\"./_components/Header\\";", + "import { SentryProvider } from \\"./_providers/Sentry\\";", "import \\"./globals.css\\";", "", "const inter = Inter({", @@ -1090,16 +1098,20 @@ exports[`common > should update src/app/layout.tsx 1`] = ` "", "export default function Layout({ children }: LayoutProps<\\"/\\">) {", " return (", - " ", + " ", " attributes before hydration.", + " suppressHydrationWarning", " className={clsx(", " inter.className,", " \\"bg-gray-700 text-gray-200 min-h-screen flex flex-col\\",", " )}", " >", - "
", - "
{children}
", - "