Context
The system has several concurrent-access patterns: worker queue claiming, optimistic concurrency on card updates, SignalR presence tracking, and batch processing. These deserve targeted concurrency tests beyond the existing Playwright multi-session coverage.
Test Scenarios
Queue Claim Races
- Double-claim prevention: 10 parallel workers all try to claim the same Pending LLM queue item → exactly one succeeds, 9 get DomainException or false return
- Capture triage claim: `TryClaimProcessingCaptureAsync` with stale `expectedUpdatedAt` → returns false
- Batch processing with concurrent workers: Two workers call `ProcessBatchAsync` simultaneously → no item processed twice
Card Update Conflicts
- Concurrent card moves: User A and User B both move the same card to different columns simultaneously → one succeeds, one gets 409 Conflict
- Concurrent card edits: Both users update the same card's description → stale-write detection fires
- Column reorder race: Two users reorder cards in the same column simultaneously → final state is consistent (no duplicated or lost positions)
Proposal Approval Races
- Double-approve: Two requests to approve the same proposal simultaneously → only one succeeds
- Approve + Expire race: Proposal is being approved while housekeeping worker expires it → one wins cleanly
Board Presence
- Rapid join/leave: 20 connections join and leave a board rapidly → presence snapshot is eventually consistent
- Disconnect during edit: User sets editing card, then connection drops → presence snapshot clears the editing state
Webhook Delivery
- Concurrent webhook deliveries: Multiple events fire for the same subscription → each gets its own delivery record, no duplicate delivery
Rate Limiting Under Load
- Burst beyond limit: 100 requests in quick succession → correct number throttled, retry headers accurate
- Cross-user isolation under load: User A hitting rate limit doesn't affect User B's requests
Implementation Notes
- Use `Task.WhenAll` with multiple `HttpClient` instances for HTTP-level concurrency
- For queue claim tests: seed items, then fire N parallel claim attempts
- For card conflicts: use EF Core concurrency tokens already in place
- For presence tests: create multiple SignalR connections to the same board
- Consider using `SemaphoreSlim` barriers to ensure truly simultaneous execution
- Measure: no deadlocks, no data loss, no duplicate processing, consistent final state
Risk Areas
- SQLite doesn't handle write concurrency as well as PostgreSQL — some tests may surface SQLite-specific serialization issues that would not occur in production with a different database. Document these clearly.
- The `Task.Delay(backoff)` in retry path holds a scope for the duration — under high concurrency this could exhaust scope factories
Context
The system has several concurrent-access patterns: worker queue claiming, optimistic concurrency on card updates, SignalR presence tracking, and batch processing. These deserve targeted concurrency tests beyond the existing Playwright multi-session coverage.
Test Scenarios
Queue Claim Races
Card Update Conflicts
Proposal Approval Races
Board Presence
Webhook Delivery
Rate Limiting Under Load
Implementation Notes
Risk Areas