pounce/memory-bank/systemPatterns.md

3.1 KiB

Pounce - System Patterns

Architecture

┌─────────────────┐      ┌────────────────────┐
│   Next.js App   │◀────▶│     FastAPI API     │
│   (Port 3000)   │      │     (Port 8000)     │
└─────────────────┘      └──────────┬─────────┘
                                    │
                    ┌───────────────┼────────────────┐
                    │               │                │
              ┌─────▼─────┐   ┌────▼────┐     ┌─────▼─────┐
              │ Postgres  │   │  Redis  │     │ External   │
              │ (primary) │   │ queue + │     │ I/O (DNS,  │
              └───────────┘   │ limiter │     │ WHOIS, HTTP│
                              └─────────┘     └───────────┘

Separate processes (recommended):
- API: `ENABLE_SCHEDULER=false`
- Scheduler: `python backend/run_scheduler.py`
- Worker: `arq app.jobs.worker.WorkerSettings`

Design Patterns

Backend

  • Repository Pattern: Database operations abstracted through SQLAlchemy
  • Service Layer: Business logic in /services (DomainChecker, AuthService)
  • Dependency Injection: FastAPI's Depends() for DB sessions and auth
  • Async First: All database and I/O operations are async

Frontend

  • Component-Based: Reusable React components
  • Global State: Zustand store for auth and domain state
  • API Client: Centralized API calls in /lib/api.ts
  • Server Components: Next.js 14 App Router with client components where needed

Authentication Flow

1. User registers → Creates user + free subscription
2. User logs in → Backend sets HttpOnly auth cookie (JWT inside cookie)
3. Frontend calls API with `credentials: 'include'`
4. Backend validates cookie → Returns user data
5. OAuth uses `state` + validated redirects, then sets cookie (no JWT in URL)

Domain Checking Strategy

1. Normalize domain (lowercase, remove protocol/www)
2. Quick DNS check (A + NS records)
3. Full WHOIS lookup for details
4. If WHOIS says available but DNS has records → Trust DNS
5. Store result and update domain status

Scheduler Pattern

APScheduler (AsyncIO mode) in separate scheduler process
    │
    ├── Domain checks (tier-based frequency)
    ├── TLD price scrape + change detection
    ├── Auction scrape + cleanup
    └── Health cache refresh (writes DomainHealthCache used by UI)

Database Models

User (1) ─────┬───── (N) Domain
              │
              └───── (1) Subscription

Domain (1) ────── (N) DomainCheck

API Response Patterns

  • Success: JSON with data
  • Error: {"detail": "error message"}
  • Pagination: {items, total, page, per_page, pages}
  • Auth errors: 401 Unauthorized
  • Permission errors: 403 Forbidden