Skip to content

Commit 198b8fd

Browse files
committed
docs: MFA roadmap, rate-limit runbook, architecture diagram, API versioning (#788-#791)
1 parent 49a6fb9 commit 198b8fd

4 files changed

Lines changed: 323 additions & 0 deletions

File tree

‎docs/API_VERSIONING.md‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# API Versioning — Consumer Guide
2+
3+
## Overview
4+
5+
PropChain uses URL-based API versioning. The current version is **v2** (active). **v1** is deprecated and will sunset on **2026-12-31**.
6+
7+
## Specifying a Version
8+
9+
### Option 1: URL Path (Recommended)
10+
11+
```
12+
GET /api/v2/properties
13+
GET /api/v2/users/me
14+
```
15+
16+
### Option 2: Accept Header
17+
18+
```
19+
Accept: application/vnd.propchain.v2+json
20+
```
21+
22+
### Option 3: Custom Header
23+
24+
```
25+
X-API-Version: v2
26+
```
27+
28+
If no version is specified, the request defaults to **v2**.
29+
30+
## Version Status
31+
32+
| Version | Status | Released | Sunset Date |
33+
|---------|--------|----------|-------------|
34+
| v1 | Deprecated | 2026-01-01 | 2026-12-31 |
35+
| v2 | Active | 2026-04-01 | — |
36+
37+
## Deprecation Policy
38+
39+
When a version is deprecated:
40+
41+
1. **Response headers** include deprecation warnings:
42+
- `Deprecation: true`
43+
- `Sunset: <date>`
44+
- `Link: <next-version-docs>; rel="successor-version"`
45+
46+
2. **Console warnings** are logged on the server for deprecated-version requests.
47+
48+
3. A **6-month overlap** period exists where both versions remain functional.
49+
50+
## Breaking Changes
51+
52+
Breaking changes only occur in new major versions. Within a version:
53+
54+
- New fields may be added to responses ( additive )
55+
- Existing fields will not be removed or renamed
56+
- Response codes will not change for existing success paths
57+
- New optional parameters may be added to requests
58+
59+
## Migration from v1 to v2
60+
61+
Key differences:
62+
63+
- Versioning headers now included in all responses
64+
- New endpoint decorators available: `@ApiVersion('v2')`
65+
- Response format standardized across all endpoints
66+
67+
To migrate, update your base URL:
68+
69+
```diff
70+
- GET https://api.propchain.io/api/v1/properties
71+
+ GET https://api.propchain.io/api/v2/properties
72+
```
73+
74+
## Monitoring Deprecated Usage
75+
76+
Check the `X-API-Version` header in your requests. If you see `v1`, migrate to `v2` before the sunset date.
77+
78+
For questions, contact support@propchain.com.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Incident Runbook: Rate-Limit Misfire
2+
3+
## Symptoms
4+
5+
- Legitimate users receiving `429 Too Many Requests` unexpectedly
6+
- Rate-limit headers show exhausted counters for low-traffic IPs
7+
- Redis memory growing unbounded on rate-limit keys
8+
- `console.error('Rate limit check error:', error)` appearing in logs
9+
10+
## Diagnosis
11+
12+
### 1. Inspect Redis Rate-Limit Keys
13+
14+
```bash
15+
# Connect to Redis
16+
redis-cli
17+
18+
# List all rate-limit keys
19+
KEYS rate-limit:*
20+
21+
# Check a specific user's counter
22+
HGETALL rate-limit:user:<userId>
23+
24+
# Check IP-based counter
25+
HGETALL rate-limit:ip:<ipAddress>
26+
27+
# Check endpoint-specific counters
28+
HGETALL rate-limit:endpoint:POST:/api/auth/login
29+
30+
# Check TTL on a key
31+
TTL rate-limit:user:<userId>
32+
```
33+
34+
### 2. Check for Key Accumulation
35+
36+
If keys are not expiring:
37+
38+
```bash
39+
# Count total rate-limit keys
40+
SCAN 0 MATCH rate-limit:* COUNT 1000
41+
42+
# Check Redis memory usage
43+
INFO memory
44+
```
45+
46+
### 3. Verify Guard Configuration
47+
48+
Check `src/auth/rate-limit.config.ts` for:
49+
- Window size (should match `RATE_LIMIT_WINDOW_MS`)
50+
- Max requests per window
51+
- Whether endpoint-specific overrides are misconfigured
52+
53+
## Resolution
54+
55+
### Manual Counter Reset
56+
57+
```bash
58+
# Reset a specific user's rate limit
59+
DEL rate-limit:user:<userId>
60+
61+
# Reset an IP's rate limit
62+
DEL rate-limit:ip:<ipAddress>
63+
64+
# Nuclear option — flush all rate-limit keys (CAREFUL)
65+
# Only in production if widespread misfire
66+
redis-cli KEYS "rate-limit:*" | xargs redis-cli DEL
67+
```
68+
69+
### If Redis Is Unreachable
70+
71+
The `RateLimitGuard` catches Redis errors and **allows the request** (fail-open). Check:
72+
73+
1. Redis connection string in `.env` (`REDIS_URL`)
74+
2. Redis server health: `redis-cli ping`
75+
3. Network connectivity between app server and Redis
76+
77+
### If Counters Are Stuck
78+
79+
1. Restart the NestJS application to reinitialize the RateLimitService
80+
2. Check for orphaned keys from previous deployments
81+
3. Verify `cache-manager-redis-store` version compatibility
82+
83+
## Escalation
84+
85+
1. **P1 (production down)**: Page on-call engineer, flush Redis rate-limit keys, restart app
86+
2. **P2 (intermittent 429s)**: Check Redis memory, review rate-limit config, file ticket
87+
3. **P3 (false positives)**: Add IP/user to skip list via `@SkipRateLimit()` decorator
88+
89+
## Prevention
90+
91+
- Monitor Redis memory via `INFO memory` in health checks
92+
- Set `maxmemory-policy allkeys-lru` on Redis to auto-evict stale keys
93+
- Add Grafana alert for `redis_connected_clients` and `used_memory`

‎docs/MFA_ROADMAP.md‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< ours
12
# Multi-Factor Authentication (MFA) Roadmap
23

34
## Purpose
@@ -40,3 +41,52 @@ These endpoints are currently implemented in the `AuthService` as enrollment and
4041
- The API contract is simple and opt-in.
4142
- Existing auth workflows continue to work for users who do not enable MFA.
4243
- Future expansion can include push notifications, SMS OTP, or hardware keys.
44+
=======
45+
# MFA / 2FA Roadmap
46+
47+
## Current State
48+
49+
Two-factor authentication is fully implemented using TOTP (Time-based One-Time Password).
50+
51+
### Endpoints
52+
53+
| Endpoint | Method | Description |
54+
|----------|--------|-------------|
55+
| `POST /api/auth/2fa/setup` | POST | Initialize 2FA — returns secret + QR code URL |
56+
| `POST /api/auth/2fa/verify` | POST | Verify a TOTP code and activate 2FA |
57+
| `POST /api/auth/2fa/disable` | POST | Disable 2FA (requires current TOTP code) |
58+
| `POST /api/auth/2fa/backup-codes` | POST | Regenerate backup codes |
59+
60+
### DTOs
61+
62+
- **`VerifyTwoFactorDto`** — `{ code: string }` — used by `POST /api/auth/2fa/verify`
63+
- **`SetupTwoFactorResponse`** — `{ secret: string; qrCodeUrl: string; otpAuthUrl: string }`
64+
65+
### Login Flow with 2FA
66+
67+
1. User submits email + password
68+
2. If `twoFactorEnabled === true`, server returns `{ requiresTwoFactor: true, tempToken }`
69+
3. Client calls `POST /api/auth/2fa/verify` with `tempToken` + TOTP `code`
70+
4. Server validates code against stored `twoFactorSecret` using `verifyTotpCode()`
71+
5. Backup codes are supported — each use invalidates the code
72+
73+
### Backup Codes
74+
75+
- 8 codes generated at setup via `generateBackupCodes()`
76+
- Stored as SHA-256 hashes in `twoFactorBackupCodes` array
77+
- Verified with timing-safe comparison via `verifyBackupCode()`
78+
- Each code can only be used once
79+
80+
### Dependencies
81+
82+
- `src/auth/security.utils.ts` — TOTP generation/verification, backup codes, QR code URL
83+
- `src/auth/auth.service.ts` — `setupTwoFactor()`, `verifyTwoFactor()`, `disableTwoFactor()`
84+
- `src/types/prisma.types.ts` — `twoFactorEnabled`, `twoFactorSecret`, `twoFactorBackupCodes` fields
85+
86+
## Future Enhancements
87+
88+
- [ ] SMS-based 2FA as fallback
89+
- [ ] Hardware key (WebAuthn/FIDO2) support
90+
- [ ] Admin-enforced 2FA for agent/admin roles
91+
- [ ] Trusted device management
92+
>>>>>>> theirs

‎docs/architecture.md‎

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Architecture Diagram
2+
3+
```mermaid
4+
graph TB
5+
Client[Client App] -->|HTTP/WS| Gateway[NestJS Gateway]
6+
7+
Gateway --> Auth[Auth Module]
8+
Gateway --> Users[Users Module]
9+
Gateway --> Properties[Properties Module]
10+
Gateway --> Transactions[Transactions Module]
11+
Gateway --> Documents[Documents Module]
12+
Gateway --> Search[Search Module]
13+
Gateway --> Admin[Admin Module]
14+
Gateway --> Fraud[Fraud Module]
15+
Gateway --> Notifications[Notifications Module]
16+
17+
Auth --> JWT[JWT Strategy]
18+
Auth --> Google[Google OAuth]
19+
Auth --> MFA[2FA / TOTP]
20+
Auth --> RateLimit[Rate Limit Guard]
21+
Auth --> APIKeys[API Key Management]
22+
23+
Users --> Prisma[(Prisma Client)]
24+
Properties --> Prisma
25+
Transactions --> Prisma
26+
Documents --> Prisma
27+
Search --> Prisma
28+
Admin --> Prisma
29+
Fraud --> Prisma
30+
31+
Prisma --> PostgreSQL[(PostgreSQL)]
32+
33+
Properties --> Blockchain[Blockchain Service]
34+
Blockchain --> Ethereum[Ethereum / Sepolia]
35+
36+
Documents --> Uploads[File Uploads]
37+
Uploads --> LocalFS[Local FS / S3]
38+
39+
Notifications --> WebSocket[WebSocket Gateway]
40+
Notifications --> Email[Email Service]
41+
Notifications --> SMS[SMS Service]
42+
43+
Fraud --> Email
44+
Admin --> Backup[Backup Service]
45+
Backup --> PgDump[pg_dump]
46+
47+
Search --> Cache[(Redis Cache)]
48+
RateLimit --> Cache
49+
Cache --> CacheWarming[Cache Warming]
50+
51+
Admin --> BullMQ[BullMQ Queues]
52+
Transactions --> BullMQ
53+
54+
Gateway --> GraphQL[GraphQL / Apollo]
55+
```
56+
57+
## Request Flow
58+
59+
```mermaid
60+
sequenceDiagram
61+
participant C as Client
62+
participant G as NestJS Gateway
63+
participant RL as Rate Limit Guard
64+
participant AU as Auth Service
65+
participant S as Feature Service
66+
participant DB as PostgreSQL
67+
participant BC as Blockchain
68+
69+
C->>G: HTTP Request
70+
G->>RL: canActivate()
71+
RL->>RL: Check Redis counters
72+
alt Rate limit exceeded
73+
RL-->>C: 429 Too Many Requests
74+
else Within limits
75+
RL->>G: Allow
76+
G->>AU: Validate JWT
77+
AU->>AU: Verify token + roles
78+
AU->>G: Authenticated context
79+
G->>S: Handle request
80+
S->>DB: Query/Mutate
81+
DB-->>S: Result
82+
alt Blockchain required
83+
S->>BC: Record transaction
84+
BC-->>S: Tx hash
85+
end
86+
S-->>C: Response
87+
end
88+
```
89+
90+
## Module Relationships
91+
92+
| Module | Depends On | Provides |
93+
|--------|-----------|----------|
94+
| Auth | Users, JWT, Redis | Authentication, 2FA, API keys |
95+
| Users | Prisma | User CRUD, profiles |
96+
| Properties | Prisma, Blockchain, Geocoding | Property listings, images |
97+
| Transactions | Prisma, Blockchain | Transaction lifecycle |
98+
| Documents | Prisma, Uploads | Document management, signing |
99+
| Search | Prisma, Redis | Full-text search, facets, autocomplete |
100+
| Fraud | Prisma, Email | Fraud detection, alerts, auto-block |
101+
| Admin | Prisma, Backup, BullMQ | Admin ops, backups, reports |
102+
| Notifications | WebSocket, Email, SMS | Real-time + async notifications |

0 commit comments

Comments
 (0)