- pgSchema "mesh" with 4 tables isolating the peer mesh domain - Enums: visibility, transport, tier, role - audit_log is metadata-only (E2E encryption enforced at broker/client) - Cascade on mesh delete, soft-delete via archivedAt/revokedAt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
64 lines
1.6 KiB
TypeScript
64 lines
1.6 KiB
TypeScript
import { notFound, redirect } from "next/navigation";
|
|
import { z } from "zod";
|
|
|
|
import { messageSchema, partSchema } from "@turbostarter/ai/chat/schema";
|
|
import { toChatMessage } from "@turbostarter/ai/chat/utils";
|
|
import { handle } from "@turbostarter/api/utils";
|
|
|
|
import { pathsConfig } from "~/config/paths";
|
|
import { api } from "~/lib/api/server";
|
|
import { getSession } from "~/lib/auth/server";
|
|
import { getMetadata } from "~/lib/metadata";
|
|
import { ViewChat } from "~/modules/chat/layout/view";
|
|
|
|
export const generateMetadata = async ({
|
|
params,
|
|
}: {
|
|
params: Promise<{ id: string; locale: string }>;
|
|
}) => {
|
|
const id = (await params).id;
|
|
const data = await handle(api.ai.chat.chats[":id"].$get, { throwOnError: false })({
|
|
param: { id },
|
|
});
|
|
|
|
return getMetadata({
|
|
...(data?.name && { title: data.name }),
|
|
})({ params });
|
|
};
|
|
|
|
export default async function Chat({
|
|
params,
|
|
}: {
|
|
params: Promise<{ id: string }>;
|
|
}) {
|
|
const { user } = await getSession();
|
|
|
|
if (!user) {
|
|
return redirect(pathsConfig.auth.login);
|
|
}
|
|
|
|
const id = (await params).id;
|
|
|
|
const data = await handle(api.ai.chat.chats[":id"].$get, { throwOnError: false })({
|
|
param: { id },
|
|
});
|
|
|
|
if (!data) {
|
|
return notFound();
|
|
}
|
|
|
|
const messages = await handle(api.ai.chat.chats[":id"].messages.$get, {
|
|
throwOnError: false,
|
|
schema: z.array(
|
|
messageSchema.extend({
|
|
parts: z.array(partSchema),
|
|
}),
|
|
),
|
|
})({
|
|
param: { id },
|
|
});
|
|
const initialMessages = (messages ?? []).map(toChatMessage);
|
|
|
|
return <ViewChat id={id} initialMessages={initialMessages} />;
|
|
}
|