Project Structure
A map of the deplo.ai monorepo for contributors and the curious: where the dashboard, API, workers, detection engine, and CLI live, and the layering rules that keep them honest.
deplo.ai is a monorepo with three deployable applications — the Next.js client, the Express server, and the npm CLI — plus shared CI workflows. The client deploys to Vercel, the server to Render, and the CLI publishes to npm as @deplo.ai/cli.
deplo-ai/
├── client/ # Next.js 16 (App Router) — deploys to Vercel
│ ├── app/
│ │ ├── page.tsx # Landing page
│ │ ├── dashboard/ # Repos, deployments, integrations, monitoring
│ │ ├── onboarding/ # Post-signup provider connection flow
│ │ ├── auth/ # OAuth callback handling
│ │ ├── cli-auth/ # Browser side of `deplo login`
│ │ └── docs/ # This documentation portal
│ ├── components/
│ │ ├── landing/ dashboard/ docs/ auth/ seo/ providers/
│ ├── lib/ # auth.ts, dashboard-api.ts, docs/navigation.ts
│ └── next.config.ts # Security headers + /api/* rewrite proxy
│
├── server/ # Express + TypeScript API — deploys to Render
│ ├── prisma/ # schema.prisma + migrations
│ └── src/
│ ├── config/ # Zod-validated env
│ ├── domain/ # Entities + repository interfaces (pure TS)
│ ├── application/
│ │ ├── services/ # Auth, Deployment, Integration, CliToken, …
│ │ ├── analysis/ # Stack-detection engine + Groq reasoning
│ │ ├── orchestration/ # DeploymentOrchestrator
│ │ └── notifications/ # Deployment lifecycle emails
│ ├── infrastructure/
│ │ ├── database/ # Prisma client + repository implementations
│ │ ├── queue/ # BullMQ: DeploymentWorker, MonitoringWorker
│ │ ├── redis/ # CacheService
│ │ ├── github/ vercel/ render/ groq/ email/ # external adapters
│ ├── interfaces/
│ │ ├── http/ # REST controllers + middleware
│ │ └── swagger/ # OpenAPI spec (dev-only UI)
│ └── shared/ # Winston logger, AppError
│
├── cli/ # @deplo.ai/cli — publishes to npm (bin: deplo)
│ └── src/
│ ├── commands/ # login, deploy, status, whoami, connect
│ ├── api.ts config.ts git.ts handoff.ts ui.ts
│
├── .github/workflows/ # ci.yml, pr-lint.yml, docker.yml, release-cli.yml
└── docker-compose.yml # Local Postgres 16 + Redis 7client/ — the web app#
A single Next.js 16 application (React 19, TailwindCSS v4, TypeScript strict) containing the marketing landing page, the dashboard, onboarding, the /cli-auth hand-off page, and this docs portal. Server components are the default; "use client" appears only where browser APIs are required.
The most architecturally important file is next.config.ts: its rewrites() proxy every /api/* request to the backend using the server-only API_URL variable, which is why the browser only ever sees one domain. There are no route handlers under app/api/ — the client contains no API logic at all. See Architecture.
The docs portal itself follows a registry pattern: lib/docs/navigation.ts is the single source of truth for the page tree, and it drives the sidebar, breadcrumbs, prev/next links, search index, and sitemap. Adding a page means one entry there plus one page.tsx.
server/ — the API and workers#
One Node.js 20 process serves the REST API (/api/v1) and runs the background workers. It follows strict clean architecture — each layer depends only inward:
| Layer | Responsibility | Depends on |
|---|---|---|
| domain/ | Entities and repository interfaces. Pure TypeScript — no framework imports of any kind. | Nothing |
| application/ | Business logic: services, the detection engine, the deployment orchestrator, notifications. | domain, shared |
| infrastructure/ | Concrete tech: Prisma, Redis, BullMQ, and the GitHub/Vercel/Render/Groq/SMTP adapters. | domain, application |
| interfaces/ | Delivery: REST controllers, middleware, Swagger. Controllers route; services decide. | application |
config/ and shared/ are usable by every layer. The composition root is src/index.ts: it connects Postgres and Redis, wires repositories → services → controllers by constructor injection, starts the BullMQ deployment worker and the five-minute monitoring scheduler, and mounts the Express app — one process, no DI framework, no service mesh.
Places worth reading first#
application/analysis/— the detection engine:RepositoryAnalyzer,StructureAnalyzer,FrameworkDetectorwith its declarativeframeworkSignatures.ts,EnvVarScanner, andGroqReasoningService. See Architecture for how the pipeline fits together.application/orchestration/DeploymentOrchestrator.ts— the deployment state machine: analysis, backend-first deploy, URL wiring, failure diagnosis. Narrated in Deployment Lifecycle.infrastructure/queue/—DeploymentQueue(job definitions),DeploymentWorker(retry semantics),MonitoringWorker(uptime probes).prisma/schema.prisma— the whole data model: users, repositories, deployments,ProviderConnection, CLI tokens, uptime samples.
cli/ — the terminal client#
@deplo.ai/cli (v0.1.0, Node 20+, bin name deplo) is a thin client over the same REST API the dashboard uses — it holds no deployment logic of its own. commands/ maps one file per command (login, deploy, status, whoami, connect); handoff.ts implements the loopback browser hand-off described in Authentication & Security; git.ts matches the current directory's GitHub remote to your synced repositories. Full usage in the CLI docs.
CI and local development#
Four GitHub Actions workflows keep the monorepo honest: ci.yml (lint, type-check, test, build for client and server), pr-lint.yml (fast PR gate), docker.yml (Docker build verification), and release-cli.yml (publishing the CLI to npm). Locally, docker-compose.yml provides Postgres 16 and Redis 7:
$ docker compose up postgres redis -d
# server → http://localhost:4000 (REST /api/v1 · Swagger /docs)
$ cd server && npm install && cp .env.example .env
$ npm run prisma:migrate && npm run dev
# client → http://localhost:3000 (rewrites /api/* to 127.0.0.1:4000)
$ cd client && npm install && npm run devlocalhost:4000/docs; it is disabled in production, where this portal is the documentation surface.Related pages#
- Architecture — how these directories behave at runtime.
- Deployment Lifecycle — the orchestrator end to end.
- API Reference — the REST surface exposed by
server/.