# Project export: AptiForge: AI-Powered Placement Aptitude Preparation

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: AptiForge — AI-powered placement preparation that analyses company question patterns, identifies your weaknesses, and delivers personalized daily aptitude challenges to help you prepare smarter.
- Devpost: https://devpost.com/software/aptiforge-ai-powered-placement-aptitude-preparation
- GitHub: https://github.com/Yogita-61/Apti_forge
- Video: https://www.youtube.com/embed/UeUwdmKoY7Y?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Yogita-61 (5 commits)

## Devpost submission (written by the team)

### Inspiration

For many college students, aptitude is an integral part of the placement preparation. However, most students do not have an effective way of practicing and preparing while understanding what companies care about, what they are weak in, and what they should focus on next. We wanted to build something that helps students get more out of their placement preparation by making it more personalized, data driven and consistent This inspired us to build AptiForge, an AI powered placement aptitude preparation platform that bridges the three important pillars of preparation: company tendencies, personal performance analytics, and daily practice. Our aim was simple: do not just practice more, practice better

### What it does

AptiForge is an AI powered platform that helps students prepare better for their placement aptitude exams. AptiForge consolidates multiple experiences of preparation into one single place, namely: Comprehensive Aptitude: Covers QA, LR, VA, and Technical aptitude across various levels and types of questions Company Intelligence: Use historical and public information on question patterns of companies to understand what topics to expect from a certain company Data Driven: See analytics on what topics are important, what difficulty levels are common, and what are the patterns in specific companies Personalized Performance Analytics: See your own performance, accuracy, speed, topics of strength and weakness, and patterns in mistakes AI Powered Mistake Mining: Understand what type of mistake you commonly make (conceptual, calculation, misinterpretation, etc) Personalized Recommendations: Get personalized recommendations based on your performance, weaknesses, target companies, and learning history Daily 10: Practice a personalized set of 10 aptitude questions everyday Learning Reinforcement: Learn topics through repeated practice in the upcoming Daily 10s of the next few days Streaks, Challenges, and Contests: Keep track of your streaks, and participate in daily contests to keep yourself motivated Placement Readiness: Get an estimate of how well you are prepared for a particular company based on your accuracy, speed, topic strengths, recent practice, and importance of topics in the company AI Mentor: Ask your mentor questions and get personalized help with your performance, weaknesses, and recommendations The learning loop in AptiForge follows this cycle: [learn → practice → analyze → understand weakness → personalize → practice again] AptiForge aims to take aptitude preparation from being a set of random questions to a personalized and consistent learning experience that follows you for your entire placement journey.

### How we built it

AptiForge is a state of the art full-stack AI platform built to offer the best possible learning experience for placement aptitude preparation. The frontend is written in Next.js, React, TypeScript, Tailwind, and shadcn/ui . We use prisma + sqlite for our database, which stores: students questions topics companies practice data user responses learning data daily 10s streaks and contests performance analytics We use recharts to render the various charts related to company data, and students' performance analytics. Our intelligence layer is powered by powerful GPT-5.6, which is used for various purposes within the application, such as: explaining questions analyzing mistakes identifying weaknesses generating recommendations providing learning insights helping with the AI mentor feature The personalization engine uses a mix of deterministic and AI driven insights to power various recommendations. We have built our own personalization engine for recommending topics based on a mix of factors such as: weak topics recent mistakes topics learned recently target company difficulty of the question historical performance and streaks practice frequency Similarly, the Daily 10 feature uses these signals to recommend a personalized set of 10 questions. For example, if you learn Percentages today, then the Daily 10 for tomorrow can focus on Percentages along with your weak topics and recent mistakes. For company patterns, we have a collection of curated data that has been mined from public sources and historical information on company placements. We analyze this data for patterns in topics and difficulty and use that to power company specific analytics. We make sure to separate between historical data, curated data, and AI generated data, and make this clear to the user. Similarly, we use Codex extensively to accelerate our development process, and power various aspects of the full-stack application, such as: project scaffolding frontend development database modeling API dev AI integration debugging, testing, and iteration

### Challenges we ran into

One of our main challenges was to make sure that the platform provides a truly personalized experience based on the user's performance, and not just randomly generated questions. Aptitude has a huge number of topics and question types, and we had to come up with an intelligent way to personalize the practice sets based on what the user practices and learns. Another challenge was to make sure that while using GPT-5.6 for recommendations, the application remains deterministic and the scoring, streaks, readiness, and other factors remain reliable and predictable. We had to make intelligent choices in separating the roles of AI and deterministic code to make the system reliable and yet personalized. A challenge specific to the company patterns was to make sure that we differentiate between historical data, curated data, and AI generated data, and not present it in a way that implies anything other than what it is. Finally, we had to make sure that we deliver a complete experience within the limited hackathon time by focusing on the most impactful features

### Accomplishments we're proud of

We are extremely proud to have built AptiForge as a personalized aptitude preparation platform. Our main accomplishment is to make sure that the application provides a continuous loop of learning, practice, and personalization based on the user's performance. We are especially proud of having built: a comprehensive preparation experience covering multiple areas of aptitude company specific preparation and analytics personalized Daily 10 that builds upon what the user learns everyday learning analytics that goes beyond simple performance percentages "Mistake DNA" to understand and explain weaknesses in the user's performance placement readiness estimation based on performance, speed, and topic importance in target companies. having streaks, challenges, and contests as part of the motivational system integration of GPT-5.6 into the learning experience and using it for recommendations, explanations, and the AI mentor the use of codex to accelerate the development of the full-stack application The type of experience that we wanted to build was simple: a personalized aptitude preparation where AptiForge knows what you learned, what you struggle with, what companies care about, and helps you decide what to practice next

### What we learned

Building AptiForge was an eye-opening experience for us, and we learned a lot of important lessons. One important lesson was that when it comes to education, personalization is key and AI should be used to drive personalization. We learned that the most useful AI assistant is the one that knows the most about the user. We realized that an effective AI learning assistant is a combination of: AI Intelligence personal performance data learning history and feedback from the user We also learned the importance of separating between AI generated data and other data sources, and making sure to cite information when appropriate. For example, while AI can power recommendation and explanations, the system should be deterministic when it comes to scoring, streaks, placement readiness, and other important factors. We also learned the usefulness of Codex in rapidly developing a full-stack application. Instead of spending too much time on implementing generic functionality, we were able to use Codex to accelerate the development and focus on more important parts of the application. Most importantly, we learned that personalization is continuous. A student should be able to get recommendations based on their learning, mistakes, and progress. That is why some of the most impactful features in AptiForge are the continuous streaks, learning, and practice loops.

### What's next

While AptiForge focuses on aptitude, our ultimate goal is to transform it into a comprehensive AI powered placement preparation ecosystem. Some of our immediate goals include: increasing the number of questions and topics covered expanding the company specific patterns improving the company specific preparation and practice introducing adaptive mock placement tests offering personalized preparation planning based on a student's placement calendar adding coding and technical interview prep supporting multilingual practice and explanations adding voice chat for AI learning and practice enhancing the AI mentor with more long-term planning and insights adding institute wide analytics and faculty dashboards Our ultimate vision is to make sure that the students get better recommendations with every use. We hope to empower every student to answer this important question: "I have a placement test coming up. What should I practice and learn today to be better prepared for tomorrow?"

## README (from the GitHub repository)


# AptiForge

**Forge your aptitude. Target your placement.** AptiForge is a polished hackathon MVP for students preparing for placement aptitude rounds. It turns performance, company-pattern datasets, learning activity and daily habits into a focused next-practice recommendation.

## What makes it different

Instead of only serving questions, AptiForge closes a loop: learn a topic → practice → track accuracy and speed → identify mistake patterns → weight company relevance → personalize Daily 10 → strengthen streak and readiness.

Included experiences: demo login/dashboard, question practice with feedback, Daily 10, readiness, streak display, Mistake DNA, learn-topic reinforcement, company intelligence/comparison, analytics, mentor fallback, and leaderboard.

## Architecture

Next.js App Router provides the UI and API routes. Demo data and the deterministic personalization engine live in `lib/`; no external service is required for judging. A Prisma SQLite schema is included as the production migration path. AI routes safely use a deterministic response if `OPENAI_API_KEY` is unavailable; use `OPENAI_MODEL` (default `gpt-5.6`) when adding live OpenAI calls server-side.

Readiness is accuracy 35%, speed 20%, topic mastery 20%, recent improvement 15%, and company relevance 10%. Daily 10 prioritizes recent learning, weak topics, past mistake patterns, company relevance and revision.

Company analytics use seeded, educational sample mappings inspired by publicly available historical/candidate-reported data. They are not official hiring criteria or a hiring prediction.

## Run locally

```bash
npm install
copy .env.example .env
npm run dev
```

Open http://localhost:3000 and choose **Demo dashboard**. Demo student: Yogita, readiness 78, TCS target, 12-day streak.

Validation commands: `npm run lint`, `npm test`, `npm run build`.

## Deployment

Deploy the Next.js project to Vercel. Set `OPENAI_API_KEY`, `OPENAI_MODEL`, and a production `DATABASE_URL` if enabling live AI and persistence.

## How Codex Accelerated Development

Codex scaffolded this Next.js MVP, implemented its seeded personalization engine and routes, built the responsive UI, added a Prisma migration schema and deterministic tests, then ran build/test checks. This log intentionally describes only work performed in this workspace.


## Detected evidence (automated analysis)

Indexed codebase: 40 recognized source files, 56 KB.
- CSS (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- Vercel (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (46 of 46)

```
.env.example
.gitignore
app/analytics/page.tsx
app/api/ai/mentor/route.ts
app/api/auth/login/route.ts
app/api/auth/logout/route.ts
app/api/auth/me/route.ts
app/api/auth/register/route.ts
app/api/daily-10/route.ts
app/api/daily-10/submit/route.ts
app/api/dashboard/route.ts
app/api/leaderboard/route.ts
app/api/learn/route.ts
app/api/questions/route.ts
app/companies/[company]/page.tsx
app/companies/compare/page.tsx
app/companies/page.tsx
app/daily-10/page.tsx
app/dashboard/page.tsx
app/globals.css
app/layout.tsx
app/leaderboard/page.tsx
app/learn/page.tsx
app/login/page.tsx
app/mentor/page.tsx
app/page.tsx
app/practice/[id]/page.tsx
app/practice/page.tsx
app/register/page.tsx
CODEX_DEVELOPMENT_LOG.md
components.tsx
eslint.config.mjs
lib/auth.ts
lib/client-store.ts
lib/data.ts
lib/engine.ts
lib/prisma.ts
next-env.d.ts
next.config.ts
package.json
postcss.config.js
prisma/schema.prisma
README.md
tailwind.config.ts
tests/engine.test.ts
tsconfig.json
```

### Dependencies

- package.json: @prisma/client@^6.19.2, @types/bcryptjs@^2.4.6, @types/node@^20.17.6, @types/react@^19.2.17, @vitejs/plugin-react@latest, autoprefixer@^10.5.4, bcryptjs@^3.0.3, class-variance-authority@^0.7.1, clsx@^2.1.1, eslint@^8.57.0, eslint-config-next@^15.5.20, lucide-react@^0.468.0, next@^15.1.0, postcss@^8.5.21, prisma@^6.19.2, react@^19.0.0, react-dom@^19.0.0, recharts@^2.15.0, tailwind-merge@^3.6.0, tailwindcss@^3.4.17, typescript@^5.7.0, vitest@^2.1.0, zod@^3.24.0

### Recent commits (newest first)

- Update README.md
- Resolve README merge conflict
- Initial commit
- Enhance README with project details and instructions
- Initial commit

## Key source files (fetched from GitHub, selected and truncated for size)

### CODEX_DEVELOPMENT_LOG.md

```markdown
# Codex development log

- Bootstrapped the AptiForge Next.js application from an empty workspace.
- Implemented the demo dashboard, practice flow, Daily 10, company intelligence, analytics, learning and mentor views.
- Added deterministic demo data, personalization functions, API routes, Prisma schema, environment template and engine tests.
- Validated with the project test and production build commands.

```

### package.json

```
{"name":"aptiforge","version":"1.0.0","private":true,"scripts":{"dev":"next dev","build":"next build","start":"next start","lint":"eslint .","test":"vitest run"},"dependencies":{"@prisma/client":"^6.19.2","@vitejs/plugin-react":"latest","autoprefixer":"^10.5.4","bcryptjs":"^3.0.3","class-variance-authority":"^0.7.1","clsx":"^2.1.1","lucide-react":"^0.468.0","next":"^15.1.0","postcss":"^8.5.21","react":"^19.0.0","react-dom":"^19.0.0","recharts":"^2.15.0","tailwind-merge":"^3.6.0","tailwindcss":"^3.4.17","zod":"^3.24.0"},"devDependencies":{"@types/bcryptjs":"^2.4.6","@types/node":"^20.17.6","@types/react":"^19.2.17","eslint":"^8.57.0","eslint-config-next":"^15.5.20","prisma":"^6.19.2","typescript":"^5.7.0","vitest":"^2.1.0"}}
```

### app/layout.tsx

```typescript
import type { Metadata } from 'next';
import './globals.css';
export const metadata: Metadata = { title: 'AptiForge', description: 'Forge your aptitude. Target your placement.' };
export default function RootLayout({children}:{children:React.ReactNode}) { return <html lang="en"><body>{children}</body></html>; }

```

### app/page.tsx

```typescript
﻿import Link from 'next/link';
import {Nav,Card} from '../components';
import {ArrowRight,Brain,Building2,Flame,Target} from 'lucide-react';
export default function Home(){const features=[[Brain,'Personal performance'],[Building2,'Company intelligence'],[Flame,'Daily 10'],[Target,'Placement readiness']];return <><Nav/><main><section className="hero"><div className="shell"><div className="eyebrow">Your placement preparation workspace</div><h1>Forge your aptitude.<br/><span style={{color:'#5b5cf0'}}>Target your placement.</span></h1><p>Build a real preparation record with focused practice, company-pattern analytics, and daily challenges. Your dashboard starts with your own activity — nothing prefilled.</p><div style={{display:'flex',gap:12,marginTop:30,flexWrap:'wrap'}}><Link className="button" href="/register">Create your account <ArrowRight size={16}/></Link><Link className="button ghost" href="/login">Sign in</Link></div><div className="preview"><div className="app-top"><div className="dots"><i/><i/><i/></div><span>AptiForge workspace</span></div><div className="preview-inner"><div><div className="eyebrow" style={{color:'#a9a7ff'}}>Built from your activity</div><h2>Every practice session becomes your next best step.</h2><p>Your account owns the data. Practice builds your topic history; Daily 10 contributes to your real ranking; your dashboard shows only what you complete.</p><Link className="button" href="/practice" style={{marginTop:22}}>Start practicing <ArrowRight size={15}/></Link></div><div className="flow"><div className="flow-item"><div className="flow-num">01</div><div><b>Practice a topic</b><span>Choose a skill and solve real questions.</span></div></div><div className="flow-item"><div className="flow-num">02</div><div><b>Complete Daily 10</b><span>Save an account-specific daily result.</span></div></div><div className="flow-item"><div className="flow-num">03</div><div><b>Track real progress</b><span>See your own activity and ranking evolve.</span></div></div></div></div></div></div></section><section className="shell page"><div className="eyebrow">A personalized practice loop</div><h2 className="title">Every question can inform your next step.</h2><div className="grid" style={{gridTemplateColumns:'repeat(auto-fit,minmax(210px,1fr))',marginTop:26}}>{features.map(([Icon,label])=>{const I=Icon as typeof Brain;return <Card key={label as string}><I color="#5b5cf0" size={25}/><h3>{label as string}</h3><p className="muted">Earn meaningful insights from your completed activity.</p></Card>})}</div></section></main></>}
```

### app/companies/page.tsx

```typescript
import Link from 'next/link';import {AppNav,Card} from '../../components';import {companies} from '../../lib/data';export default function Companies(){return <><AppNav/><main className="shell page"><div className="eyebrow">Dataset-based intelligence</div><h1 className="title">Target the right patterns.</h1><p className="sub">Publicly available historical/candidate-reported data used for educational analysis.</p><div className="grid" style={{gridTemplateColumns:'repeat(auto-fit,minmax(220px,1fr))',marginTop:25}}>{companies.map(([slug,name,r])=><Card key={slug}><div className="row"><div style={{font:'700 20px Space Grotesk'}}>{name}</div><span className="tag">{r}% ready</span></div><p className="muted">120+ mapped questions · medium-weighted</p><Link className="button ghost" href={'/companies/'+slug}>View intelligence</Link></Card>)}</div><Link className="button" style={{marginTop:20}} href="/companies/compare">Compare companies</Link></main></>}

```

### app/leaderboard/page.tsx

```typescript
﻿'use client';
import {useEffect,useState} from 'react';import {AppNav,Card} from '../../components';
type Row={name:string;score:number;accuracy:number;timeSeconds:number;date:string};export default function Leaderboard(){const [rows,setRows]=useState<Row[]|null>(null);useEffect(()=>{fetch('/api/leaderboard').then(r=>r.json()).then(d=>setRows(d.rows))},[]);return <><AppNav/><main className="shell page"><div className="eyebrow">Daily 10</div><h1 className="title">Live student leaderboard</h1><p className="sub">Ranked by results completed by registered AptiForge students.</p><Card style={{marginTop:24}}>{rows===null?<p className="muted">Loading live results…</p>:rows.length?<table className="table"><thead><tr><th>Rank</th><th>Student</th><th>Score</th><th>Accuracy</th><th>Time</th></tr></thead><tbody>{rows.map((x,i)=><tr key={x.name+x.date}><td>{i+1}</td><td>{x.name}</td><td>{x.score}/10</td><td>{x.accuracy}%</td><td>{Math.floor(x.timeSeconds/60)}:{String(x.timeSeconds%60).padStart(2,'0')}</td></tr>)}</tbody></table>:<div><h3>No results yet</h3><p className="muted">Complete Daily 10 to appear on the leaderboard.</p></div>}</Card></main></>}
```

### app/analytics/page.tsx

```typescript
import {AppNav,Card} from '../../components';export default function Analytics(){return <><AppNav/><main className="shell page"><div className="eyebrow">Personal analytics</div><h1 className="title">Progress you can act on.</h1><div className="grid" style={{gridTemplateColumns:'repeat(auto-fit,minmax(170px,1fr))',marginTop:22}}>{[['Questions solved','146'],['Accuracy','76%'],['Avg. time','58 sec'],['Improvement','+14%']].map(([a,b])=><Card key={a}><div className="muted">{a}</div><div className="kpi">{b}</div></Card>)}</div><div className="twocol" style={{marginTop:20}}><Card><h3>Topic mastery</h3>{[['Percentages',88],['Reading Comprehension',91],['Number Systems',56],['Time & Work',48]].map(([a,b])=><div key={a} style={{margin:'14px 0'}}><div className="row"><b>{a}</b><span>{b}%</span></div><div className="bar"><span style={{width:b+'%'}}/></div></div>)}</Card><Card><h3>Mistake DNA</h3>{[['Concept Gap',35],['Calculation Error',30],['Time Pressure',25],['Careless Error',10]].map(([a,b])=><div key={a} style={{margin:'14px 0'}}><div className="row"><b>{a}</b><span>{b}%</span></div><div className="bar"><span style={{width:b+'%'}}/></div></div>)}<p className="muted">AI insight: accuracy improved by 14% in 7 days. Your biggest leverage point is timed Time & Work practice.</p></Card></div></main></>}

```

### app/login/page.tsx

```typescript
﻿'use client';
import {useState} from 'react';import {useRouter} from 'next/navigation';import Link from 'next/link';import {Nav,Card} from '../../components';
export default function Login(){const router=useRouter();const [email,setEmail]=useState(''),[password,setPassword]=useState(''),[error,setError]=useState(''),[busy,setBusy]=useState(false);async function submit(e:React.FormEvent){e.preventDefault();setBusy(true);setError('');const r=await fetch('/api/auth/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({email,password})});const d=await r.json();setBusy(false);if(!r.ok)return setError(d.error);router.push('/dashboard');router.refresh()}return <><Nav/><main className="shell page question"><Card><div className="eyebrow">Welcome back</div><h1 className="title">Sign in to AptiForge</h1><form onSubmit={submit} className="list"><input required placeholder="Email" type="email" value={email} onChange={e=>setEmail(e.target.value)}/><input required placeholder="Password" type="password" value={password} onChange={e=>setPassword(e.target.value)}/>{error&&<p style={{color:'#d54b34'}}>{error}</p>}<button className="button" disabled={busy}>{busy?'Signing in…':'Sign in'}</button></form><p className="muted">New here? <Link href="/register">Create an account</Link></p></Card></main></>}
```

### app/register/page.tsx

```typescript
﻿'use client';
import {useState} from 'react';import {useRouter} from 'next/navigation';import Link from 'next/link';import {Nav,Card} from '../../components';
export default function Register(){const router=useRouter();const [name,setName]=useState(''),[email,setEmail]=useState(''),[password,setPassword]=useState(''),[error,setError]=useState(''),[busy,setBusy]=useState(false);async function submit(e:React.FormEvent){e.preventDefault();setBusy(true);setError('');const r=await fetch('/api/auth/register',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name,email,password})});const d=await r.json();setBusy(false);if(!r.ok)return setError(d.error);router.push('/dashboard');router.refresh()}return <><Nav/><main className="shell page question"><Card><div className="eyebrow">Start your placement plan</div><h1 className="title">Create an account</h1><form onSubmit={submit} className="list"><input required minLength={2} placeholder="Your name" value={name} onChange={e=>setName(e.target.value)}/><input required placeholder="Email" type="email" value={email} onChange={e=>setEmail(e.target.value)}/><input required minLength={4} placeholder="Password (4+ characters)" type="password" value={password} onChange={e=>setPassword(e.target.value)}/>{error&&<p style={{color:'#d54b34'}}>{error}</p>}<button className="button" disabled={busy}>{busy?'Creating account…':'Create account'}</button></form><p className="muted">Already registered? <Link href="/login">Sign in</Link></p></Card></main></>}
```

### app/practice/page.tsx

```typescript
'use client';import {useMemo,useState} from 'react';import Link from 'next/link';import {AppNav,Card} from '../../components';import {categories,questions} from '../../lib/data';
export default function Practice(){const [cat,setCat]=useState('');const [topic,setTopic]=useState('');const visible=useMemo(()=>questions.filter(q=>(!cat||q.category===cat)&&(!topic||q.topic===topic)),[cat,topic]);return <><AppNav/><main className="shell page"><div className="eyebrow">Practice hub</div><h1 className="title">Build skill, one pattern at a time.</h1><p className="sub">Curated practice questions, clearly labelled by topic and company pattern.</p><div className="card" style={{marginTop:25,display:'flex',gap:12,flexWrap:'wrap'}}><select value={cat} onChange={e=>{setCat(e.target.value);setTopic('')}}><option value="">All categories</option>{Object.keys(categories).map(x=><option key={x}>{x}</option>)}</select><select value={topic} onChange={e=>setTopic(e.target.value)}><option value="">All topics</option>{(cat?categories[cat as keyof typeof categories]:Object.values(categories).flat()).map(x=><option key={x}>{x}</option>)}</select></div><div className="grid" style={{gridTemplateColumns:'repeat(auto-fit,minmax(260px,1fr))',marginTop:20}}>{visible.map(q=><Card key={q.id}><div className="row"><span className="tag">{q.category}</span><span className="muted">{q.difficulty}</span></div><h3>{q.topic}</h3><p className="muted">{q.text}</p><Link className="button ghost" href={'/practice/'+q.id}>Practice question</Link></Card>)}</div></main></>}

```

[30 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]