Skip to content

Conversation

@ejscheepers
Copy link
Contributor

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.

@vercel
Copy link

vercel bot commented Nov 17, 2025

@ejscheepers is attempting to deploy a commit to the Dendi Team on Vercel.

A member of the Team first needs to authorize it.

@dendianugerah dendianugerah merged commit ca0576c into dendianugerah:main Nov 19, 2025
2 of 3 checks passed
@dendianugerah
Copy link
Owner

Tested and solid, thanks mann

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants