Real-time API server powering the ForkOff ecosystem
Features • Tech Stack • Quick Start • API Reference • WebSocket
- 🔐 Secure Authentication - JWT-based auth via Supabase
- 📡 Real-time Communication - WebSocket support for instant updates
- 📱 Device Management - Pair and manage multiple development machines
- 💬 Claude Session Handling - Manage AI coding sessions across devices
- 📊 Analytics & Tracking - Token usage, session history, achievements
- 🔔 Push Notifications - Expo push notifications for mobile alerts
- ⏰ Prompt Queue - Queue and schedule prompts during rate limits
| Technology | Purpose |
|---|---|
| NestJS | Backend framework |
| PostgreSQL | Database (via Supabase) |
| Prisma | ORM & database toolkit |
| Socket.io | Real-time WebSocket communication |
| Supabase | Auth & database hosting |
| Swagger | API documentation |
- Node.js 18+
- Supabase account with a project
git clone https://github.com/Forkoff-app/forkoff-backend.git
cd forkoff-backend
npm installcp .env.example .envEdit .env with your Supabase credentials:
| Variable | Where to Find |
|---|---|
DATABASE_URL |
Supabase → Project Settings → Database → Connection string (pooling) |
DIRECT_URL |
Supabase → Project Settings → Database → Connection string (direct) |
SUPABASE_URL |
Supabase → Project Settings → API → Project URL |
SUPABASE_ANON_KEY |
Supabase → Project Settings → API → anon public |
SUPABASE_SERVICE_KEY |
Supabase → Project Settings → API → service_role |
JWT_SECRET |
Supabase → Project Settings → API → JWT Secret |
# Push schema to database
npm run db:push
# Seed achievements (optional)
npm run db:seed# Development (hot reload)
npm run start:dev
# Production
npm run build && npm run start:prodServer runs at http://localhost:3000
📚 API Docs: http://localhost:3000/docs
All endpoints require a Bearer token (except device registration):
Authorization: Bearer <supabase-jwt-token>| Method | Endpoint | Description |
|---|---|---|
GET |
/api/devices |
List user's devices |
GET |
/api/devices/:id |
Get device details |
POST |
/api/devices/register |
Generate pairing code (CLI) |
POST |
/api/devices/pair |
Pair with code (mobile) |
PATCH |
/api/devices/:id |
Update device |
DELETE |
/api/devices/:id |
Remove device |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/claude-sessions/device/:deviceId |
Get sessions for device |
GET |
/api/claude-sessions/:sessionId |
Get session details |
DELETE |
/api/claude-sessions/:sessionId |
Delete session |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/queue |
Get queued prompts |
POST |
/api/queue |
Add prompt to queue |
DELETE |
/api/queue/:id |
Cancel queued prompt |
GET |
/api/queue/schedule |
Get queue schedule |
PATCH |
/api/queue/schedule |
Update schedule |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/analytics/usage |
Get usage summary |
GET |
/api/analytics/daily |
Get daily breakdown |
GET |
/api/achievements |
List all achievements |
GET |
/api/achievements/user |
Get user's achievements |
Connect to ws://localhost:3000 with authentication:
import { io } from 'socket.io-client';
const socket = io('ws://localhost:3000', {
auth: { token: 'your-jwt-token' }
});| Event | Direction | Description |
|---|---|---|
device_status |
Server → Client | Device online/offline status |
claude_message |
Server → Client | AI response streaming |
claude_approval_request |
Server → Client | Permission request from CLI |
achievement_unlocked |
Server → Client | New achievement earned |
prompt_queued |
Server → Client | Prompt added to queue |
| Event | Direction | Description |
|---|---|---|
claude_session_update |
CLI → Server | Session state changed |
user_message |
Server → CLI | Message from mobile app |
claude_approval_response |
Server → CLI | Approval decision |
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ CLI │ │ Server │ │ Mobile App │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ POST /devices/register │ │
│─────────────────────────────────>│ │
│ │ │
│ { pairingCode: "ABC123" } │ │
│<─────────────────────────────────│ │
│ │ │
│ Display QR Code │ │
│ │ │
│ │ POST /devices/pair │
│ │<─────────────────────────────────│
│ │ │
│ │ { device: {...} } │
│ │─────────────────────────────────>│
│ │ │
│ WebSocket: device_paired │ │
│<─────────────────────────────────│ │
│ │ │
# Generate Prisma client
npm run db:generate
# Push schema changes
npm run db:push
# Open Prisma Studio
npm run db:studio
# Create migration
npm run db:migrate-
Get your local IP:
- Windows:
ipconfig - macOS/Linux:
ifconfigorip addr
- Windows:
-
Update mobile app
.env:EXPO_PUBLIC_API_URL=http://YOUR_IP:3000/api EXPO_PUBLIC_WS_URL=ws://YOUR_IP:3000 -
Start both servers
src/
├── auth/ # Authentication & user profile
├── devices/ # Device management & pairing
├── claude-sessions/# Claude session handling
├── terminal/ # Terminal sessions
├── prompt-queue/ # Queue management
├── analytics/ # Usage analytics
├── achievements/ # Gamification
├── notifications/ # Push notifications
├── websocket/ # WebSocket gateway (real-time relay)
├── app-config/ # App version checks & feature flags
├── config/ # Secrets management (AWS Secrets Manager)
├── crypto/ # E2EE key exchange support
├── geo-ip/ # GeoIP country detection
├── health/ # Health check endpoint
├── logging/ # Winston logging & exception filters
└── prisma/ # Database client & schema
- ForkOff Mobile App - React Native app
- ForkOff CLI - Command line tool
- ForkOff Website - Landing page
Made with ❤️ by the ForkOff team
