- Add MinIO service to compose.yaml with named volume - Add generic /api/uploads POST+GET route with auth, 5 MB, image/* guards - Add src/lib/minio.ts singleton client with ensureBucket helper - Add garden Drizzle schema: containers, plants, care_logs, care_schedules, species_cache - Register garden module in src/modules/index.ts and src/lib/db.ts - Apply migration 0015_garden_schema.sql - Add MINIO_* and PERENUAL_API_KEY to .env.example - Add task briefs 70-75 for the full garden feature arc - Add uploads.spec.ts E2E test (RED → GREEN on route auth guard)
30 lines
827 B
TypeScript
30 lines
827 B
TypeScript
import { Client } from "minio";
|
|
|
|
const rawEndpoint = process.env.MINIO_ENDPOINT ?? "http://localhost:9000";
|
|
const endpointUrl = new URL(rawEndpoint);
|
|
|
|
export const minioClient = new Client({
|
|
endPoint: endpointUrl.hostname,
|
|
port: endpointUrl.port
|
|
? parseInt(endpointUrl.port)
|
|
: endpointUrl.protocol === "https:"
|
|
? 443
|
|
: 80,
|
|
useSSL: endpointUrl.protocol === "https:",
|
|
accessKey: process.env.MINIO_ROOT_USER ?? "",
|
|
secretKey: process.env.MINIO_ROOT_PASSWORD ?? "",
|
|
});
|
|
|
|
export const MINIO_BUCKET = process.env.MINIO_BUCKET ?? "garden";
|
|
|
|
let bucketReady = false;
|
|
|
|
export async function ensureBucket(): Promise<void> {
|
|
if (bucketReady) return;
|
|
const exists = await minioClient.bucketExists(MINIO_BUCKET);
|
|
if (!exists) {
|
|
await minioClient.makeBucket(MINIO_BUCKET);
|
|
}
|
|
bucketReady = true;
|
|
}
|