- Fix add()'s upsert SQL (was invalid SQL from typos) and use it for
the new merge() as well.
- Fix remove()'s missing FROM keyword and drop the unindexed LIKE scan
in favor of an exact match.
- Add latestDate(), all() with optional sinceDays filtering, and
prune() with a retention-day cutoff.
- Add Contribution (immutable value object) and ContributionCollection
(IteratorAggregate + Countable) so all() returns something typed
instead of a raw date => count array.
- Cover all of the above with unit tests against an in-memory SQLite
database.