Skip to content

feat: add data retention with auto-delete, pin exemption, and warning emails#109

Merged
alexneamtu merged 13 commits intomainfrom
feat/data-retention
Mar 5, 2026
Merged

feat: add data retention with auto-delete, pin exemption, and warning emails#109
alexneamtu merged 13 commits intomainfrom
feat/data-retention

Conversation

@alexneamtu
Copy link
Contributor

@alexneamtu alexneamtu commented Mar 5, 2026

Summary

  • Configurable retention: Org-level and per-user auto-delete after 30/60/90/180/365 days (0 = disabled)
  • Pin exemption: Videos can be pinned to protect them from auto-deletion (toggle on VideoDetail, indicator on Library)
  • Warning emails: 7-day Listmonk email notification before deletion
  • Daily worker: Background worker with two passes — warn expiring videos, then soft-delete after grace period
  • Playlist cleanup: Removes videos from playlists on retention delete

Changes

Backend

  • Migration 000051: retention_days on users/organizations, pinned + retention_warned_at on videos
  • PUT /api/videos/{id}/pin — toggle pin status
  • retentionDays added to user profile, org settings, and limits API
  • SendRetentionWarning email method (bypasses allowlist)
  • StartRetentionWorker — daily ticker, processes warnings then deletions in batches of 100
  • LISTMONK_RETENTION_WARNING_TEMPLATE_ID env var

Frontend

  • Data Retention dropdown in personal Settings and Workspace Settings
  • Pin/Unpin button on VideoDetail with filled/outline icon and "Pinned" badge
  • Pin indicator overlay on Library video cards

Docs

  • OpenAPI spec updated with pin endpoint, retention fields, org endpoints

Test plan

  • All Go tests pass (20 packages)
  • All 685 frontend tests pass (37 files)
  • Set retention to 30 days on personal settings, verify limits API returns retentionDays: 30
  • Set retention on workspace settings, verify org response includes retentionDays
  • Pin a video, verify pin icon fills and "Pinned" badge appears
  • Verify pinned videos show pin indicator on Library page
  • Verify retention worker logs on startup

- Add RetentionDays field to userResponse and updateUserRequest
- Include retention_days in GetUser SELECT query
- Add validation (0, 30, 60, 90, 180, 365) in UpdateUser handler
- Add 2 tests for valid and invalid retention_days updates
- Add RetentionDays field to orgListItem, orgDetailResponse, updateOrgRequest
- Include retention_days in List, Get, and Update SELECT queries
- Add validation (0, 30, 60, 90, 180, 365) and dynamic SET clause in Update
- Add 2 tests for valid and invalid retention_days updates
Resolve effective retention for current context: org retention_days
for workspace videos, user retention_days for personal videos.
Listmonk transactional email for 7-day retention warning.
Bypasses allowlist. Template ID via LISTMONK_RETENTION_WARNING_TEMPLATE_ID.
Daily ticker warns users 7 days before deletion, then soft-deletes
videos after grace period. Cleans up playlist_videos on delete.
…e Settings

Select from Off/30/60/90/180/365 days. Personal and workspace scopes.
Pinned videos excluded (noted in description).
…ibrary

Pin/Unpin button in video actions bar with filled/outline icon.
Pinned badge in metadata. Pin indicator overlay on library video cards.
Add PUT /videos/{id}/pin, retentionDays to user/org/limits responses,
pinned + retentionWarnedAt to video schema, org endpoints with retention.
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

Preview deployed: https://pr-109.app.sendrec.eu

Use flexbox on video cards so the Copy link footer aligns at the
bottom regardless of metadata height. Add Pin/Unpin option to the
three-dot menu on library video cards.
Without this, the Library page couldn't show pin indicators and
VideoDetail lost pinned state on refresh.
@alexneamtu alexneamtu merged commit 3d37c03 into main Mar 5, 2026
4 checks passed
@alexneamtu alexneamtu deleted the feat/data-retention branch March 5, 2026 09:34
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

Preview environment cleaned up.

@alexneamtu alexneamtu self-assigned this Mar 6, 2026
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.

1 participant