← Back to documentation

push-notification-test-report

Push Notification Test Report — BUY-3131

Test Date: 2026-04-18
Test Environment: Production Docker deployment
Test Status: ❌ BLOCKED — multiple infrastructure issues found


Executive Summary

End-to-end browser push notification testing cannot proceed due to four critical blockers:

  1. Push notification router code not deployed to Docker
  2. webpush Python package missing from requirements.txt
  3. VAPID keys not configured (both public and private keys are empty strings)
  4. Push notifications disabled (web_push_enabled: False)

Test Cases & Results

Test 1: Subscribe Browser to Push Notifications

Endpoint: POST /api/auth/me/push
Status: ❌ CANNOT TEST

Reason: The push notification router (push_notifications.py) exists in the local codebase at app/routers/push_notifications.py but is NOT present in the Docker container at /app/app/routers/. The Docker image was built before this feature was added.

Evidence:

# Local code exists:
$ ls -la app/routers/push_notifications.py
-rw-rw-r-- 1 paperclip paperclip 6668 Apr 18 09:52 app/routers/push_notifications.py

# Docker container does NOT have it:
$ docker exec buywhere-api-api-1 ls /app/app/routers/push_notifications.py
# (empty - file does not exist)

Full path that should exist: /api/auth/me/push

Test 2: Get VAPID Public Key

Endpoint: GET /api/auth/me/push/vapid-public-key
Status: ❌ CANNOT TEST

Reason: Route does not exist in running server (not deployed).

Test 3: Service Worker Delivery

Endpoint: GET /api/auth/me/push/service-worker.js
Status: ❌ CANNOT TEST

Reason: Route does not exist. The service worker file static/push/sw.js exists locally but would need to be served via the router.

Test 4: Push Notification Manifest

Endpoint: GET /api/auth/me/push/manifest.json
Status: ❌ CANNOT TEST

Reason: Route does not exist.

Test 5: Trigger Test Push via API

Cron Script: python scripts/price_alert_push_cron.py --once
Status: ❌ CANNOT TEST

Reason 1: webpush package not in requirements.txt:

# From app/services/push_notification.py line 96:
import webpush  # This will fail at runtime

Reason 2: VAPID keys not configured in .env:

web_push_vapid_public_key=""
web_push_vapid_private_key=""
web_push_enabled=False

Test 6: Verify Notification in Chrome + Firefox

Status: ❌ BLOCKED — depends on Tests 1-5

Test 7: Test on Mobile (iOS Safari)

Status: ❌ BLOCKED — iOS Safari requires VAPID authentication and HTTPS

Note: iOS Safari push notifications require:

  • HTTPS endpoint (localhost won't work for iOS)
  • Valid VAPID keys
  • Service worker registration

Test 8: Fallback to Email When Push Not Subscribed

Status: ⚠️ NOT TESTED — requires price alert system verification

The code path exists in app/services/push_notification.py but email fallback logic needs review.


Infrastructure Issues Found

Issue 1: Code Not Deployed

Severity: Critical
File: app/routers/push_notifications.py

The push notification router was created locally but the Docker image was not rebuilt. The container still runs the old code without push routes.

Fix Required:

# Rebuild and restart the Docker container
docker-compose build api
docker-compose up -d api

Issue 2: Missing webpush Package

Severity: Critical
File: requirements.txt

The web-push Python package is imported in app/services/push_notification.py but is missing from requirements.txt.

Fix Required:

# Add to requirements.txt:
echo "web-push==1.0.0" >> requirements.txt

Or wherever the maintained version is. Need to verify correct package name.

Issue 3: VAPID Keys Not Configured

Severity: Critical
File: .env

Both VAPID keys are empty strings. VAPID keys are required for Web Push protocol security.

Fix Required:

# Generate VAPID keys using web-push library:
python -c "from webpush import webpush; keys = webpush.generateVAPIDKeys(); print(f'Public: {keys[\"public_key\"]}\\nPrivate: {keys[\"private_key\"]}')"

# Add to .env:
web_push_vapid_public_key=<generated_public_key>
web_push_vapid_private_key=<generated_private_key>
web_push_vapid_subject=mailto:alerts@buywhere.ai
web_push_enabled=True

Issue 4: Push Disabled by Default

Severity: High
File: app/config.py

web_push_enabled: bool = False  # Default is False

Fix Required: Set web_push_enabled=True in .env or change default in config.py.

Issue 5: Database Migration Not Applied

Severity: Critical
Database: catalog (PostgreSQL)

The push subscription tables (push_subscriptions, push_notification_logs) do not exist in the database. The migration 041_add_push_subscriptions.py has NOT been applied.

Current alembic version: 036_add_bulk_ingestion_jobs
Required version: 041

Fix Required:

# Apply pending migrations
alembic upgrade head
# Or specifically:
alembic upgrade 041

Tables that should exist after migration:

  • push_subscriptions (with indexes on user_id and is_active)
  • push_notification_logs (with indexes on subscription_id, alert_id, status, created_at)

Push Notification Architecture Summary

Components

ComponentFileStatus
Routerapp/routers/push_notifications.py✅ Code exists locally, ❌ Not deployed
Serviceapp/services/push_notification.py✅ Code exists locally, ❌ Not deployed
Modelapp/models/push_subscription.py✅ Code exists locally, ❌ Not deployed
Schemaapp/schemas/push_subscription.py✅ Code exists locally, ❌ Not deployed
Service Workerstatic/push/sw.js✅ File exists locally, ❌ Not served
Cron Scriptscripts/price_alert_push_cron.py✅ Code exists locally, ❌ Not deployable
Database Migrationalembic/versions/041_add_push_subscriptions.py❓ Unknown if migration was run

API Endpoints (when deployed)

MethodEndpointAuth RequiredDescription
GET/api/auth/me/push/service-worker.jsNoServes service worker
GET/api/auth/me/push/manifest.jsonNoPush manifest
GET/api/auth/me/push/vapid-public-keyNoGet VAPID public key
POST/api/auth/me/pushYesSubscribe to push
GET/api/auth/me/pushYesList subscriptions
DELETE/api/auth/me/push/{subscription_id}YesUnsubscribe
DELETE/api/auth/me/push/by-endpointYesUnsubscribe by endpoint

Recommendations

Immediate Actions (to enable testing)

  1. Deploy push notification code:

    • Ensure app/routers/push_notifications.py is included in Docker image
    • Rebuild Docker container: docker-compose build api && docker-compose up -d
  2. Add webpush package:

    • Add web-push to requirements.txt
    • Rebuild container
  3. Configure VAPID keys:

    • Generate keys
    • Add to .env or environment variables
    • Set web_push_enabled=True
  4. Run database migration:

    • Apply migration 041_add_push_subscriptions.py which creates:
      • push_subscriptions table
      • push_notification_logs table
    • Current DB version: 036_add_bulk_ingestion_jobs
    • Run: alembic upgrade head

Pre-requisites for iOS Safari Testing

  • Valid HTTPS endpoint (not localhost)
  • Valid SSL certificate
  • VAPID keys configured
  • Service worker must be served over HTTPS

Conclusion

The push notification system was built (BUY-3101) but not deployed. The code exists locally and appears well-structured, but cannot be end-to-end tested until:

  1. Docker image is rebuilt with new code (push_notifications.py missing from container)
  2. web-push package is added to dependencies (not in requirements.txt)
  3. VAPID keys are generated and configured (both keys are empty strings)
  4. Database migration 041 is applied (push tables do not exist)
  5. Push notifications are enabled (web_push_enabled=False)

Estimated time to enable testing: 30-60 minutes of DevOps work (rebuild, configure keys, migrate, deploy).

Test environment health check:

  • API running: ✅ Yes (Docker)
  • Push routes deployed: ❌ No
  • web-push package: ❌ Missing
  • VAPID keys: ❌ Empty
  • DB migration 041: ❌ Not applied
  • Push enabled: ❌ No

Report generated by Relay (Backend Engineer) — BUY-3131