Modern ESM Node.js/Express backend for the Keylight intake form system.
This is a modern ESM-first Node.js application with clean separation of concerns:
src/
├── config/ # Environment and configuration
├── models/ # Data models and database access
├── routes/ # API route definitions
├── middleware/ # Express middleware
├── services/ # Business logic layer
└── app.js # Express application setup
database/
├── migrations/ # Database schema migrations
└── seeds/ # Sample data for development
tests/ # Test files
server.js # Application entry point
- Node.js 18+ - Modern JavaScript runtime
- PostgreSQL 14+ - Database server
- jq (optional) - For pretty JSON output in test scripts
- Ubuntu/Debian:
sudo apt-get install jq
- macOS:
brew install jq
- Windows:
choco install jq
- Ubuntu/Debian:
- ESM-native: Uses modern ES modules throughout
- Clean Architecture: Proper separation of concerns
- Environment-based Config: Flexible configuration management
- Migration System: Proper database schema management
- Service Layer: Business logic separated from routes
- Comprehensive Testing: Built for testability
# Install dependencies
npm install
# Run in development mode
npm run dev
# Run database migrations
npm run migrate
# Seed development data
npm run seed
# Run tests
npm test
Copy .env.example
to .env
and configure:
DATABASE_URL=postgresql://username:password@localhost:5432/keylight_intake_db
PORT=3000
NODE_ENV=development
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
[email protected]
EMAIL_PASS=your-app-password
ADMIN_PASSWORD=admin123
GET /health
- Health checkGET /api/test-db
- Database connection testPOST /api/submissions
- Create submissionGET /api/submissions
- List submissionsGET /api/submissions/:id
- Get submissionPUT /api/submissions/:id
- Update submission
This application is designed to deploy on Render.com with managed PostgreSQL.
# Check what tables exist
psql -d keylight_intake_db -U postgres -h localhost -c "\dt"
# Check intake_submissions structure (especially user_id and project_id columns)
psql -d keylight_intake_db -U postgres -h localhost -c "\d intake_submissions"
# Check if users table has any data
psql -d keylight_intake_db -U postgres -h localhost -c "SELECT COUNT(*) FROM users;"
# Check if projects table has any data
psql -d keylight_intake_db -U postgres -h localhost -c "SELECT COUNT(*) FROM projects;"
# Check if intake_submissions has any data and what the user_id/project_id columns look like
psql -d keylight_intake_db -U postgres -h localhost -c "SELECT id, full_name, email_address, user_id, project_id FROM intake_submissions LIMIT 5;"