Community-powered interview experience sharing with company pages, question clustering, and prediction hints.
This folder is self-contained and can be used as its own Git repo root.
Architecture walkthrough: ARCHITECTURE.md
flowchart LR
U[User]
subgraph Vercel
UI[Interview Bank UI]
end
subgraph Render
API[Interview Bank Service]
end
subgraph Supabase
DB[(Postgres)]
end
TG[Token Generator]
U --> UI
UI -->|/api/v1/*| API
API --> DB
UI -. verified contributor token .-> TG
sequenceDiagram
participant U as User
participant UI as Submit Page
participant API as Interview Bank Service
participant JWT as ContributorTokenValidator
participant DB as Postgres
U->>UI: Paste token and submit experience
UI->>API: POST /api/v1/experiences
API->>JWT: validateAndExtract(token)
JWT-->>API: claims
API->>DB: check jti not used
API->>DB: save experience + questions
DB-->>API: saved entity
API-->>UI: 201 Created
UI-->>U: Show submitted experience
interview-bank/
├── service/ Spring Boot API on :8080
├── ui/ React + Vite UI on :5173
├── docker-compose.yml Local stack for this repo
└── .env.example
Interview submissions still use the standalone token-generator service.
- Interview Bank UI:
http://localhost:5173 - Interview Bank API:
http://localhost:8080 - Token Generator UI:
http://localhost:5174 - Token Generator API:
http://localhost:8081 JWT_SECRETmust be identical in both repos
Browsing and reading experiences works without token-generator. Submission flow needs token-generator running.
Docker path:
- Docker Desktop
- Docker Compose v2
Local dev path:
- Java 17+
- Maven 3.8+
- Node.js 20+
- npm
Create the repo-level env file:
cd /home/chinu/interview-bank
cp .env.example .envThe repo-root .env is auto-loaded by the Spring Boot service for local runs.
From the repo root:
cd /home/chinu/interview-bank
docker compose up --buildStop it later with:
cd /home/chinu/interview-bank
docker compose downServices started by this repo:
- UI:
http://localhost:5173 - API:
http://localhost:8080 - Postgres:
localhost:5432
Note: Docker runs the service in the prod profile, so H2 console is not available in this mode.
Terminal 1:
cd /home/chinu/interview-bank/service
mvn spring-boot:runTerminal 2:
cd /home/chinu/interview-bank/ui
npm install
npm run devLocal URLs:
- UI:
http://localhost:5173 - API:
http://localhost:8080 - H2 console:
http://localhost:8080/h2-console
If you want token-based submission to work end-to-end, run both repos.
Terminal 1:
cd /home/chinu/token-generator
docker compose up redis -dTerminal 2:
cd /home/chinu/token-generator/service
mvn spring-boot:runTerminal 3:
cd /home/chinu/token-generator/ui
npm install
npm run devTerminal 4:
cd /home/chinu/interview-bank/service
mvn spring-boot:runTerminal 5:
cd /home/chinu/interview-bank/ui
npm install
npm run devThen use:
http://localhost:5174/?app=interview-bankto generate a tokenhttp://localhost:5173/submitto submit an experience
Repo root .env:
JWT_SECRET=change-me-to-a-strong-random-secret-at-least-32-chars
DATABASE_URL=jdbc:postgresql://postgres:5432/interviewbank
DATABASE_USERNAME=ib_user
DATABASE_PASSWORD=ib_passOptional UI env file for custom API or hosted environments:
cd /home/chinu/interview-bank/ui
cp .env.example .env.localui/.env.local values:
VITE_API_BASE_URL=http://localhost:8080/api/v1
VITE_TOKEN_GENERATOR_UI_URL=http://localhost:5174In local dev mode the service uses H2 automatically. Database variables are mainly for Docker or the prod profile.
Production setup for this repo is:
ui/on Vercelservice/on Render- Postgres on Supabase
- Vercel rewrites
/api/v1/*to the deployed backend service
Create a Supabase project first, then open Connect in the Supabase dashboard and copy a Postgres connection string.
For Spring Boot on a hosted platform, use a JDBC URL in this shape:
DATABASE_URL=jdbc:postgresql://HOST:PORT/postgres?sslmode=require
DATABASE_USERNAME=YOUR_SUPABASE_DB_USER
DATABASE_PASSWORD=YOUR_SUPABASE_DB_PASSWORDIf your host cannot use Supabase direct IPv6 connections, use Supavisor session mode from the same Connect screen and convert that URL to jdbc:postgresql://....
In Render, create a Web Service from this repo and set:
- Runtime:
Docker - Dockerfile Path:
service/Dockerfile - Health Check Path:
/actuator/health
Recommended Render variables on the interview-bank service:
SPRING_PROFILES_ACTIVE=prod
PORT=8080
JWT_SECRET=your-shared-jwt-secret
APP_CORS_ALLOWED_ORIGINS=https://your-interview-bank.vercel.app
DATABASE_URL=jdbc:postgresql://HOST:PORT/postgres?sslmode=require
DATABASE_USERNAME=YOUR_SUPABASE_DB_USER
DATABASE_PASSWORD=YOUR_SUPABASE_DB_PASSWORDNotes:
DATABASE_URLmust use thejdbc:postgresql://...format for Spring Boot.SPRING_PROFILES_ACTIVE=prodis required for hosted Postgres.- The service reads
PORT, so it can run correctly on Render. - Render free services can spin down after inactivity, so expect a cold start after idle time.
In Vercel, import this repo and set:
- Root Directory:
ui - Framework Preset:
Vite - Build Command:
npm run build - Output Directory:
dist
Set Vercel environment variables:
VITE_API_BASE_URL=/api/v1
VITE_TOKEN_GENERATOR_UI_URL=https://your-token-generator.vercel.appThis repo's vercel.json proxies /api/v1/:path* to the deployed backend service. If the Render URL changes later, update only that destination URL. The UI code itself does not need to change.
Test in this order:
- Render health:
https://YOUR-INTERVIEW-BANK.onrender.com/actuator/health - Render API:
https://YOUR-INTERVIEW-BANK.onrender.com/api/v1/companies - Vercel proxied API:
https://YOUR-INTERVIEW-BANK.vercel.app/api/v1/companies - Vercel UI:
https://YOUR-INTERVIEW-BANK.vercel.app
Expected health response:
{"status":"UP"}GET /api/v1/companiesGET /api/v1/companies/trendingGET /api/v1/companies/{slug}GET /api/v1/companies/{slug}/experiencesGET /api/v1/experiences/{id}POST /api/v1/experiencesGET /api/v1/companies/{slug}/predict?role=...
POST /api/v1/experiences requires X-Contributor-Token, issued by the separate token-generator service.