Skip to main content

Backend

Description

The backend is Next.js API routes inside apps/web/app/api/, backed by Prisma and PostgreSQL. There is no separate backend server — the same deployment serves UI and API. The one exception is the git microservice, which lives in the WebSocket app.

Stack

ConcernChoice
RuntimeNext.js 14 route handlers (Node)
ORMPrisma 5
DatabasePostgreSQL
AuthNextAuth v4, JWT sessions
StorageS3-compatible (LocalStack / R2 / AWS)
AIGroq
MediaLiveKit server SDK
GitHubOctokit

Route groups

~40 route directories. Grouped by domain:

GroupRoutes
Authauth/[...nextauth], auth/signup, auth/send-otp, auth/setcookie
Groupsgroups, groups/[groupId], my-groups, create-group-data, add-group-member, check-group-member, send-invite, guest-mode
Chatsave-group-message, direct-message, direct-message/unread
Usersprofile, profile/avatar, check-user, check-phone-number, lookup-user, get-user-id, get-user-number, set-phone, friends, friend-search
GitHubgithub/link, github/status, github/collaborator, github/invitations
Filesfiles, file-content, file-chunk, file-download, delete-file, save-coding-files, trash
VCSvcs/branches, vcs/base-sha, vcs/change-request, vcs/merge, vcs/reject, vcs/reconnect, change-request, commit-changes, modified-files, rejected-cr
Workspaceworkspace/[groupId]/{ui-design,mind-map,db-schema,planning}
Callscalls/initiate, calls/token, calls/[id], calls/livekit-webhook, calls/push-subscribe, calls/health
Miscnotifications, bug-report, generate-readme, testimonial-card, group-live-url

Full detail in the API reference.

Route handler shape

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";

export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const userId = searchParams.get("userId");

if (!userId) {
return NextResponse.json(
{ success: false, error: "userId required" },
{ status: 400 },
);
}

const notifications = await prisma.notifications.findMany({
where: { userId },
});

return NextResponse.json({ success: true, notifications });
}

Responses consistently carry a success boolean, which the client checks before reading data.

Shared library modules

apps/web/app/lib/ holds the cross-cutting pieces. Reuse these rather than reimplementing:

ModuleResponsibility
prisma.tsClient singleton — avoids exhausting connections in dev
apiAuth.tsSession and permission checks for handlers
encryption.tsAES-256-CBC for GitHub tokens at rest
wsToken.tsMints short-lived HMAC tokens for the WS service
livekit.tsCall access tokens
s3.tsObject storage
vcs.ts, vcsLimits.tsBranch/diff/merge, with size guards
gitClient.tsTalks to the git microservice
githubCollaborator.ts, githubFiles.ts, githubLink.tsOctokit wrappers
draftStore.tsUnsaved editor drafts
memberEvents.ts, systemMessages.tsMembership events → chat messages

Database

PostgreSQL via Prisma. The schema lives at apps/web/prisma/schema.prisma — 673 lines, 34 models, 12 enums.

:::warning packages/db is empty Despite the name and the old README's claim, packages/db contains no schema and no source. It is a leftover husk. The schema is in apps/web/prisma/. :::

See the data model for a domain breakdown.

Next