DB-backed rate limiting service #11

Closed
opened 2026-07-04 14:52:01 +02:00 by fable-5 · 0 comments
Collaborator

Context

Signup, login, and token endpoints must be rate-limited (ADR 0007) without Redis (ADR 0002).

Scope

Implement a reusable RateLimitService (fixed-window counters in a rate_limits table keyed by scope+key, e.g. login:ip:1.2.3.4) and a Nest guard/decorator @RateLimit(scope, limit, windowSeconds). Include automatic cleanup of expired windows (piggyback on writes). Apply limits from operations.md once the endpoints exist (their stories reference this).

Acceptance criteria

  • exceeding the limit returns 429 with a localized error and Retry-After
  • counters are per IP and per account where the decorator says so
  • unit tests cover window rollover and concurrent increments (transactional upsert)
  • expired rows do not accumulate unboundedly (test the cleanup)

Technical notes

  • ADR 0007, operations.md limits table.
  • Read client IP via the reverse-proxy header chain (trust configuration in one place).

Dependencies

Depends on #3.

Size: ~1 day


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context Signup, login, and token endpoints must be rate-limited (ADR 0007) without Redis (ADR 0002). ## Scope Implement a reusable `RateLimitService` (fixed-window counters in a `rate_limits` table keyed by scope+key, e.g. `login:ip:1.2.3.4`) and a Nest guard/decorator `@RateLimit(scope, limit, windowSeconds)`. Include automatic cleanup of expired windows (piggyback on writes). Apply limits from operations.md once the endpoints exist (their stories reference this). ## Acceptance criteria - [ ] exceeding the limit returns 429 with a localized error and `Retry-After` - [ ] counters are per IP and per account where the decorator says so - [ ] unit tests cover window rollover and concurrent increments (transactional upsert) - [ ] expired rows do not accumulate unboundedly (test the cleanup) ## Technical notes - ADR 0007, operations.md limits table. - Read client IP via the reverse-proxy header chain (trust configuration in one place). ## Dependencies Depends on #3. **Size**: ~1 day --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M1 — Accounts & authentication milestone 2026-07-04 14:52:01 +02:00
fable-5 added the
auth
backend
labels 2026-07-04 14:52:01 +02:00
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#11
No description provided.