Skip to content
Merged
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
35 changes: 34 additions & 1 deletion apps/web/actions/folders/add-videos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { db } from "@cap/database";
import { getCurrentUser } from "@cap/database/auth/session";
import { nanoId } from "@cap/database/helpers";
import {
folders,
sharedVideos,
Expand Down Expand Up @@ -50,7 +51,39 @@ export async function addVideosToFolder(

const isAllSpacesEntry = spaceId === user.activeOrganizationId;

//if video already exists in the space, then move it
//if we're adding videos to a folder from Caps page, then insert the videos into the folder
if (isAllSpacesEntry && folder.spaceId) {
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

Condition mismatch between insert and update blocks.

The insert block (line 55) uses isAllSpacesEntry && folder.spaceId, while the update block (line 87) only checks isAllSpacesEntry. This creates inconsistent routing:

  • Scenario: isAllSpacesEntry = true, folder.spaceId = null
    • Insert → spaceVideos (else branch)
    • Update → sharedVideos
    • Result: Insert and update target different tables

Ensure both blocks use the same condition to maintain consistency. If folder.spaceId is required for sharedVideos, include it in the update condition as well.

Apply this diff to align the conditions:

-		if (isAllSpacesEntry) {
+		if (isAllSpacesEntry && folder.spaceId) {
 			await db()
 				.update(sharedVideos)

Also applies to: 87-87

🤖 Prompt for AI Agents
In apps/web/actions/folders/add-videos.ts around lines 55 and 87, the insert
uses "isAllSpacesEntry && folder.spaceId" while the update only checks
"isAllSpacesEntry", causing inserts and updates to route to different tables
when folder.spaceId is null; update the condition at line 87 to match the insert
(change it to "isAllSpacesEntry && folder.spaceId") so both insert and update
branches use the same routing logic, or alternatively unify both conditions to a
single shared boolean variable and use that in both places if preferred.

await db()
.insert(sharedVideos)
.values(
validVideoIds.map((videoId) => {
const id = nanoId();
return {
id,
videoId,
folderId,
organizationId: user.activeOrganizationId,
sharedByUserId: user.id,
};
}),
);
} else {
await db()
.insert(spaceVideos)
.values(
validVideoIds.map((videoId) => {
const id = nanoId();
return {
id,
videoId,
folderId,
spaceId,
addedById: user.id,
};
}),
);
}
Comment on lines +54 to +85
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 | 🔴 Critical

🧩 Analysis chain

Duplicate records: Insert followed by update on same videos.

The new insertion logic creates records for validVideoIds, but lines 87-107 immediately update existing records using those same validVideoIds. This will produce duplicate associations if any video already has a folder assignment:

  1. Insert (lines 54-85): Creates new videoId → folderId records
  2. Update (lines 87-107): Modifies existing videoId → folderId records

Neither sharedVideos nor spaceVideos schema enforces a unique constraint on (videoId, folderId) or (videoId, organizationId/spaceId), so duplicates are allowed. Consider using an upsert pattern (e.g., .onConflictDoUpdate() if a unique constraint exists, or inserting only videos that have no prior folder association).

Run this script to check for unique constraints and potential duplicate risks:


🏁 Script executed:

#!/bin/bash
# Verify schema constraints and search for existing duplicate-prevention logic

# Check schema definitions for unique constraints
rg -nP -A5 'export const (sharedVideos|spaceVideos) = mysqlTable' packages/database/schema.ts

# Search for upsert or duplicate-handling patterns in similar code
rg -nP --type=ts -C3 '\.(insert|upsert)\((sharedVideos|spaceVideos)\)' apps/web/actions/

# Look for existing duplicate checks
rg -nP --type=ts -C3 'onConflict|onDuplicate|IGNORE|REPLACE' apps/web/actions/

Length of output: 3821


🏁 Script executed:

#!/bin/bash
# Show validVideoIds usage
rg -n -C5 'validVideoIds' apps/web/actions/folders/add-videos.ts

# Show any update queries
rg -n -C5 '\.update' apps/web/actions/folders/add-videos.ts

Length of output: 2416


Prevent duplicate folder associations in folders/add-videos.ts
The code always inserts new sharedVideos/spaceVideos records for validVideoIds before updating, but without a unique constraint on (videoId, folderId) this creates duplicate entries. Replace the insert-then-update pattern with an upsert (.onConflictDoUpdate()) or guard the insert to only add videos not already assigned to the folder.


if (isAllSpacesEntry) {
await db()
.update(sharedVideos)
Expand Down
Loading