- Next.js 15 + Tailwind v4 + shadcn/ui + TanStack Table - Prisma + PostgreSQL schema for ResponseCard, ProcessingJob, AppSettings - Ollama vision integration with structured extraction prompts - PDF-to-image pipeline with pdf2pic + sharp - MinIO S3 storage for uploaded files and extracted images - Chokidar-based folder monitoring for automatic processing - REST API (9 endpoints) ready for Monday.com integration - Dashboard with filterable data table, chip filters, bulk actions, CSV export - Card detail page with editable fields and side-by-side scanned images - Upload page with drag-and-drop and real-time processing queue - Settings page for Ollama, folder watch, and Monday.com config - Dockerfile (multi-stage) + docker-compose for local dev - Configured for Coolify deployment at echo.stillwell.cloud Made-with: Cursor
46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
import { S3Client, PutObjectCommand, GetObjectCommand, DeleteObjectCommand } from "@aws-sdk/client-s3";
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
|
|
const MINIO_ENDPOINT = process.env.MINIO_ENDPOINT || "192.168.68.105";
|
|
const MINIO_PORT = parseInt(process.env.MINIO_PORT || "9000");
|
|
const MINIO_ACCESS_KEY = process.env.MINIO_ACCESS_KEY || "minioadmin";
|
|
const MINIO_SECRET_KEY = process.env.MINIO_SECRET_KEY || "";
|
|
const MINIO_BUCKET = process.env.MINIO_BUCKET || "echos-ocr";
|
|
|
|
export const s3 = new S3Client({
|
|
endpoint: `http://${MINIO_ENDPOINT}:${MINIO_PORT}`,
|
|
region: "us-east-1",
|
|
credentials: {
|
|
accessKeyId: MINIO_ACCESS_KEY,
|
|
secretAccessKey: MINIO_SECRET_KEY,
|
|
},
|
|
forcePathStyle: true,
|
|
});
|
|
|
|
export const BUCKET = MINIO_BUCKET;
|
|
|
|
export async function uploadBuffer(key: string, buffer: Buffer, contentType: string): Promise<string> {
|
|
await s3.send(
|
|
new PutObjectCommand({
|
|
Bucket: BUCKET,
|
|
Key: key,
|
|
Body: buffer,
|
|
ContentType: contentType,
|
|
})
|
|
);
|
|
return key;
|
|
}
|
|
|
|
export async function getPresignedUrl(key: string, expiresIn = 3600): Promise<string> {
|
|
return getSignedUrl(
|
|
s3,
|
|
new GetObjectCommand({ Bucket: BUCKET, Key: key }),
|
|
{ expiresIn }
|
|
);
|
|
}
|
|
|
|
export async function deleteObject(key: string): Promise<void> {
|
|
await s3.send(
|
|
new DeleteObjectCommand({ Bucket: BUCKET, Key: key })
|
|
);
|
|
}
|