Skip to content

Architecture

Suryaprakash edited this page Jul 27, 2026 · 1 revision

Architecture

System design and technical architecture of Nexora.


High-Level Overview

┌─────────────────────────────────────────────────────────────────┐
│                        Client (Browser)                         │
│  React 18 + TypeScript + Tailwind + Vite + WebSocket           │
└──────────────────────────┬──────────────────────────────────────┘
                           │ HTTPS / WSS
                           ▼
┌─────────────────────────────────────────────────────────────────┐
│                     Reverse Proxy (nginx)                       │
│  TLS termination, static files, rate limiting, compression     │
└──────────────────────────┬──────────────────────────────────────┘
                           │ HTTP
                           ▼
┌─────────────────────────────────────────────────────────────────┐
│                      Go API Server (Chi)                        │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │
│  │   Auth      │ │  Files      │ │  Search     │ │  Admin    │ │
│  │  (JWT,     │ │  (CRUD,     │ │  (SQLite    │ │  (Users,  │ │
│  │   TOTP,    │ │   upload,   │ │   FTS5 /    │ │   Roots,  │ │
│  │   Session) │ │   download) │ │   pg tsv)   │ │   Audit)  │ │
│  └─────────────┘ └─────────────┘ └─────────────┘ └───────────┘ │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │
│  │  Preview    │ │  Sharing    │ │  WebSocket  │ │  Jobs     │ │
│  │  (thumb,    │ │  (links,    │ │  (live      │ │  (archive,│ │
│  │   transcode)│ │   password) │ │   updates)  │ │   extract)│ │
│  └─────────────┘ └─────────────┘ └─────────────┘ └───────────┘ │
└──────────────────────────┬──────────────────────────────────────┘
                           │
           ┌───────────────┼───────────────┐
           ▼               ▼               ▼
    ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
    │   SQLite    │ │  Filesystem │ │   S3/MinIO  │
    │  (metadata, │ │  (local,    │ │  (remote    │
    │   search,   │ │   network)  │ │   roots)    │
    │   users)    │ │             │ │             │
    └─────────────┘ └─────────────┘ └─────────────┘

Frontend Architecture

Layer Technology
Framework React 18 + TypeScript
Build Vite 5
Styling Tailwind CSS 3 (JIT, dark mode)
State Zustand (global) + TanStack Query v5 (server)
Routing React Router 6
Animations Motion One
UI Primitives Base UI (Radix-like, unstyled)

Project Structure

web/
├── src/
│   ├── components/       # Reusable UI components
│   │   ├── ui/           # Base primitives (Button, Modal, Dropdown, etc.)
│   │   ├── FileBrowser.tsx   # Grid/List view
│   │   ├── FileThumb.tsx     # Thumbnail rendering
│   │   └── ...
│   ├── hooks/            # Custom hooks
│   ├── store/            # Zustand stores (ui, selection, playlists)
│   ├── api/              # TanStack Query hooks
│   ├── lib/              # Utilities (format, cn, animations)
│   └── types/            # TypeScript interfaces
├── public/
└── index.html

State Management

Store Purpose Persistence
ui Theme, view mode, density, sidebar localStorage
selection Selected paths, select mode session only
playlists Audio playlists, current track localStorage
transfers Upload/download queue session only

Backend Architecture

Layer Technology
Language Go 1.21+
Router Chi v5
Database SQLite (default) / PostgreSQL 14+
Auth JWT (HS256) + TOTP (RFC 6238)
File Storage Local FS, S3 (AWS/MinIO)
Search SQLite FTS5 / PostgreSQL tsvector
Transcoding FFmpeg
Thumbnails libvips (via bimg)
WebSocket gorilla/websocket

Project Structure

internal/
├── api/              # HTTP handlers + middleware
│   ├── server.go     # Router setup
│   ├── handlers_*.go # Grouped by domain
│   └── middleware/   # Auth, CSRF, rate limit
├── auth/             # JWT, sessions, TOTP, passwords
├── database/         # DB connections + migrations
├── storage/          # Local FS + S3 abstraction
├── search/           # FTS5 / tsvector
├── preview/          # Thumbnails, metadata, transcode
├── sharing/          # Share links
├── playlists/        # Audio playlists
├── jobs/             # Background job queue
├── config/           # Configuration
├── logger/           # Structured logging
└── metrics/          # Prometheus metrics

Authentication Flow

┌─────────┐     POST /auth/login      ┌─────────┐
│ Client  │ ───────────────────────▶ │ Server  │
└─────────┘                           └─────────┘
     │                                      │
     │         Set-Cookie: session=JWT      │
     │         HttpOnly; Secure; SameSite   │
     │◀─────────────────────────────────────│
     │                                      │
     │         GET /api/v1/files            │
     │   Cookie: session=JWT                │
     │   X-CSRF-Token: <from cookie>        │
     │────────────────────────────────────▶│
     │                                      │
     │         200 OK + files JSON          │
     │◀─────────────────────────────────────│

Database Schema (Key Tables)

-- Users
CREATE TABLE users (
    id TEXT PRIMARY KEY,
    username TEXT UNIQUE NOT NULL,
    password_hash TEXT NOT NULL,
    role TEXT NOT NULL DEFAULT 'user',
    totp_secret TEXT,
    created_at INTEGER NOT NULL
);

-- Storage Roots
CREATE TABLE roots (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    type TEXT NOT NULL,  -- 'local', 's3'
    config TEXT NOT NULL, -- JSON
    created_at INTEGER NOT NULL
);

-- Root Permissions
CREATE TABLE root_permissions (
    root_id TEXT NOT NULL REFERENCES roots(id),
    user_id TEXT NOT NULL REFERENCES users(id),
    permission TEXT NOT NULL, -- 'read', 'write'
    PRIMARY KEY (root_id, user_id)
);

-- File Metadata
CREATE TABLE files (
    root_id TEXT NOT NULL,
    path TEXT NOT NULL,
    name TEXT NOT NULL,
    is_dir INTEGER NOT NULL,
    size INTEGER,
    mime TEXT,
    modified_at INTEGER,
    extension TEXT,
    checksum TEXT,
    PRIMARY KEY (root_id, path)
);

-- FTS5 Virtual Table for Search
CREATE VIRTUAL TABLE files_fts USING fts5(
    root_id, path, name, content, tags,
    content='files', content_rowid='rowid'
);

-- Shares
CREATE TABLE shares (
    token TEXT PRIMARY KEY,
    root_id TEXT NOT NULL,
    path TEXT NOT NULL,
    permission TEXT NOT NULL,
    password_hash TEXT,
    expires_at INTEGER,
    download_count INTEGER DEFAULT 0,
    created_by TEXT NOT NULL REFERENCES users(id),
    created_at INTEGER NOT NULL
);

-- Audit Log
CREATE TABLE audit_log (
    id TEXT PRIMARY KEY,
    user_id TEXT REFERENCES users(id),
    action TEXT NOT NULL,
    resource_type TEXT,
    resource_id TEXT,
    details TEXT, -- JSON
    ip TEXT,
    created_at INTEGER NOT NULL
);

WebSocket Protocol

Client → Server: {"type": "subscribe", "roots": ["root1"]}
Server → Client: {"type": "file_created", "payload": {root, path, item}}
Server → Client: {"type": "file_updated", "payload": {root, path, item}}
Server → Client: {"type": "file_deleted", "payload": {root, path}}
Server → Client: {"type": "upload_progress", "payload": {id, progress}}
Server → Client: {"type": "notification", "payload": {level, message}}

Security Architecture

Layer Controls
Network TLS 1.3, HSTS, CSP
Transport Secure cookies, SameSite, CSRF double-submit
Application JWT validation, RBAC, input validation
Data Argon2id passwords, encrypted secrets
Storage Path traversal prevention, root boundary check

Scaling Considerations

Component Horizontal Scale Vertical Scale
API Server Stateless replicas More CPU
Database Read replicas (PG) Larger instance
Search Dedicated search index More RAM
Storage S3/MinIO cluster
WebSocket Sticky sessions / Redis pubsub More connections

Observability

Endpoint Purpose
GET /healthz Liveness probe
GET /readyz Readiness probe
GET /metrics Prometheus metrics

Key metrics: request rate, latency percentiles, active sessions, job queue depth, storage usage.


Related Pages

Clone this wiki locally