Skip to content
Open
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
6 changes: 6 additions & 0 deletions .server-changes/remove-deprecated-realtime-stream-action.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: improvement
---

Remove the deprecated realtime stream write endpoint used by retired v3 task clients.
71 changes: 0 additions & 71 deletions apps/webapp/app/routes/realtime.v1.streams.$runId.$streamId.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,15 @@
import { type ActionFunctionArgs } from "@remix-run/server-runtime";
import { z } from "zod";
import { $replica } from "~/db.server";
import { getRequestAbortSignal } from "~/services/httpAsyncStorage.server";
import { getRealtimeStreamInstance } from "~/services/realtime/v1StreamsGlobal.server";
import { anyResource, createLoaderApiRoute } from "~/services/routeBuilders/apiBuilder.server";
import { runStore } from "~/v3/runStore.server";
import { controlPlaneResolver } from "~/v3/runOpsMigration/controlPlaneResolver.server";

const ParamsSchema = z.object({
runId: z.string(),
streamId: z.string(),
});

// Plain action for backwards compatibility with older clients that don't send auth headers
export async function action({ request, params }: ActionFunctionArgs) {
const parsedParams = ParamsSchema.safeParse(params);

if (!parsedParams.success) {
return new Response("Invalid parameters", { status: 400 });
}

const { runId, streamId } = parsedParams.data;

// Look up the run without environment scoping for backwards compatibility
const run = await runStore.findRun(
{
friendlyId: runId,
},
{
select: {
id: true,
friendlyId: true,
streamBasinName: true,
runtimeEnvironmentId: true,
},
},
$replica
);

if (!run) {
return new Response("Run not found", { status: 404 });
}

const environment = await controlPlaneResolver.resolveAuthenticatedEnv(run.runtimeEnvironmentId);

if (!environment) {
return new Response("Run not found", { status: 404 });
}

// Extract client ID from header, default to "default" if not provided
const clientId = request.headers.get("X-Client-Id") || "default";
const streamVersion = request.headers.get("X-Stream-Version") || "v1";

if (!request.body) {
return new Response("No body provided", { status: 400 });
}

const resumeFromChunk = request.headers.get("X-Resume-From-Chunk");
let resumeFromChunkNumber: number | undefined = undefined;
if (resumeFromChunk) {
const parsed = parseInt(resumeFromChunk, 10);
if (isNaN(parsed) || parsed < 0) {
return new Response(`Invalid X-Resume-From-Chunk header value: ${resumeFromChunk}`, {
status: 400,
});
}
resumeFromChunkNumber = parsed;
}

const realtimeStream = getRealtimeStreamInstance(environment, streamVersion, {
run,
});

return realtimeStream.ingestData(
request.body,
run.friendlyId,
streamId,
clientId,
resumeFromChunkNumber
);
}

export const loader = createLoaderApiRoute(
{
params: ParamsSchema,
Expand Down