#123 · Rollup retention + outline_url NULL semantics
Description
Context
Two related cleanup items from the onboarding feature's team-review:
A. Outline doc accumulation, no retention (security WARNING) The 02:00 ET cron creates a new Outline document every day, indefinitely. After 12 months that's ~365 docs in the Community Digest collection, all titled "Community Digest — week of …" with overlapping 7-day windows. Collection becomes unsearchable; older docs drift past mental "this week" and become a discoverability surface for old aggregated activity.
B. outline_url NOT NULL semantics conflict (architecture WARNING) apps/signal-bot/database/060_community_rollups.sql declares outline_url TEXT NOT NULL, but community-rollup.ts writes outline_url: '' for no_activity and failed paths because no doc was actually created. The getLatestCommunityRollup query filters outline_url <> '' to compensate, but semantically it should be NULL.
Acceptance criteria
For (A) — choose one of two strategies and implement:
Option 1: Update-in-place (preferred) — keep one rolling "Community Digest" doc that's overwritten daily. URL stable, search bookmarked.
- [ ] Track
community_digest_doc_idin a single-row config table OR reusedaily_community_rollupswith ais_canonicalflag - [ ] On 02:00 cron: if a canonical doc exists,
outlineClient.updateDocument(docId, newMarkdown); else create + flag canonical - [ ] Welcome flow continues to use
getLatestCommunityRollup(now always returns the same canonical URL)
Option 2: Per-day docs with monthly archival
- [ ] Keep current per-day creation
- [ ] Monthly cron (e.g., 03:00 ET on day 1): archive (Outline
documents.archive) all rollup docs older than 30 days - [ ]
daily_community_rollups.archived_atcolumn to track - [ ] Welcome flow unchanged
For (B):
- [ ] New migration
apps/signal-bot/database/061_outline_url_nullable.sql:
ALTER TABLE daily_community_rollups ALTER COLUMN outline_url DROP NOT NULL;
-- Backfill: any historical rows with empty string become NULL
UPDATE daily_community_rollups SET outline_url = NULL WHERE outline_url = '';
- [ ] Update
getLatestCommunityRollupfilter fromoutline_url <> ''tooutline_url IS NOT NULL - [ ] Update
persistRowto writenull(not'') for non-success rows
Technical hints
- Outline's
documents.updateAPI: https://www.getoutline.com/developers#tag/documents/POST/documents.update - Option 1 (update-in-place) is cheaper, avoids the doc-glut problem entirely, and keeps the welcome URL stable forever — recommended unless there's a specific reason to keep weekly snapshots
- If you go Option 2, also add an admin command to manually archive an old rollup doc
--- *M-tier (100 pts + 40 merge_pr = 140). Combined cleanup; covers schema fix + retention. Half-day of work.*
Relevant files
No relevant files linked yet.
Hints
No hints yet.
Activity
No points have been awarded for this bounty yet.
Comments
Sign in to join the discussion.
No comments yet. Be the first to weigh in.