Skip to main content

System Architecture

Traces is built as a modern, cloud-native application with a focus on security, reliability, and forensic integrity.

Architecture Diagram

                                 ┌─────────────────┐
│ Clerk Auth │
└────────┬────────┘

┌──────────────┐ REST/SSE ┌─────────▼────────┐
│ Customer │◄──────────────►│ Next.js App │
│ Browser │ │ (Railway) │
└──────────────┘ └─────────┬────────┘

┌─────────▼────────┐
│ PostgreSQL │
│ (Supabase) │
└─────────┬────────┘

┌─────────▼────────┐
│ Job Queue │
│ (pg-boss / PG) │
└─────────┬────────┘

┌─────────▼────────┐
│ Worker Node │
│ (Railway) │
└─────────┬────────┘

┌───────────────────────────┼───────────────────────────┐
│ │ │
┌─────────▼────────┐ ┌─────────▼────────┐ ┌─────────▼────────┐
│ Platform APIs │ │ Cloudflare R2 │ │ Doppler │
│ (Slack, etc.) │ │ (File Storage) │ │ (Secrets) │
└──────────────────┘ └──────────────────┘ └──────────────────┘
SSRF guard

All outbound requests to platform/connector-controlled URLs (from both the web app and the worker) pass through a shared SSRF guard that blocks internal/metadata/private targets and re-validates each redirect hop. See Security.

Components

Web Application (Next.js)

  • Framework: Next.js 14 with App Router
  • Hosting: Railway (apps/web/railway.toml)
  • Responsibilities:
    • User interface for customers and analysts
    • REST API endpoints (route handlers under apps/web/src/app/api)
    • Server-Sent Events for real-time updates
    • The connector/endpoint editor and test runner

Worker Node

  • Runtime: Node.js
  • Hosting: Railway
  • Responsibilities:
    • Process collection jobs from queue
    • Execute API calls against platforms
    • Handle pagination and dependencies
    • Store collected data
    • Compute and validate hashes

Database (PostgreSQL)

  • Provider: Supabase
  • ORM: Prisma
  • Responsibilities:
    • Store all application data
    • Chain of custody events
    • Collection metadata
    • Connector configurations

Queue (pg-boss)

  • Backend: PostgreSQL (the same Supabase database)
  • Library: pg-boss (packages/queue)
  • Responsibilities:
    • Job queue for collections, credential validation, delivery, and cleanup
    • Job status tracking
    • Retry handling
    • Priority queuing
note

There is no separate Redis/Upstash queue. The job queue is backed by Postgres via pg-boss; packages/queue maps familiar BullMQ-style concepts onto pg-boss equivalents.

File Storage (Cloudflare R2)

  • Provider: Cloudflare
  • Responsibilities:
    • Store collected files
    • Store delivery ZIP files
    • Server-side encryption
    • Versioning for integrity

Secrets Management (Doppler)

  • Service: Doppler (apps/web/src/lib/secrets)
  • Responsibilities:
    • Store credentials encrypted with AES-256-GCM (only a secret reference is kept in the DB)
    • Credential retrieval at collection time
    • Access logging (credential_access_logs)
    • Secure deletion / revocation
note

Credentials are stored in Doppler, not AWS Secrets Manager. The DB column is still named secret_arn for historical reasons but holds a Doppler secret name. The web app's only AWS dependency is the S3 SDK used to talk to Cloudflare R2.

Authentication (Clerk)

  • Provider: Clerk
  • Responsibilities:
    • User authentication
    • Session management
    • OAuth providers
    • Webhook notifications

Data Flow

Collection Request

1. Customer creates collection request
2. Web app validates and stores in database
3. Job enqueued via pg-boss (Postgres-backed)
4. Worker picks up job
5. Worker validates credentials
6. Worker executes connector endpoints
7. Worker stores files in R2
8. Worker updates database with progress
9. Web app notifies customer via SSE

Data Collection

1. Worker retrieves connector configuration
2. Worker retrieves credentials from Doppler (decrypted in-memory)
3. Worker executes endpoints in order
4. For each endpoint:
a. Make API request
b. Log request/response details
c. Handle pagination
d. Extract and store data
e. Compute file hash
f. Validate hash
g. Store file in R2
5. Update collection progress
6. Handle dependencies between endpoints

Delivery

1. Collection marked complete
2. Analyst reviews and signs off
3. Worker generates ZIP package
4. ZIP stored in R2
5. Customer notified
6. Customer downloads via signed URL

Technology Choices

ComponentTechnologyReason
FrontendNext.js + ReactModern, full-stack, SSR
DatabasePostgreSQL (Supabase)Reliable, full-featured
Queuepg-boss (Postgres)One fewer moving part; transactional with the DB
StorageCloudflare R2S3-compatible, cost-effective
SecretsDoppler (AES-256-GCM)Managed secrets, app-side encryption
AuthClerkDeveloper-friendly, secure

Scaling Considerations

Horizontal Scaling

  • Web: Railway service (scalable)
  • Workers: Multiple worker instances on Railway
  • Database: Supabase scaling options

Performance

  • Connection pooling for database (transaction pooler at runtime, direct connection for migrations)
  • pg-boss for durable background job processing
  • Stream processing for large files
  • Pagination for API responses

Next Steps