6.8 KiB
6.8 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.2.0] - 2026.09.05
Added
notifyHourUtc(0-23) andnotifyMinuteUtc(0-59) are required on an alert-authorization batch, both integers and both UTC — the field names carry the frame, so no offset or zone travels with them. Stored zero-padded as oneHH:MMvalue innotify_hour_min_utc. Required rather than optional because the alternative default is not "no gate" but "the first tick after midnight UTC", which puts every user in one five-minute window. The scheduler holds a user's whole daily run, search included, until that instant, and reports the held users asdeferred. A stored UTC time does not follow the user through a daylight-saving change; a fresh batch carrying the new offset corrects it- Both alertSearch schedulers pick their users with one query per pass (
listPendingForDay) instead of one per user: it returns everyone holding an unused JWT for the current UTC day, flagged by whether theirnotify_hour_min_utchas arrived. A user who has already run that day no longer appears, so an idle tick over 2000 users costs 0 queries and ~1ms, down from 3 queries per user and ~141ms - Both passes work on
ALERT_SEARCH_USER_CONCURRENCYusers at a time (src/util/concurrency.ts, default 8) instead of serially; at 50ms of API latency a 2000-user pass drops from ~106s to ~13s, which is what keeps it inside its own tick - The notify hour and
timezoneare accepted onPUT /notifications/alert-authorizationas well, and the push scheduler honours the stored hour - Optional
timezone(IANA name) on an alert-authorization batch, validated and stored besidenotify_hour_min_utcand read by nothing. It is recorded for a future mechanism that would re-derive the UTC time across a DST change; the column carries that reason as a SQL comment DELETE /notifications/alert-authorizationandDELETE /notify-sms/alert-authorizationremove every batch and JWT a DID holds in that channel, so a user can turn alerts off; verified phone numbers and alertSearch cursors survive, and the SMS revocation is logged asalert-authorization-deletedunder therevoke-alert-searchaction claim/notify-smsSMS channel: phone registration with a 6-digit possession check, a per-channel delegated-JWT inventory and cursor, a Twilio sender, anSTOP/START/HELPwebhook, and a daily digest text alongside the FCM one; off unlessSMS_ENABLED- Blocks record their origin (
opt-out/provider-opt-out/manual) and are never downgraded; a Twilio21610refusal auto-blocks asprovider-opt-out, andpnpm run sms:blockslists and manages the list by origin sms_blocked_numberssuppression list:STOPnow blocks durably instead of only unverifying,STARTlifts the block, and a blocked number is refused at registration and verification and skipped by the digest;SMS_BLOCKED_NUMBERSblocks by configurationSMS_ALLOWED_RECIPIENT_DIDSrestricts which DIDs an instance may text, guarding both the verification code and the daily digest, so a test server with live Twilio credentials cannot message a restored production database- Every log line is prefixed with an ISO-8601 UTC timestamp (
src/util/log.ts) pnpm run sms:sendandpnpm run sms:smokeexercise the Twilio path and the full/notify-smsroute flow against a stub Endorser and unsigned test-local JWTspnpm run twilio:whoamireports which Twilio account a send would bill and distinguishes a mismatched credential pair from a valid test pair
Changed
- Alert-authorization batches no longer schedule from a
timezone. Days are UTC days: each delegated JWT must be valid for the whole UTC day it names (nbfat or before its midnight,expat or after the next), the daily run selects by UTC day and reports it asutcDay, andnotifyTimesupplies its own offset. RemovesInvalidAlertAuthorizationTimezoneError loadAlertSearchCursors,advanceAlertSearchCursors,runAlertSearchCycle, andrunDailyAlertSearchtake a channel ("fcm"default), selecting the JWT inventory and cursor table
[0.1.14] - 2026.09.01
Changed
- Production runbook: Docker/
node dist/index.jsis the canonical deploy path; document durable SQLite, single replica, Firebase credential options, and smoke checks
[0.1.13] - 2026.08.31
Added
- AlertSearch scheduler delivers a TimeSafari FCM digest (
type: alert_search) when a completed run consumed today's JWT anddigest.hasUpdatesis true; WAKEUP_PING and JWT/cursor rules are unchanged
[0.1.12] - 2026.08.31
Added
runDailyAlertSearchincludes a Phase 6Adigeston retrieval attempts (nullwhen no batch or today's JWT is missing); JWT consumption is still based on both sources completing, nothasUpdates
[0.1.11] - 2026.08.28
Added
buildAlertSearchDigestturns a completed Endorser+Partner alertSearch retrieve into structured per-bucket records and counts for a future app/plugin payload (no notification message or FCM send)
[0.1.10] - 2026.08.28
Added
- Dedicated user-level alertSearch scheduler (
startAlertSearchScheduler) that callsrunDailyAlertSearchonce per authorization-batch user, with a process-local in-flight guard; independent of FCMWAKEUP_PING
[0.1.9] - 2026.08.28
Added
runDailyAlertSearchselects today's unused delegated JWT from the stored batch timezone, runsrunAlertSearchCycle, and consumes that JWT only when both Endorser and Partner complete (successorempty)
[0.1.8] - 2026.08.27
Added
runAlertSearchCycleintegration of cursor load, alertSearch retrieve, and independent cursor advance
Changed
- Partner pages of 50 profiles that share the oldest
updatedAtare classified incomplete so the cursor cannot skip tied rows
[0.1.7] - 2026.08.27
Added
- Persistent per-user Endorser and Partner alertSearch cursors (advanced only after complete retrievals)
[0.1.6] - 2026.08.27
Added
- AlertSearch retrieval layer for Endorser and Partner GET endpoints (pagination, independent cursors; not scheduled yet)
Changed
- Endorser in-run beforeId is MAX of per-bucket minima; plansNearby hitting the row limit is classified incomplete
[0.1.5] - 2026.08.26
Added
PUT /notifications/alert-authorizationstores a 100-JWT delegated alert-authorization batch per user (SQLite), authenticated with the current user JWT
[0.1.4] - 2026.08.07
Changed
- Renamed
FCM_TOKEN_DATA_DIRenv var toNOTIFY_DATA_DIR
[0.1.3] - 2026.07.30
Changed
- Persistence changed from file to SQLite
[0.1.2] - 2026.07.16
Added
- Validation via Endorser service, with new ENDORSER_URL variable
[0.1.1] - 2026.06.28
Added
- Base functionality