Node.js & Express REST API for the CheckD mobile application with PostgreSQL persistence and JWT authentication.
- Prerequisites
- Local Setup
- Environment Variables
- Database Migrations & Seeding
- Running Tests
- Starting the Server
- Deploying Against Hosted Postgres (Neon / Supabase)
- Node.js: v18.0.0 or later (v22+ recommended)
- npm: v9+
- PostgreSQL: v16+ (local or hosted)
-
Navigate to the backend directory:
cd checkd-backend -
Install dependencies:
npm install
-
Configure environment variables: Copy
.env.exampleto.env:cp .env.example .env
Generate a secure random string for
JWT_SECRET:node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Update your
.envfile with your local credentials:PORT=3000 DATABASE_URL=postgresql://arshiloffcampus@localhost:5432/checkd_db DATABASE_SSL=false JWT_SECRET=your_generated_jwt_secret_here
-
Initialize database schema and seed:
psql -U arshiloffcampus -d checkd_db -f schema.sql npm run seed
| Variable | Required | Description | Example |
|---|---|---|---|
PORT |
Optional | Port on which the Express server listens (default: 3000) |
3000 |
DATABASE_URL |
Yes | Postgres connection string URI | postgresql://user:pass@localhost:5432/checkd_db |
DATABASE_SSL |
Optional | Set to true to enable SSL (rejectUnauthorized: false for Neon/Supabase) |
false (local) / true (hosted) |
JWT_SECRET |
Yes | Secret key for signing and verifying JWT tokens. Server exits if missing. | 64-character hex string |
-
Initialize / Update Schema:
psql "$DATABASE_URL" -f schema.sqlschema.sqlcreates all required tables (users,connections,nudges,nudge_history,notifications,cheers,medications,medication_logs) and indexes idempotently withIF NOT EXISTS. -
Seed Sample Data:
npm run seed
Seeds the default user (
arshil@example.com/password123), circle connections, sample nudges, and care cabinet items. -
Hash Plaintext Passwords (One-time migration script):
node scripts/hash-plaintext-passwords.js
Finds any user record whose password does not start with bcrypt hash prefix
$2and upgrades it in place to a secure bcrypt hash.
Automated integration tests are built using Node's native node:test runner and supertest:
npm testThe test suite validates:
GET /healthdatabase connectivity check (returns 200{"status":"ok"})POST /signupuser registration and token generationPOST /loginwith correct passwordPOST /loginrejection with wrong password (returns 400)GET /metoken protection (returns 401 when unauthenticated)
-
Development mode (auto-reload via nodemon):
npm run dev
-
Production mode:
npm start
-
Health check:
curl http://localhost:3000/health # Response: {"status":"ok"}
-
Neon:
- Create a project on Neon.
- In the Dashboard, copy the connection string:
postgresql://<user>:<password>@<ep-identifier>.us-east-2.aws.neon.tech/neondb?sslmode=require
-
Supabase:
- Create a project on Supabase.
- Under Project Settings > Database > Connection string, copy the URI (choose Transaction pooler or Direct connection).
Run schema.sql against the hosted database:
-
Via psql CLI:
psql "<YOUR_HOSTED_DATABASE_URL>" -f schema.sql -
Via Web SQL Console: Open Neon's SQL Editor or Supabase's SQL Editor, paste the contents of
schema.sql, and execute. -
(Optional) Seed initial data:
DATABASE_URL="<YOUR_HOSTED_DATABASE_URL>" DATABASE_SSL=true npm run seed
On your hosting platform (e.g., Render, Railway, Fly.io, Heroku):
- Set
DATABASE_URLto your hosted connection string. - Set
DATABASE_SSL=true(enables SSL withrejectUnauthorized: falserequired for managed certificates). - Set
JWT_SECRETto a strong random 256-bit secret. - Set
PORT(or let provider set it automatically viaprocess.env.PORT).
Test the health check and authentication on your deployed API:
curl https://<your-backend-domain>/health
# Expected: {"status":"ok"}