Skip to content

Latest commit

 

History

History
359 lines (282 loc) · 10.2 KB

File metadata and controls

359 lines (282 loc) · 10.2 KB

Bind Server

Production-ready Next.js server for Bind - seamless cross-device text transfer system.

Features

  • ✅ JWT Authentication
  • ✅ RESTful API for push/pull operations
  • ✅ Response System with Status Tracking (pending, processing, success, failed, cancelled)
  • ✅ LLM Integration (OpenAI, Gemini, Claude) for automatic responses
  • ✅ Manual Response Resolution via dashboard
  • ✅ Async Workflow Support with status tracking
  • ✅ Chat messaging system
  • ✅ User settings sync
  • ✅ Modern dashboard UI
  • ✅ Cloudflare D1 database integration
  • ✅ TypeScript with full type safety
  • ✅ Tailwind CSS for styling
  • ✅ Production-ready error handling

Tech Stack

  • Framework: Next.js 16 (App Router)
  • Runtime: Edge (Cloudflare Pages)
  • Database: Cloudflare D1 (SQLite)
  • Auth: JWT with jose
  • Styling: Tailwind CSS v3
  • Language: TypeScript

Prerequisites

  • Node.js 20.18+
  • npm or yarn
  • Cloudflare account
  • Wrangler CLI installed globally

Getting Started

1. Install Dependencies

npm install

2. Database Setup

The database is already configured with:

  • Database Name: bind-database
  • Database ID: 3f6e853b-c79d-45d6-ace1-c47a192c3989
  • Schema: Initialized with users, binds, chat_messages, user_settings tables

3. Environment Variables

Create .env.local for local development:

JWT_SECRET=your-secret-key-here

# LLM API Keys (optional - only needed if using AI responses)
OPENAI_API_KEY=your-openai-api-key
GEMINI_API_KEY=your-gemini-api-key
ANTHROPIC_API_KEY=your-anthropic-api-key

For production, set these environment variables in Cloudflare Pages settings.

4. Development

npm run dev

Open http://localhost:3000

5. Build

npm run build

API Endpoints

All API routes require authentication except /api/auth.

Authentication

POST /api/auth

  • Login or signup
  • Headers: X-Action: login | signup
  • Body: { email: string, password: string }
  • Returns: { token: string, userId: string }

Push Operation

POST /api/push

  • Save a bind or provide response
  • Headers: Authorization: Bearer <token>
  • Body:
    • Standard push: { id: string, group: string, content: string, metadata?: object }
    • With manual response: { id: string, group: string, content: string, res: true }
    • With AI response: { id: string, group: string, content: string, res: "ai" | "openai" | "gemini" | "claude" }
    • Provide response: { id: string, group: string, response_content: string }
  • Returns: { success: boolean, id: string, group: string, status: string }
  • Status values: pending, processing, success, failed

Pull Operation

GET /api/pull

  • Retrieve binds, status, or responses
  • Headers: Authorization: Bearer <token>
  • Query parameters:
    • Get all binds: No parameters
    • Get specific bind: ?id=<id>&group=<group>
    • Get status: ?id=<id>&group=<group>&status=true
    • Get latest response: ?id=<id>&group=<group>&res=true
    • Get specific response: ?id=<id>&group=<group>&res=true&resIndex=<number>
  • Returns:
    • Binds: { success: boolean, binds: Array<Bind> }
    • Status: { success: boolean, status: string, status_message?: string }
    • Response: { success: boolean, content: string }

Chat

POST /api/chat

  • Send a message
  • Headers: Authorization: Bearer <token>
  • Body: { message: string, group?: string }
  • Returns: { success: boolean }

GET /api/chat

  • Get messages
  • Headers: Authorization: Bearer <token>
  • Query: ?group=<group>&limit=<number> (optional)
  • Returns: { success: boolean, messages: Array<Message> }

Settings

GET /api/settings

  • Get user settings
  • Headers: Authorization: Bearer <token>
  • Returns: { success: boolean, settings: object }

PUT /api/settings

  • Update settings
  • Headers: Authorization: Bearer <token>
  • Body: { settings: object }
  • Returns: { success: boolean, settings: object }

Deployment

Deploy to Cloudflare Pages

npm run pages:deploy

Or manually:

npm run build
wrangler pages deploy .next

Production Configuration

  1. Go to Cloudflare Pages dashboard
  2. Connect your GitHub repository
  3. Set build command: npm run build
  4. Set build output directory: .next
  5. Add environment variables:
    • JWT_SECRET (required)
    • OPENAI_API_KEY (optional - for AI responses)
    • GEMINI_API_KEY (optional - for AI responses)
    • ANTHROPIC_API_KEY (optional - for AI responses)
  6. D1 database binding is configured in wrangler.toml
  7. Run migrations on remote database (see Development Tips)

Project Structure

server/
├── app/                    # Next.js app directory
│   ├── api/               # API routes (edge runtime)
│   │   ├── auth/          # Authentication
│   │   ├── push/          # Push operation
│   │   ├── pull/          # Pull operation
│   │   ├── chat/          # Chat messaging
│   │   └── settings/      # User settings
│   ├── dashboard/         # Dashboard pages
│   │   ├── binds/         # Bind management
│   │   ├── groups/        # Group view
│   │   ├── chat/          # Chat interface
│   │   └── settings/      # Settings page
│   ├── login/             # Login page
│   ├── layout.tsx         # Root layout
│   ├── page.tsx           # Home page
│   └── globals.css        # Global styles
├── lib/                   # Core library code
│   ├── auth/              # JWT utilities
│   │   ├── jwt.ts         # Token creation/verification
│   │   └── middleware.ts  # Auth middleware
│   ├── db/                # Database layer
│   │   ├── client.ts      # D1 client wrapper
│   │   ├── context.ts     # Database context helper
│   │   └── migrations/    # SQL migration files
│   │       ├── 001_init.sql          # Initial schema
│   │       └── 002_response_system.sql  # Response system
│   ├── llm/               # LLM integration
│   │   └── service.ts     # LLM providers (OpenAI, Gemini, Claude)
│   └── types/             # TypeScript types
│       ├── api.ts         # API request/response types
│       └── database.ts    # Database schema types
├── components/            # React components (future)
├── wrangler.toml          # Cloudflare configuration
├── next.config.js         # Next.js configuration
├── tailwind.config.ts     # Tailwind configuration
├── tsconfig.json          # TypeScript configuration
└── package.json           # Dependencies

Database Schema

users

  • id (TEXT, PRIMARY KEY)
  • email (TEXT, UNIQUE)
  • password_hash (TEXT)
  • created_at (INTEGER)

binds

  • id (TEXT)
  • group_name (TEXT)
  • content (TEXT)
  • metadata (TEXT/JSON)
  • created_at (INTEGER)
  • updated_at (INTEGER)
  • user_id (TEXT)
  • status (TEXT) - Values: pending, processing, success, failed, cancelled
  • response_id (TEXT) - Links to response entry
  • type (TEXT) - Values: data, question, prompt, response
  • source_id (TEXT) - For response entries, links to source
  • provider (TEXT) - LLM provider used: ai, openai, gemini, claude, manual
  • response_count (INTEGER) - Number of responses created
  • status_message (TEXT) - Detailed status/error message
  • PRIMARY KEY (id, group_name, user_id)

chat_messages

  • id (INTEGER, PRIMARY KEY, AUTOINCREMENT)
  • group_name (TEXT)
  • message (TEXT)
  • user_id (TEXT)
  • created_at (INTEGER)

user_settings

  • user_id (TEXT, PRIMARY KEY)
  • settings (TEXT/JSON)
  • updated_at (INTEGER)

Response System

The server supports an async workflow system for handling entries that require responses (manual or AI-generated).

Workflow

  1. Standard Push (no response needed):

    POST /api/push { id: "notes", group: "work", content: "Meeting notes" }
    # Creates entry with status: "success", type: "data"
  2. Manual Response Request:

    POST /api/push { id: "question1", group: "all", content: "What is the capital?", res: true }
    # Creates entry with status: "pending", type: "question"
    # User resolves from dashboard
  3. AI Response Request:

    POST /api/push { id: "question2", group: "all", content: "Explain quantum physics", res: "openai" }
    # Creates entry with status: "processing", type: "question"
    # LLM processes asynchronously
    # Creates response entry (type: "response") and links it
    # Updates status to "success"
  4. Provide Manual Response:

    POST /api/push { id: "question1", group: "all", response_content: "Paris" }
    # Creates response entry and updates status
  5. Check Status:

    GET /api/pull?id=question2&group=all&status=true
    # Returns: { status: "processing", status_message: "Processing with openai..." }
  6. Pull Response:

    GET /api/pull?id=question2&group=all&res=true
    # Returns latest response content
    GET /api/pull?id=question2&group=all&res=true&resIndex=1
    # Returns first response (res#1)

Response Entry Naming

Response entries are created with IDs based on the source entry:

  • Source: question1@all
  • Response #1: question1-out-1@all
  • Response #2: question1-out-2@all

Security Features

  • JWT token-based authentication
  • Password hashing with bcrypt
  • Edge runtime for minimal attack surface
  • Input validation with Zod
  • SQL injection prevention (prepared statements)
  • CORS handled by Cloudflare
  • Secure headers by default

Development Tips

Query D1 Database

# Local database
wrangler d1 execute bind-database --command="SELECT * FROM users"

# Remote database
wrangler d1 execute bind-database --remote --command="SELECT * FROM binds LIMIT 10"

Run Migrations

# Local
wrangler d1 execute bind-database --file=./lib/db/migrations/001_init.sql

# Remote
wrangler d1 execute bind-database --remote --file=./lib/db/migrations/001_init.sql

Local Development with D1

npm run pages:dev

This starts Next.js dev server with Wrangler for D1 access.

License

MIT

Support

For issues and feature requests, please create an issue on GitHub.