implement backend components for push notifications
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
package pushnotify
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// Service is the full surface for per-device push token storage. HTTP handlers
|
||||
// use Register/Unregister; the worker's notifier uses ListForHumans and
|
||||
// DeleteByToken. Both consumers share the same underlying repository.
|
||||
type Service interface {
|
||||
// Register upserts a token for the given human. Returns ErrInvalidToken /
|
||||
// ErrInvalidPlatform on bad input.
|
||||
Register(ctx context.Context, humanID string, in RegisterInput) error
|
||||
// Unregister removes a token, scoped to the calling human so a user can't
|
||||
// delete another user's token. Returns ErrNotFound if the token doesn't
|
||||
// belong to humanID (or doesn't exist).
|
||||
Unregister(ctx context.Context, humanID, token string) error
|
||||
// ListForHumans returns every push token belonging to any of the given
|
||||
// human IDs. Returns an empty slice when nothing matches.
|
||||
ListForHumans(ctx context.Context, humanIDs []string) ([]*PushToken, error)
|
||||
// DeleteByToken removes a token regardless of owning human. Used by the
|
||||
// notifier to clean up after Expo returns 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)
|
||||
}
|
||||
Reference in New Issue
Block a user