feat: add a subscription clock offset to dev settings - #798
Conversation
Dev Settings > PAYKIT > Demo clock offset (days) moves Paykit subscription scheduling forward so a recorded demo can show a renewal without waiting a billing period. It covers proposal anchors and expiry, acceptance, due periods, renewal dates and due notifications. One-time requests, invoices, payments and allowance checks keep real time. Off by default and ignored outside Debug.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Pushed ab595f9: merged master, renamed the demo clock to the subscription clock offset, and addressed the review findings from the Android twin (synonymdev/bitkit-android#1341) that apply here.
Unit tests: the simulator build for testing succeeds on this head; the tests have not run on it yet because no simulator host with free space was available. The earlier head passed 193 tests across the subscription suites. The recording follows once a host is available. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ab595f9a62
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
Pushed 6657bb0 for the Codex and Greptile findings; all five threads are replied to and resolved.
Unit tests on this head: 202 passed across |
|
Pushed 9f38bf1: a test for the catch-up alerts across subscriptions, plus the recording and screenshots in the description.
|
jvsena42
left a comment
There was a problem hiding this comment.
One LOW inline (debug only). No HIGH/MEDIUM.
I checked every lead from the Android twin, synonymdev/bitkit-android#1341:
- Acceptance is stored on real time (
PaykitPaymentRequestService.swift:1672), and the restored fallback is real (:2024). - Published
startsAt/anchorand proposal expiry stay on real time. - Notification fire dates are
startsAt - offset, replaced in place under stable identifiers, so a change or reset produces no duplicates. - Catch-up is limited to
(previousNow, now], one per subscription before the cap, and keeps the final period pastendsAt. - A superseded sync does not consume the jump.
- Periods paid under the offset appear in history.
No double pay. Ids derive from billingPeriod.startsAt, and recurringPending excludes proof-submitted, completed and in-flight ids. Recurring requests have no expiresAt, so the real-clock expiry check cannot block an offset-due period. Gating holds: SubscriptionClock.isAvailable = Env.isDebug, so a stored offset is ignored in TestFlight/App Store builds even with dev settings unlocked.
Device gate: n/a — dev-settings-only change with no journey files.
…nder the clock offset
|
Pushed 04258ea for @jvsena42's review: the subscription review sheet now passes the real time as acceptedAt for its period preview and its timer, so under an offset it names the period that accepting pays (a monthly proposal starting Jan 2 with offset 31 shows "ends Feb 2", not "Mar 2"). The thread is resolved. Unit tests on this head: 204 passed across the subscription suites, including the new review-period test. |
jvsena42
left a comment
There was a problem hiding this comment.
Delta since 9f38bf176 (04258ea): no findings. The review-sheet LOW is fixed.
paymentDueOnAcceptance(at:acceptedAt:)now usesperiods(through: shifted, acceptedAt: real), which matchesaccept(real acceptance atPaykitPaymentRequestService.swift:1672, earliest pending period). This covers the swipe title, the "first period ends" label and the transition date.- The new test covers it.
- With the offset Off,
acceptedAtdefaults todate, so behaviour is unchanged.
The Android twin synonymdev/bitkit-android#1341 has the same fix.
Device gate: n/a — dev-settings-only change with no journey files.
jvsena42
left a comment
There was a problem hiding this comment.
Approved!
OBS: Could have some permanent AI instructions to improve discoverability by AI
Twin: synonymdev/bitkit-android#1341
Description
Out of Scope
Design
N/A — no design available.
Preview
subscription-clock-renewal.mp4
QA Notes
Journeys
temporarysecond-billing-period.xml— with a 31-day offset the next period comes due as a Payment Request and the subscription detail lists two paymentssecond-billing-period.xml
Manual Tests
N/A
Automated Checks
SubscriptionClockTests.swift— presets, clamping and the offset applied to subscription datesPaykitPaymentRequestServiceTests.swift— the offset makes the next billing period due, accepting with the offset on keeps the first period due, proposals keep real-time start dates, and due notifications are rescheduled, raised once per subscription, served for every subscription and kept within the cap when the offset changesSubscriptionClockTests,PaykitPaymentRequestServiceTests,PaykitSubscriptionProposalTests,PaykitPaymentRequestPollingScheduleTestsandPaykitPaymentProofServiceTestson the current head: 203 tests passed