CapTraK (Capstone Project Tracker) is a full-stack web application for managing and tracking capstone projects using Node.js (backend), React/Vite (frontend), PostgreSQL (database), Docker, and OnlyOffice for document editing.
- Architecture Overview
- Prerequisites
- Quick Start (Development)
- Environment Variables & Credentials Guide
- Running in Development Mode
- Running Tests
- Deployment
- Common Commands Reference
- Troubleshooting
┌─────────────────────────────────────────────────────────────────────┐
│ Your Local Machine │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────────┐ │
│ │ Backend │ │ Frontend │ │ PostgreSQL │ │
│ │ (localhost) │ │ (localhost) │ │ (Docker) │ │
│ │ :3000 │ │ :5173 │ │ localhost:5433 │ │
│ └─────────────┘ └─────────────┘ └──────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ OnlyOffice (Docker) localhost:8080 │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Ollama AI (Docker) localhost:11434 │ │
│ └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
| Tool | Version / Notes |
|---|---|
| Node.js | v18+ (LTS recommended) |
| npm | v9+ (comes with Node.js) |
| Docker Desktop | v24+ (with WSL2 backend on Windows) |
| Git | v2.x+ |
| PostgreSQL | Not needed locally (runs in Docker) |
| Ollama | Runs in Docker (optional, for AI features) |
# Clone the repository
git clone https://github.com/M-Ahsen/CapTrak
cd captrak
# Install backend dependencies
cd backend
npm install
# Install frontend dependencies
cd ../frontend
npm install
# Return to project root
cd ..IMPORTANT: The project uses .env files for configuration. Never commit real credentials to version control.
# Step 1: Copy the example files to create your actual .env files
copy .env.example .env
copy backend\.env.example backend\.env
copy frontend\.env.example frontend\.env
# Step 2: Edit each .env file and replace placeholder values
# (See the credentials guide below for detailed instructions)# Start database, OnlyOffice, and Ollama
docker-compose up db onlyoffice ollama -d
# Wait ~60 seconds for Ollama to download AI modelsOpen two separate terminals:
# Terminal 1: Backend
cd backend
npm run dev
# Terminal 2: Frontend
cd frontend
npm run dev# After backend is running, seed the database with test accounts:
.\dev-seed.bat| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:3000 |
| OnlyOffice | http://localhost:8080 |
| PostgreSQL | localhost:5433 (user: admin, password: password, db: captrak) |
This project uses three .env files. Below is a complete guide to every credential required, where to get it, and which file(s) it goes in.
| Credential | Root .env |
backend/.env |
frontend/.env |
docker-compose.yml |
|---|---|---|---|---|
| Database credentials | ✅ | ✅ (in DATABASE_URL) | ❌ | ✅ (hardcoded) |
| Google OAuth Client ID | ✅ | ✅ | ❌ | ✅ (referenced) |
| Google OAuth Client Secret | ✅ | ✅ | ❌ | ✅ (referenced) |
| JWT Secret | ✅ | ✅ | ❌ | ✅ (referenced) |
| Session Secret | ✅ | ✅ | ❌ | ❌ |
| Admin Email/Password | ✅ | ✅ | ❌ | ❌ |
| OnlyOffice JWT Secret | ✅ | ✅ | ❌ | ✅ (referenced) |
| Email (Gmail) credentials | ❌ | ✅ | ❌ | ❌ |
| Backend/Frontend URLs | ✅ | ✅ | ✅ | ❌ |
Legend: ✅ = configured here, ❌ = not needed, (referenced) = reads from root
.envat runtime
Files to edit:
- .env (root)
- backend/.env
Steps:
1. Go to https://console.cloud.google.com/apis/credentials
2. Create a new project (or select existing)
3. Go to "OAuth consent screen" → Configure → "External" → Create
4. Fill in app name, support email, developer contact info
5. Add scopes: email, profile, openid
6. Go to "Credentials" → "Create Credentials" → "OAuth client ID"
7. Application type: "Web application"
8. Name: "CapTraK Development"
9. Authorized JavaScript origins: http://localhost:5173
10. Authorized redirect URIs: http://localhost:3000/api/auth/google/callback
11. Click "Create"
12. Copy the Client ID and Client Secret into both .env files
Files to edit:
- .env (root)
- backend/.env
Generate in terminal:
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
or
openssl rand -base64 32
Paste the output into:
JWT_SECRET=<paste-here>
SESSION_SECRET=<paste-another-here>
File to edit:
- backend/.env
Steps:
1. Go to https://myaccount.google.com/security
2. Enable "2-Step Verification" (2FA) - required
3. Go to https://myaccount.google.com/apppasswords
4. Select app: "Mail" and device: "Other (Custom name)" → "CapTraK"
5. Click "Generate"
6. Copy the 16-character app password (without spaces)
7. Paste into backend/.env:
EMAIL_USER=your-email@gmail.com
EMAIL_APP_PASSWORD=your-16-char-app-password
Files to edit:
- .env (root)
- backend/.env
OnlyOffice requires a JWT secret for secure document editing.
Generate it like JWT secrets above, or use any complex random string.
ONLYOFFICE_JWT_SECRET=your-unique-jwt-secret-for-onlyoffice
Files to edit:
- .env (root)
- backend/.env
These are the system admin account credentials used when seeding the database.
For local development, you can keep the example values.
For production, CHANGE IMMEDIATELY to strong, unique credentials.
ADMIN_EMAIL=admin@yourdomain.com
ADMIN_PASSWORD=YourVeryStrong!AdminPassw0rd
Purpose: Supplies environment variables to docker-compose.yml
Used by: docker-compose up db onlyoffice ollama -d
Template: .env.example
Variables:
DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME
→ PostgreSQL connection for Docker containers
→ Defaults work fine for local development
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
→ REQUIRED for Google OAuth login
→ Get from Google Cloud Console (see guide above)
JWT_SECRET, SESSION_SECRET
→ REQUIRED for authentication tokens
→ Generate random strings (see guide above)
FRONTEND_URL, BACKEND_URL
→ Service URLs for CORS & internal communication
→ Defaults fine for local dev
ONLYOFFICE_JWT_SECRET
→ Required for OnlyOffice document editing security
ADMIN_EMAIL, ADMIN_PASSWORD
→ System admin credentials for seed script
→ CHANGE for production!
Purpose: Configures the Node.js/Express backend server
Used by: npm run dev (in backend/)
Template: backend/.env.example
Variables:
DATABASE_URL → PostgreSQL connection string
Format: postgresql://user:password@host:port/database
Default: postgresql://admin:password@localhost:5433/captrak
PORT → Backend server port (default: 3000)
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_CALLBACK_URL
→ Same Google OAuth credentials as root .env
JWT_SECRET, SESSION_SECRET
→ Same as root .env
ADMIN_EMAIL, ADMIN_PASSWORD
→ Same as root .env
FRONTEND_URL → CORS origin (default: http://localhost:5173)
ONLYOFFICE_URL, ONLYOFFICE_JWT_SECRET, ONLYOFFICE_JWT_ENABLED
→ OnlyOffice configuration
BACKEND_URL, PUBLIC_BACKEND_URL
→ Backend reachable URLs (for callbacks & file downloads)
EMAIL_USER, EMAIL_APP_PASSWORD
→ Gmail credentials for sending emails (see guide above)
OLLAMA_URL → Ollama AI endpoint (default: http://localhost:11434)
Purpose: Configures the React/Vite frontend application
Used by: npm run dev (in frontend/)
Template: frontend/.env.example
Variables:
VITE_API_URL → Backend API URL (default: http://localhost:3000)
VITE_ONLYOFFICE_URL → OnlyOffice URL (default: http://localhost:8080)
NOTE: Frontend only needs URLs. All secrets are handled by the backend.
Purpose: Orchestrates all Docker services
Uses: Root .env file for variable substitution
Credentials passed directly:
- PostgreSQL user/password (hardcoded: admin/password)
- Google OAuth (FROM root .env)
- JWT Secret (FROM root .env)
- OnlyOffice JWT (FROM root .env)
This runs backend and frontend natively, with PostgreSQL + OnlyOffice in Docker.
# 1. Start infrastructure
docker-compose up db onlyoffice ollama -d
# 2. Start backend (Terminal 1)
cd backend
npm run dev
# 3. Start frontend (Terminal 2)
cd frontend
npm run dev
# 4. (Optional) Seed test data
.\dev-seed.batRuns everything in Docker containers for production-like testing.
# Start all services
docker-compose up
# Stop all services
docker-compose down| Script | Description |
|---|---|
dev-start.bat |
Start infrastructure (Docker) + seed + backend + frontend |
dev-stop.bat |
Stop all Docker containers |
dev-reset.bat |
Full reset: stop all, delete DB volumes, restart |
dev-seed.bat |
Seed database with test accounts |
dev-test.bat |
Run Playwright E2E tests |
Before running tests, ensure:
- Infrastructure is running:
docker-compose up db onlyoffice ollama -d - Backend is running:
cd backend && npm run dev - Frontend is running:
cd frontend && npm run dev - Test accounts are seeded:
.\dev-seed.bat
Test files contain placeholder credentials that must be replaced with actual seeded accounts:
| File | Description | Credentials Location |
|---|---|---|
test/multi-login.spec.js |
Playwright E2E login tests | const ACCOUNTS = {...} (top of file) |
test/open-all-accounts.js |
Opens 5 browser sessions | const ACCOUNTS = {...} (top of file) |
❗ IMPORTANT: Replace the placeholder emails/passwords in these test files with the actual accounts created by dev-seed.bat.
# Run all Playwright tests
npx playwright test
# Run tests with visible browser windows
npx playwright test --headed
# Run specific test projects
npx playwright test --project=coordinator --project=admin
# Open all 5 accounts in browser windows (for manual testing)
node test/open-all-accounts.js# 1. Set up production environment files with REAL credentials
# - Copy .env.example → .env
# - Replace ALL placeholder values with production credentials
# - Use strong secrets, real domain names, production OAuth credentials
# 2. Build and start all services
docker-compose up --build -d
# 3. The backend will be on port 3000, frontend on port 80- Replace ALL placeholder credentials in
.envandbackend/.env - Generate strong JWT_SECRET and SESSION_SECRET
- Create production Google OAuth credentials (different from dev)
- Set FRONTEND_URL to your production domain
- Set strong ADMIN_EMAIL and ADMIN_PASSWORD
- Configure production email credentials
- Set ONLYOFFICE_JWT_SECRET to a strong unique value
- Change database passwords to strong values
- Enable HTTPS (use a reverse proxy like Nginx + Let's Encrypt)
- Remove/disable the batch scripts (
dev-*.bat) on production - Ensure
.envfiles are in.gitignore(never commit secrets!)
# Backend
cd backend
npm install --production
npm run build # if a build step exists
npm start
# Frontend (served via Nginx or similar)
cd frontend
npm install
npm run build
# Serve the dist/ folder with a web server# ── Infrastructure ──
docker-compose up db onlyoffice ollama -d # Start services
docker-compose down # Stop all
docker-compose down -v # Stop + delete volumes
docker-compose ps # Check status
docker-compose logs -f db # View DB logs
# ── Database ──
docker exec -it captrak-db-1 psql -U admin -d captrak # Connect via psql
# ── Backend ──
cd backend && npm run dev # Start dev server
cd backend && npx prisma generate # Regenerate Prisma client
cd backend && npx prisma db push # Push schema to DB
# ── Frontend ──
cd frontend && npm run dev # Start dev server
# ── Tests ──
npx playwright test # Run E2E tests
node test/open-all-accounts.js # Open all accounts manually# Check what's using the port
netstat -ano | findstr :3000
netstat -ano | findstr :5433
netstat -ano | findstr :8080
# Kill the process (replace PID with actual process ID)
taskkill /PID <PID> /F# Restart Docker Desktop
# Or run:
docker-compose down
docker-compose up db onlyoffice -d# Wait for database to be ready
docker-compose ps
# View database logs
docker-compose logs db# Restart OnlyOffice
docker-compose restart onlyoffice
# View logs
docker-compose logs -f onlyoffice# Complete reset (deletes all data!)
.\dev-reset.bat
# Or manually:
docker-compose down -v
docker-compose up db -d
cd backend
npx prisma generate
npx prisma db push# If test login fails:
# 1. Ensure test accounts are seeded: .\dev-seed.bat
# 2. Check the actual seeded emails/passwords
# 3. Update them in test/multi-login.spec.js and test/open-all-accounts.js- NEVER commit
.envfiles to version control (they are in.gitignore) - ALWAYS use
.env.exampleas templates for new environments - ROTATE credentials regularly in production
- Use different OAuth credentials for development vs production
- Generate unique JWT secrets for each environment
- Keep the OnlyOffice JWT secret consistent across
.envandbackend/.env
captrak/
├── .env # Docker Compose env vars (SANITIZED)
├── .env.example # Template for .env
├── docker-compose.yml # Docker services config
├── backend/
│ ├── .env # Backend config (SANITIZED)
│ ├── .env.example # Template for backend/.env
│ └── ...
├── frontend/
│ ├── .env # Frontend config
│ ├── .env.example # Template for frontend/.env
│ └── ...
└── test/
├── multi-login.spec.js # Test file (SANITIZED)
└── open-all-accounts.js # Test script (SANITIZED)
Files marked (SANITIZED) have had their real credentials replaced with placeholder values for security.