d262f734f0
* mobile: wire notification registration and listener
* implement backend components for push notifications
* refactor: agentic comment cleanup
* docs: use proper module name for particle processor
* set required env variables for push notifications
* bump version
* fix: always upsert push token on mobile start
* Revert "fix: always upsert push token on mobile start"
This reverts commit 90ff18a788.
* send push notifications regardless of online status
67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
package pushnotify
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// Service stores per-device Expo push tokens and exposes the operations
|
|
// needed by both the HTTP handlers and the worker-side notifier.
|
|
type Service interface {
|
|
// Register returns ErrInvalidToken / ErrInvalidPlatform on bad input.
|
|
Register(ctx context.Context, humanID string, in RegisterInput) error
|
|
// Unregister is scoped to humanID so a user can't delete another user's
|
|
// token. Returns ErrNotFound if the token isn't owned by humanID.
|
|
Unregister(ctx context.Context, humanID, token string) error
|
|
// ListForHumans returns an empty slice when nothing matches.
|
|
ListForHumans(ctx context.Context, humanIDs []string) ([]*PushToken, error)
|
|
// DeleteByToken removes a token regardless of owner — used to prune after
|
|
// Expo reports DeviceNotRegistered.
|
|
DeleteByToken(ctx context.Context, token string) error
|
|
}
|
|
|
|
type RegisterInput struct {
|
|
Token string
|
|
Platform Platform
|
|
AppVersion string
|
|
}
|
|
|
|
type serviceImpl struct {
|
|
repo repository
|
|
}
|
|
|
|
func NewService(pool *pgxpool.Pool) Service {
|
|
return &serviceImpl{repo: newRepository(pool)}
|
|
}
|
|
|
|
func (s *serviceImpl) Register(ctx context.Context, humanID string, in RegisterInput) error {
|
|
if !in.Platform.Valid() {
|
|
return ErrInvalidPlatform
|
|
}
|
|
if !IsValidExpoToken(in.Token) {
|
|
return ErrInvalidToken
|
|
}
|
|
return s.repo.upsert(ctx, &PushToken{
|
|
Token: in.Token,
|
|
HumanID: humanID,
|
|
Platform: in.Platform,
|
|
AppVersion: in.AppVersion,
|
|
})
|
|
}
|
|
|
|
func (s *serviceImpl) Unregister(ctx context.Context, humanID, token string) error {
|
|
if token == "" {
|
|
return ErrInvalidToken
|
|
}
|
|
return s.repo.deleteForHuman(ctx, humanID, token)
|
|
}
|
|
|
|
func (s *serviceImpl) ListForHumans(ctx context.Context, humanIDs []string) ([]*PushToken, error) {
|
|
return s.repo.listForHumans(ctx, humanIDs)
|
|
}
|
|
|
|
func (s *serviceImpl) DeleteByToken(ctx context.Context, token string) error {
|
|
return s.repo.deleteByToken(ctx, token)
|
|
}
|