feat(db): mesh data model — meshes, members, invites, audit log
- 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>
This commit is contained in:
44
apps/web/src/modules/pdf/upload/hooks/use-upload.tsx
Normal file
44
apps/web/src/modules/pdf/upload/hooks/use-upload.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
|
||||
import { handle } from "@turbostarter/api/utils";
|
||||
import { useTranslation } from "@turbostarter/i18n";
|
||||
import { generateId } from "@turbostarter/shared/utils";
|
||||
|
||||
import { api } from "~/lib/api/client";
|
||||
import { authClient } from "~/lib/auth/client";
|
||||
import { readFile } from "~/modules/pdf/upload/utils";
|
||||
|
||||
import type { FileInput } from "~/modules/pdf/upload/utils";
|
||||
|
||||
export const useUpload = () => {
|
||||
const { t } = useTranslation("ai");
|
||||
const { data: session } = authClient.useSession();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (data: { file: FileInput }) => {
|
||||
if (!session?.user.id) {
|
||||
throw new Error(t("pdf.upload.error.unauthorized"));
|
||||
}
|
||||
|
||||
const path = `documents/${session.user.id}/${generateId()}.pdf`;
|
||||
|
||||
const { url: uploadUrl } = await handle(api.storage.upload.$get)({
|
||||
query: { path },
|
||||
});
|
||||
|
||||
const response = await fetch(uploadUrl, {
|
||||
method: "PUT",
|
||||
body: await readFile(data.file),
|
||||
headers: {
|
||||
"Content-Type": "application/pdf",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(t("pdf.upload.error.api"));
|
||||
}
|
||||
|
||||
return { path };
|
||||
},
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user