Skip to content

docs: add implementation plan for email expiration & auto-cleanup feature#2

Merged
don4of4 merged 7 commits intomainfrom
claude/prisma-notification-migration-HQwRF
Jan 1, 2026
Merged

docs: add implementation plan for email expiration & auto-cleanup feature#2
don4of4 merged 7 commits intomainfrom
claude/prisma-notification-migration-HQwRF

Conversation

@don4of4
Copy link
Owner

@don4of4 don4of4 commented Jan 1, 2026

This plan details how to implement automatic cleanup of "aged out" emails
(notifications, newsletters, promotions) with configurable expiration periods.

Key features:

  • Per-category expiration settings (Notifications: 7d, Newsletters: 30d, etc.)
  • Daily cron job via QStash for processing
  • Archive + "Inbox Zero/Expired" label for audit trail
  • Settings UI for user configuration
  • Optional AI-based custom expiration rules
  • Integration with existing cleanup infrastructure

…ture

This plan details how to implement automatic cleanup of "aged out" emails
(notifications, newsletters, promotions) with configurable expiration periods.

Key features:
- Per-category expiration settings (Notifications: 7d, Newsletters: 30d, etc.)
- Daily cron job via QStash for processing
- Archive + "Inbox Zero/Expired" label for audit trail
- Settings UI for user configuration
- Optional AI-based custom expiration rules
- Integration with existing cleanup infrastructure
Major changes to the implementation plan:

- LLM analyzes email content to extract relevant dates
  (package delivery, events, sale end dates)
- Per-email expiresAt stored on EmailMessage model
- Two processing paths:
  1. Real-time: Hook after runRules() in webhook processing
  2. Batch backfill: Cron for emails without expiration set
- Cleanup cron finds emails past expiresAt and archives them
- Stores LLM reasoning for transparency
- Falls back to category defaults when no date found
- Hooks into existing cron pattern (/api/cron/expiration/*)

Example transformations:
- "Package arrives Nov 5" → expiresAt: Nov 12
- "Meeting tomorrow" → expiresAt: day after meeting
- "Sale ends tonight" → expiresAt: tomorrow
Key changes:
- Phase 4: Use existing /api/watch/all cron for cleanup instead of new endpoints
- Remove Phase 7: No new cron schedules needed
- Update file structure: Clarify new files vs files to modify
- Cleanup runs in existing cron, backfill uses existing bulk button
Phase 1: Schema changes
- Add expiresAt, expiredAt, expirationReason to EmailMessage
- Add EmailExpirationSettings model for user configuration
- Add ExpiredEmailLog model for audit trail
- Add composite index for expiration queries

Phase 2: Core utilities
- Add utils/expiration/categories.ts for category detection
- Add utils/expiration/process-expired.ts for cleanup logic
- Add "expired" label to inboxZeroLabels

Phase 3: Hook into existing cron
- Modify /api/watch/all to call cleanupExpiredEmails()
- Graceful error handling - cleanup failures don't break watch

Note: LLM-based expiration analysis (Phase 2 of plan) not yet implemented.
This commit provides the infrastructure for cleanup; expiration dates
need to be set by a future analyzeExpiration() implementation.
Adds the "smart" part of email expiration - LLM analyzes email content
to extract relevant dates and set context-aware expiration.

New file:
- utils/expiration/analyze-expiration.ts
  - analyzeExpirationWithLLM(): Calls LLM to extract dates from content
  - analyzeAndSetExpiration(): Main entry point that checks settings,
    detects category, runs LLM analysis, and stores result

Hooks into existing flows:
- process-history-item.ts: Runs expiration analysis in background via
  after() for new incoming emails
- bulk-process-emails.ts: Runs expiration analysis after runRules()
  for each message during bulk processing

Examples of LLM analysis:
- "Your package arrives November 5th" -> expires Nov 12 (7 days after)
- "Event tomorrow at 3pm" -> expires day after event
- "Weekly newsletter" -> expires in 30 days (default)
- Add API endpoint: /api/user/expiration-settings (GET/POST)
- Add ExpirationSection.tsx component with:
  - Master toggle to enable/disable auto-expiration
  - Option to apply "Expired" label when archiving
  - Per-category toggles and default day settings
  - AI analyzes email content for specific dates as fallback
- Integrate into Settings page under "Email Account" tab
Create migration to add:
- EmailExpirationSettings table for per-account expiration preferences
- ExpiredEmailLog table for audit logging of archived emails
- expiresAt, expiredAt, expirationReason columns to EmailMessage
- Composite index for efficient expiration queries
@don4of4 don4of4 merged commit cbe7e7b into main Jan 1, 2026
1 check passed
@don4of4 don4of4 deleted the claude/prisma-notification-migration-HQwRF branch January 1, 2026 19:58
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