// apps/api/src/api/v1/documents.routes.ts (partial)
.post(
"/upload",
async (c) => {
const supabase = getSupabase(c);
const { data: { user } } = await supabase.auth.getUser();
if (!user) {
throw new HTTPException(401, { message: "Unauthorized" });
}
const formData = await c.req.parseBody();
const file = formData["file"] as File;
// Validate file type
const fileExtension = file.name.split(".").pop()?.toLowerCase();
if (!fileExtension || !ALLOWED_TYPES.has(fileExtension)) {
throw new HTTPException(400, {
message: "Unsupported file type. Allowed types: PDF",
});
}
// Upload to storage
const buffer = await file.arrayBuffer();
const filePath = `${user.id}/${Date.now()}_${file.name}`;
const { data, error } = await supabase.storage
.from("documents")
.upload(filePath, buffer, {
contentType: ALLOWED_TYPES.get(fileExtension),
upsert: false,
});
// Create database record
const [document] = await db
.insert(documents)
.values({
userId: user.id,
fileUrl: signedUrl,
content: "", // Will be populated by background processing
metadata: {
originalName: file.name,
contentType: file.type,
extension: fileExtension,
uploadTimestamp: new Date().toISOString(),
size: file.size,
sizeInKb: Math.round(file.size / 1024),
// Additional metadata...
},
processingStatus: "pending",
// Additional fields...
})
.returning();
// Queue background processing
const client = new Client({ token: c.env.QSTASH_TOKEN });
await client.queue({ queueName: "document-processing" }).enqueueJSON({
url: `${c.env.API_URL}/api/v1/admin/documents/process`,
body: {
documentId: document.id,
fileType: document.fileType,
},
headers: {
Authorization: `Bearer ${c.env.ADMIN_TOKEN}`,
},
});
return c.json({
success: true,
message: "Document uploaded successfully",
data: {
// Document data...
}
}, 201);
}
)