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:
Alejandro Gutiérrez
2026-04-04 21:19:32 +01:00
commit d3163a5bff
1384 changed files with 314925 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
import { handle } from "@turbostarter/api/utils";
import { logger } from "@turbostarter/shared/logger";
import { api } from "~/lib/api/client";
import type { SyntheticEvent } from "react";
export function onPromise<T>(promise: (event: SyntheticEvent) => Promise<T>) {
return (event: SyntheticEvent) => {
promise(event).catch((error) => {
logger.error("Unexpected error", error);
});
};
}
interface UploadParams {
path: string;
file: File;
maxRetries?: number;
}
/**
* Uploads a file to storage with retry logic
*/
export async function uploadWithRetry({
path,
file,
maxRetries = 3,
}: UploadParams): Promise<{ path: string }> {
let lastError: Error | null = null;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const { url: uploadUrl } = await handle(api.storage.upload.$get)({
query: { path },
});
const response = await fetch(uploadUrl, {
method: "PUT",
body: file,
headers: {
"Content-Type": file.type,
},
});
if (!response.ok) {
throw new Error(`Upload failed with status ${response.status}`);
}
return { path };
} catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
logger.warn(
`Upload attempt ${attempt + 1}/${maxRetries} failed:`,
lastError.message,
);
if (attempt < maxRetries - 1) {
// Exponential backoff: 1s, 2s, 4s
await new Promise((resolve) =>
setTimeout(resolve, Math.pow(2, attempt) * 1000),
);
}
}
}
throw lastError ?? new Error("Upload failed after all retries");
}