Local Development Setup
This guide provides a comprehensive walkthrough for setting up a complete ZServed development environment on your local machine.
Prerequisites
Before beginning development, ensure your system meets these requirements:
Required Software
Node.js 18 or later
# Check your Node.js versionnode --version
# Install via package manager (macOS)brew install node
# Install via package manager (Ubuntu/Debian)curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -sudo apt-get install -y nodejs
Package Manager
# npm (comes with Node.js)npm --version
# Or use pnpm (recommended for faster installs)npm install -g pnpmpnpm --version
Git Version Control
# Check Git installationgit --version
# Install Git if needed# macOS: git comes with Xcode Command Line Tools# Ubuntu/Debian: sudo apt-get install git# Windows: Download from git-scm.com
Cloudflare Wrangler CLI
# Install globallynpm install -g wrangler
# Verify installationwrangler --version
# Authenticate with Cloudflarewrangler login
Development Tools (Recommended)
Visual Studio Code
- Download from code.visualstudio.com
- Install recommended extensions (see VS Code Setup section)
Database Browser
- DB Browser for SQLite for viewing D1 databases
- TablePlus for advanced database management
Repository Setup
Clone and Install
# Clone the repositorygit clone https://github.com/your-org/zserved.gitcd zserved
# Install root dependenciesnpm install
# Install webapp dependenciescd webappnpm installcd ..
# Install documentation dependencies (optional)cd docsnpm installcd ..
Project Structure Overview
zserved/├── webapp/ # Main Astro application│ ├── src/│ │ ├── pages/ # Routes and API endpoints│ │ ├── components/ # UI components│ │ ├── layouts/ # Page layouts│ │ └── styles/ # CSS files├── src/ # Shared services and utilities│ ├── services/ # Business logic│ └── utils/ # Helper functions├── migrations/ # Database schema├── scripts/ # Utility scripts├── docs/ # Documentation (Starlight)├── wrangler.jsonc # Cloudflare Workers config└── package.json # Root dependencies
Environment Configuration
Environment Variables
Create your local environment configuration:
# Copy the example environment filecp .env.example .env
# Edit with your valuesnano .env
Required Environment Variables:
# Cloudflare Account SettingsCLOUDFLARE_ACCOUNT_ID=your_account_id_hereCLOUDFLARE_API_TOKEN=your_api_token_here
# Development SettingsNODE_ENV=developmentDEBUG=true
# AI Integration (Optional)OPENAI_API_KEY=your_openai_key_here
# External Services (Optional)SQUARE_APPLICATION_ID=your_square_app_idSQUARE_ACCESS_TOKEN=your_square_tokenSQUARE_LOCATION_ID=your_square_locationSQUARE_ENVIRONMENT=sandbox
Cloudflare Account Setup
If you don’t have a Cloudflare account:
- Sign up at cloudflare.com
- Get your Account ID:
- Go to the Cloudflare dashboard
- Right sidebar shows your Account ID
- Create an API Token:
- Go to “My Profile” → “API Tokens”
- Click “Create Token”
- Use “Workers:Edit” template
- Add account and zone permissions as needed
Cloudflare Resources Setup
Create Required Resources
# Create D1 Databasewrangler d1 create zserved-db
# Create R2 Bucket for file storagewrangler r2 bucket create zserved-fileswrangler r2 bucket create zserved-files-preview
# Create KV Namespaceswrangler kv:namespace create "TENANTS"wrangler kv:namespace create "FILE_METADATA"
# Create Vectorize Index for AI featureswrangler vectorize create document-embeddings --preset @cf/baai/bge-base-en-v1.5wrangler vectorize create client-metadata --preset @cf/baai/bge-base-en-v1.5
# Create AutoRAG Instance (if available in your region)wrangler autorag create zserved-legal-knowledge \ --description "Legal document knowledge base for ZServed"
Update Wrangler Configuration
After creating resources, update wrangler.jsonc
with the returned IDs:
{ "name": "zserved", "main": "dist/_worker.js", "compatibility_date": "2025-04-15", "vars": { "OPENAI_API_KEY": "", "NODE_ENV": "development" }, "kv_namespaces": [ { "binding": "TENANTS", "id": "your_tenants_namespace_id" }, { "binding": "FILE_METADATA", "id": "your_file_metadata_namespace_id" } ], "r2_buckets": [ { "binding": "zserved_files", "bucket_name": "zserved-files", "preview_bucket_name": "zserved-files-preview" } ], "d1_databases": [ { "binding": "DB", "database_name": "zserved-db", "database_id": "your_database_id" } ], "ai": { "binding": "AI" }, "vectorize": [ { "binding": "VECTORIZE", "index_name": "document-embeddings" }, { "binding": "CLIENT_VECTORIZE", "index_name": "client-metadata" } ], "autorag": [ { "binding": "LEGAL_RAG", "autorag_name": "zserved-legal-knowledge" } ]}
Database Setup
Initialize Schema
# Run the initial database migrationwrangler d1 execute zserved-db --file=./migrations/schema.sql
# Verify the setupwrangler d1 execute zserved-db --command="SELECT name FROM sqlite_master WHERE type='table';"
Seed Development Data
# Create sample tenant datawrangler d1 execute zserved-db --command="INSERT INTO tenants (id, name, slug, subdomain, contact_email, created_at)VALUES ('dev-tenant', 'Development Law Firm', 'dev-firm', 'dev', 'admin@dev.local', datetime('now'));"
# Create sample userwrangler d1 execute zserved-db --command="INSERT INTO users (id, tenant_id, email, password_hash, role, name, created_at)VALUES ('dev-user', 'dev-tenant', 'admin@dev.local', 'hashed_password', 'admin', 'Dev Admin', datetime('now'));"
Optional: Seed Legal Knowledge Base
If you have AutoRAG configured:
# Seed with sample legal documentscd scriptsnpx tsx seed-knowledge-base.ts dev-tenant
Development Servers
Start All Services
You’ll need multiple terminal windows/tabs:
Terminal 1: Cloudflare Workers (API)
# Start the Workers development serverwrangler dev
# Available at: http://localhost:8787# Hot reload enabled for API changes
Terminal 2: Astro Frontend
cd webappnpm run dev
# Available at: http://localhost:4321# Hot reload enabled for frontend changes
Terminal 3: Documentation (Optional)
cd docsnpm run dev
# Available at: http://localhost:4322# Hot reload enabled for docs changes
Access Your Development Environment
- Main Application: http://localhost:4321
- Tenant Subdomain: http://dev.localhost:4321
- API: http://localhost:8787
- Documentation: http://localhost:4322
VS Code Setup
Recommended Extensions
Install these extensions for optimal development experience:
{ "recommendations": [ "astro-build.astro-vscode", "bradlc.vscode-tailwindcss", "ms-vscode.vscode-typescript-next", "esbenp.prettier-vscode", "ms-vscode.vscode-json", "cloudflare.vscode-wrangler" ]}
Workspace Settings
Create .vscode/settings.json
:
{ "typescript.preferences.includePackageJsonAutoImports": "auto", "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "astro.trace.server": "verbose", "tailwindCSS.includeLanguages": { "astro": "html" }, "files.associations": { "*.astro": "astro" }}
Debug Configuration
Create .vscode/launch.json
:
{ "version": "0.2.0", "configurations": [ { "name": "Debug Wrangler", "type": "node", "request": "launch", "program": "${workspaceFolder}/node_modules/.bin/wrangler", "args": ["dev", "--local"], "env": { "NODE_ENV": "development" }, "console": "integratedTerminal" } ]}
Development Workflow
Making Changes
Frontend Changes (webapp/src/)
- Edit Astro pages, components, or styles
- Changes appear instantly with hot reload
- TypeScript errors shown in VS Code and terminal
API Changes (webapp/src/pages/api/)
- Edit API endpoint files
- Wrangler restarts automatically
- Test API endpoints with curl or Postman
Service Logic (src/services/)
- Edit business logic and utilities
- Restart Wrangler to see changes
- Use TypeScript for better development experience
Testing Changes
Manual Testing
# Test API endpointscurl http://localhost:8787/api/health
# Test with authenticationcurl -H "Authorization: Bearer token" http://localhost:8787/api/client-portal/matters
Automated Testing
# Run unit testsnpm test
# Run integration testsnpm run test:integration
# Run type checkingnpm run type-check
Database Development
View Database
# List all tableswrangler d1 execute zserved-db --command="SELECT name FROM sqlite_master WHERE type='table';"
# Query datawrangler d1 execute zserved-db --command="SELECT * FROM tenants LIMIT 5;"
# Export database for inspectionwrangler d1 export zserved-db --output=backup.sql
Schema Changes
# Create new migration filetouch migrations/002_add_new_feature.sql
# Apply migrationwrangler d1 execute zserved-db --file=./migrations/002_add_new_feature.sql
Mobile Development Setup
Capacitor Configuration
cd webapp
# Install Capacitornpm install @capacitor/core @capacitor/cli
# Initialize Capacitornpx cap init
# Add platformsnpx cap add iosnpx cap add android
iOS Setup (macOS only)
# Install Xcode from Mac App Store# Install iOS Simulator
# Copy web assets and open Xcodenpm run cap:ios
Android Setup
# Install Android Studio# Set up Android SDK and emulator
# Copy web assets and open Android Studionpm run cap:android
Troubleshooting
Common Issues
Wrangler Authentication Errors
# Clear auth and re-loginwrangler logoutwrangler login
Database Connection Issues
# Verify database existswrangler d1 list
# Check database ID in wrangler.jsoncwrangler d1 info zserved-db
Port Conflicts
# Find process using portlsof -i :8787lsof -i :4321
# Kill process if neededkill -9 <PID>
Module Resolution Errors
# Clear node_modules and reinstallrm -rf node_modules package-lock.jsonnpm install
# Clear Astro cachecd webapprm -rf dist .astronpm run build
AutoRAG Not Available
- Check if AutoRAG is available in your region
- Verify the AutoRAG instance name in wrangler.jsonc
- The system falls back gracefully if AutoRAG is unavailable
Debug Tools
Wrangler Debugging
# View live logswrangler tail
# Enable verbose loggingwrangler dev --log-level debug
# Local development modewrangler dev --local
Network Debugging
# Test API connectivitycurl -v http://localhost:8787/api/health
# Check CORS issuescurl -H "Origin: http://localhost:4321" \ -H "Access-Control-Request-Method: POST" \ -X OPTIONS \ http://localhost:8787/api/client-portal/matters
Performance Optimization
Development Performance
Faster Builds
# Use pnpm instead of npmpnpm install
# Parallel processingnpm run dev -- --host 0.0.0.0 --port 4321
Code Splitting
// Use dynamic imports for large componentsconst HeavyComponent = lazy(() => import('./HeavyComponent.astro'));
Development vs Production
// Environment-specific codeif (import.meta.env.DEV) { console.log('Development mode');}
Resource Monitoring
# Monitor Workers usagewrangler metrics
# Check KV usagewrangler kv:key list --binding=TENANTS
# Monitor R2 storagewrangler r2 object list zserved-files
Next Steps
Once your development environment is running:
- Explore the Codebase: Start with
webapp/src/pages/index.astro
- Make Your First Change: Edit the welcome message
- Test API Endpoints: Use the client portal APIs
- Add Features: Follow the feature development guide
- Deploy: When ready, follow the deployment guide
For additional help:
- Check the troubleshooting guide
- Review the API documentation
- Join our development community discussions