71 lines
2.2 KiB
Go
71 lines
2.2 KiB
Go
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)
|
|
}
|