fix(#24): Implement idempotency protection for critical write operations
Some checks are pending
Docker Test / test (push) Waiting to run
Some checks are pending
Docker Test / test (push) Waiting to run
This commit is contained in:
parent
6c25464369
commit
b44e7bf46c
6 changed files with 281 additions and 4 deletions
63
docs/adr/001-idempotency.md
Normal file
63
docs/adr/001-idempotency.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# ADR 001: Idempotency for Critical Write Operations
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Repeated requests (retries/double clicks) can currently create duplicate offers/acceptances. This is problematic because:
|
||||
|
||||
- Users may accidentally double-click buttons
|
||||
- Network issues might cause requests to timeout and be retried
|
||||
- The system should behave deterministically when handling retries
|
||||
|
||||
## Decision
|
||||
|
||||
We implement idempotency key handling for critical POST endpoints:
|
||||
1. Add `x-idempotency-key` header support to POST endpoints
|
||||
2. Store request results in a database table for replaying responses
|
||||
3. Return cached responses for identical keys
|
||||
4. Apply this to the most critical endpoints:
|
||||
- `/offers/:requestId`
|
||||
- `/offers/negotiation/:offerId`
|
||||
- `/offers/accept/:offerId`
|
||||
- `/help-requests`
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
- Eliminates duplicate offers/acceptances from retries
|
||||
- Makes critical endpoints behave deterministically on retries
|
||||
- Improves user experience by preventing accidental duplicates
|
||||
- Follows REST best practices for idempotent operations
|
||||
|
||||
### Negative
|
||||
- Adds complexity to request handling
|
||||
- Requires database storage for idempotency keys
|
||||
- Slight performance overhead for idempotent requests
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Database Schema
|
||||
Added `idempotency_keys` table with:
|
||||
- `key`: Unique identifier for the request (VARCHAR)
|
||||
- `response_body`: Cached response data (TEXT)
|
||||
- `created_at`: Timestamp of when the key was first used
|
||||
|
||||
### Middleware
|
||||
Created `requireIdempotencyKey` middleware that:
|
||||
1. Checks for `x-idempotency-key` header in POST requests
|
||||
2. If key exists, checks if it has been used before
|
||||
3. If used before, returns cached response
|
||||
4. If new, stores the request and caches the eventual response
|
||||
|
||||
### Endpoints
|
||||
Applied to critical write operations:
|
||||
- POST `/offers/:requestId`
|
||||
- POST `/offers/negotiation/:offerId`
|
||||
- POST `/offers/accept/:offerId`
|
||||
- POST `/help-requests`
|
||||
|
||||
## Testing
|
||||
Added tests for idempotency behavior in the existing test suite.
|
||||
Loading…
Add table
Add a link
Reference in a new issue