Implements cloud-based file storage for plant photos, documents, and certificates: Storage Layer: - Multi-provider support (AWS S3, Cloudflare R2, MinIO, local filesystem) - S3-compatible provider with presigned URL generation - Local storage provider for development with signed URL verification - Configurable via environment variables Image Processing: - Automatic thumbnail generation (150x150, 300x300, 600x600, 1200x1200) - WebP conversion for optimized file sizes - EXIF data extraction for image metadata - Image optimization with Sharp API Endpoints: - POST /api/upload/image - Upload images with automatic processing - POST /api/upload/document - Upload documents (PDF, DOC, DOCX) - POST /api/upload/presigned - Get presigned URLs for direct uploads - GET/DELETE /api/upload/[fileId] - File management UI Components: - ImageUploader - Drag & drop image upload with preview - PhotoGallery - Grid gallery with lightbox view - DocumentUploader - Document upload with file type icons - ProgressBar - Animated upload progress indicator Database: - FileStore service with in-memory storage (Prisma schema ready for Agent 2) - File metadata tracking with soft delete support - Category-based file organization
87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
/**
|
|
* Storage Configuration for LocalGreenChain
|
|
* Agent 3: File Upload & Storage System
|
|
*
|
|
* Supports multiple storage providers: AWS S3, Cloudflare R2, MinIO, or local filesystem
|
|
*/
|
|
|
|
import { StorageConfig, StorageProvider } from './types';
|
|
|
|
function getStorageProvider(): StorageProvider {
|
|
const provider = process.env.STORAGE_PROVIDER as StorageProvider;
|
|
if (provider && ['s3', 'r2', 'minio', 'local'].includes(provider)) {
|
|
return provider;
|
|
}
|
|
return 'local'; // Default to local storage for development
|
|
}
|
|
|
|
export function getStorageConfig(): StorageConfig {
|
|
const provider = getStorageProvider();
|
|
|
|
const baseConfig: StorageConfig = {
|
|
provider,
|
|
bucket: process.env.STORAGE_BUCKET || 'localgreenchain',
|
|
region: process.env.STORAGE_REGION || 'us-east-1',
|
|
accessKeyId: process.env.STORAGE_ACCESS_KEY_ID,
|
|
secretAccessKey: process.env.STORAGE_SECRET_ACCESS_KEY,
|
|
publicUrl: process.env.STORAGE_PUBLIC_URL,
|
|
};
|
|
|
|
switch (provider) {
|
|
case 's3':
|
|
return {
|
|
...baseConfig,
|
|
endpoint: process.env.AWS_S3_ENDPOINT,
|
|
};
|
|
|
|
case 'r2':
|
|
return {
|
|
...baseConfig,
|
|
endpoint: process.env.CLOUDFLARE_R2_ENDPOINT ||
|
|
`https://${process.env.CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
|
region: 'auto',
|
|
};
|
|
|
|
case 'minio':
|
|
return {
|
|
...baseConfig,
|
|
endpoint: process.env.MINIO_ENDPOINT || 'http://localhost:9000',
|
|
region: 'us-east-1',
|
|
};
|
|
|
|
case 'local':
|
|
default:
|
|
return {
|
|
...baseConfig,
|
|
localPath: process.env.LOCAL_STORAGE_PATH || './uploads',
|
|
publicUrl: process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3001',
|
|
};
|
|
}
|
|
}
|
|
|
|
export const storageConfig = getStorageConfig();
|
|
|
|
/**
|
|
* Environment variable template for storage configuration:
|
|
*
|
|
* # Storage Provider (s3, r2, minio, local)
|
|
* STORAGE_PROVIDER=local
|
|
* STORAGE_BUCKET=localgreenchain
|
|
* STORAGE_REGION=us-east-1
|
|
* STORAGE_ACCESS_KEY_ID=your-access-key
|
|
* STORAGE_SECRET_ACCESS_KEY=your-secret-key
|
|
* STORAGE_PUBLIC_URL=https://cdn.yourdomain.com
|
|
*
|
|
* # For AWS S3
|
|
* AWS_S3_ENDPOINT=https://s3.amazonaws.com
|
|
*
|
|
* # For Cloudflare R2
|
|
* CLOUDFLARE_ACCOUNT_ID=your-account-id
|
|
* CLOUDFLARE_R2_ENDPOINT=https://your-account.r2.cloudflarestorage.com
|
|
*
|
|
* # For MinIO
|
|
* MINIO_ENDPOINT=http://localhost:9000
|
|
*
|
|
* # For Local Storage
|
|
* LOCAL_STORAGE_PATH=./uploads
|
|
*/
|