Skip to content

Commit 7a00e94

Browse files
authored
chore: add projectId to trpc get trace and observations queries (langfuse#2926)
1 parent f9dda60 commit 7a00e94

File tree

11 files changed

+53
-19
lines changed

11 files changed

+53
-19
lines changed

web/src/components/session/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export const SessionPage: React.FC<{
113113
className="group grid gap-3 border-border p-2 shadow-none hover:border-ring md:grid-cols-3"
114114
key={trace.id}
115115
>
116-
<SessionIO traceId={trace.id} />
116+
<SessionIO traceId={trace.id} projectId={projectId} />
117117
<div className="-mt-1 p-1 opacity-50 transition-opacity group-hover:opacity-100">
118118
<Link
119119
href={`/project/${projectId}/traces/${trace.id}`}
@@ -158,9 +158,15 @@ export const SessionPage: React.FC<{
158158
);
159159
};
160160

161-
const SessionIO = ({ traceId }: { traceId: string }) => {
161+
const SessionIO = ({
162+
traceId,
163+
projectId,
164+
}: {
165+
traceId: string;
166+
projectId: string;
167+
}) => {
162168
const trace = api.traces.byId.useQuery(
163-
{ traceId: traceId },
169+
{ traceId, projectId },
164170
{
165171
enabled: typeof traceId === "string",
166172
trpc: {

web/src/components/star-toggle.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,21 +158,21 @@ export function StarTraceDetailsToggle({
158158
setIsLoading(true);
159159

160160
// Snapshot the previous value
161-
const prevData = utils.traces.byId.getData({ traceId });
161+
const prevData = utils.traces.byId.getData({ traceId, projectId });
162162

163163
return { prevData };
164164
},
165165
onError: (err, _newTodo, context) => {
166166
setIsLoading(false);
167167
trpcErrorToast(err);
168168
// Rollback to the previous value if mutation fails
169-
utils.traces.byId.setData({ traceId }, context?.prevData);
169+
utils.traces.byId.setData({ traceId, projectId }, context?.prevData);
170170
},
171171
onSettled: () => {
172172
setIsLoading(false);
173173

174174
utils.traces.byId.setData(
175-
{ traceId },
175+
{ traceId, projectId },
176176
(oldQueryData: RouterOutput["traces"]["byId"] | undefined) => {
177177
return oldQueryData
178178
? {

web/src/components/table/use-cases/generations.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ export default function GenerationsTable({
561561
<GenerationsDynamicCell
562562
observationId={observationId}
563563
traceId={traceId}
564+
projectId={projectId}
564565
col="input"
565566
singleLine={rowHeight === "s"}
566567
/>
@@ -581,6 +582,7 @@ export default function GenerationsTable({
581582
<GenerationsDynamicCell
582583
observationId={observationId}
583584
traceId={traceId}
585+
projectId={projectId}
584586
col="output"
585587
singleLine={rowHeight === "s"}
586588
/>
@@ -604,6 +606,7 @@ export default function GenerationsTable({
604606
<GenerationsDynamicCell
605607
observationId={observationId}
606608
traceId={traceId}
609+
projectId={projectId}
607610
col="metadata"
608611
singleLine={rowHeight === "s"}
609612
/>
@@ -780,18 +783,21 @@ export default function GenerationsTable({
780783
const GenerationsDynamicCell = ({
781784
traceId,
782785
observationId,
786+
projectId,
783787
col,
784788
singleLine = false,
785789
}: {
786790
traceId: string;
787791
observationId: string;
792+
projectId: string;
788793
col: "input" | "output" | "metadata";
789794
singleLine: boolean;
790795
}) => {
791796
const observation = api.observations.byId.useQuery(
792797
{
793-
observationId: observationId,
794-
traceId: traceId,
798+
observationId,
799+
traceId,
800+
projectId,
795801
},
796802
{
797803
enabled: typeof traceId === "string" && typeof observationId === "string",

web/src/components/table/use-cases/traces.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ export default function TracesTable({
464464
return (
465465
<TracesDynamicCell
466466
traceId={traceId}
467+
projectId={projectId}
467468
col="input"
468469
singleLine={rowHeight === "s"}
469470
/>
@@ -482,6 +483,7 @@ export default function TracesTable({
482483
return (
483484
<TracesDynamicCell
484485
traceId={traceId}
486+
projectId={projectId}
485487
col="output"
486488
singleLine={rowHeight === "s"}
487489
/>
@@ -503,6 +505,7 @@ export default function TracesTable({
503505
return (
504506
<TracesDynamicCell
505507
traceId={traceId}
508+
projectId={projectId}
506509
col="metadata"
507510
singleLine={rowHeight === "s"}
508511
/>
@@ -728,15 +731,17 @@ export default function TracesTable({
728731

729732
const TracesDynamicCell = ({
730733
traceId,
734+
projectId,
731735
col,
732736
singleLine = false,
733737
}: {
734738
traceId: string;
739+
projectId: string;
735740
col: "input" | "output" | "metadata";
736741
singleLine?: boolean;
737742
}) => {
738743
const trace = api.traces.byId.useQuery(
739-
{ traceId: traceId },
744+
{ traceId, projectId },
740745
{
741746
enabled: typeof traceId === "string",
742747
trpc: {

web/src/components/trace/ObservationPreview.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export const ObservationPreview = (props: {
4242
const observationWithInputAndOutput = api.observations.byId.useQuery({
4343
observationId: props.currentObservationId,
4444
traceId: props.traceId,
45+
projectId: props.projectId,
4546
});
4647

4748
const preloadedObservation = props.observations.find(

web/src/components/trace/index.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { usePostHogClientCapture } from "@/src/features/posthog-analytics/usePos
3333
import { Tabs, TabsList, TabsTrigger } from "@/src/components/ui/tabs";
3434
import { TraceTimelineView } from "@/src/components/trace/TraceTimelineView";
3535
import { type APIScore } from "@langfuse/shared";
36+
import { useSession } from "next-auth/react";
3637

3738
export function Trace(props: {
3839
observations: Array<ObservationReturnType>;
@@ -181,8 +182,9 @@ export function TracePage({ traceId }: { traceId: string }) {
181182
const capture = usePostHogClientCapture();
182183
const router = useRouter();
183184
const utils = api.useUtils();
185+
const session = useSession();
184186
const trace = api.traces.byId.useQuery(
185-
{ traceId },
187+
{ traceId, projectId: router.query.projectId as string },
186188
{
187189
retry(failureCount, error) {
188190
if (error.data?.code === "UNAUTHORIZED") return false;
@@ -201,7 +203,10 @@ export function TracePage({ traceId }: { traceId: string }) {
201203
skipBatch: true,
202204
},
203205
},
204-
enabled: !!trace.data?.projectId && trace.isSuccess,
206+
enabled:
207+
!!trace.data?.projectId &&
208+
trace.isSuccess &&
209+
session.status === "authenticated",
205210
},
206211
);
207212

web/src/features/datasets/components/DatasetRunItemsTable.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export function DatasetRunItemsTable(
168168
return trace ? (
169169
<TraceObservationIOCell
170170
traceId={trace.traceId}
171+
projectId={props.projectId}
171172
observationId={trace.observationId}
172173
io="input"
173174
singleLine={rowHeight === "s"}
@@ -186,6 +187,7 @@ export function DatasetRunItemsTable(
186187
return trace ? (
187188
<TraceObservationIOCell
188189
traceId={trace.traceId}
190+
projectId={props.projectId}
189191
observationId={trace.observationId}
190192
io="output"
191193
singleLine={rowHeight === "s"}
@@ -290,18 +292,20 @@ export function DatasetRunItemsTable(
290292

291293
const TraceObservationIOCell = ({
292294
traceId,
295+
projectId,
293296
observationId,
294297
io,
295298
singleLine = false,
296299
}: {
297300
traceId: string;
301+
projectId: string;
298302
observationId?: string;
299303
io: "input" | "output";
300304
singleLine?: boolean;
301305
}) => {
302306
// conditionally fetch the trace or observation depending on the presence of observationId
303307
const trace = api.traces.byId.useQuery(
304-
{ traceId: traceId },
308+
{ traceId, projectId },
305309
{
306310
enabled: observationId === undefined,
307311
trpc: {
@@ -315,7 +319,8 @@ const TraceObservationIOCell = ({
315319
const observation = api.observations.byId.useQuery(
316320
{
317321
observationId: observationId as string, // disabled when observationId is undefined
318-
traceId: traceId,
322+
projectId,
323+
traceId,
319324
},
320325
{
321326
enabled: observationId !== undefined,

web/src/features/tag/components/TagTraceDetailsPopover.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,20 @@ export function TagTraceDetailsPopover({
2929
await utils.traces.byId.cancel();
3030
setIsLoading(true);
3131
// Snapshot the previous value
32-
const prev = utils.traces.byId.getData({ traceId });
32+
const prev = utils.traces.byId.getData({ traceId, projectId });
3333

3434
return { prev };
3535
},
3636
onError: (err, _newTags, context) => {
3737
setIsLoading(false);
3838
trpcErrorToast(err);
3939
// Rollback to the previous value if mutation fails
40-
utils.traces.byId.setData({ traceId }, context?.prev);
40+
utils.traces.byId.setData({ traceId, projectId }, context?.prev);
4141
},
4242
onSettled: (data, error, { traceId, tags }) => {
4343
setIsLoading(false);
4444
utils.traces.byId.setData(
45-
{ traceId },
45+
{ traceId, projectId },
4646
(oldQueryData: RouterOutput["traces"]["byId"] | undefined) => {
4747
return oldQueryData
4848
? {

web/src/server/api/routers/observations.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ export const observationsRouter = createTRPCRouter({
1010
z.object({
1111
observationId: z.string(),
1212
traceId: z.string(), // required for protectedGetTraceProcedure
13+
projectId: z.string(), // required for protectedGetTraceProcedure
1314
}),
1415
)
1516
.query(async ({ input, ctx }) => {
1617
const observation = await ctx.prisma.observation.findFirstOrThrow({
1718
where: {
1819
id: input.observationId,
1920
traceId: input.traceId,
21+
projectId: input.projectId,
2022
},
2123
});
2224
const scores = observation.traceId

web/src/server/api/routers/traces.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,15 @@ export const traceRouter = createTRPCRouter({
273273
byId: protectedGetTraceProcedure
274274
.input(
275275
z.object({
276-
traceId: z.string(),
276+
traceId: z.string(), // used for security check
277+
projectId: z.string(), // used for security check
277278
}),
278279
)
279280
.query(async ({ input, ctx }) => {
280281
const trace = await ctx.prisma.trace.findFirstOrThrow({
281282
where: {
282283
id: input.traceId,
284+
projectId: input.projectId,
283285
},
284286
});
285287
const observations = await ctx.prisma.observationView.findMany({

0 commit comments

Comments
 (0)