You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit cd42d7b
Browse filesBrowse the repository at this point in the historyBrowse files
feat(reports): send each community report once, and queue the ones that can't go out
The same report kept arriving more than once. Issue #10's came through three
times minutes apart, one number arrived 12 times on 2026-08-31, and the
Worker's five-minute, address-keyed dedup catches neither. Notification
actions also threw away the submission result, so a report made offline or
while rate-limited was silently lost.
CommunityReportSubmitter now claims the report in a day-long ledger
(number + vote type, in the no-backup DataStore) before any network call. A
repeat within the day returns ALREADY_SUBMITTED without sending, across a
double tap or a process death. A report that fails for a reason waiting can
fix (offline, 429, 5xx) goes to CommunityReportWorker, a unique-work outbox
keyed by number and type with a network constraint. It's delivered once the
connection is back and given up after 12 attempts that actually ran. Every
entry point (Lookup, number detail, overlay, notification actions) goes
through it and now takes a Context.
The Worker's "Duplicate report" 429 now counts as delivered: it means an
earlier attempt was stored and only its response was lost, and resending it
after the Worker's window would store it twice. A 400 is the plausibility
gate refusing the number, so it isn't retried either. contributeSmsSpam had
no callers and would have bypassed the ledger, so it's gone.
Tests (new only): the ledger's window, keying, future stamps and cap; the
Worker answer mapping; the submitter with a real DataStore (a repeat never
reaches the transport, the record survives a process death, a correction is
a separate report, a transient failure queues once, a refused number isn't
queued); and the outbox under the WorkManager test driver (queued twice
offline, delivered once when constraints are met, plus retry and give-up
rules and SMS indicators). Bypassing the claim, skipping the enqueue or
ignoring the duplicate marker each fails them. The submitter test runs
under Robolectric because DataStore on a bare JVM reads SDK 0 and falls back
to File.renameTo, which can't replace a file on Windows.
The two new strings ship with zh-rCN translations.
Copy file name to clipboardExpand all lines: README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -546,7 +546,7 @@ by locale and message type without shipping personal data:
546
546
- Quick-access to lookup and protection status
547
547
548
548
### Community
549
-
-**One-tap anonymous contribution** via [Cloudflare Worker](https://callshield-reports.snafumatthew.workers.dev)
549
+
-**One-tap anonymous contribution** via [Cloudflare Worker](https://callshield-reports.snafumatthew.workers.dev). Each number and vote goes out at most once a day, and a report made offline is sent when the connection returns
550
550
- False positive reporting subtracts votes
551
551
- Share spam warnings to any app
552
552
@@ -811,7 +811,7 @@ language in [issue #7](https://github.com/SysAdminDoc/CallShield/issues/7).
0 commit comments