Skip to content

Conversation

@JeanMeijer
Copy link
Collaborator

@JeanMeijer JeanMeijer commented Nov 3, 2025

Description

Implements PWA support for Analog Calendar, replacing server actions with tRPC for push notifications and persisting subscriptions in the database.

Screenshots / Recordings

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • UI/UX update
  • Docs update
  • Refactor / Cleanup

Related Areas

  • Authentication
  • Calendar UI
  • Data/API
  • Docs

Testing

  • Manual testing performed
  • Cross-browser testing (if UI changes)
  • Mobile responsiveness verified (if UI changes)

Checklist

  • I’ve read the CONTRIBUTING guide
  • My code works and is understandable and follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in complex areas
  • I have updated the documentation
  • Any dependent changes are merged and published

Notes

This PR introduces full PWA capabilities, including web app manifest, service worker, and push notifications managed via tRPC and stored in the database. A detailed PWA_IMPLEMENTATION.md guide is included.


Want me to make any changes? Add a review or comment with @tembo and i'll get back to work!

tembo.io


Summary by cubic

Adds full PWA support with app install, a service worker, and push notifications powered by tRPC, with subscriptions stored in the database. Also updates security headers, env validation, and adds simple UI to manage install and notifications.

  • New Features

    • Web App Manifest (apps/web/src/app/manifest.ts)
    • Service worker for push (apps/web/public/sw.js)
    • tRPC router for push: subscribe, unsubscribe, unsubscribeByEndpoint, send, list (packages/api/src/routers/push-notifications.ts)
    • DB table push_subscription with indexes and a unique user+endpoint constraint (packages/db/src/schema/push-subscriptions.ts)
    • UI components: InstallPrompt and PushNotificationManager
    • Security headers and SW headers in next.config.ts
    • Env support for VAPID keys (client/server validation) and .env.example
    • Docs: PWA_IMPLEMENTATION.md and PWA_ICONS_README.md
    • Dependency: web-push
  • Migration

    • Generate VAPID keys and set NEXT_PUBLIC_VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY
    • Run bun run db:generate then bun run db:migrate
    • Add required icon files to apps/web/public/
    • Serve over HTTPS for local testing and production

Written for commit a4d4b00. Summary will update automatically on new commits.

Co-authored-by: Jean <jean@analoginterface.io>
@vercel
Copy link

vercel bot commented Nov 3, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
analog Error Error Nov 5, 2025 3:01am

@coderabbitai
Copy link

coderabbitai bot commented Nov 3, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 17 files

Prompt for AI agents (all 3 issues)

Understand the root cause of the following 3 issues and fix them.


<file name="apps/web/public/sw.js">

<violation number="1" location="apps/web/public/sw.js:31">
Normalize `urlToOpen` to an absolute URL before comparing with `client.url`, otherwise the focus branch never runs and every notification click opens a duplicate tab.</violation>
</file>

<file name="apps/web/src/app/manifest.ts">

<violation number="1" location="apps/web/src/app/manifest.ts:15">
The manifest references /icon-192x192.png, but that file is missing from apps/web/public, so the installed PWA will have no icon. Please add the asset or update the path.</violation>
</file>

<file name="packages/db/src/schema/push-subscriptions.ts">

<violation number="1" location="packages/db/src/schema/push-subscriptions.ts:24">
Please enforce a uniqueness constraint on a user/endpoint pair – the subscribe mutation assumes only one row will exist, but concurrent inserts can currently create duplicates.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

event.notification.close();

// Open the app at the specified URL or default to home
const urlToOpen = event.notification.data?.url || "/";
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normalize urlToOpen to an absolute URL before comparing with client.url, otherwise the focus branch never runs and every notification click opens a duplicate tab.

Prompt for AI agents
Address the following comment on apps/web/public/sw.js at line 31:

<comment>Normalize `urlToOpen` to an absolute URL before comparing with `client.url`, otherwise the focus branch never runs and every notification click opens a duplicate tab.</comment>

<file context>
@@ -0,0 +1,67 @@
+  event.notification.close();
+
+  // Open the app at the specified URL or default to home
+  const urlToOpen = event.notification.data?.url || &quot;/&quot;;
+
+  event.waitUntil(
</file context>
Suggested change
const urlToOpen = event.notification.data?.url || "/";
const urlToOpen = new URL(event.notification.data?.url || "/", self.location.origin).href;

✅ Addressed in a4d4b00

theme_color: "#000000",
icons: [
{
src: "/icon-192x192.png",
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The manifest references /icon-192x192.png, but that file is missing from apps/web/public, so the installed PWA will have no icon. Please add the asset or update the path.

Prompt for AI agents
Address the following comment on apps/web/src/app/manifest.ts at line 15:

<comment>The manifest references /icon-192x192.png, but that file is missing from apps/web/public, so the installed PWA will have no icon. Please add the asset or update the path.</comment>

<file context>
@@ -0,0 +1,40 @@
+    theme_color: &quot;#000000&quot;,
+    icons: [
+      {
+        src: &quot;/icon-192x192.png&quot;,
+        sizes: &quot;192x192&quot;,
+        type: &quot;image/png&quot;,
</file context>
Fix with Cubic

},
(table) => [
index("push_subscription_user_id_idx").on(table.userId),
index("push_subscription_endpoint_idx").on(table.endpoint),
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please enforce a uniqueness constraint on a user/endpoint pair – the subscribe mutation assumes only one row will exist, but concurrent inserts can currently create duplicates.

Prompt for AI agents
Address the following comment on packages/db/src/schema/push-subscriptions.ts at line 24:

<comment>Please enforce a uniqueness constraint on a user/endpoint pair – the subscribe mutation assumes only one row will exist, but concurrent inserts can currently create duplicates.</comment>

<file context>
@@ -0,0 +1,36 @@
+  },
+  (table) =&gt; [
+    index(&quot;push_subscription_user_id_idx&quot;).on(table.userId),
+    index(&quot;push_subscription_endpoint_idx&quot;).on(table.endpoint),
+  ],
+);
</file context>

✅ Addressed in a4d4b00

@JeanMeijer
Copy link
Collaborator Author

@tembo implement the review if possible, fix the type errors, run format

@tembo
Copy link
Contributor

tembo bot commented Nov 5, 2025

@tembo implement the review if possible, fix the type errors, run format

Thanks for implementing the review feedback! I've addressed the three issues:

  1. Service Worker URL normalization: Fixed the notification click handler to convert relative URLs to absolute URLs before comparison, preventing duplicate tabs from opening
  2. Database uniqueness constraint: Added a unique constraint on the userId and endpoint pair to prevent concurrent insert race conditions
  3. Code formatting: Applied consistent formatting throughout the codebase

The changes ensure proper PWA functionality with correct notification routing and data integrity.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants