You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AI-powered interview preparation platform. Practice DSA, system design, and coding questions with AI feedback, track your progress, and chat with AI assistants (Groq + Ollama).
User → LoginPage
→ POST /api/v1/auth/login { email, password }
← { token, refreshToken, user: { id, email, name, ... } }
→ token saved to localStorage + authStore
→ Navigate to /dashboard
→ All subsequent requests: Authorization: Bearer <token>
Chat Flow
ChatPage loads → GET /api/v1/chat/sessions (load history)
User types message → useChatSession.ensureSession()
→ if no session: POST /api/v1/chat/sessions?topic=general
User sends → POST /api/v1/chat/messages { sessionId, message, model }
→ ChatService saves user message
→ CompositeAiService.chat(message) [Groq first, Ollama fallback]
← { role:"assistant", content:"AI reply", ... }
→ Message rendered in ChatPage
Topic Study Flow
Sidebar → TopicPage (/topics/:topic)
→ useTopicData(topic) fetches in parallel:
GET /api/v1/questions/category/:topic (question list)
GET /api/v1/progress (completed steps)
→ User reads TheoryCard / CodingCard questions
→ "Mark done" → PUT /api/v1/progress/:topic/:stepName { status:"done" }
→ Progress % updates in DashboardPage
Interview Flow
InterviewPage → POST /api/v1/interviews/start?topic=dsa&difficulty=easy
← InterviewSession { id, topic, status:"active" }
→ Questions displayed, user answers
→ PUT /api/v1/interviews/:sessionId/progress?questionsAttempted=10&correctAnswers=7
→ POST /api/v1/interviews/:sessionId/complete
→ TopicProgress updated (proficiency level computed)
Document RAG Flow
AdminPage / DocumentsPage
→ POST /api/v1/documents/upload (multipart/form-data)
→ DocumentService: parse file → chunk text → embed via Ollama
→ Chunks stored in DocumentChunk with embeddings
→ RagService.generateAnswerFromDocuments(query, documentId)
→ retrieve chunks → build context → AiService.chat(prompt)
Playground Flow
PlaygroundPage → Monaco editor (write code)
→ POST /api/v1/playground/hint?topic=dsa&question=...
→ POST /api/v1/playground/review?code=...&language=java
→ POST /api/v1/playground/explain?topic=dsa&concept=...
← AI-generated hint / review / explanation
Note: code execution is not available (no Docker runner)
{darkMode,sidebarOpen,toasts}// Actions: toggleDarkMode, toggleSidebar, addToast, removeToast// DOM class toggling (dark mode) handled in App.jsx useEffect — NOT in the store
AI Services
The backend uses the Strategy + Composite pattern for AI:
AiService (interface)
├── GroqService — implements AiService, calls Groq REST API
├── OllamaService — implements AiService, calls local Ollama
└── CompositeAiService (@Primary)
→ tries Groq first
→ falls back to Ollama if Groq throws
→ throws if both fail
All services (ChatService, PlaygroundController, RagService) inject AiService — they never reference Groq or Ollama directly.
AI Methods
Method
Description
chat(message)
General conversational response
reviewCode(code, language)
Code quality review
getHint(topic, question)
Hint without revealing full answer
isAvailable()
Health check
Model Configuration (application.yml)
app:
external:
ollama-model: llama2 # overridable via OLLAMA_MODEL env vargroq-model: llama-3.1-8b-instant # overridable via GROQ_MODEL env varollama-url: http://localhost:11434
Security Model
JWT Authentication
Tokens signed with HS512, 24-hour expiry (refresh: 7 days)
cd client
npm test# run once
npm run test:watch # watch mode
npm run test:coverage
Category
Files
Tests
Stores
authStore, chatStore, uiStore
18
Utilities
progress, groupByDate, clipboard
15
Hooks
useStatusPoller, useChatSession, useBookmark
10
API contracts
services/api
8
Constants
topics, ui
7
CI/CD
Continuous Integration (CI)
Runs on GitHub Actions (.github/workflows/ci-test.yml) on every push and pull request to main / develop.
Job
Runner
Steps
backend-test
ubuntu-latest
JDK 21 (Temurin) · mvn clean package · mvn test against PostgreSQL 15 + Redis 7 service containers · uploads surefire reports
frontend-build
ubuntu-latest (Node 20.x & 22.x matrix)
npm install · npm run lint · npm run build
docker-build
ubuntu-latest
Builds the backend image via Buildx with GHA layer caching (runs after tests pass, push events only)
status-check
ubuntu-latest
Aggregates job results and fails the pipeline if any job failed
Continuous Deployment (CD)
Triggered after successful CI completion (.github/workflows/cd-deploy.yml). Automatically triggered on successful CI completion to main branch, or manually via workflow dispatch.
Job
Purpose
Deployment
deploy-decision
Evaluates CI status and determines if deployment should proceed
Decision gate
push-docker-image
Authenticates to Docker Hub and builds/pushes backend image to registry with tags (latest, branch, commit SHA)
Docker Hub registry
deploy-staging
SSH-based deployment to staging environment with health checks and Slack notifications
Staging server
deploy-production
Blue-green deployment to production with smoke tests, Slack notifications, and automatic rollback on failure
Production server
rollback-production
Automatic rollback to previous image if production deployment fails
Production server
Required Secrets for CD Pipeline
Configure these under Settings → Secrets and variables → Actions:
Secret
Purpose
DOCKER_USERNAME
Docker Hub username for image push
DOCKER_PASSWORD
Docker Hub Personal Access Token (with Read & Write permissions)
STAGING_SERVER_HOST
Staging server hostname/IP
STAGING_SERVER_USER
SSH username for staging server
STAGING_SERVER_SSH_KEY
SSH private key for staging server
PROD_SERVER_HOST
Production server hostname/IP
PROD_SERVER_USER
SSH username for production server
PROD_SERVER_SSH_KEY
SSH private key for production server
PROD_DOMAIN
Production domain for health checks
SLACK_WEBHOOK
Slack webhook URL for deployment notifications
Design Principles
This codebase follows SOLID and Separation of Concerns:
Principle
Implementation
SRP
AuthService (auth only) · PasswordService (password flows) · AdminService (admin ops) · Each hook has a single responsibility
OCP
AiService interface — add a new AI provider without touching ChatService or PlaygroundController
LSP
GroqService and OllamaService are interchangeable via AiService
ISP
AiService is a focused interface (chat, reviewCode, getHint, isAvailable)
DIP
Controllers and services depend on AiService interface, not concrete GroqService/OllamaService
Mappers
UserMapper, PageResponseMapper — no duplicated mapping logic across services
DTOs
Request DTOs with validation; response DTOs that never expose entity internals
Frontend
Data fetching isolated in custom hooks; stores contain only state + actions; utilities are pure functions
About
End-to-end owner of an AI interview platform: full-stack app, RAG pipeline, vector search, Dockerized infrastructure, and CI/CD deployment. (Active Development)