Some checks failed
Files: MinIO-backed file sharing built into the broker. share_file for persistent mesh files, send_message(file:) for ephemeral attachments. Presigned URLs for download, access tracking per peer. Broker infra: MinIO in docker-compose, internal network. HTTP POST /upload endpoint. WS handlers for get_file, list_files, file_status, delete_file. Multi-target: send_message(to:) accepts string or array. Targets deduplicated before delivery. Targeted views: MCP instructions teach Claude to send tailored messages per audience instead of generic broadcasts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
29 lines
904 B
TypeScript
29 lines
904 B
TypeScript
/**
|
|
* MinIO client for file storage.
|
|
*
|
|
* Each mesh gets its own bucket (mesh-{meshId}). Files are stored under
|
|
* a key path that encodes persistence and origin:
|
|
* - persistent: shared/{fileId}/{originalName}
|
|
* - ephemeral: ephemeral/{YYYY-MM-DD}/{fileId}/{originalName}
|
|
*/
|
|
|
|
import { Client } from "minio";
|
|
import { env } from "./env";
|
|
|
|
export const minioClient = new Client({
|
|
endPoint: env.MINIO_ENDPOINT.split(":")[0]!,
|
|
port: parseInt(env.MINIO_ENDPOINT.split(":")[1] || "9000"),
|
|
useSSL: env.MINIO_USE_SSL,
|
|
accessKey: env.MINIO_ACCESS_KEY,
|
|
secretKey: env.MINIO_SECRET_KEY,
|
|
});
|
|
|
|
export async function ensureBucket(name: string): Promise<void> {
|
|
const exists = await minioClient.bucketExists(name);
|
|
if (!exists) await minioClient.makeBucket(name);
|
|
}
|
|
|
|
export function meshBucketName(meshId: string): string {
|
|
return `mesh-${meshId.toLowerCase().replace(/[^a-z0-9-]/g, "-")}`;
|
|
}
|