Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions apps/web/actions/analytics/track-user-signed-up.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export async function checkAndMarkUserSignedUpTracked(): Promise<{
return { shouldTrack: false };
}

const result = await db()
const [result] = await db()
.update(users)
.set({
preferences: sql`JSON_SET(COALESCE(${users.preferences}, JSON_OBJECT()), '$.trackedEvents.user_signed_up', true)`,
Expand All @@ -42,11 +42,7 @@ export async function checkAndMarkUserSignedUpTracked(): Promise<{
sql`(${users.id} = ${currentUser.id}) AND (${users.created_at} >= CURRENT_DATE()) AND JSON_CONTAINS(COALESCE(${users.preferences}, JSON_OBJECT()), CAST(true AS JSON), '$.trackedEvents.user_signed_up') = 0`,
);

if (result.rowsAffected && result.rowsAffected > 0) {
return { shouldTrack: true };
}

return { shouldTrack: false };
return { shouldTrack: result.affectedRows > 0 };
} catch {
return { shouldTrack: false };
}
Expand Down
6 changes: 2 additions & 4 deletions apps/web/actions/organization/remove-invite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export async function removeOrganizationInvite(
throw new Error("Only the owner can remove organization invites");
}

const result = await db()
const [result] = await db()
.delete(organizationInvites)
.where(
and(
Expand All @@ -40,9 +40,7 @@ export async function removeOrganizationInvite(
),
);

if (result.rowsAffected === 0) {
throw new Error("Invite not found");
}
if (result.affectedRows === 0) throw new Error("Invite not found");

revalidatePath("/dashboard/settings/organization");

Expand Down
6 changes: 2 additions & 4 deletions apps/web/actions/organization/remove-member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export async function removeOrganizationMember(
throw new Error("Owner cannot remove themselves");
}

const result = await db()
const [result] = await db()
.delete(organizationMembers)
.where(
and(
Expand All @@ -60,9 +60,7 @@ export async function removeOrganizationMember(
),
);

if (result.rowsAffected === 0) {
throw new Error("Member not found");
}
if (result.affectedRows === 0) throw new Error("Member not found");

revalidatePath("/dashboard/settings/organization");
return { success: true };
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/api/desktop/[...route]/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ app.post(
{ status: 404 },
);

const result = await db()
const [result] = await db()
.update(videoUploads)
.set({
uploaded,
Expand All @@ -362,7 +362,7 @@ app.post(
),
);

if (result.rowsAffected === 0)
if (result.affectedRows === 0)
await db().insert(videoUploads).values({
videoId,
uploaded,
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/api/upload/[...route]/multipart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ app.post(

const videoId = "videoId" in body ? body.videoId : videoIdFromFileKey;
if (videoId) {
const result = await db()
const [result] = await db()
.update(videos)
.set({
duration: updateIfDefined(body.durationInSecs, videos.duration),
Expand All @@ -316,7 +316,7 @@ app.post(
);

// This proves authentication
if (result.rowsAffected > 0)
if (result.affectedRows > 0)
await db()
.delete(videoUploads)
.where(eq(videoUploads.videoId, Video.VideoId.make(videoId)));
Expand Down
1 change: 1 addition & 0 deletions apps/web/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export async function middleware(request: NextRequest) {
}

export const config = {
runtime: "nodejs",
matcher: [
/*
* Match all request paths except for the ones starting with:
Expand Down
3 changes: 1 addition & 2 deletions infra/sst.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default $config({
{ key: "NEXT_PUBLIC_AXIOM_DATASET", value: AXIOM_DATASET },
{ key: "CAP_AWS_BUCKET", value: recordingsBucket.bucket },
{ key: "NEXT_PUBLIC_CAP_AWS_BUCKET", value: recordingsBucket.bucket },
{ key: "DATABASE_URL", value: secrets.DATABASE_URL_HTTP.value },
{ key: "DATABASE_URL_MYSQL", value: secrets.DATABASE_URL_MYSQL.value },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Verify environment variable name expected by the application.

The Vercel environment variable is being set with key DATABASE_URL_MYSQL, but application code typically expects DATABASE_URL. On line 291, the workflow cluster is configured with DATABASE_URL: secrets.DATABASE_URL_MYSQL.value, suggesting the application expects DATABASE_URL as the key.

Apply this diff if the application expects DATABASE_URL:

-			{ key: "DATABASE_URL_MYSQL", value: secrets.DATABASE_URL_MYSQL.value },
+			{ key: "DATABASE_URL", value: secrets.DATABASE_URL_MYSQL.value },

Alternatively, if the application has been updated to use DATABASE_URL_MYSQL, verify with:

#!/bin/bash
# Description: Check which environment variable name is used in the application code

echo "=== Searching for DATABASE_URL usage in application code ==="
rg -n "process\.env\.DATABASE_URL[^_]|DATABASE_URL[^_]" apps/web/ packages/database/ --type ts

echo "=== Searching for DATABASE_URL_MYSQL usage ==="
rg -n "process\.env\.DATABASE_URL_MYSQL|DATABASE_URL_MYSQL" apps/web/ packages/database/ --type ts
🤖 Prompt for AI Agents
In infra/sst.config.ts around line 52, the environment variable key is set to
DATABASE_URL_MYSQL but the application (and another workflow entry at line 291)
expects DATABASE_URL; change the key to DATABASE_URL while keeping the secret
value (e.g., { key: "DATABASE_URL", value: secrets.DATABASE_URL_MYSQL.value })
and ensure any other env entries or workflow configs use the same DATABASE_URL
name so they match the application; if instead the app truly uses
DATABASE_URL_MYSQL, update the other workflow/config at line 291 to use
DATABASE_URL_MYSQL consistently.

];

// new aws.s3.BucketAccelerateConfigurationV2("RecordingsBucketAcceleration", {
Expand Down Expand Up @@ -174,7 +174,6 @@ export default $config({

function Secrets() {
return {
DATABASE_URL_HTTP: new sst.Secret("DATABASE_URL_HTTP"),
DATABASE_URL_MYSQL: new sst.Secret("DATABASE_URL_MYSQL"),
CAP_AWS_ACCESS_KEY: new sst.Secret("CAP_AWS_ACCESS_KEY"),
CAP_AWS_SECRET_KEY: new sst.Secret("CAP_AWS_SECRET_KEY"),
Expand Down
4 changes: 2 additions & 2 deletions packages/database/auth/drizzle-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { STRIPE_AVAILABLE, stripe } from "@cap/utils";
import { Organisation, User } from "@cap/web-domain";
import { and, eq } from "drizzle-orm";
import type { PlanetScaleDatabase } from "drizzle-orm/planetscale-serverless";
import type { MySql2Database } from "drizzle-orm/mysql2";
import type { Adapter } from "next-auth/adapters";
import type Stripe from "stripe";
import { nanoId } from "../helpers.ts";
import { accounts, sessions, users, verificationTokens } from "../schema.ts";

export function DrizzleAdapter(db: PlanetScaleDatabase): Adapter {
export function DrizzleAdapter(db: MySql2Database): Adapter {
return {
async createUser(userData: any) {
await db.insert(users).values({
Expand Down
22 changes: 2 additions & 20 deletions packages/database/index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
import { instrumentDrizzleClient } from "@kubiks/otel-drizzle";
import { Client, type Config } from "@planetscale/database";
import { sql } from "drizzle-orm";
import type { AnyMySqlColumn } from "drizzle-orm/mysql-core";
import { drizzle } from "drizzle-orm/planetscale-serverless";
import { drizzle } from "drizzle-orm/mysql2";

function createDrizzle() {
const URL = process.env.DATABASE_URL!;

let fetchHandler: Promise<Config["fetch"]> | undefined;

if (URL.startsWith("mysql://")) {
fetchHandler = import("@mattrax/mysql-planetscale").then((m) =>
m.createFetchHandler(URL),
);
}

const connection = new Client({
url: URL,
fetch: async (input, init) => {
return await ((await fetchHandler) || fetch)(input, init);
},
});

return drizzle(connection);
return drizzle(process.env.DATABASE_URL_MYSQL!);
}

let _cached: ReturnType<typeof createDrizzle> | undefined;
Expand Down
1 change: 1 addition & 0 deletions packages/database/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"drizzle-orm": "0.44.6",
"dub": "^0.64.0",
"effect": "^3.18.4",
"mysql2": "^3.15.2",
"nanoid": "^5.0.4",
"next": "15.5.4",
"next-auth": "^4.24.5",
Expand Down
Loading