This project implements a production-grade, client-server search system built on the Next.js App Router. It provides a POST-based API endpoint that performs deterministic keyword relevance scoring against a structured dataset stored in data/data.ts and returns ranked results, summaries, and source references. The UI implements debounced real-time querying, loading states, empty-state handling, and API-driven rendering. The architecture is fully serverless-compatible and optimized for deployment on Vercel or any Node.js edge runtime.
- 🏷️ Project Title
- 🧾 Executive Summary
- 📑 Table of Contents
- 🧩 Project Overview
- 🎯 Objectives & Goals
- ✅ Acceptance Criteria
- 💻 Prerequisites
- ⚙️ Installation & Setup
- 🔗 API Documentation
- 🖥️ UI / Frontend
- 🔢 Status Codes
- 🚀 Features
- 🧱 Tech Stack & Architecture
- 🛠️ Workflow & Implementation
- 🧪 Testing & Validation
- 🔍 Validation Summary
- 🧰 Verification Testing Tools
- 🧯 Troubleshooting & Debugging
- 🔒 Security & Secrets
- ☁️ Deployment
- ⚡ Quick-Start Cheat Sheet
- 🧾 Usage Notes
- 🧠 Performance & Optimization
- 🌟 Enhancements & Features
- 🧩 Maintenance & Future Work
- 🏆 Key Achievements
- 🧮 High-Level Architecture
- 🗂️ Project Structure
- 🧭 How to Demonstrate Live
- 💡 Summary, Closure & Compliance
The application consists of a browser-based UI (app/page.tsx) and a server-side search service (app/api/search/route.ts). Users submit a search query which is validated, normalized, scored against all records in the dataset, sorted by relevance, and returned as a ranked JSON payload. The UI renders the response dynamically using fetch-based asynchronous calls.
- Provide deterministic keyword-based ranking
- Return only the top 3 most relevant records
- Support case-insensitive matching
- Expose summary and source references in JSON
- Implement a responsive, debounced user interface
| Rule | Requirement |
|---|---|
| Ranking | “trust badges” returns id=1 as highest relevance |
| Limit | Only 3 records maximum returned |
| Validation | Empty query returns HTTP 400 |
| No Matches | Returns empty array with message |
- Install Node.js and npm
- Clone the GitHub repository
- Run npm install
- Run npm run dev
- Open http://localhost:3000
| Property | Description |
|---|---|
| Endpoint | POST /api/search |
| Input | JSON { query: string } |
| Output | results[], summary, sources[] |
- Single page: app/page.tsx
- Uses fetch() to call API
- Debounce logic prevents excess calls
- Displays loading, empty, error and results states
- Styles controlled via Tailwind in globals.css
The Mini Full-Stack Search Application is designed as a lightweight but production-grade search engine. Each feature is implemented with deterministic behavior, scalable architecture, and frontend-backend orchestration.
| Layer | Feature | Technical Description |
|---|---|---|
| Frontend | Debounced Real-Time Search | User keystrokes are debounced before API invocation to prevent excessive server calls and improve UX responsiveness. |
| Backend | Relevance-Scored Search Engine | Each dataset item is scored based on keyword frequency and match weight across title and body fields. |
| API | Stateless JSON Contract | POST endpoint returns deterministic JSON with results, sources, and optional summary fields. |
| Data | In-Memory Indexed Dataset | Records stored in data/data.ts are loaded once per request and processed in-memory for fast evaluation. |
| UX | Loading, Empty, Error States | Frontend renders distinct UI states for pending, success, empty, and error responses. |
| Deployment | Serverless Ready | API routes are compatible with Vercel Edge and Node runtimes for elastic scaling. |
User Typing
│
▼
Debounce Timer
│
▼
POST /api/search
│
▼
Scoring Engine → Ranking → JSON
│
▼
UI Rendering
| Layer | Technology | Responsibility |
|---|---|---|
| UI | Next.js, TypeScript, Tailwind | User interface, input handling, rendering |
| API | Next.js Route Handlers | Validation, scoring, ranking, JSON response |
| Runtime | Node.js / Edge | Execution of serverless functions |
| Data | TypeScript Dataset | Source of searchable records |
| Build | Vercel / Next.js Compiler | Bundle, deploy, optimize |
┌──────────────────────┐
│ Browser (User) │
└─────────┬────────────┘
│
▼
┌──────────────────────┐
│ Next.js Frontend │
│ (app/page.tsx) │
└─────────┬────────────┘
│ fetch()
▼
┌──────────────────────┐
│ API Route │
│ /api/search │
└─────────┬────────────┘
│
▼
┌──────────────────────┐
│ Scoring Engine │
│ data/data.ts │
└──────────────────────┘
- User enters a search term in the UI input field.
- Debounce logic waits for typing to pause.
- Frontend sends POST request to /api/search.
- API validates that query is not empty.
- Dataset is loaded from data/data.ts.
- Each record is scored against query tokens.
- Results are sorted by score descending.
- Top 3 results are selected.
- JSON response is generated with results, summary, and sources.
- UI renders results dynamically.
Input → Debounce → API Call → Validation → Scoring → Ranking → JSON → UI
| ID | Area | Command | Expected | Explanation |
|---|---|---|---|---|
| T1 | API | POST trust | id=1 | Top relevance |
| T2 | API | POST empty | 400 | Validation |
| T3 | UI | FORM | Results | Case-insensitive |
- 404 errors indicate incorrect route path
- 405 indicates wrong HTTP method
- Module errors indicate import path issues
- Restart Next.js server to clear cache
- Debounce reduces request volume
- In-memory dataset ensures low latency
- Edge deployment minimizes network hops
User │ ▼ Web Browser │ ▼ Next.js UI (page.tsx) │ ▼ POST /api/search │ ▼ Route Handler │ ▼ Dataset Loader │ ▼ Scoring Engine │ ▼ Ranking & Slicing │ ▼ JSON Response │ ▼ UI Rendering
This flow ensures strict separation of concerns: UI, API, data processing, and response formatting.
mini-fullstack-search-app/ │ ├── app/ │ ├── api/ │ │ └── search/ │ │ └── route.ts → Backend search logic │ │ │ ├── layout.tsx → App shell │ ├── page.tsx → Search UI │ ├── globals.css → Tailwind + global styles │ └── favicon.ico │ ├── data/ │ └── data.ts → Search dataset │ ├── public/ → Static assets │ ├── screenshots/ → UI and validation proof │ ├── package.json → Dependencies & scripts ├── next.config.ts → Next.js configuration ├── tailwind.config.ts → Tailwind setup ├── tsconfig.json → TypeScript configuration ├── eslint.config.mjs ├── postcss.config.mjs ├── next-env.d.ts └── technical_project_details.pdf
This structure cleanly separates UI, API, data, and configuration, enabling maintainability and enterprise-grade scalability.