Complete guide for setting up the TBD platform for local development.
Last Updated: December 2025
- JDK 17+ - For Kotlin backend
- PostgreSQL 12+ - Database
- Node.js 18+ - For frontend (Cloudflare Workers)
- Git - Version control
# Install Java
brew install openjdk@17
# Install PostgreSQL
brew install postgresql@14
brew services start postgresql@14
# Install Node.js
brew install node# Install Java
sudo apt update
sudo apt install openjdk-17-jdk
# Install PostgreSQL
sudo apt install postgresql-14
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejsgit clone https://github.com/mikewards/flow-platform.git
cd flow-platform# Using psql
createdb flow_api
# Or using PostgreSQL client
psql -U postgres -c "CREATE DATABASE flow_api;"psql -U postgres -d flow_api -c "SELECT version();"cd flow-apiCreate .env file:
ENVIRONMENT=development
DATABASE_URL=jdbc:postgresql://localhost:5432/flow_api
DATABASE_USER=postgres
DATABASE_PASSWORD=your_password
JWT_SECRET=$(openssl rand -hex 32)
MASTER_ENCRYPTION_KEY=$(openssl rand -hex 32)
# SVIX_API_KEY=optional_for_local_dev# Generate JWT secret
openssl rand -hex 32
# Generate encryption key
openssl rand -hex 32cd flow-api
./gradlew run
# Or using the run script
./run.shBackend will start on http://localhost:8080
The frontend uses Cloudflare Workers for clean URL routing.
npm install -g wranglercd frontend
npx wrangler devFrontend will be available at http://localhost:8787
For quick testing without clean URLs:
cd frontend
python3 -m http.server 3000cd flow-api
./gradlew testcd flow-api
./gradlew buildThe application automatically creates/updates database schema on first run. No manual migrations needed.
Tables created automatically:
accountsapplicationsapplication_walletsaccess_tokensrefresh_tokensyield_accountspositionstransactionswebhooksrequest_logs
For backend development:
- Use IntelliJ IDEA with Kotlin plugin
- Enable "Build project automatically"
- Use Ktor's development mode (auto-reload on changes)
flow-platform/
├── flow-api/ # Kotlin backend
│ ├── src/
│ │ └── main/
│ │ ├── kotlin/
│ │ │ └── com/tbd/
│ │ │ ├── api/routes/ # API endpoints
│ │ │ ├── dto/ # Data transfer objects
│ │ │ ├── middleware/ # Auth, rate limiting, logging
│ │ │ ├── model/ # Database models
│ │ │ ├── service/ # Business logic
│ │ │ └── integration/ # Morpho/Aave clients
│ │ └── resources/
│ │ └── application.conf # Configuration
│ └── build.gradle.kts
├── frontend/ # Frontend application
│ ├── pages/ # HTML pages
│ ├── styles/ # CSS files
│ ├── scripts/ # JavaScript files
│ │ ├── token-manager.js # OAuth token management
│ │ ├── config.js # API configuration
│ │ └── nav-auth.js # Navigation auth state
│ ├── sdk-demos/ # SDK demo pages
│ ├── worker.js # Cloudflare Worker (URL routing)
│ └── wrangler.jsonc # Cloudflare config
└── docs/ # Documentation
- Verify PostgreSQL is running:
# macOS brew services list # Linux sudo systemctl status postgresql
- Check database credentials in
.env - Verify database exists:
psql -U postgres -l
# Find process using port 8080
lsof -i :8080
# Kill process
kill -9 <PID># Clean and rebuild
cd flow-api
./gradlew clean build- Check backend is running on port 8080
- Check CORS is configured correctly
- Verify
config.jshas correct API URL
- Open project in IntelliJ
- Import Gradle project
- Configure JDK 17
- Install Kotlin plugin (if not already installed)
- Install Kotlin extension
- Install Gradle extension
- Configure Java home:
Cmd+Shift+P→ "Java: Configure Java Runtime"
curl http://localhost:8080/healthExpected: {"status":"ok"}
curl -X POST http://localhost:8080/v1/accounts \
-H "Content-Type: application/json" \
-d '{
"username": "testuser",
"password": "testpassword123",
"email": "test@example.com"
}'curl -X POST http://localhost:8080/v1/auth/authenticate \
-H "Content-Type: application/json" \
-d '{
"username": "testuser",
"password": "testpassword123"
}'Response includes:
access_token(15 min JWT)refresh_token(30 day)expires_in(900 seconds)
curl -X POST http://localhost:8080/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "tbd_refresh_..."
}'