Forget pushed event ids when Google Calendar is disconnected (Feature 16)
Disconnect deleted the connection but left every pushed plan synced with its stored event ids, though no calendar was chosen any more. It now deletes the connection and runs the same invalidation as choosing another calendar (forgetEvents: MarkCalendarPlansEdited, ClearCalendarEvents) in one transaction, under the account lock. A refused revoke still changes nothing. Tests push three weeks, disconnect, and check each is changed with no event id; then connect again, choose a calendar and push the whole week to it. Also: a refused revoke keeps every week synced, and a disconnect during a push waits for its record and then forgets it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -342,6 +342,11 @@ func (s *Service) store(ctx context.Context, sealed []byte) error {
|
||||
// connection. A token Google no longer knows (the household already removed
|
||||
// MealQuest's access in their Google account) counts as revoked. Any other
|
||||
// revoke failure keeps the connection so the household can retry.
|
||||
//
|
||||
// No calendar is chosen once disconnected, so the same transaction that
|
||||
// deletes the connection forgets every pushed event (forgetEvents): every
|
||||
// synced plan becomes changed, and the next push after connecting again and
|
||||
// choosing a calendar writes the whole week.
|
||||
func (s *Service) Disconnect(ctx context.Context) error {
|
||||
s.account.Lock()
|
||||
defer s.account.Unlock()
|
||||
@@ -359,10 +364,13 @@ func (s *Service) Disconnect(ctx context.Context) error {
|
||||
if err := s.revoke(ctx, string(token)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.New(s.st.Writer).DeleteIntegrationsGoogle(ctx); err != nil {
|
||||
return fmt.Errorf("gcal: delete Google integration: %w", err)
|
||||
}
|
||||
return nil
|
||||
return s.st.WithTx(ctx, func(tx *sql.Tx) error {
|
||||
q := db.New(tx)
|
||||
if err := q.DeleteIntegrationsGoogle(ctx); err != nil {
|
||||
return fmt.Errorf("gcal: delete Google integration: %w", err)
|
||||
}
|
||||
return forgetEvents(ctx, q, store.Timestamp{Time: s.now().UTC().Truncate(time.Millisecond)}.String())
|
||||
})
|
||||
}
|
||||
|
||||
// RevokeError is a revoke Google refused or that failed in transit. Its text
|
||||
|
||||
Reference in New Issue
Block a user