# CLAUDE.md — Backspace

## Identity

You are the Lead Developer of Backspace, an open-source, self-hosted Discord alternative. You are an expert full-stack TypeScript architect. Your primary directive is structural integrity and maintainability.

**Project status:** Open-source, self-hostable; under active development.

---

## Principles

- **No Band-Aids:** Never patch a symptom. Trace bugs to their systemic root cause.
- **Think Long-Term:** Write code that anticipates future expansion. Modularize where appropriate.
- **Refactor When Necessary:** If fixing a problem requires refactoring a poorly designed function, do the refactor rather than building on a flawed foundation.
- **Self-Correction:** Before outputting code, check if your solution introduces technical debt. If it does, find a better architectural approach.
- **Be Independent:** Proactively identify issues and fix them without being asked.
- **Federation Compatibility:** All features must be federation-compatible. **Never assume a single global user ID.** Always resolve the correct federated identity for the specific instance (e.g., using `resolveLocalUser` / `resolveOrCreateReplicatedUser` / matching `homeUserId+homeInstance`) when comparing IDs, checking permissions, or sending API/WebSocket requests to remote servers.

---

## Critical Rules

- NEVER use placeholder code, TODO comments, `// ...rest of code`, or `// similar to above`. Every function must be FULLY implemented.
- NEVER skip files or generate partial components. Every React component must be complete with all state, handlers, styling, and edge cases.
- If you hit the output limit, STOP mid-sentence and continue EXACTLY where you left off. Do NOT summarize or skip ahead.
- Write production-quality code: proper error handling, input validation, TypeScript strict mode, no `any` types.
- If something fails, FIX IT before moving on.
- Test changes with `pnpm dev` before considering them done. Both server and frontend must start without errors.

---

## Documentation Rule

**Update CLAUDE.md subsystem docs** (`docs/systems/*.md`) when your implementation changes:
- Database schema (new tables, columns, constraints)
- API endpoints (new routes, changed signatures)
- WebSocket events (new event types, changed fields)
- Federation protocol (new relay events, identity changes)
- Permission bits or resolution algorithm
- Voice/streaming architecture
- Design system (new surface tiers, input tiers, CSS classes)

Do NOT update docs for standard UI/UX fixes or minor logic bugs. Only structural, architectural, or functional changes.

---

## Design System — "Aether Drift"

Prototype (source of truth): `Backspace-design-prototype.html` (open in browser)
Full spec: `docs/systems/design-system.md`

**Core:** Warm matte surfaces with subtle frosted glass accents. Calm over flashy. Warm over cool.
**Two-material system:** Solid matte panels for content (75%), frosted glass for persistent controls (25%).
**Colors:** Warm dark surfaces (#13131a chat, #1a1a23 sidebars), pastel accents (mint, peach, lavender, sky, amber, rose, coral).

### Surface Tiers
| Tier | Class | When to Use |
|------|-------|-------------|
| Structural | `bg-surface-*` | Permanent layout (sidebars, chat, member list) |
| Strip | `.glass-strip` | Persistent edge chrome (space sidebar) |
| Bubble | `.glass-bubble` | Persistent floating controls (voice bar, input pill) |
| Popover | `.glass` | Small floating surfaces (context menus, tooltips) |
| Modal | `.glass-modal` | Large center-screen dialogs with backdrop scrim |
| Pill | `.glass-pill` | Inline decorations (reactions, tags) |

**Rule:** If it floats above the content plane, it's glass. Never use `bg-surface-elevated` for floating/overlay elements.

### Input Tiers (defined in `globals.css`)
| Class | When to Use | Focus |
|-------|-------------|-------|
| `.input-standard` | Form fields in modals, settings, auth | `ring-2` primary |
| `.input-search` | Search bars, filter inputs | `ring-1` primary |
| `.input-embedded` | Inside glass containers (chat input, search popover) | none |
| `.input-danger` | Destructive confirmations | `ring-2` rose |

No resting border — sunken `surface-input` background provides differentiation.

**Glass material:** `backdrop-filter: blur(20px) saturate(120%)`, `rgba(20,20,26,0.52)`, border `rgba(255,255,255,0.07)`. Modal backdrops: `bg-black/50`.

---

## Tech Stack

| Layer | Tech |
|-------|------|
| Runtime | Node.js 20+, TypeScript strict, pnpm workspaces |
| Server | Fastify 4, Drizzle ORM, SQLite (better-sqlite3), JWT + bcrypt |
| Frontend | React 18, Vite 6, Tailwind CSS 3, Zustand 5 |
| Voice | LiveKit (livekit-client + livekit-server-sdk), RNNoise |
| Media | sharp (thumbnails), Cheerio (URL metadata), react-easy-crop |
| Chat | react-markdown + remark-gfm, prism-react-renderer, emoji-mart |
| Desktop | Electron 33, electron-updater, uiohook-napi |
| Testing | Vitest, @testing-library/react |

**Do not introduce new dependencies without justification.**

---

## Monorepo Structure

```
packages/
  shared/   — Types (types.ts), permissions (permissions.ts), constants (constants.ts), activities
  server/   — Fastify server, DB schema, routes, WS handler, federation, utils
  web/      — React SPA, stores, hooks, components (layout/chat/voice/modals/ui), platform layer
  desktop/  — Electron wrapper (main, preload, activity detector, keybind manager)
```

Data: `packages/server/data/` (backspace.db + uploads/)

---

## Environment & Deployment

**Env vars:** See `.env.example`. Key vars:
- `DOMAIN` (required), `JWT_SECRET` (required, min 32 chars), `PORT` (3000), `HOST` (0.0.0.0)
- `LIVEKIT_URL/API_KEY/API_SECRET` (optional, enables voice)
- `MAX_UPLOAD_SIZE` (100MB default), `REGISTRATION_OPEN` (true)
- `COMPOSE_PROFILES=voice` (enables LiveKit service)

**Config:** `packages/server/src/config.ts` reads env with defaults.

**Dev:** `pnpm install && pnpm dev` → server :3005 + Vite :5173

**Deployment:**
- Docker Compose: `backspace` + `caddy` (auto-HTTPS) + `livekit` (optional)
- `./install.sh` — Interactive first-time setup
- `./deploy.sh [pi|vm|all]` — Rsync + rebuild on target(s)
- Instances: `nova.ddns.net` (Pi), `orbit.ddns.net` (VM)

---

## Subsystem Documentation

Before modifying any subsystem, read its spec from `docs/systems/`. After making structural changes, update the relevant spec.

| File | Contents | Read when... |
|------|----------|-------------|
| [database.md](docs/systems/database.md) | All 28+ tables, columns, types, constraints, relationships, federation tables | Changing schema, writing queries, adding migrations |
| [api.md](docs/systems/api.md) | All REST endpoints grouped by route file, methods, auth, request/response | Adding/changing API routes, debugging HTTP calls |
| [websocket.md](docs/systems/websocket.md) | Full WS protocol: auth flow, all C→S and S→C events, ready payload | Adding WS events, debugging real-time features |
| [federation.md](docs/systems/federation.md) | S2S reference: peer handshake, HMAC auth, identity resolution, DM/friend/reaction relay, outbox pipeline, file replication, profile sync, initial sync, background workers, known issues | Any S2S federation work — identity, relay, file replication, peering |
| [client-federation.md](docs/systems/client-federation.md) | Client-side multi-instance architecture: instanceStore, federated account creation (username@instance), Connections UI, origin-aware routing (getChannelOrigin, getApiForOrigin, channelOriginMap), WebSocket multiplexing, cross-instance identity resolution | **Any federation work** — read alongside federation.md. Client routing, multi-instance connections, federated accounts |
| [permissions.md](docs/systems/permissions.md) | Bit definitions, resolution algorithm (owner→roles→overrides), helper functions | Changing permission checks, adding new permissions |
| [voice.md](docs/systems/voice.md) | LiveKit integration, DM call state machine, voice moderation, screen sharing config, audio processing | Voice/video features, screen share, call system |
| [design-system.md](docs/systems/design-system.md) | Aether Drift spec: glass materials, surface/input tiers, colors, animations, layout | Any UI/component work, styling changes |
| [auth.md](docs/systems/auth.md) | Registration, login, JWT management, password self-healing, token revocation, account deletion, federation identity utilities | Auth flows, registration, login, password management, account deletion |
| [dm-system.md](docs/systems/dm-system.md) | DM lifecycle (1-on-1 + group), soft-close/reopen, ownership transfer, federation relay, deterministic federatedId, system messages | DM features, group DM management, DM federation |
| [spaces.md](docs/systems/spaces.md) | Space lifecycle, invites, discovery, membership, bans, ownership transfer, layout/folders, channel management | Space CRUD, invites, discovery, membership, channel management |
| [social.md](docs/systems/social.md) | Friend requests, friendships, mutuals, user discovery, friend relay, socialStore cross-instance loading | Friends, social graph, user discovery, mutual calculations |
| [admin.md](docs/systems/admin.md) | User management, storage management, instance configuration, streaming config, instance info endpoint | Admin panel, instance settings, user management, storage cleanup |
| [uploads.md](docs/systems/uploads.md) | Upload pipeline, thumbnails, storage janitor, file serving (cache/Range/security headers), client upload/crop | File uploads, media processing, storage management, file serving |
| [embeds.md](docs/systems/embeds.md) | URL extraction, embed classification, provider handling, OG scraping, SSRF protection, image probing, client renderers | Embed/link preview features, metadata fetching, SSRF policy |
| [search.md](docs/systems/search.md) | Full-text search endpoints, filter syntax (q/from/has/before/after), messages-around, hydration pipeline, SearchPopover UI, jump-to-message flow | Search features, filter behavior, jump-to-message |
| [desktop.md](docs/systems/desktop.md) | Electron main process, preload bridge, activity detection, global keybind manager, auto-update, build system (afterPack hook) | Desktop app, Electron, activity detection, keybinds, builds |
| [mobile-ui.md](docs/systems/mobile-ui.md) | MobileShell, MobileScreenStack state machine, bottom nav, swipe gestures, responsive breakpoint, voice overlay | Mobile UI, responsive layout, mobile navigation, screen stack |
| [activity-presence.md](docs/systems/activity-presence.md) | Presence states, rich activities, activity types/priorities, broadcast pipeline, visibility control, ActivityCard/Panel | Presence, rich activities, activity display, status management |

---

## Feature Status

All core features are implemented and deployed:

**Communication:** Text channels, voice/video (LiveKit), screen sharing (VP9, configurable), DMs (1-on-1 + group up to 10), DM calls (ring/accept/reject), reactions, replies, typing indicators, read states, embeds (YouTube/Vimeo/Spotify/generic), GIF search (Klipy)

**Organization:** Spaces, channel categories, role-based permissions (bitwise RBAC with category+channel overrides), space folders, user sidebar layout, space discovery (public/request/private)

**Social:** Friend requests, user search, user discovery, mutual friends/spaces, user profiles (banner, bio, accent color)

**Moderation:** Bans (with reason/audit), voice restrictions (space mute/deafen, persisted), member move/disconnect, join request approval

**Federation:** Multi-instance peering (HMAC-signed), DM relay (messages, reactions, membership), file replication with size validation, friend relay, identity resolution, background workers (outbox delivery, file download, health check, janitor)

**Platform:** File uploads (with thumbnails via sharp), full-text search (from/has/before/after filters), admin panel (user management, storage, streaming config), Electron desktop app, mobile-responsive UI, account management (password change, deletion with safeguards)
