fix: revert r2 to minio for file storage#218
Conversation
WalkthroughThe codebase transitions its file storage integration from Cloudflare R2 to MinIO. All R2-related configuration, types, helpers, and service modules are removed and replaced with new MinIO equivalents. Environment variables, type definitions, and service logic are updated accordingly, including file upload and deletion flows. The Next.js image configuration is also restricted to local MinIO sources. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Frontend
participant Backend
participant MinIO
User->>Frontend: Uploads file via form (with bucket)
Frontend->>Backend: Sends FormData (file, bucket)
Backend->>MinIO: Check/Create bucket
Backend->>MinIO: Set bucket policy (public read)
Backend->>MinIO: Upload file (with metadata)
MinIO-->>Backend: Returns upload result
Backend-->>Frontend: Responds with file URL and info
Frontend-->>User: Shows uploaded file URL/info
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (5)
src/server/services/minio/index.ts (1)
1-2: Inconsistent import stylesYou're using two different import styles in these lines - absolute path with '@/' prefix for the client and relative path for the config. Consider standardizing to one approach for better maintainability.
-import { minioClient } from '@/server/services/minio/client' -import { getBucketPolicy } from './config' +import { minioClient } from './client' +import { getBucketPolicy } from './config'src/env.d.ts (1)
16-22: MinIO environment variables properly definedThe environment variables for MinIO are well-structured and complete, covering all necessary configuration options. However, consider adding documentation explaining which variables need to be public and which should be kept server-side only.
Consider adding a brief comment explaining why some variables have the NEXT_PUBLIC prefix while others don't, to guide future developers on security considerations.
src/server/actions/file/upload.ts (3)
45-47: Simplified filename generationThe filename generation for data URLs has been simplified to use only a timestamp instead of a UUID. While this works, it could potentially lead to filename collisions in high-traffic scenarios.
Consider using a more unique identifier for filename generation:
-fileName = `${Date.now()}.${extension}` +fileName = `${Date.now()}-${Math.random().toString(36).substring(2, 10)}.${extension}`
93-102: File upload with proper metadataThe MinIO upload includes content type and cache control headers, which is good for proper file serving.
Consider making the cache control duration configurable based on the bucket or file type, rather than hardcoding it to one year for all files:
-'Cache-Control': 'max-age=31536000' // Cache for 1 year +// Adjust cache time based on bucket type +'Cache-Control': bucket === 'avatars' || bucket === 'banners' + ? 'max-age=31536000' // Cache for 1 year for stable content + : 'max-age=604800' // Cache for 1 week for other content
117-122: Error handling is present but minimalThe error handling captures and returns errors appropriately, but lacks any logging which might be useful for debugging in production.
Consider adding logging for critical errors to aid in troubleshooting:
} catch (error) { + console.error('File upload error:', error); return { success: false, error: error instanceof Error ? error.message : 'An error occurred while uploading file.' } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
.env.example(0 hunks)next.config.mjs(0 hunks)package.json(1 hunks)src/env.d.ts(2 hunks)src/server/actions/file/upload.ts(2 hunks)src/server/actions/user/delete.ts(2 hunks)src/server/services/minio/client.ts(1 hunks)src/server/services/minio/config.ts(1 hunks)src/server/services/minio/index.ts(1 hunks)src/server/services/minio/types.ts(1 hunks)src/server/services/r2/client.ts(0 hunks)src/server/services/r2/config.ts(0 hunks)src/server/services/r2/helpers.ts(0 hunks)src/server/services/r2/index.ts(0 hunks)src/server/services/r2/types.ts(0 hunks)
💤 Files with no reviewable changes (7)
- .env.example
- next.config.mjs
- src/server/services/r2/types.ts
- src/server/services/r2/index.ts
- src/server/services/r2/helpers.ts
- src/server/services/r2/config.ts
- src/server/services/r2/client.ts
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/server/services/minio/client.ts (1)
src/server/services/minio/index.ts (1)
minioClient(11-11)
src/server/services/minio/config.ts (1)
src/server/services/minio/index.ts (1)
getBucketPolicy(11-11)
src/server/services/minio/index.ts (1)
src/server/services/minio/client.ts (1)
minioClient(3-9)
src/server/actions/file/upload.ts (6)
src/server/utils/types.ts (1)
ActionResponse(1-5)src/server/services/minio/types.ts (1)
MinioUploadResult(16-21)src/server/validations/file.ts (1)
FileValidation(5-21)src/server/services/minio/client.ts (1)
minioClient(3-9)src/server/services/minio/config.ts (1)
getBucketPolicy(1-12)src/server/utils/image-processor.ts (3)
compressAvatar(107-117)compressBanner(119-129)compressImage(21-104)
🔇 Additional comments (14)
package.json (1)
56-56: Dependency added for MinIO integration.The addition of the
miniopackage is consistent with the PR objective to revert from Cloudflare R2 to MinIO for file storage.src/server/services/minio/client.ts (1)
4-6: Review security implications of NEXT_PUBLIC_ prefixed environment variables.Using the
NEXT_PUBLIC_prefix exposes these environment variables to the client-side JavaScript, which could potentially expose connection details of your MinIO instance.Verify if these connection details should be exposed to client-side. Consider removing the
NEXT_PUBLIC_prefix if these are meant to be server-side only.src/server/services/minio/config.ts (1)
1-12: Bucket policy grants broad public read access.The bucket policy grants public read access to all objects within the specified bucket. While this may be necessary for publicly accessible files, it's a broad permission that should be carefully considered from a security perspective.
Consider if all files need to be publicly readable or if more restrictive policies would be appropriate for certain buckets. You might want to:
- Create different policy functions for different access levels
- Add conditional statements to restrict access to specific paths
- Add time-limited access policies for sensitive content
export const getBucketPolicy = (bucketName: string) => ({ Version: '2012-10-17', Statement: [ { Sid: 'PublicRead', Effect: 'Allow', Principal: '*', Action: ['s3:GetObject'], - Resource: [`arn:aws:s3:::${bucketName}/*`] + Resource: [`arn:aws:s3:::${bucketName}/public/*`] // Example: Only allow public access to files in a "public" prefix } ] })src/server/actions/user/delete.ts (1)
56-56: Improved error logging.The change from
console.logtoconsole.errorand the inclusion of the file URL in the error message is a good improvement for debugging.src/server/services/minio/index.ts (2)
9-11: Export type signatures look goodThe type exports and function exports are properly structured, making it easy for other modules to import these entities.
13-18: Well-organized default exportThe default export provides a clean interface for importing all Minio functionality with a single import. This pattern works well for service modules.
src/env.d.ts (1)
6-7: Comment update reflects database changeThe comment change from "Xata" to "PostgreSQL" accurately reflects the database system in use. This is a good practice for documentation.
src/server/services/minio/types.ts (3)
1-7: MinioConfig interface is well-structuredThe MinioConfig interface correctly defines all the properties needed for connecting to a MinIO server, matching the parameters used in the client configuration.
9-14: MinioUploadOptions provides flexible configurationThe upload options interface includes all necessary parameters and makes metadata and cache control optional, which is good for flexibility.
16-21: MinioUploadResult interface is completeThe result interface captures all the essential information about an uploaded file. This aligns well with what clients typically need after an upload operation.
src/server/actions/file/upload.ts (4)
3-10: Updated import and function signatureThe function signature has been properly updated to use MinIO types instead of R2 types.
13-19: Improved validation for required parametersThe validation now checks for both file and bucket presence, which is a good practice.
85-91: Image compression based on bucket nameThe code now determines the compression method based on the bucket name instead of a type parameter. This is a clear and maintainable approach.
104-106: URL generation from environment variablesThe URL generation uses the environment variable correctly to construct the complete URL to the uploaded file.
This is an automated pull request for branch fix/revert-r2-to-minio
Summary by CodeRabbit