Skip to content

Commit

Permalink
Feature/add posthog envvars to buildtime variables (#232)
Browse files Browse the repository at this point in the history
* Revert "Revert: Removed posthog"

This reverts commit ee8da35.

* add posthog env vars to build time environment

* added client env vars to health check so that we fail before deploying if client env vars are missing
  • Loading branch information
geclos authored Sep 19, 2024
1 parent ee8da35 commit 2766b01
Show file tree
Hide file tree
Showing 16 changed files with 195 additions and 65 deletions.
2 changes: 2 additions & 0 deletions apps/infra/Pulumi.core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ config:
secure: v1:/+DMPM/zWsNsNHDg:JIlxC1v0ocfdfX1TsDXXTZClL8Uza74CMq5YSst7Ymu+CPulRNgUejrSQEFVW3F6BkXMA1QU3s4=
infra:MAILER_API_KEY:
secure: v1:Br02wGwX0UOAZiNp:wIzQFfWCzWygBRCVJNDs/ZP65EXEAIFhduPOOniN6EOeXPyJ4UHjOefPyO2bhOBkR5E3CWLmQBsVjIGrGwAHZYZCQg==
infra:NEXT_PUBLIC_POSTHOG_KEY:
secure: v1:cI6gi7pKYG9cQJDk:FYV6+v87vWFw+ikVdYQNqr3vY4vWpsB4D1YG5u1GowcTW7yrxOSa12HXPsWRkw8IIFEhqpXiaG00AF/G2pYm
infra:SENTRY_DSN:
secure: v1:TFAocHKQe31DxpAX:8+iplSLckN3i91KshS+8mab3s158nFkNyWD8JBZM8Ojtu2zstpna5N50ugkXuH9hdcuUv4db088pI9Dkvuc/84OJDEm47z/0bJgD803f4ZWqVtA7Yt8Z2pyTSGqGzsj9RErstG0N
infra:SENTRY_ORG:
Expand Down
5 changes: 5 additions & 0 deletions apps/infra/src/core/secrets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ const defaultProviderApiKey = createSecretWithVersion(
'DEFAULT_PROVIDER_API_KEY',
'Default provider API key',
)
const postHogApiKey = createSecretWithVersion(
'NEXT_PUBLIC_POSTHOG_KEY',
'Posthog API Key for product analytics',
)

export const mailerApiKeyArn = mailerApiKey.arn
export const sentryDsnArn = sentryDsn.arn
Expand All @@ -78,3 +82,4 @@ export const websocketsSecretRefreshTokenArn = websocketsSecretRefreshToken.arn
export const workersWebsocketsSecretTokenArn = workersWebsocketsSecretToken.arn
export const defaultProjectIdArn = defaultProjectId.arn
export const defaultProviderApiKeyArn = defaultProviderApiKey.arn
export const postHogApiKeyArn = postHogApiKey.arn
5 changes: 5 additions & 0 deletions apps/infra/src/deployments/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const defaultProjectIdArn = coreStack.requireOutput('defaultProjectIdArn')
const defaultProviderApiKeyArn = coreStack.requireOutput(
'defaultProviderApiKeyArn',
)
const postHogApiKeyArn = coreStack.requireOutput('postHogApiKeyArn')

const getSecretString = (arn: pulumi.Output<any>) => {
return arn.apply((secretId) =>
Expand Down Expand Up @@ -57,6 +58,7 @@ export const sentryDsn = getSecretString(sentryDsnArn)
export const sentryOrg = getSecretString(sentryOrgArn)
export const sentryProject = getSecretString(sentryProjectArn)
export const defaultProviderApiKey = getSecretString(defaultProviderApiKeyArn)
export const postHogApiKey = getSecretString(postHogApiKeyArn)

export const dbUrl = pulumi.interpolate`postgresql://${dbUsername}:${dbPassword}@${dbEndpoint}/${dbName}?sslmode=verify-full&sslrootcert=/app/packages/core/src/assets/eu-central-1-bundle.pem`
export const environment = pulumi
Expand All @@ -72,6 +74,7 @@ export const environment = pulumi
sentryProject,
defaultProjectId,
defaultProviderApiKey,
postHogApiKey,
])
.apply(() => {
return [
Expand Down Expand Up @@ -110,5 +113,7 @@ export const environment = pulumi
{ name: 'AWS_ACCESS_SECRET', value: awsAccessSecret },
{ name: 'DEFAULT_PROJECT_ID', value: defaultProjectId },
{ name: 'DEFAULT_PROVIDER_API_KEY', value: defaultProviderApiKey },
{ name: 'NEXT_PUBLIC_POSTHOG_KEY', value: postHogApiKey },
{ name: 'NEXT_PUBLIC_POSTHOG_HOST', value: 'https://eu.i.posthog.com' },
]
})
49 changes: 27 additions & 22 deletions apps/infra/src/deployments/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import {
coreStack,
environment,
postHogApiKey,
sentryDsn,
sentryOrg,
sentryProject,
Expand All @@ -27,30 +28,34 @@ const coreRepo = new aws.ecr.Repository('latitude-llm-core-repo')
// Build and push the Docker image
const token = await aws.ecr.getAuthorizationToken()

const image = pulumi.all([sentryDsn, sentryOrg, sentryProject]).apply(
([sentryDsn, sentryOrg, sentryProject]) =>
new docker.Image('LatitudeLLMAppImage', {
build: {
platform: 'linux/amd64',
context: resolve('../../../'),
dockerfile: resolve('../../../apps/web/docker/Dockerfile'),
cacheFrom: {
images: [pulumi.interpolate`${repo.repositoryUrl}:latest`],
const image = pulumi
.all([sentryDsn, sentryOrg, sentryProject, postHogApiKey])
.apply(
([sentryDsn, sentryOrg, sentryProject, postHogApiKey]) =>
new docker.Image('LatitudeLLMAppImage', {
build: {
platform: 'linux/amd64',
context: resolve('../../../'),
dockerfile: resolve('../../../apps/web/docker/Dockerfile'),
cacheFrom: {
images: [pulumi.interpolate`${repo.repositoryUrl}:latest`],
},
args: {
SENTRY_DSN: sentryDsn,
SENTRY_ORG: sentryOrg,
SENTRY_PROJECT: sentryProject,
NEXT_PUBLIC_POSTHOG_KEY: postHogApiKey,
NEXT_PUBLIC_POSTHOG_HOST: 'https://eu.i.posthog.com',
},
},
args: {
SENTRY_DSN: sentryDsn,
SENTRY_ORG: sentryOrg,
SENTRY_PROJECT: sentryProject,
imageName: pulumi.interpolate`${repo.repositoryUrl}:latest`,
registry: {
server: repo.repositoryUrl,
username: token.userName,
password: pulumi.secret(token.password),
},
},
imageName: pulumi.interpolate`${repo.repositoryUrl}:latest`,
registry: {
server: repo.repositoryUrl,
username: token.userName,
password: pulumi.secret(token.password),
},
}),
)
}),
)
const coreImage = new docker.Image('LatitudeLLMCoreImage', {
build: {
platform: 'linux/amd64',
Expand Down
6 changes: 6 additions & 0 deletions apps/web/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ ARG PROJECT
ARG SENTRY_DSN
ARG SENTRY_ORG
ARG SENTRY_PROJECT
ARG NEXT_PUBLIC_POSTHOG_KEY
ARG NEXT_PUBLIC_POSTHOG_HOST

ENV SENTRY_DSN=$SENTRY_DSN
ENV SENTRY_ORG=$SENTRY_ORG
ENV SENTRY_PROJECT=$SENTRY_PROJECT
ENV NEXT_PUBLIC_POSTHOG_KEY=$NEXT_PUBLIC_POSTHOG_KEY
ENV NEXT_PUBLIC_POSTHOG_HOST=$NEXT_PUBLIC_POSTHOG_HOST

WORKDIR /app

Expand All @@ -62,6 +66,8 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
SENTRY_ORG=$SENTRY_ORG \
SENTRY_PROJECT=$SENTRY_PROJECT \
SENTRY_DSN=$SENTRY_DSN \
NEXT_PUBLIC_POSTHOG_KEY=$NEXT_PUBLIC_POSTHOG_KEY \
NEXT_PUBLIC_POSTHOG_HOST=$NEXT_PUBLIC_POSTHOG_HOST \
pnpm turbo build --filter="${PROJECT}..."

RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm prune --prod --no-optional
Expand Down
2 changes: 0 additions & 2 deletions apps/web/env.example

This file was deleted.

11 changes: 6 additions & 5 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"test:watch": "vitest"
},
"dependencies": {
"yaml": "^2.4.5",
"@latitude-data/compiler": "workspace:^",
"@latitude-data/core": "workspace:*",
"@latitude-data/env": "workspace:^",
Expand Down Expand Up @@ -43,11 +42,13 @@
"next-themes": "^0.3.0",
"nextjs-toploader": "^1.6.12",
"nprogress": "^0.2.0",
"posthog-js": "^1.161.6",
"react": "19.0.0-rc-f994737d14-20240522",
"react-dom": "19.0.0-rc-f994737d14-20240522",
"socket.io-react-hook": "^2.4.5",
"swr": "^2.2.5",
"use-debounce": "^10.0.1",
"yaml": "^2.4.5",
"zod": "^3.23.8",
"zsa": "^0.5.1",
"zsa-react": "^0.2.2"
Expand All @@ -57,6 +58,9 @@
"@latitude-data/eslint-config": "workspace:*",
"@latitude-data/typescript-config": "workspace:*",
"@next/eslint-plugin-next": "^14.2.4",
"@testing-library/dom": "^10.3.2",
"@testing-library/react": "^16.0.0",
"@testing-library/react-hooks": "^8.0.1",
"@types/js-cookie": "^3.0.6",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.14.10",
Expand All @@ -68,10 +72,7 @@
"node-mocks-http": "^1.15.0",
"postcss": "^8.4.39",
"tailwindcss": "^3.4.4",
"vitest": "^2.0.3",
"@testing-library/dom": "^10.3.2",
"@testing-library/react": "^16.0.0",
"@testing-library/react-hooks": "^8.0.1"
"vitest": "^2.0.3"
},
"optionalDependencies": {
"svelte": "^4.2.19",
Expand Down
20 changes: 13 additions & 7 deletions apps/web/src/app/(private)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { getSession } from '$/services/auth/getSession'
import { ROUTES } from '$/services/routes'
import { redirect } from 'next/navigation'

import { CSPostHogProvider, IdentifyUser } from '../providers'

export default async function PrivateLayout({
children,
}: Readonly<{
Expand All @@ -22,12 +24,16 @@ export default async function PrivateLayout({
const { workspace, user } = await getCurrentUser()

return (
<SocketIOProvider>
<SessionProvider currentUser={user} workspace={workspace}>
<LatitudeWebsocketsProvider socketServer={env.WEBSOCKETS_SERVER}>
{children}
</LatitudeWebsocketsProvider>
</SessionProvider>
</SocketIOProvider>
<CSPostHogProvider>
<IdentifyUser user={user} workspace={workspace}>
<SocketIOProvider>
<SessionProvider currentUser={user} workspace={workspace}>
<LatitudeWebsocketsProvider socketServer={env.WEBSOCKETS_SERVER}>
{children}
</LatitudeWebsocketsProvider>
</SessionProvider>
</SocketIOProvider>
</IdentifyUser>
</CSPostHogProvider>
)
}
1 change: 1 addition & 0 deletions apps/web/src/app/(public)/api/health/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import _ from '$/env'
import { envClient as __ } from '$/envClient'

export async function GET() {
return Response.json({ status: 'ok' })
Expand Down
45 changes: 45 additions & 0 deletions apps/web/src/app/providers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use client'

import { ReactNode, useEffect } from 'react'

import { User, Workspace } from '@latitude-data/core/browser'
import { envClient } from '$/envClient'
import posthog from 'posthog-js'
import { PostHogProvider, usePostHog } from 'posthog-js/react'

if (
typeof window !== 'undefined' &&
envClient.NEXT_PUBLIC_POSTHOG_KEY &&
envClient.NEXT_PUBLIC_POSTHOG_HOST
) {
posthog.init(envClient.NEXT_PUBLIC_POSTHOG_KEY, {
api_host: envClient.NEXT_PUBLIC_POSTHOG_HOST,
person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
})
}
export function CSPostHogProvider({ children }: { children: ReactNode }) {
return <PostHogProvider client={posthog}>{children}</PostHogProvider>
}

export function IdentifyUser({
user,
workspace,
children,
}: {
user: User
workspace: Workspace
children: ReactNode
}) {
const posthog = usePostHog()

useEffect(() => {
if (user) {
posthog?.identify(user.id, {
email: user.email,
})
posthog?.group('workspace', String(workspace.id))
}
}, [posthog, user.id, user.email, workspace.id])

return children
}
2 changes: 1 addition & 1 deletion apps/web/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default createEnv({
NODE_ENV: z.string(),
DATABASE_URL: z.string(),
GATEWAY_HOSTNAME: z.string(),
GATEWAY_PORT: z.coerce.number().optional(),
WEBSOCKETS_SERVER: z.string(),
GATEWAY_PORT: z.coerce.number().optional(),
GATEWAY_SSL: z
.enum(['true', 'false'])
.transform((value) => value === 'true')
Expand Down
13 changes: 13 additions & 0 deletions apps/web/src/envClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { createEnv } from '@t3-oss/env-nextjs'
import { z } from 'zod'

export const envClient = createEnv({
client: {
NEXT_PUBLIC_POSTHOG_KEY: z.string(),
NEXT_PUBLIC_POSTHOG_HOST: z.string(),
},
runtimeEnv: {
NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY ?? '',
NEXT_PUBLIC_POSTHOG_HOST: process.env.NEXT_PUBLIC_POSTHOG_HOST ?? '',
},
})
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ services:
build:
context: .
dockerfile: apps/web/docker/Dockerfile
args:
- BUILDING_CONTAINER=true
- NODE_ENV=production
- SENTRY_ORG=latitude-i5
- SENTRY_PROJECT=latitude-app-llm
- SENTRY_DSN=http://sentrymock.com
- NEXT_PUBLIC_POSTHOG_KEY=eu.posthog.com
- NEXT_PUBLIC_POSTHOG_HOST=test
profiles: [building]
environment:
- NODE_ENV=production
Expand Down
2 changes: 1 addition & 1 deletion packages/env/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const env = createEnv({
WEBSOCKET_REFRESH_SECRET_TOKEN_KEY: z.string(),
WEBSOCKET_SECRET_TOKEN_KEY: z.string(),
WORKERS_WEBSOCKET_SECRET_TOKEN: z.string(),
DEFAULT_PROVIDER_ID: z.string(),
AWS_ACCESS_KEY: z.string().optional(),
AWS_ACCESS_SECRET: z.string().optional(),
AWS_REGION: z.string().optional(),
Expand All @@ -79,7 +80,6 @@ export const env = createEnv({
SENTRY_DSN: z.string().optional(),
SENTRY_ORG: z.string().optional(),
SENTRY_PROJECT: z.string().optional(),
DEFAULT_PROVIDER_ID: z.string(),
},
runtimeEnv: {
...process.env,
Expand Down
Loading

0 comments on commit 2766b01

Please sign in to comment.