Mobile notifications for iOS (#210)

* 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
This commit was merged in pull request #210.
This commit is contained in:
Arjun Patel
2026-05-18 12:44:31 -07:00
committed by GitHub
parent a564ea819b
commit d262f734f0
61 changed files with 1682 additions and 531 deletions
+4 -7
View File
@@ -28,7 +28,7 @@ var ErrInvalidRetentionHours = errors.New("message retention hours must be betwe
type Service interface {
Reader
// Create creates a network and adds adminHumanId as the first member. Returns ErrInvalidName if name is empty.
// Create adds adminHumanId as the first member. Returns ErrInvalidName if name is empty.
Create(ctx context.Context, name, adminHumanId string) (*Network, error)
// SetName returns ErrNotFound or ErrInvalidName.
SetName(ctx context.Context, id, name string) error
@@ -145,10 +145,8 @@ func (s *serviceImpl) RemoveMember(ctx context.Context, networkID, humanId strin
return nil
}
// mirrorAddMembership / mirrorRemoveMembership keep the live store membership
// projection (humans/{humanId}.networks) in sync with Postgres. Called after
// the Postgres transaction commits. Failures are logged but not returned:
// Postgres is the source of truth and the reconciler will heal drift.
// Mirror the live store membership projection (humans/{humanId}.networks).
// Postgres is the source of truth: failures are logged and the reconciler heals drift.
func (s *serviceImpl) mirrorAddMembership(ctx context.Context, humanId, networkID string) {
if err := s.pub.Add(ctx, humanId, networkID); err != nil {
slog.Error("membership publish add failed", "error", err, "humanId", humanId, "networkID", networkID)
@@ -161,8 +159,7 @@ func (s *serviceImpl) mirrorRemoveMembership(ctx context.Context, humanId, netwo
}
}
// mutateMembers runs fn in a tx, recounts seats, calls billing.SyncSeats,
// and commits. Any error rolls the membership change back.
// Runs fn in a tx and syncs seats to billing atomically. Any error rolls back.
func (s *serviceImpl) mutateMembers(ctx context.Context, networkID string, fn func(pgx.Tx) error) error {
tx, err := s.pool.Begin(ctx)
if err != nil {