Backend Architecture
Backend Architecture
All server-side logic runs inside Next.js App Router API routes (app/api/). There are no
separate microservices. Three service libraries — text filtering, reputation scoring, and
anonymous fingerprinting — are shared across both API routes and edge middleware. PostgreSQL
is accessed through a single connection-pool client (lib/db/client.ts). Rate limiting is
currently in-memory (broken on serverless) and must be migrated to Upstash Redis before launch.
graph TD
subgraph "Edge (middleware.ts)"
MW["Middleware\n(rate limit · security headers)"]
end
subgraph "API Routes (app/api/)"
PR["profiles/\nGET list · POST create\nGET [alias]"]
RV["reviews/\nPOST submit\nPATCH [id]/moderate"]
RP["removal/\nPOST removal request"]
AB["reports/\nPOST abuse report"]
end
subgraph "Service Libraries (lib/)"
TF["moderation/textFilter.ts\n(regex · PII · threats)"]
FL["moderation/flagging.ts\n(risk score)"]
RS["reputation/scorer.ts\n(weighted avg · recency decay)"]
FP["anonymity/fingerprint.ts\n(hash-based reviewer ID)"]
DB["db/client.ts\n(pg connection pool)"]
end
subgraph "Database"
PG[(PostgreSQL)]
end
subgraph "External Services"
Redis["Upstash Redis\n(rate limiting — ❌ not yet)"]
HC["hCaptcha\n(CAPTCHA — ❌ not yet)"]
end
MW --> PR & RV & RP & AB
RV --> TF --> FL
RV --> FP
RV --> RS
PR & RV & RP & AB --> DB --> PG
MW -.-> Redis
RV -.-> HC
API Surface
| Route | Method | Description |
|---|---|---|
/api/profiles | GET | List profiles (search, pagination) |
/api/profiles | POST | Create profile (admin) |
/api/profiles/[alias] | GET | Single profile + reviews |
/api/reviews | POST | Submit anonymous review |
/api/reviews/[id]/moderate | PATCH | Approve / reject / quarantine |
/api/removal | POST | Removal request submission |
/api/reports | POST | Abuse report submission |
Known Issues
| Issue | Impact | Fix |
|---|---|---|
Rate limiting uses in-memory Map | Broken on serverless/Edge — resets per instance | Migrate to Upstash Redis |
| Moderation dashboard auth fails open | Anyone can access without ADMIN_SECRET | Implement session-based admin auth |
| Respect dimension missing from scorer | Reputation score understates respect | Add 0 % weight redistribution in scorer |