Web Push notifications foundation (CIRCLE-38)#107
Draft
HamptonMakes wants to merge 1 commit intomainfrom
Draft
Conversation
Sets up the plumbing for browser-based push notifications without yet delivering any. Subsequent work hooks comment-reply/mention events into this pipeline. Engine - coplan_web_push_subscriptions table + model with per-device records (endpoint digest, keys, UA, last_seen_at, last_delivered_at, counter). - Idempotent upsert_for tolerant of concurrent insert races; atomic increment for delivery counters. - Service worker served from /coplan_service_worker.js (engine-scoped, no auth, no-cache, rendered inline so reverse proxies don't intercept). - Push handler shows notifications and routes notification clicks to a matching same-origin tab (preserves URL hash for anchor deep links). - POST/DELETE /web_push/subscription endpoints, scoped to current_user. - Shared coplan/web_push ES module (subscribe/unsubscribe/isSupported). - Settings card to enable/disable per-device + list of known devices with friendly labels (Chrome on macOS, Safari on iOS, etc.). - VAPID public key + service worker URL exposed via meta tags only when configured. Configuration gains vapid_public_key/vapid_private_key/ vapid_subject and web_push_configured?. - web-push gem dependency + bundle exec rake coplan:web_push:generate_keys. Host - Dev VAPID key pair wired into config/initializers/coplan.rb via ENV fallbacks so local Settings UI is testable out-of-the-box. Generated with Amp Amp-Thread-ID: https://ampcode.com/threads/T-019df459-b110-726a-97e2-ff15e2903435 Co-authored-by: Amp <amp@ampcode.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Foundation for in-browser push notifications. No notifications are delivered yet — that lands in follow-up work hooked into comment-reply / mention events.
Linear: CIRCLE-38
What's here
Per-device subscription storage
coplan_web_push_subscriptionstable (FK tocoplan_users) andCoPlan::WebPushSubscriptionmodel.upsert_foris idempotent and rescuesRecordNotUniquefor concurrent inserts;record_delivery!uses an atomicincrement!so concurrent deliveries can't lose updates.device_labelreturns friendly strings like "Chrome on macOS" / "Safari on iOS".Service worker
/coplan_service_worker.js(engine-mounted route), no auth,Cache-Control: no-cache. Rendered inline so reverse proxies that interceptX-Sendfilewon't try to reach into the gem on disk.Subscription endpoints
POST /web_push/subscription— upserts the browser subscription forcurrent_user.DELETE /web_push/subscription— scoped tocurrent_userso a leaked endpoint can't unsubscribe someone else.Browser-side JS
coplan/web_push.jsES module withisSupported / permission / isSubscribed / subscribe / unsubscribe. Pinned via importmap.navigator.serviceWorker.readyafterregister()so PushManager has an active worker (fixes the "no active Service Worker" failure on first subscribe).CoPlan.configuration.web_push_configured?.Settings UI
[hidden] { display: none !important; }sohiddenactually hides.btnelements.Configuration
CoPlan::Configurationgainsvapid_public_key / vapid_private_key / vapid_subjectandweb_push_configured?.bundle exec rake coplan:web_push:generate_keys.config/initializers/coplan.rbships a checked-in dev VAPID keypair behind ENV overrides so the Settings UI works out-of-the-box locally. Production should override via env / encrypted credentials.Verification
bundle exec rspec→ 814 examples, 0 failures.WebPushSubscriptionmodel, subscriptions controller (POST/DELETE), service worker route.Out of scope (next PRs)
web-pushgem + VAPID signing) wired into comment-reply / mention events.coplan-square.Generated with Amp