Skip to content

Connector mutations lack same-connector user-intent ordering #3334

Description

@Chris0Jeky

Summary

frontend/taskdeck-web/src/store/integrationStore.ts starts update/delete/enable/disable requests concurrently for the same connector. The integration API exposes no expected revision/If-Match contract, and IntegrationConnector.UpdatedAt is not configured as an EF concurrency token. Same-connector commits and responses can therefore diverge from user-intent order.

This is a source-traced successor to #3331 / stacked PR #3332. Keep it separate: #3332 owns session replacement and stale-lifetime settlement; this issue owns live-session ordering for one connector.

Reachable schedules

  • Enable followed immediately by Disable can send both requests together. The Disable response may arrive first and the older Enable response later, leaving the client Active even if the user’s final intent was Disabled.
  • Two configuration/name updates can settle in reverse order and display the older payload.
  • Update/Delete or Enable/Delete races can produce misleading success/error ordering and an avoidable late write against an entity the user already asked to remove.

The service maps UpdatedAt into responses, but neither the DTO nor persistence contract uses it as an expected version. Client settlement currently compares no timestamp and serializes no mutation.

Expected contract

  • One mutation lane per connector ID serializes update/delete/enable/disable transport in user-intent order.
  • The first mutation starts immediately; later same-ID intent waits. Different connector IDs remain concurrent.
  • Queued work rechecks the initiating lifecycle epoch before transport, preserving fix(integrations): invalidate mutations on session replacement #3332’s logout/account replacement boundary.
  • A failed predecessor does not cancel the next queued intent.
  • Delete has an explicit terminal rule: later queued intent may run and receive NotFound, or the queue may refuse it before transport, but the behavior must be deliberate and tested rather than settlement-order dependent.
  • Error/toast/cache settlement remains owned by the initiating lifecycle.
  • Document that one-client serialization does not solve cross-device concurrency without a server revision contract.

Acceptance

  • Deferred regressions for Enable→Disable and two Updates, proving the second transport starts only after the first settles and final cache matches intent order.
  • Update→Delete, Delete→Update and failed-predecessor cases have explicit outcomes.
  • Logout/session replacement cancels queued old-session transport without claiming rollback of the first already-started request.
  • Different connector IDs remain concurrent.
  • Existing fix(integrations): bind connector reads to request lifetimes #3329 and fix(integrations): invalidate mutations on session replacement #3332 read/session tests remain green.
  • Frontend lint, typecheck, build, full Vitest and exact-head hosted CI pass.

Server follow-up boundary

IntegrationConnectorDto returns UpdatedAt, but UpdateIntegrationConnectorDto, enable/disable routes and EF configuration provide no precondition. Cross-client conflict semantics require a separate backend/API design and deterministic database tests.

Provenance

Found during fresh-context review of PR #3332 and IntegrationRegistryService, integration DTOs, entity and EF configuration on 2026-09-21. Searches found no matching open tracker.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfrontendPrimary implementation impact in Vue/TypeScript UI and client runtime.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions