+
handleUpload(e.target.files[0])} />
+ {uploading &&
}
+
+ );
+}
+```
+
+## Common Patterns
+
+### User Avatar Upload
+
+```typescript
+async function uploadAvatar(userId: string, imageFile: Buffer) {
+ // Upload original
+ const path = `avatars/${userId}/original.jpg`;
+ await storage.upload({
+ path,
+ data: imageFile,
+ contentType: 'image/jpeg',
+ });
+
+ // Generate thumbnail
+ const thumbnail = await resizeImage(imageFile, { width: 128, height: 128 });
+ await storage.upload({
+ path: `avatars/${userId}/thumbnail.jpg`,
+ data: thumbnail,
+ contentType: 'image/jpeg',
+ });
+
+ return {
+ original: storage.getUrl(path),
+ thumbnail: storage.getUrl(`avatars/${userId}/thumbnail.jpg`),
+ };
+}
+```
+
+### Document Management
+
+```typescript
+async function uploadDocument(doc: {
+ recordId: string;
+ file: Buffer;
+ fileName: string;
+ uploadedBy: string;
+}) {
+ const path = `documents/${doc.recordId}/${Date.now()}-${doc.fileName}`;
+
+ await storage.upload({
+ path,
+ data: doc.file,
+ contentType: getMimeType(doc.fileName),
+ metadata: {
+ recordId: doc.recordId,
+ uploadedBy: doc.uploadedBy,
+ fileName: doc.fileName,
+ },
+ });
+
+ // Create signed URL for secure download
+ const downloadUrl = await storage.getSignedUrl(path, { expiresIn: 86400 }); // 24 hours
+
+ return { path, downloadUrl };
+}
+```
+
+## Best Practices
+
+1. **Path Organization**: Use hierarchical paths (e.g., `object/recordId/filename`)
+2. **Content Types**: Always specify correct `contentType`
+3. **Security**: Use signed URLs for private files
+4. **Cleanup**: Delete files when records are deleted
+5. **Validation**: Validate file types and sizes before upload
+6. **Metadata**: Store useful metadata with files
+7. **Backups**: Implement backup strategy for S3 buckets
+
+## Performance Considerations
+
+- **Streaming**: Use streams for large files to reduce memory usage
+- **CDN**: Put CloudFront or similar CDN in front of S3
+- **Compression**: Compress files before upload when appropriate
+- **Caching**: Cache file URLs and metadata
+- **Multipart**: Use multipart upload for files > 5MB
+
+## Contract Implementation
+
+Implements `IStorageService` from `@objectstack/spec/contracts`:
+
+```typescript
+interface IStorageService {
+ upload(options: UploadOptions): Promise