Open-source court ERP platform for judges, lawyers, clerks, and the public. Manage cases, documents, hearings, and payments with ease.
tpt-court/
├── apps/
│ ├── api/ # Fastify REST API + Socket.io
│ ├── web/ # Next.js 15 web application
│ └── desktop/ # Electron desktop wrapper
├── packages/
│ ├── database/ # Prisma ORM, schema, seed
│ ├── types/ # Shared TypeScript types
│ └── ui/ # Shared UI components (React + Tailwind)
├── docker/ # Docker Compose + Dockerfiles
└── turbo.json # Turborepo configuration
- Node.js >= 20
- pnpm >= 9
- PostgreSQL 16
- Redis 7 (optional, for Socket.io)
# Clone and install
git clone <repo-url>
cd tpt-court
pnpm install
# Setup database
cp apps/api/.env.example apps/api/.env
# Edit apps/api/.env with your DATABASE_URL
pnpm db:generate
pnpm db:push
pnpm db:seed
# Start development
pnpm dev
# API: http://localhost:3001
# Web: http://localhost:3000The seed script creates:
- A demo court (Central District Court, code: MAIN)
- Admin user: admin@court.example / Admin1234!
- Judge user: judge@court.example / Judge1234!
- Clerk user: clerk@court.example / Clerk1234!
- Lawyer user: lawyer@court.example / Lawyer1234!
- Sample case with parties and hearing
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 3001 |
DATABASE_URL |
PostgreSQL connection string | Required |
JWT_SECRET |
JWT signing secret | Required |
CORS_ORIGIN |
Allowed CORS origins | http://localhost:3000 |
STRIPE_SECRET_KEY |
Stripe secret key | Optional |
STRIPE_WEBHOOK_SECRET |
Stripe webhook secret | Optional |
UPLOADS_DIR |
File upload directory | ./uploads |
| Variable | Description | Default |
|---|---|---|
NEXT_PUBLIC_API_URL |
API base URL | http://localhost:3001/api |
NEXT_PUBLIC_SOCKET_URL |
Socket.io URL | http://localhost:3001 |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY |
Stripe publishable key | Optional |
POST /api/auth/register— Register new userPOST /api/auth/login— LoginPOST /api/auth/logout— LogoutGET /api/auth/me— Current user
GET /api/public/cases— Search public casesGET /api/public/cases/:caseNumber— Public case detail
GET /api/cases— List casesPOST /api/cases— Create case (Clerk/Admin/Judge)GET /api/cases/:id— Case detailPUT /api/cases/:id— Update caseDELETE /api/cases/:id— Delete case (Admin)POST /api/cases/:id/parties— Add partyDELETE /api/cases/:id/parties/:partyId— Remove party
GET /api/documents/list/:caseId— List documentsPOST /api/documents/upload— Upload documentGET /api/documents/download/:id— Download document
GET /api/hearings— Calendar view (Judge/Clerk/Admin)GET /api/hearings/case/:caseId— Case hearingsPOST /api/hearings— Create hearingPUT /api/hearings/:id— Update hearingDELETE /api/hearings/:id— Delete hearing
GET /api/notifications— List notificationsPATCH /api/notifications/:id/read— Mark readPATCH /api/notifications/read-all— Mark all read
GET /api/payments— List paymentsPOST /api/payments/create-intent— Create Stripe PaymentIntentPOST /api/payments/webhook— Stripe webhook
GET /api/users— List users (Admin)GET /api/users/me— ProfilePUT /api/users/me— Update profileGET /api/users/:id— User detail (Admin)PUT /api/users/:id— Admin update user
# Copy environment
cp docker/.env.example docker/.env
# Edit docker/.env
# Start services
cd docker
docker compose up -d
# Run migrations
docker compose exec api npx prisma db push
docker compose exec api npx prisma db seed- Backend: Fastify, Prisma, Socket.io, Stripe, Zod
- Frontend: Next.js 15, React 19, Tailwind CSS, Socket.io Client
- Database: PostgreSQL
- Desktop: Electron
- Monorepo: Turborepo, pnpm workspaces
MIT