S3 lifecycle management features #64
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds advanced S3 lifecycle management features, including per-connection retention controls, automatic S3 cleanup on connection deletion/rename, and a feature for S3 retention cleanup.
Features Added
1. Per-Connection S3 Retention Cleanup Control
• Each connection now has its own s3_cleanup_on_retention setting (defaults to enabled)
• Gives users granular control over which backups are cleaned from S3 during scheduled retention cleanup
• UI toggle in backup schedule dialog (only visible when S3 is enabled)
• Dedicated API endpoint POST /api/connections/{id}/settings for updating connection settings without testing connection
Database Migration:
• apps/api/internal/database/migrations/20251114111904_add_s3_cleanup_to_connections.sql
Files Modified:
• apps/api/internal/connection/model.go - Added S3CleanupOnRetention field
• apps/api/internal/connection/connection_repository.go - Updated all queries to include new field
• apps/api/internal/connection/connection_service.go - Added UpdateConnectionSettings() method
• apps/api/internal/connection/connection.go - Added UpdateConnectionSettings HTTP handler
• apps/web/components/views/connections/connection-list/backup-schedule-dialog.tsx - Added UI toggle
• apps/web/lib/api/connections.ts - Added API client method
• apps/web/types/connection.ts - Updated TypeScript types
2. S3 Retention Cleanup
• S3 backups were never being deleted during scheduled retention cleanup
• The scheduler was only deleting local files, leaving S3 objects orphaned indefinitely
• Cleanup now properly deletes from both S3 and local storage
• Respects per-connection s3_cleanup_on_retention setting
• Added comprehensive error handling and logging for cleanup operations
• Query now includes s3_object_key to enable S3 deletion
Files Modified:
• apps/api/internal/backup/backup_scheduler.go - Completely rewrote cleanupOldBackups() method
• apps/api/internal/backup/backup_repository.go - Updated GetBackupsOlderThan() to include S3 keys
3. Automatic S3 Folder Rename on Connection Name Change
• When a connection is renamed, all associated S3 objects are automatically moved to the new folder
• Maintains consistency between connection names and S3 folder structure
• Database records are updated with new S3 object keys
• Uses copy-then-delete pattern to ensure safe S3 object moves
• Added MoveFile() method to S3 storage client
Files Modified:
• apps/api/internal/backup/s3_storage.go - Added MoveFile() method
• apps/api/internal/backup/backup_service.go - Added RenameS3FolderForConnection() method
• apps/api/internal/backup/backup_repository.go - Added UpdateBackupS3ObjectKey() method
• apps/api/internal/connection/connection.go - Trigger S3 rename on connection name change
4. S3 Cleanup on Connection Deletion
• Optional cleanup of all S3 backups when deleting a connection
• Prevents orphaned S3 objects after connection deletion
• UI switch in delete confirmation dialog allows user to choose
• Query parameter cleanup_s3=true triggers S3 cleanup before connection deletion
• Comprehensive logging of cleanup operations
Files Modified:
• apps/api/internal/backup/backup_service.go - Added CleanupS3BackupsForConnection() method
• apps/api/internal/backup/backup_repository.go - Added GetBackupsByConnectionID() method
• apps/api/internal/connection/connection.go - Updated DeleteConnection handler to check cleanup flag
• apps/api/cmd/api-server/main.go - Reordered initialization (backupService before connHandler)
• apps/web/components/views/connections/connection-list/delete-connection-dialog.tsx - Added cleanup toggle (Switch component)
• apps/web/lib/api/connections.ts - Updated delete method to accept cleanupS3 parameter
• apps/web/types/connection.ts - Updated types
Impact
The retention cleanup bug fix is critical - without it, S3 storage costs could grow indefinitely as old backups were never removed from S3, even
though they were deleted locally and from the database. This fix ensures S3 storage is properly managed according to retention policies.
User Benefits
• Cost Control: Users can now manage S3 storage costs through retention policies that actually work
• Flexibility: Per-connection S3 cleanup control allows keeping some backups in S3 long-term while cleaning others
• Data Hygiene: Automatic cleanup on connection deletion prevents orphaned S3 objects
• Consistency: Connection renames automatically keep S3 folder structure in sync
Testing Performed
✅ Retention Cleanup: Verified S3 objects older than retention period are deleted ✅ Per-Connection Control: Verified s3_cleanup_on_retention
setting is respected ✅ Connection Deletion: Verified S3 cleanup option removes all associated S3 objects ✅ Connection Rename: Verified all S3
objects are moved to new folder and database updated ✅ Error Handling: Verified operations continue gracefully when S3 operations fail
Breaking Changes
None - all new features are opt-in or have sensible defaults that maintain existing behavior.