Burn after N reads #49
Notifications
Total Time Spent: 6 seconds
poslop
6 seconds
No due date set.
Dependencies
No dependencies set.
Reference: poslop/palette#49
Reference in New Issue
Block a user
Extend burn-after-read: currently it burns after the first read. Add an option for the paste to be readable N times before burning. UI: when burn-after-read is checked, show a number input for read count (default 1). Backend: add a read_count column (or reads_remaining), decrement on each view, hard-delete or soft-delete when it hits zero. Views counting and burn decrement must not double-count refreshes within the same session (decide: decrement per unique viewer/session cookie or per view; document the choice). API: accept burn_after_reads (int) alongside burn_after_read. Show remaining reads in the paste view stats pill.
DECISION (2026-09-08): a read is counted per unique viewer session. Implementation: an anonymous viewer cookie (random id, set on first paste view if absent) identifies the browser. The paste records which viewer ids have already counted against its read budget. Same viewer returning within 15 minutes does NOT decrement again; a view from the same viewer after 15 minutes of last viewing DOES count as a new read. So the N-read budget means N distinct viewing sessions. Note the tension: viewers who block cookies will re-count every visit - acceptable tradeoff, document it in the stats pill tooltip or README. The 15-minute window should ideally be configurable later via the admin endpoint (#40).
Implemented in
d5a47b1. Reads counted per unique viewer session per the decision comment: reads_limit/reads_used columns (guarded ALTER TABLE) + paste_views (paste_id, viewer_id, last_viewed). Same viewer within 15 min does not decrement; after 15 min it counts again (injectable clock in tests). /raw counts as a read too (documented in code + docs/API.md); view_count independent. API: burn_after_reads (default 1). Stats pill shows 'Reads left: N of M' when a limit is set. Tests: distinct viewers, dedupe window, window expiry, default-1, page-view counting — all pass.