diff --git a/internal/api/devices.go b/internal/api/devices.go index e44cc8a..8c5a834 100644 --- a/internal/api/devices.go +++ b/internal/api/devices.go @@ -29,6 +29,7 @@ func (a *api) upsertDeviceHandler(w http.ResponseWriter, r *http.Request) { } d.ActiveUntil = time.Now().Unix() + domain.DeviceGracePeriodDuration + d.GracePeriodUntil = d.ActiveUntil + domain.DeviceGracePeriodAfterReceiptExpiry if err := a.deviceRepo.CreateOrUpdate(ctx, d); err != nil { a.errorResponse(w, r, 500, err.Error()) diff --git a/internal/api/receipt.go b/internal/api/receipt.go index 325c1dc..98036f4 100644 --- a/internal/api/receipt.go +++ b/internal/api/receipt.go @@ -52,6 +52,7 @@ func (a *api) checkReceiptHandler(w http.ResponseWriter, r *http.Request) { _ = a.deviceRepo.Delete(ctx, apns) } else { dev.ActiveUntil = time.Now().Unix() + domain.DeviceActiveAfterReceitCheckDuration + dev.GracePeriodUntil = dev.ActiveUntil + domain.DeviceGracePeriodAfterReceiptExpiry _ = a.deviceRepo.Update(ctx, &dev) } } diff --git a/internal/domain/device.go b/internal/domain/device.go index a002ba4..66dd5d6 100644 --- a/internal/domain/device.go +++ b/internal/domain/device.go @@ -9,13 +9,15 @@ import ( const ( DeviceGracePeriodDuration = 3600 // 1 hour DeviceActiveAfterReceitCheckDuration = 3600 * 24 * 30 // ~1 month + DeviceGracePeriodAfterReceiptExpiry = 3600 * 24 * 30 // ~1 month ) type Device struct { - ID int64 - APNSToken string - Sandbox bool - ActiveUntil int64 + ID int64 + APNSToken string + Sandbox bool + ActiveUntil int64 + GracePeriodUntil int64 } func (dev *Device) Validate() error { diff --git a/internal/repository/postgres_device.go b/internal/repository/postgres_device.go index 2da3a1d..440e3ce 100644 --- a/internal/repository/postgres_device.go +++ b/internal/repository/postgres_device.go @@ -32,6 +32,7 @@ func (p *postgresDeviceRepository) fetch(ctx context.Context, query string, args &dev.APNSToken, &dev.Sandbox, &dev.ActiveUntil, + &dev.GracePeriodUntil, ); err != nil { return nil, err } @@ -42,7 +43,7 @@ func (p *postgresDeviceRepository) fetch(ctx context.Context, query string, args func (p *postgresDeviceRepository) GetByID(ctx context.Context, id int64) (domain.Device, error) { query := ` - SELECT id, apns_token, sandbox, active_until + SELECT id, apns_token, sandbox, active_until, grace_period_until FROM devices WHERE id = $1` @@ -59,7 +60,7 @@ func (p *postgresDeviceRepository) GetByID(ctx context.Context, id int64) (domai func (p *postgresDeviceRepository) GetByAPNSToken(ctx context.Context, token string) (domain.Device, error) { query := ` - SELECT id, apns_token, sandbox, active_until + SELECT id, apns_token, sandbox, active_until, grace_period_until FROM devices WHERE apns_token = $1` @@ -76,7 +77,7 @@ func (p *postgresDeviceRepository) GetByAPNSToken(ctx context.Context, token str func (p *postgresDeviceRepository) GetByAccountID(ctx context.Context, id int64) ([]domain.Device, error) { query := ` - SELECT devices.id, apns_token, sandbox, active_until + SELECT devices.id, apns_token, sandbox, active_until, grace_period_until FROM devices INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id WHERE devices_accounts.account_id = $1` @@ -86,7 +87,7 @@ func (p *postgresDeviceRepository) GetByAccountID(ctx context.Context, id int64) func (p *postgresDeviceRepository) GetInboxNotifiableByAccountID(ctx context.Context, id int64) ([]domain.Device, error) { query := ` - SELECT devices.id, apns_token, sandbox, active_until + SELECT devices.id, apns_token, sandbox, active_until, grace_period_until FROM devices INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id WHERE devices_accounts.account_id = $1 AND devices_accounts.inbox_notifiable = TRUE` @@ -96,7 +97,7 @@ func (p *postgresDeviceRepository) GetInboxNotifiableByAccountID(ctx context.Con func (p *postgresDeviceRepository) GetWatcherNotifiableByAccountID(ctx context.Context, id int64) ([]domain.Device, error) { query := ` - SELECT devices.id, apns_token, sandbox, active_until + SELECT devices.id, apns_token, sandbox, active_until, grace_period_until FROM devices INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id WHERE devices_accounts.account_id = $1 AND devices_accounts.watcher_notifiable = TRUE` @@ -106,10 +107,10 @@ func (p *postgresDeviceRepository) GetWatcherNotifiableByAccountID(ctx context.C func (p *postgresDeviceRepository) CreateOrUpdate(ctx context.Context, dev *domain.Device) error { query := ` - INSERT INTO devices (apns_token, sandbox, active_until) - VALUES ($1, $2, $3) + INSERT INTO devices (apns_token, sandbox, active_until, grace_period_until) + VALUES ($1, $2, $3, $4) ON CONFLICT(apns_token) DO - UPDATE SET active_until = $3 + UPDATE SET active_until = $3, grace_period_until = $4 RETURNING id` return p.pool.QueryRow( @@ -118,6 +119,7 @@ func (p *postgresDeviceRepository) CreateOrUpdate(ctx context.Context, dev *doma dev.APNSToken, dev.Sandbox, dev.ActiveUntil, + dev.GracePeriodUntil, ).Scan(&dev.ID) } @@ -128,8 +130,8 @@ func (p *postgresDeviceRepository) Create(ctx context.Context, dev *domain.Devic query := ` INSERT INTO devices - (apns_token, sandbox, active_until) - VALUES ($1, $2, $3) + (apns_token, sandbox, active_until, grace_period_until) + VALUES ($1, $2, $3, $4) RETURNING id` return p.pool.QueryRow( @@ -138,6 +140,7 @@ func (p *postgresDeviceRepository) Create(ctx context.Context, dev *domain.Devic dev.APNSToken, dev.Sandbox, dev.ActiveUntil, + dev.GracePeriodUntil, ).Scan(&dev.ID) } @@ -148,10 +151,10 @@ func (p *postgresDeviceRepository) Update(ctx context.Context, dev *domain.Devic query := ` UPDATE devices - SET active_until = $2 + SET active_until = $2, grace_period_until = $3 WHERE id = $1` - res, err := p.pool.Exec(ctx, query, dev.ID, dev.ActiveUntil) + res, err := p.pool.Exec(ctx, query, dev.ID, dev.ActiveUntil, dev.GracePeriodUntil) if res.RowsAffected() != 1 { return fmt.Errorf("weird behaviour, total rows affected: %d", res.RowsAffected()) @@ -211,7 +214,7 @@ func (p *postgresDeviceRepository) GetNotifiable(ctx context.Context, dev *domai } func (p *postgresDeviceRepository) PruneStale(ctx context.Context, before int64) (int64, error) { - query := `DELETE FROM devices WHERE active_until < $1` + query := `DELETE FROM devices WHERE grace_period_until < $1` res, err := p.pool.Exec(ctx, query, before)