# WarpBox Tech Stack

This document is a light technical map of WarpBox. It avoids deep internals,
but should be enough to understand what the project is built from and where the
main pieces live.

## Backend

WarpBox is written in Go.

Main libraries:

- `github.com/gin-gonic/gin` for HTTP routing, middleware, JSON responses, and
  HTML template rendering.
- `github.com/gin-contrib/gzip` for compressed static asset responses.
- `github.com/spf13/cobra` for the small command-line interface.

The app starts from `cmd/main.go`. The `warpbox run` command calls the server
package, loads templates from `templates/*.html`, registers routes, mounts
`/static`, starts the thumbnail worker, and serves HTTP.

The main request surfaces are:

- `GET /` for the upload box UI.
- `GET /box/:id` for shared box pages.
- `GET /box/:id/login` and `POST /box/:id/login` for password-protected boxes.
- `GET /box/:id/download` for ZIP downloads.
- `GET /box/:id/files/:filename` for individual file downloads.
- `GET /box/:id/thumbnails/:file_id` for image previews.
- `POST /box` for new upload box creation.
- `POST /box/:id/files/:file_id/upload` for manifest-based uploads.
- `POST /box/:id/files/:file_id/status` for upload status updates.
- `POST /box/:id/upload` and `POST /upload` for legacy upload compatibility.
- `/admin/*` for the admin UI and settings.

## Frontend

The frontend is server-rendered HTML with vanilla JavaScript.

- Templates live in `templates/`.
- Browser behavior lives in `static/js/app.js` and `static/js/box.js`.
- Styling lives in `static/css/`.
- Visual assets, fonts, icons, cursors, popups, and sprites live under
  `static/`.

There is no frontend build step. The browser receives HTML from Gin templates
and static assets directly from the Go server.

## Storage

WarpBox uses the local filesystem for box data and BadgerDB for app metadata.

Uploaded boxes are stored under:

```text
data/uploads/
```

Each box directory contains uploaded files plus a `.warpbox.json` manifest.
The manifest tracks file names, statuses, retention, password metadata,
download options, and thumbnail state. BadgerDB stores users, tags, sessions,
and runtime settings overrides.

## Upload Flow

```mermaid
sequenceDiagram
    participant Browser as Browser UI
    participant Server as Gin server
    participant Store as boxstore
    participant Disk as Local disk

    Browser->>Server: POST /box
    Server->>Store: create box directory + manifest
    Store->>Disk: write .warpbox.json
    Server-->>Browser: box id + upload URLs
    Browser->>Server: POST /box/:id/files/:file_id/upload
    Server->>Store: save file and update manifest
    Store->>Disk: write file + manifest
    Browser->>Server: POST /box/:id/files/:file_id/status
    Server->>Store: update file status
    Store->>Disk: rewrite manifest
    Browser->>Server: GET /box/:id/status
    Server-->>Browser: current file states
```

## Download Flow

Shared boxes are served from `/box/:id`.

Users can download individual files when the box allows it. ZIP downloads are
created on demand from the files currently marked complete. One-time download
boxes force ZIP download and delete the box after a successful ZIP response.

```mermaid
flowchart LR
    Shared[Shared box page]
    File[Individual file download]
    Zip[ZIP download]
    OneTime[One-time ZIP only]
    Delete[Delete box after success]

    Shared --> File
    Shared --> Zip
    OneTime --> Zip
    Zip --> Delete
```

## Thumbnail Worker

The thumbnail worker is a background goroutine. On each pass it scans upload
boxes, finds complete image files without thumbnails, generates small JPEG
previews, and updates the manifest.

Tuning is done with:

- `WARPBOX_THUMBNAIL_BATCH_SIZE`
- `WARPBOX_THUMBNAIL_INTERVAL_SECONDS`

## Configuration

Runtime configuration is centralized in `lib/config`. Startup applies built-in
defaults, environment variables, then safe BadgerDB settings overrides.

Storage paths are derived from `WARPBOX_DATA_DIR`:

```text
<WARPBOX_DATA_DIR>/uploads
<WARPBOX_DATA_DIR>/db
```

The admin account is bootstrapped from `WARPBOX_ADMIN_PASSWORD` when no admin
user exists. If the password is empty, admin login stays disabled unless an
admin user already exists in BadgerDB.

Primary environment variables:

- `WARPBOX_DATA_DIR`
- `WARPBOX_ADMIN_PASSWORD`
- `WARPBOX_ADMIN_USERNAME`
- `WARPBOX_ADMIN_EMAIL`
- `WARPBOX_ADMIN_ENABLED`
- `WARPBOX_ALLOW_ADMIN_SETTINGS_OVERRIDE`
- `WARPBOX_ADMIN_COOKIE_SECURE`
- `WARPBOX_GUEST_UPLOADS_ENABLED`
- `WARPBOX_API_ENABLED`
- `WARPBOX_ZIP_DOWNLOADS_ENABLED`
- `WARPBOX_ONE_TIME_DOWNLOADS_ENABLED`
- `WARPBOX_RENEW_ON_ACCESS_ENABLED`
- `WARPBOX_RENEW_ON_DOWNLOAD_ENABLED`
- `WARPBOX_DEFAULT_GUEST_EXPIRY_SECONDS`
- `WARPBOX_MAX_GUEST_EXPIRY_SECONDS`
- `WARPBOX_GLOBAL_MAX_FILE_SIZE_GB`
- `WARPBOX_GLOBAL_MAX_BOX_SIZE_GB`
- `WARPBOX_DEFAULT_USER_MAX_FILE_SIZE_GB`
- `WARPBOX_DEFAULT_USER_MAX_BOX_SIZE_GB`
- `WARPBOX_SESSION_TTL_SECONDS`
- `WARPBOX_BOX_POLL_INTERVAL_MS`
- `WARPBOX_THUMBNAIL_BATCH_SIZE`
- `WARPBOX_THUMBNAIL_INTERVAL_SECONDS`

Size limit settings use `_GB` env names with `1024^3` conversion. Legacy `_MB` and `_BYTES` names remain accepted for compatibility. `WARPBOX_ADMIN_ENABLED`
accepts `auto`, `true`, or `false`.

The HTTP listen address is configured through the CLI flag:

```bash
go run ./cmd run --addr :8080
```

## Code Map

```text
cmd/main.go              CLI setup
lib/server/server.go     Gin engine setup and worker startup
lib/server/handlers.go   HTTP handlers
lib/server/admin.go      Admin handlers
lib/routing/routes.go    Route table
lib/boxstore/store.go    Box manifests, uploads, downloads, retention
lib/boxstore/thumbnails.go
                          Thumbnail scanning and generation
lib/config/config.go     Typed config and settings definitions
lib/metastore/           BadgerDB metadata store
lib/models/models.go     Shared data structures
```

## Tests

Existing tests cover config, storage, server security, and metastore behavior.
Run them with:

```bash
go test ./...
```
