refactor: rename snapshot types to PublicChatSnapshot prefix

This commit is contained in:
CREDO23 2026-02-02 16:05:23 +02:00
parent e62e4faaa5
commit d890c562d4
9 changed files with 95 additions and 91 deletions

View file

@ -1,17 +1,16 @@
import { atomWithMutation } from "jotai-tanstack-query";
import { toast } from "sonner";
import type {
CreateSnapshotRequest,
CreateSnapshotResponse,
PublicChatSnapshotCreateRequest,
PublicChatSnapshotCreateResponse,
} from "@/contracts/types/chat-threads.types";
import { chatThreadsApiService } from "@/lib/apis/chat-threads-api.service";
export const createSnapshotMutationAtom = atomWithMutation(() => ({
mutationFn: async (request: CreateSnapshotRequest) => {
return chatThreadsApiService.createSnapshot(request);
export const createPublicChatSnapshotMutationAtom = atomWithMutation(() => ({
mutationFn: async (request: PublicChatSnapshotCreateRequest) => {
return chatThreadsApiService.createPublicChatSnapshot(request);
},
onSuccess: (response: CreateSnapshotResponse) => {
// Construct URL using frontend origin (backend returns its own URL which differs)
onSuccess: (response: PublicChatSnapshotCreateResponse) => {
const publicUrl = `${window.location.origin}/public/${response.share_token}`;
navigator.clipboard.writeText(publicUrl);
if (response.is_new) {

View file

@ -3,18 +3,18 @@ import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-quer
import { chatThreadsApiService } from "@/lib/apis/chat-threads-api.service";
import { cacheKeys } from "@/lib/query-client/cache-keys";
export const searchSpaceSnapshotsAtom = atomWithQuery((get) => {
export const publicChatSnapshotsAtom = atomWithQuery((get) => {
const searchSpaceId = get(activeSearchSpaceIdAtom);
return {
queryKey: cacheKeys.snapshots.bySearchSpace(Number(searchSpaceId) || 0),
queryKey: cacheKeys.publicChatSnapshots.bySearchSpace(Number(searchSpaceId) || 0),
enabled: !!searchSpaceId,
staleTime: 5 * 60 * 1000,
queryFn: async () => {
if (!searchSpaceId) {
return { snapshots: [] };
}
return chatThreadsApiService.listSearchSpaceSnapshots({
return chatThreadsApiService.listPublicChatSnapshotsForSearchSpace({
search_space_id: Number(searchSpaceId),
});
},

View file

@ -5,7 +5,7 @@ import { useAtomValue, useSetAtom } from "jotai";
import { Globe, User, Users } from "lucide-react";
import { useCallback, useMemo, useState } from "react";
import { toast } from "sonner";
import { createSnapshotMutationAtom } from "@/atoms/chat/chat-thread-mutation.atoms";
import { createPublicChatSnapshotMutationAtom } from "@/atoms/chat/chat-thread-mutation.atoms";
import { currentThreadAtom, setThreadVisibilityAtom } from "@/atoms/chat/current-thread.atom";
import { myAccessAtom } from "@/atoms/members/members-query.atoms";
import { Button } from "@/components/ui/button";
@ -54,7 +54,7 @@ export function ChatShareButton({ thread, onVisibilityChange, className }: ChatS
// Snapshot creation mutation
const { mutateAsync: createSnapshot, isPending: isCreatingSnapshot } = useAtomValue(
createSnapshotMutationAtom
createPublicChatSnapshotMutationAtom
);
// Permission check for public sharing

View file

@ -1,9 +1,9 @@
import { z } from "zod";
/**
* Snapshot info
* Public chat snapshot info
*/
export const snapshotInfo = z.object({
export const publicChatSnapshotInfo = z.object({
id: z.number(),
share_token: z.string(),
public_url: z.string(),
@ -12,13 +12,13 @@ export const snapshotInfo = z.object({
});
/**
* Create snapshot
* Create public chat snapshot
*/
export const createSnapshotRequest = z.object({
export const publicChatSnapshotCreateRequest = z.object({
thread_id: z.number(),
});
export const createSnapshotResponse = z.object({
export const publicChatSnapshotCreateResponse = z.object({
snapshot_id: z.number(),
share_token: z.string(),
public_url: z.string(),
@ -26,28 +26,28 @@ export const createSnapshotResponse = z.object({
});
/**
* List snapshots
* List public chat snapshots for thread
*/
export const listSnapshotsRequest = z.object({
export const publicChatSnapshotListRequest = z.object({
thread_id: z.number(),
});
export const listSnapshotsResponse = z.object({
snapshots: z.array(snapshotInfo),
export const publicChatSnapshotListResponse = z.object({
snapshots: z.array(publicChatSnapshotInfo),
});
/**
* Delete snapshot
* Delete public chat snapshot
*/
export const deleteSnapshotRequest = z.object({
export const publicChatSnapshotDeleteRequest = z.object({
thread_id: z.number(),
snapshot_id: z.number(),
});
/**
* Search space snapshot info (includes thread context)
* Public chat snapshot with thread context
*/
export const searchSpaceSnapshotInfo = z.object({
export const publicChatSnapshotDetail = z.object({
id: z.number(),
share_token: z.string(),
public_url: z.string(),
@ -58,23 +58,23 @@ export const searchSpaceSnapshotInfo = z.object({
});
/**
* List snapshots for search space
* List public chat snapshots for search space
*/
export const listSearchSpaceSnapshotsRequest = z.object({
export const publicChatSnapshotsBySpaceRequest = z.object({
search_space_id: z.number(),
});
export const listSearchSpaceSnapshotsResponse = z.object({
snapshots: z.array(searchSpaceSnapshotInfo),
export const publicChatSnapshotsBySpaceResponse = z.object({
snapshots: z.array(publicChatSnapshotDetail),
});
// Type exports
export type SnapshotInfo = z.infer<typeof snapshotInfo>;
export type CreateSnapshotRequest = z.infer<typeof createSnapshotRequest>;
export type CreateSnapshotResponse = z.infer<typeof createSnapshotResponse>;
export type ListSnapshotsRequest = z.infer<typeof listSnapshotsRequest>;
export type ListSnapshotsResponse = z.infer<typeof listSnapshotsResponse>;
export type DeleteSnapshotRequest = z.infer<typeof deleteSnapshotRequest>;
export type SearchSpaceSnapshotInfo = z.infer<typeof searchSpaceSnapshotInfo>;
export type ListSearchSpaceSnapshotsRequest = z.infer<typeof listSearchSpaceSnapshotsRequest>;
export type ListSearchSpaceSnapshotsResponse = z.infer<typeof listSearchSpaceSnapshotsResponse>;
export type PublicChatSnapshotInfo = z.infer<typeof publicChatSnapshotInfo>;
export type PublicChatSnapshotCreateRequest = z.infer<typeof publicChatSnapshotCreateRequest>;
export type PublicChatSnapshotCreateResponse = z.infer<typeof publicChatSnapshotCreateResponse>;
export type PublicChatSnapshotListRequest = z.infer<typeof publicChatSnapshotListRequest>;
export type PublicChatSnapshotListResponse = z.infer<typeof publicChatSnapshotListResponse>;
export type PublicChatSnapshotDeleteRequest = z.infer<typeof publicChatSnapshotDeleteRequest>;
export type PublicChatSnapshotDetail = z.infer<typeof publicChatSnapshotDetail>;
export type PublicChatSnapshotsBySpaceRequest = z.infer<typeof publicChatSnapshotsBySpaceRequest>;
export type PublicChatSnapshotsBySpaceResponse = z.infer<typeof publicChatSnapshotsBySpaceResponse>;

View file

@ -1,28 +1,30 @@
import {
type CreateSnapshotRequest,
type CreateSnapshotResponse,
createSnapshotRequest,
createSnapshotResponse,
type DeleteSnapshotRequest,
deleteSnapshotRequest,
type ListSearchSpaceSnapshotsRequest,
type ListSearchSpaceSnapshotsResponse,
type ListSnapshotsRequest,
type ListSnapshotsResponse,
listSearchSpaceSnapshotsRequest,
listSearchSpaceSnapshotsResponse,
listSnapshotsRequest,
listSnapshotsResponse,
type PublicChatSnapshotCreateRequest,
type PublicChatSnapshotCreateResponse,
type PublicChatSnapshotDeleteRequest,
type PublicChatSnapshotListRequest,
type PublicChatSnapshotListResponse,
type PublicChatSnapshotsBySpaceRequest,
type PublicChatSnapshotsBySpaceResponse,
publicChatSnapshotCreateRequest,
publicChatSnapshotCreateResponse,
publicChatSnapshotDeleteRequest,
publicChatSnapshotListRequest,
publicChatSnapshotListResponse,
publicChatSnapshotsBySpaceRequest,
publicChatSnapshotsBySpaceResponse,
} from "@/contracts/types/chat-threads.types";
import { ValidationError } from "../error";
import { baseApiService } from "./base-api.service";
class ChatThreadsApiService {
/**
* Create a public snapshot for a thread.
* Create a public chat snapshot for a thread.
*/
createSnapshot = async (request: CreateSnapshotRequest): Promise<CreateSnapshotResponse> => {
const parsed = createSnapshotRequest.safeParse(request);
createPublicChatSnapshot = async (
request: PublicChatSnapshotCreateRequest
): Promise<PublicChatSnapshotCreateResponse> => {
const parsed = publicChatSnapshotCreateRequest.safeParse(request);
if (!parsed.success) {
const errorMessage = parsed.error.issues.map((issue) => issue.message).join(", ");
@ -31,15 +33,17 @@ class ChatThreadsApiService {
return baseApiService.post(
`/api/v1/threads/${parsed.data.thread_id}/snapshots`,
createSnapshotResponse
publicChatSnapshotCreateResponse
);
};
/**
* List all snapshots for a thread.
* List all public chat snapshots for a thread.
*/
listSnapshots = async (request: ListSnapshotsRequest): Promise<ListSnapshotsResponse> => {
const parsed = listSnapshotsRequest.safeParse(request);
listPublicChatSnapshots = async (
request: PublicChatSnapshotListRequest
): Promise<PublicChatSnapshotListResponse> => {
const parsed = publicChatSnapshotListRequest.safeParse(request);
if (!parsed.success) {
const errorMessage = parsed.error.issues.map((issue) => issue.message).join(", ");
@ -48,15 +52,15 @@ class ChatThreadsApiService {
return baseApiService.get(
`/api/v1/threads/${parsed.data.thread_id}/snapshots`,
listSnapshotsResponse
publicChatSnapshotListResponse
);
};
/**
* Delete a specific snapshot.
* Delete a public chat snapshot.
*/
deleteSnapshot = async (request: DeleteSnapshotRequest): Promise<void> => {
const parsed = deleteSnapshotRequest.safeParse(request);
deletePublicChatSnapshot = async (request: PublicChatSnapshotDeleteRequest): Promise<void> => {
const parsed = publicChatSnapshotDeleteRequest.safeParse(request);
if (!parsed.success) {
const errorMessage = parsed.error.issues.map((issue) => issue.message).join(", ");
@ -69,12 +73,12 @@ class ChatThreadsApiService {
};
/**
* List all snapshots for a search space.
* List all public chat snapshots for a search space.
*/
listSearchSpaceSnapshots = async (
request: ListSearchSpaceSnapshotsRequest
): Promise<ListSearchSpaceSnapshotsResponse> => {
const parsed = listSearchSpaceSnapshotsRequest.safeParse(request);
listPublicChatSnapshotsForSearchSpace = async (
request: PublicChatSnapshotsBySpaceRequest
): Promise<PublicChatSnapshotsBySpaceResponse> => {
const parsed = publicChatSnapshotsBySpaceRequest.safeParse(request);
if (!parsed.success) {
const errorMessage = parsed.error.issues.map((issue) => issue.message).join(", ");
@ -83,7 +87,7 @@ class ChatThreadsApiService {
return baseApiService.get(
`/api/v1/searchspaces/${parsed.data.search_space_id}/snapshots`,
listSearchSpaceSnapshotsResponse
publicChatSnapshotsBySpaceResponse
);
};
}

View file

@ -82,7 +82,8 @@ export const cacheKeys = {
publicChat: {
byToken: (shareToken: string) => ["public-chat", shareToken] as const,
},
snapshots: {
bySearchSpace: (searchSpaceId: number) => ["snapshots", "search-space", searchSpaceId] as const,
publicChatSnapshots: {
bySearchSpace: (searchSpaceId: number) =>
["public-chat-snapshots", "search-space", searchSpaceId] as const,
},
};