Wikimedia Product Infrastructure team/Push Notifications Infrastructure/Design Decisions

Architecture overview
This project will provide two new software components:
 * a service for managing push notification subscriptions and processing notification requests, and
 * a MediaWiki extension (Extension:PushNotifications) for associating MediaWiki global user IDs with push subscriptions and forwarding Echo events to the push service.

MW extension

 * Maintain a database table mapping global user accounts to push subscriptions
 * Provide an API for wiki users to associate their global user accounts with device push subscriptions
 * Provide an Echo notifier type to allow handling notifications with push
 * Provide a handler implementation for formatting notification requests and forwarding them to the push notification service

Push notification service

 * Maintain a database of device push subscriptions based on provider tokens
 * Provide an API for users to register, renew, and unregister push subscriptions
 * Provide an API for accepting notification requests
 * Forward notification requests to providers (Apple Push Notification Service, Firebase Cloud Messaging, etc.)

Client to call MW API for notification message details

 * Status: proposed
 * Decision: The Push Service provides some sort of notification type, which is the cue for the app client to invoke a known MW API query.
 * Pros:
 * No personal data transmitted
 * No need for I18N in push infrastructure and needed tracking of what locale a given notification should be sent to. A client could just use existing mechanisms to specify the locale in the MW API request (accept-language header, etc.).
 * Some clients cannot subscribe to push notifications (e.g. app on an Android device without Google Play Services). They may need to know about these queries, too, so they can poll instead.
 * Cons:
 * One more request for clients to make
 * Client needs to know about the notification type to handle it (client discards unknown types)
 * Question: Should client log notifications received with unknown types using event logging?
 * Date: 2020-04-21

Write push specific MW code directly in Echo extension

 * Reason: 1. It takes too long to get a new extension approved.
 * Date: 2020-05-05

Store only user-push subscription ID mappings

 * Status: proposed (https://gerrit.wikimedia.org/r/#/c/mediawiki/extensions/PushNotifications/+/587792/)
 * Decision: Manage push subscriptions primarily in the external service. Manage mappings between wiki user accounts and push subscriptions in MediaWiki.
 * Reason: Push credentials are specific to a web browser or native app installation and not to a wiki user. Handling them separately allows for cleanly supporting anons and multi-user devices.
 * Date: 2020-04-28

Use external push provider or host internally?

 * Status: investigating

Write from scratch

 * Decision: Write from scratch but incorporate non-intuitive bits (if any) from existing projects.
 * Reason: The FOSS projects we found were stale and unmaintained. The last commit to the front-runner project was 5 years ago.

Write the push service in Node.js

 * Alternatives: Go, Python, Java, ...
 * Reason: More experience in the Foundation running services in Node.js than the others.
 * Date: 2020-04-20

Try using TypeScript

 * Reason: Added type safety
 * Date: 2020-04-20

Use service-runner

 * Reason: service-runner provides health metrics reporting required by SRE + logging
 * Date: 2020-04-20

Base project on service-template-node

 * Reason: Provides a code structure that is consistent with other Node.js services running in WMF production
 * Date: 2020-04-20

Use Gerrit for code review

 * Reason: Deployment pipeline is not ready for Github
 * Date: 2020-04-21

Store primary subscription data but not user IDs

 * Status: proposed (https://gerrit.wikimedia.org/r/#/c/mediawiki/extensions/PushNotifications/+/587792/)
 * Decision: Manage push subscriptions primarily in the service. Manage mappings between wiki user accounts and push subscriptions in MediaWiki.
 * Reason: Push credentials are specific to a web browser or native app installation and not to a wiki user. Handling them separately allows for cleanly supporting anons and multi-user devices.
 * Date: 2020-04-28

Housekeeping
Some ideas on what to include in decision records. Pretty much everything here is optional for now.

Template

 * Status: [proposed | rejected | accepted | deprecated]
 * Decision:
 * Reason:
 * Date: [YYYY-MM-DD when the decision was last updated]