Bedrud Documentation

Map of the server/ directory and its contents.

Project Tree

bedrud/
├── apps/
│   ├── web/             # React frontend (TanStack Start)
│   ├── site/            # Astro marketing/docs site
│   ├── desktop/         # Rust + Slint desktop app
│   ├── android/         # Native Android
│   └── ios/             # Native iOS
├── agents/              # Python LiveKit bots
├── packages/api-types/  # Shared TypeScript types
├── server/              # Go backend (module: bedrud)
│   ├── cmd/
│   │   ├── bedrud/      # Production CLI entrypoint
│   │   └── server/      # Dev API-only entrypoint (Air hot-reload)
│   ├── config/          # Config structs + Load() + livekit example
│   ├── internal/
│   │   ├── auth/        # JWT, passkeys, OAuth, sessions
│   │   ├── cli/         # Cobra commands (run, install, update, user, room, …)
│   │   ├── database/    # GORM init + migrations
│   │   ├── handlers/    # Fiber HTTP handlers
│   │   ├── install/     # bedrud install/update (systemd/OpenRC/SysV)
│   │   ├── livekit/     # Embedded LiveKit binary lifecycle
│   │   ├── lkutil/      # LiveKit client helpers
│   │   ├── middleware/  # Auth, RBAC, rate limits
│   │   ├── models/      # GORM models
│   │   ├── queue/       # Async jobs + email templates
│   │   ├── repository/  # Data access layer
│   │   ├── scheduler/   # Background cleanup (gocron)
│   │   ├── server/      # Bootstrap: Run() wires everything
│   │   ├── services/    # Room cleanup, recording service
│   │   ├── storage/     # Chat/avatar/recording storage
│   │   └── utils/       # TLS certs, net helpers, …
│   ├── frontend/        # Embedded built web assets (//go:embed)
│   └── docs/            # Generated Swagger (swag)
├── docs/server/         # Engineer-facing backend docs (repo)
└── Makefile             # Build & dev automation (repo root)

Directory Map

/cmd/bedrud

Production entrypoint: Cobra CLI (run, install, update/upgrade, user, room, config, …).

/cmd/server

Dev API process (Air). No full CLI surface; may differ slightly from prod route registration.

/config

  • config.go: Config struct, Load(), env overrides
  • livekit.yaml.example: External LiveKit sample

/internal

PackageRole
authJWT, OAuth (Goth), passkeys, session store, email verification tokens
cliAll management subcommands
databaseSQLite/Postgres connection, AutoMigrate
handlersHTTP: auth, rooms, admin, webhooks, LiveKit webhook, certs
installLinux installer, in-place update/upgrade
livekitExtract/run embedded livekit-server
lkutilShared LiveKit API helpers
middlewareProtected, RequireAccess, rate limiters, email-verified gate
modelsGORM schemas
queueJob worker + handlers (delete, suspend, webhook, email, …)
repositoryData access
schedulerIdle rooms, job cleanup, cert renewal, recording retention
serverRun() bootstrap and route table (production routes)
servicesRoom cascade cleanup; recording service (planned routes)
storageDisk/S3/inline chat uploads, avatars
utilsSelf-signed TLS, safe IO, keys

/docs (within server)

Swagger/OpenAPI generated by swag → UI at /api/swagger and Scalar at /api/scalar.

Technical Deep Dive

1. Binary Embedding

  • Frontend: Built assets embedded via server/ui.go (//go:embed all:frontend)
  • LiveKit: Binary under internal/livekit/bin/; extracted at runtime and launched as a subprocess

2. LiveKit Reverse Proxy

When not livekit.external, requests under /livekit are reverse-proxied to the internal LiveKit host (install default often 127.0.0.1:7880; local multi-process dev often 7072).

3. Middleware Locals

Auth middleware stores claims in c.Locals("user"). Handlers read *auth.Claims.

4. Configuration Overrides

File + env (see Configuration). Runtime admin overrides live in SystemSettings (DB).

VariableDescription
SERVER_PORTMain listener port
SERVER_ENABLE_TLSHTTPS
SERVER_DOMAINDomain (ACME / passkey)
DB_TYPE / DB_PATHDatabase type / SQLite path
LIVEKIT_HOSTPublic LiveKit URL
LIVEKIT_API_KEYLiveKit key
JWT_SECRETAccess token secret
CONFIG_PATH / BEDRUD_CONFIGConfig file path

Coding Standards

  1. Repository pattern — handlers call repos, not GORM directly
  2. Structured errors — Fiber status + JSON
  3. Zerologlog.Info / Error / Debug (not fmt.Println)
  4. Naming — files snake_case.go, exported types PascalCase

See also