Repository navigation
v1.4.0-beta.4
Pre-release
Pre-release
·
25 commits
to main
since this release
[Unreleased]
Features
- Publish subscriptions as an iCal feed by @John710
Calendar clients can only be given a URL, so the feed carries a dedicated
token in the query string instead of an API bearer token: it is hashed at
rest, shown once, and revoked without deleting the row. The plan is a
projection of the next 180 days, never the ledger.
A token in a query string is also something a proxy logs, so the README
documents the Traefik router that turns access logging off for this path. - Recurring commitments and plan-vs-actual by @John710
The dashboard could only list rules whose stale next_date fell inside five
days, so a subscription that is actually owed showed nothing about what the
user is signed up to pay. It now carries the monthly total the active schedules
are worth and the next outstanding occurrences from the projection, and reports
gain a plan-vs-actual chart: the plan side is what the schedules ask for, the
actual side is what the ledger booked under those rules, so a payment made at a
different amount is visible as variance. - Recurring subscriptions UI with calendar and history by @John710
Expose the backend occurrence contract where users act on it: the recurring
list shows the occurrence actually owed (pay/skip targets it), a month
calendar projects occurrences across a window, and a history modal renders
the audit trail with amounts converted through the rates store.
Calendar pay/skip is click-based rather than drag-based: the API only
accepts exact scheduled occurrence dates, so dropping a payment on an
arbitrary day would be rejected. - Expose the owed occurrence the pay/skip actions target by @John710
The row buttons and run-now act on the first unpaid occurrence from the
ledger cursor, which points backwards from today for overdue rules while
next_occurrence always looks forwards.
Refactor
- Load rules and project occurrences from one place by @John710
The REST routes, the dashboard and the reports each rebuilt the same
family-sharing join, the same paid/skipped exception query and the same
flattened occurrence list, which is three chances for them to disagree about
what is owed. Move the reads into services/recurring-rules.js and the
projection into recurring-schedule.projectOccurrences().
Testing
- Match the UID the feed actually emits by @John710
The blackbox assertion assumed a compact date in the UID while both the
service and its unit test pin the dashed occurrence date, so the shape check
rejected a valid feed. It now reads the UID line it is talking about. - Cover the calendar feed end to end by @John710
The feed is the only recurring surface a browser never calls, so nothing else
proves the token round-trip, the all-day DTSTART shape or that a revoked link
stops serving. Runs inside the container against a live instance.
Full Changelog: v1.3.2...