feat(25-00): add shared types, validators, and test stubs for file system

- Add ChatFile, ChatFileReference, ChatFileUploadResponse, ChatFileListResponse interfaces to types/chat.ts
- Add optional files?: ChatFile[] field to ChatMessage interface
- Add uploadChatFileSchema and createFileReferenceSchema Zod validators to validators/chat.ts
- Re-export all new types and validators from shared/src/index.ts
- Create test stubs for chat-file-service.test.ts and chat-file-routes.test.ts with it.todo() entries
This commit is contained in:
Nexus Dev 2026-04-01 23:01:03 +00:00
parent df88eaa56f
commit f335d3762b
5 changed files with 78 additions and 0 deletions

View file

@ -595,12 +595,16 @@ export {
handoffSchema,
searchMessagesSchema,
branchConversationSchema,
uploadChatFileSchema,
createFileReferenceSchema,
type CreateConversation,
type UpdateConversation,
type CreateMessage,
type Handoff,
type SearchMessages,
type BranchConversation,
type UploadChatFile,
type CreateFileReference,
} from "./validators/index.js";
export type {
@ -615,6 +619,10 @@ export type {
ChatBookmarkWithMessage,
ChatBookmarkListResponse,
ChatBookmarkToggleResponse,
ChatFile,
ChatFileReference,
ChatFileUploadResponse,
ChatFileListResponse,
} from "./types/chat.js";
export { API_PREFIX, API } from "./api.js";

View file

@ -25,6 +25,41 @@ export interface ChatConversationListItem {
branchFromMessageId: string | null;
}
export interface ChatFile {
id: string;
companyId: string;
conversationId: string | null;
messageId: string | null;
filename: string;
originalFilename: string;
mimeType: string;
sizeBytes: number;
objectKey: string;
sha256: string;
source: "user_upload" | "agent_generated";
category: "image" | "document" | "code" | "other" | null;
projectId: string | null;
createdAt: string;
updatedAt: string;
}
export interface ChatFileReference {
id: string;
fileId: string;
conversationId: string;
messageId: string | null;
createdAt: string;
}
export interface ChatFileUploadResponse {
file: ChatFile;
contentPath: string;
}
export interface ChatFileListResponse {
items: ChatFile[];
}
export interface ChatMessage {
id: string;
conversationId: string;
@ -34,6 +69,7 @@ export interface ChatMessage {
messageType: string | null;
createdAt: string;
updatedAt: string | null;
files?: ChatFile[];
}
export interface ChatConversationListResponse {

View file

@ -45,3 +45,18 @@ export const branchConversationSchema = z.object({
export type SearchMessages = z.infer<typeof searchMessagesSchema>;
export type BranchConversation = z.infer<typeof branchConversationSchema>;
export const uploadChatFileSchema = z.object({
conversationId: z.string().uuid().optional(),
messageId: z.string().uuid().optional(),
source: z.enum(["user_upload", "agent_generated"]).default("user_upload"),
projectId: z.string().uuid().optional(),
});
export const createFileReferenceSchema = z.object({
fileId: z.string().uuid(),
messageId: z.string().uuid().optional(),
});
export type UploadChatFile = z.infer<typeof uploadChatFileSchema>;
export type CreateFileReference = z.infer<typeof createFileReferenceSchema>;

View file

@ -0,0 +1,10 @@
import { describe, it } from "vitest";
describe("chatFileRoutes", () => {
it.todo("POST /conversations/:id/files uploads a file and returns 201");
it.todo("GET /conversations/:id/files lists files for conversation");
it.todo("GET /files/:fileId/content serves file content");
it.todo("POST /files/:fileId/references creates a cross-conversation reference");
it.todo("rejects upload when file exceeds size limit");
it.todo("rejects upload when content type is not allowed");
});

View file

@ -0,0 +1,9 @@
import { describe, it } from "vitest";
describe("chatFileService", () => {
it.todo("creates a file record after upload");
it.todo("lists files for a conversation");
it.todo("lists files for a message");
it.todo("creates a file reference in another conversation");
it.todo("returns file with contentPath");
});