Skip to content

Backend Architecture

The KanjiIQ backend is a Dart Frog REST API that serves flashcard content, manages locale configurations, and provides admin analytics.

API Structure

/api/v1/
├── config/
│   └── locale/[locale]              # GET - Locale configuration
├── kanji/
│   ├── index                        # GET - List with filtering
│   ├── [id]                         # GET - Single kanji
│   └── random/index                 # GET - Random batch
├── vocabulary/
│   ├── index                        # GET - List with filtering
│   ├── [id]                         # GET - Single vocabulary
│   └── random/index                 # GET - Random batch
└── admin/                           # Protected routes (API key required)

Middleware Stack

Every request passes through a layered middleware pipeline defined in _middleware.dart:

graph TD
    R[Incoming Request] --> M1[ipBlocklistCheck]
    M1 -->|Blocked IP| R404[404 Response]
    M1 -->|Allowed| M2[securityMiddleware]
    M2 -->|Malicious Path| R404
    M2 -->|Clean| M3[corsHeaders]
    M3 --> M4[regionalAnalytics]
    M4 --> M5[requestLogger]
    M5 --> M6[databaseProvider]
    M6 --> H[Route Handler]

Middleware Details

Middleware Purpose
ipBlocklistCheck Rejects requests from blocked IP addresses (manual + auto-blocked)
securityMiddleware Blocks malicious file extension probes, detects SQL injection patterns, prevents path traversal
corsHeaders Adds CORS headers for cross-origin requests
regionalAnalytics Tracks request origin (country, device type, IP hash), flags suspicious activity, auto-blocks repeat offenders
requestLogger Logs all requests with timing information
databaseProvider Initializes PostgreSQL connection pool

Admin Middleware

Admin routes (/api/v1/admin/*) have additional protection:

  • API key authentication via X-API-Key header
  • Stricter rate limiting (50 req/min via Traefik)
  • Exempt from auto-blocking (to prevent locking out admins)

Database Connection

The backend resolves database credentials in priority order:

  1. DATABASE_URL environment variable (production — injected from Kubernetes Secret)
  2. Individual env vars: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
  3. Defaults: localhost:5432

Security Features

Malicious Path Detection

Returns 404 for requests probing for server-side scripts, sensitive configuration files, and common framework endpoints that do not exist in this stack.

Auto-Blocking

The analytics middleware implements automatic IP blocking:

  1. Each suspicious request is flagged in the regional_analytics table
  2. IPs that accumulate suspicious requests above a configurable threshold are automatically added to the blocklist
  3. Auto-blocks expire after a configurable duration
  4. Admin paths are exempt to prevent self-lockout

Privacy Compliance

Analytics data follows GDPR/CCPA requirements:

  • Raw IP addresses are retained for 7 days only
  • After 7 days, IPs are replaced with SHA-256 hashes
  • Country-level geolocation uses Cloudflare's CF-IPCountry header (no IP geolocation databases)
  • Users can request data deletion via admin API