Full-stack research lab website. Static HTML/CSS/JS frontend served from htmlFiles/, and a Node.js + Express + TypeScript backend in backend/ with PostgreSQL (via Prisma) and S3-compatible storage (MinIO/AWS/Supabase).
.
├── backend/ # Express 5 + TS + Prisma + S3
│ ├── src/
│ │ ├── auth/ # Google OAuth helper
│ │ ├── config/ # Prisma + S3 clients
│ │ ├── controllers/ # Business logic
│ │ ├── middlewares/ # Auth, error handler, etc.
│ │ ├── routes/ # Mounted under /api
│ │ ├── s3/ # Presign helpers, deletion utils
│ │ ├── types/ # Express TS augmentations
│ │ └── utils/ # asyncHandler, response, etc.
│ ├── prisma/ # schema.prisma + migrations/
│ ├── generated/prisma/ # Prisma client output (generated)
│ ├── docs/API.md # Full REST reference
│ ├── scripts/admin.js # Create ADMIN user interactively
│ ├── docker-compose.yml # Postgres + MinIO + backend
│ └── Dockerfile # Multi-stage image (builder/runner)
├── htmlFiles/ # Static frontend (no build step)
│ ├── js/config.js # Picks API base (local/prod) at runtime
│ └── ...
└── README.md
Backend API modules:
- Users (JWT + Google OAuth)
- Images (S3 presigned upload/download/delete)
- Recent Updates and Highlights
- Research Areas and Facilities
- Publications: Books, Book Chapters, Conference Papers, Journal Papers, Patents, Generic Publications
- Projects
- Photo Gallery and Events
- Outreach or Courses
Frontend:
- Static, responsive pages organized by section (admin, users, people, research, publications, outreach, media, etc.)
- Runtime-configured API base via
htmlFiles/js/config.js
- Node.js 18+
- npm or pnpm
- PostgreSQL 15+
- Optional: Docker Desktop (for one-command infra with Postgres + MinIO)
This repository is configured to run the backend as a serverless function on Vercel using backend/vercel.json. When deployed to Vercel:
- Build will run against
src/index.tsvia@vercel/node. - Prisma assets under
generated/prismaandprismaare included in the Vercel build (seevercel.json). - The app will export an Express handler and won't start a local HTTP listener (the serverless wrapper handles requests).
S3: This project has been updated to use Tabi.io as the S3-compatible storage provider in production. Tabi.io provides S3-compatible endpoints and credentials.
To configure Tabi.io in production, set the following env vars (on Vercel or your CI):
ACCESS_KEY_ID=your_tabi_access_key
SECRET_ACCESS_KEY=your_tabi_secret
S3_ENDPOINT=https://s3.tabi.io # example, confirm your region/endpoint with Tabi
S3_REGION=auto-or-specific-region # per Tabi guidance
S3_BUCKET=your_bucket_name
Notes:
- Ensure
S3_ENDPOINTuseshttps://for production providers like Tabi.io. - Keep
forcePathStyle: true(already used by the project S3 client) — Tabi.io is compatible with this. - When deploying, set
VERCEL=1or leavePRODUCTION_SERVER_TYPE=serverlessso the serverless export is used.
- Clone and install backend deps
git clone https://github.com/suryanshvermaa/NEXT-GENERATION-ADAPTIVE-SYSTEM-LAB-NASL-.git
cd NEXT-GENERATION-ADAPTIVE-SYSTEM-LAB-NASL-\backend
npm install- Configure environment (
backend/.env)
Copy .env.example to .env and fill values:
# Server/runtime
PRODUCTION_SERVER_TYPE=serverless or traditional
NODE_ENV=development or production
PORT=3000
# Auth
AUTH_SECRET=your_jwt_secret
CLIENT_ID=your_google_oauth_client_id
CLIENT_SECRET=your_google_oauth_client_secret
# Database
DATABASE_URL=postgres://user:pass@host:5432/dbname
# S3 storage (use http URL for non-AWS providers)
# Local / MinIO example:
ACCESS_KEY_ID=minio_access_key
SECRET_ACCESS_KEY=minio_secret
S3_ENDPOINT=http://localhost:9000
S3_REGION=us-east-1
S3_BUCKET=your_s3_bucket
# Production / Tabi.io example (on Vercel):
# ACCESS_KEY_ID=your_tabi_access_key
# SECRET_ACCESS_KEY=your_tabi_secret
# S3_ENDPOINT=https://s3.tabi.io
# S3_REGION=auto-or-specific-region
# S3_BUCKET=your_bucket_name
Notes:
- The backend expects
S3_ENDPOINTto be a full URL (e.g.,http://s3:9000in Docker orhttp://localhost:9000locally). The S3 client usesforcePathStyle: truefor MinIO/Supabase compatibility. - Google OAuth redirect is currently set in code to
https://nasl-lab-nitp.vercel.app/users/googleCallback.html. Update the OAuth client or adjustsrc/auth/googleAuth.tsfor your environment.
- Database and Prisma
npx prisma generate
npx prisma migrate dev --name init- Run the backend (dev)
npm run devAPI (dev): http://localhost:3000/api Health: http://localhost:3000/health
- Serve the frontend
Use any static web server (Live Server extension recommended). The runtime script htmlFiles/js/config.js chooses API base by hostname:
localhost→http://localhost:3000- otherwise →
https://nasl-lab-backend.vercel.app
You can override at runtime by setting window.NASL.API_BASE before loading config.js.
Inside backend/:
# Start Postgres and MinIO in background
docker compose up -d postgres s3
# First time only: create a bucket via MinIO Console (http://localhost:9001)
# Login with MINIO_ROOT_USER/MINIO_ROOT_PASSWORD from compose (default: suryansh / suryansh)
# Build and run backend
docker compose up --build nasl-backendCompose details:
- Backend exposed on port 3000, service name
nasl-backend - Postgres on 5432 with volume
./postgres_data - MinIO API 9000, Console 9001 with volume
./minio_data
Environment tips when running in Compose:
DATABASE_URLhost should bepostgresS3_ENDPOINTshould behttp://s3:9000
From backend/:
npm run dev— Start dev server with nodemonnpm run build— TypeScript build todist/npm start— Run compiled servernpm run lint/npm run lint:fix— ESLintnpm run format— Prettier writenpm run createAdmin— Interactive admin user creation
Prisma:
npx prisma generate,npx prisma migrate dev --name <name>,npx prisma studio
Base path: /api
Routers mounted in backend/src/routes/index.ts:
/user/image/recentUpdate/highlight/researchArea/researchFacility/book/book-chapter/conference-paper/journal-paper/project/patent/photo-gallery/event/publication/outreachorcourses
Full endpoint details live in backend/docs/API.md.
Health check: GET /health → { "message": "healty", "data": {} }
Auth:
- JWT via
Authorization: Bearer <token>(requiresAUTH_SECRET) - Google OAuth via
POST /api/user/loginWithGooglewith{ code }
- The Prisma client is emitted to
backend/generated/prismaand imported from there. - When deploying to Vercel,
backend/vercel.jsonbuildssrc/index.tswith@vercel/nodeand bundles Prisma assets. - In serverless environments, the app exports a handler and does not start an HTTP listener; locally it listens on
PORTunlessPRODUCTION_SERVER_TYPE=serverlessorVERCEL=1. - Keep
.envout of version control. Rotate secrets regularly.
ISC — see backend/package.json.