Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
24 changes: 7 additions & 17 deletions apps/api/src/routes/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,24 +105,14 @@ video.openapi(getVideoStatus, async (c) => {
let content:
| { type: "video"; url: string; mime_type?: string | null }[]
| undefined;
if (job.status === "completed") {
const log = await db.query.log.findFirst({
where: {
requestId: { eq: job.requestId },
if (job.status === "completed" && job.logId) {
content = [
{
type: "video" as const,
url: buildSignedGatewayVideoLogContentUrl(job.logId),
mime_type: job.contentType ?? null,
},
columns: {
id: true,
},
});
if (log) {
content = [
{
type: "video" as const,
url: buildSignedGatewayVideoLogContentUrl(log.id),
mime_type: job.contentType ?? null,
},
];
}
];
}

return c.json(
Expand Down
29 changes: 4 additions & 25 deletions apps/gateway/src/videos/videos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2206,21 +2206,6 @@ function getInlineGoogleVertexVideoFromBodies(
return null;
}

async function getVideoLogIdByRequestId(
requestId: string,
): Promise<string | null> {
const existingLog = await db
.select({
id: tables.log.id,
})
.from(tables.log)
.where(eq(tables.log.requestId, requestId))
.limit(1)
.then((rows) => rows[0]);

return existingLog?.id ?? null;
}

async function getPublicVideoContentUrl(
job: VideoJobRecord,
logId?: string | null,
Expand All @@ -2229,8 +2214,7 @@ async function getPublicVideoContentUrl(
return null;
}

const resolvedLogId =
logId ?? (await getVideoLogIdByRequestId(job.requestId));
const resolvedLogId = logId ?? job.logId;
if (
resolvedLogId &&
(job.contentUrl ||
Expand Down Expand Up @@ -4274,12 +4258,7 @@ videos.openapi(getVideoLogContent, async (c) => {
const videoJob = await db
.select()
.from(tables.videoJob)
.where(
and(
eq(tables.videoJob.projectId, log.projectId),
eq(tables.videoJob.requestId, log.requestId),
),
)
.where(eq(tables.videoJob.logId, log.id))
.limit(1)
.then((rows) => rows[0]);
if (!videoJob) {
Expand Down Expand Up @@ -4347,7 +4326,7 @@ videos.openapi(getVideoContent, async (c) => {

if (!job.contentUrl && !job.storageUri) {
if (shouldProxyDirectUpstreamVideoContent(job)) {
const logId = await getVideoLogIdByRequestId(job.requestId);
const logId = job.logId;
const response = await streamDirectUpstreamVideoContent(job);
if (logId) {
await markVideoDownloaded(logId);
Expand Down Expand Up @@ -4393,7 +4372,7 @@ videos.openapi(getVideoContent, async (c) => {
});
}

const logId = await getVideoLogIdByRequestId(job.requestId);
const logId = job.logId;
const response = await streamVideoFromUrl(contentUrl, job.contentType);
if (logId) {
await markVideoDownloaded(logId);
Expand Down
19 changes: 2 additions & 17 deletions apps/worker/src/services/video-jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -662,21 +662,6 @@ function getInlineGoogleVertexVideo(
return null;
}

async function getVideoLogIdByRequestId(
requestId: string,
): Promise<string | null> {
const existingLog = await db
.select({
id: tables.log.id,
})
.from(tables.log)
.where(eq(tables.log.requestId, requestId))
.limit(1)
.then((rows) => rows[0]);

return existingLog?.id ?? null;
}

async function getPublicVideoContentUrl(
job: VideoJobRecord,
logId?: string | null,
Expand All @@ -685,8 +670,7 @@ async function getPublicVideoContentUrl(
return null;
}

const resolvedLogId =
logId ?? (await getVideoLogIdByRequestId(job.requestId));
const resolvedLogId = logId ?? job.logId;
if (
resolvedLogId &&
(job.contentUrl || job.storageUri || getInlineGoogleVertexVideo(job))
Expand Down Expand Up @@ -1666,6 +1650,7 @@ async function finalizeVideoJob(job: VideoJobRecord): Promise<void> {
.update(tables.videoJob)
.set({
resultLoggedAt: now,
logId,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Insert the log before assigning its FK

When a terminal video job is finalized, this update writes a freshly generated logId before tx.insert(tables.log) creates that row. The migration adds a non-deferrable FK from video_job.log_id to log.id, so Postgres checks this statement immediately and rejects every first-time finalization with a foreign-key violation; the transaction never reaches the log insert, so completed/failed video jobs are not logged and the rest of finalization cannot run. Insert the log first or assign logId in a second update after the insert.

Useful? React with 👍 / 👎.

})
.where(
and(
Expand Down
4 changes: 4 additions & 0 deletions packages/db/migrations/1781645725_pink_morlocks.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE "video_job" ADD COLUMN "log_id" text;--> statement-breakpoint
UPDATE "video_job" SET "log_id" = "log"."id" FROM "log" WHERE "log"."request_id" = "video_job"."request_id";--> statement-breakpoint

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope the log backfill to the job project

This backfill matches only on request_id, but video request IDs are accepted from the caller's x-request-id header and are only indexed, not unique, so the same value can exist in multiple projects or orgs. In that case this UPDATE can attach a video_job to an unrelated log; after this change the API and gateway trust job.logId for signed content URLs and log-to-job lookup, so migrated historical jobs can serve or fetch the wrong log's video content. Include at least project_id (and ideally organization_id) in the join.

Useful? React with 👍 / 👎.

CREATE INDEX "video_job_log_id_idx" ON "video_job" ("log_id");--> statement-breakpoint
ALTER TABLE "video_job" ADD CONSTRAINT "video_job_log_id_log_id_fkey" FOREIGN KEY ("log_id") REFERENCES "log"("id") ON DELETE SET NULL;
Loading
Loading