feat(retention): add message retention scheduling (Task 2.6)

- Add daily retention job that deletes old channel messages, DMs, and
  advertisements based on configurable age threshold
- Add GET/POST /api/retention-settings endpoints
- Extend cleanup_old_messages() to optionally include DMs and adverts
- Wire up APScheduler in create_app() (also enables existing archiving
  and contact cleanup schedulers that were never started in v2)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-03-01 17:28:54 +01:00
parent d89e276054
commit b034a181ce
5 changed files with 230 additions and 5 deletions
+19 -3
View File
@@ -515,14 +515,30 @@ class Database:
stats['db_size_bytes'] = self.db_path.stat().st_size if self.db_path.exists() else 0
return stats
def cleanup_old_messages(self, days: int) -> int:
"""Delete channel messages older than N days. Returns count deleted."""
def cleanup_old_messages(self, days: int, include_dms: bool = False,
include_adverts: bool = False) -> dict:
"""Delete messages older than N days. Returns counts per table."""
cutoff = int((datetime.now() - timedelta(days=days)).timestamp())
result = {}
with self._connect() as conn:
cursor = conn.execute(
"DELETE FROM channel_messages WHERE timestamp < ?", (cutoff,)
)
return cursor.rowcount
result['channel_messages'] = cursor.rowcount
if include_dms:
cursor = conn.execute(
"DELETE FROM direct_messages WHERE timestamp < ?", (cutoff,)
)
result['direct_messages'] = cursor.rowcount
if include_adverts:
cursor = conn.execute(
"DELETE FROM advertisements WHERE timestamp < ?", (cutoff,)
)
result['advertisements'] = cursor.rowcount
return result
# ================================================================
# Backup