Skip to content

Engineering Overview

Cosella is a pnpm workspace monorepo managed by Turborepo. This document provides a high-level overview of the architecture.

apps/
dashboard – React web app (sales rep daily driver, 15 feature slices)
admin – React web app (internal admin panel, 15 feature slices)
desktop – Electron desktop copilot (overlay + settings windows)
marketing – Astro + React static site
docs – Astro + Starlight (this site)
storybook – Storybook 9 + Vite (component development)
packages/
ui – React component library (25+ components)
tokens – Design tokens (CSS @theme + JS constants)
domain – Zod schemas + inferred TypeScript types
api-client – openapi-fetch typed client + TanStack Query hooks
realtime – WebSocket client with exponential-backoff reconnect
auth – Auth provider, session store (stub)
permissions – Capability-based permission helpers
testing – MSW server + handlers + fixtures
observability – Error boundaries, Sentry, redaction, rate limiting
app-shell – AppShell layout, Sidebar, TopBar, CommandPalette
forms – React Hook Form + Zod integration
audio-capture – Audio capture (Web + Electron implementations)
audio-engine – Audio pipeline, VAD, Opus encoding
tooling/
eslint-config – Shared ESLint configs (base, react, boundaries)
ts-config – Shared TypeScript configs (base, react, node)
plop-templates – Handlebars templates for code generation
apps ──────> packages (one direction only, never reverse)
tokens ─────> (nothing internal)
domain ─────> (nothing internal)
ui ─────────> tokens ONLY
api-client ─> domain
realtime ───> domain
auth ───────> domain
permissions > domain + auth (declared exception)
testing ───> domain
observability > ui + domain (NEVER auth)
app-shell ──> auth + tokens + ui
forms ──────> ui
audio-capture > domain
audio-engine > domain

Enforced at lint time by eslint-plugin-boundaries.

Each dashboard and admin feature lives in features/<slice>/ with:

  • types.ts — Feature-specific TypeScript types
  • mock-data.ts — Mock data for development
  • hooks/ — Custom React hooks (data fetching, state)
  • components/ — Feature-specific UI components

Never gate on plan or role — use useCapability() from @cosella/permissions:

import { useCapability } from '@cosella/permissions';
function AdminPanel() {
const canManage = useCapability('admin:manage');
if (!canManage) return null;
return <div>Admin content</div>;
}

All TanStack Query keys use centralized factory functions:

export const callKeys = {
all: ['calls'] as const,
lists: () => [...callKeys.all, 'list'] as const,
list: (filters: CallFilters) => [...callKeys.lists(), filters] as const,
details: () => [...callKeys.all, 'detail'] as const,
detail: (id: string) => [...callKeys.details(), id] as const,
};

TanStack Router with auto-generated route trees (routeTree.gen.ts). Never edit this file manually — it regenerates on pnpm dev/pnpm build.

Tailwind v4 @theme {} blocks with no tailwind.config.js. All tokens defined in packages/tokens/src/theme.css.

  • exactOptionalPropertyTypes: true
  • noUncheckedIndexedAccess: true
  • No as casts (unless absolutely necessary with comment)
  • No any types (except generated files)
  • No ! non-null assertions

See the ADR index for recorded architectural decisions.

ADRTitle
ADR-0001Monorepo Stack Selection
ADR-0002Frontend Observability & Error Handling
ADR-0003Desktop App Scope
ADR-0004Content Protection (Stealth Mode)
ADR-0005Desktop Release Rules