A full-stack EdTech application designed to reduce student decision fatigue. Built with Next.js, Node.js, PostgreSQL, and AWS Bedrock, the platform uses an advanced AI pipeline to generate personalized daily tasks while requiring explicit user consent for all database mutations.

The Core Problem
Most digital career platforms serve a static roadmap to thousands of students, causing decision fatigue. The product goal was to build a system that acts as an active mentor, issuing small, dynamic daily task queues based on a user’s evolving skill level.
The primary engineering challenge was state management. Large Language Models (LLMs) are stateless functions — they have no persistent memory of past interactions, nor do they inherently understand database constraints.
To provide real value, we built a stateful orchestration layer around the LLM. The system needed to know exactly what the user had completed in the database, read recent chat context, and safely propose changes to the user's learning path without corrupting the core application state.
System Design & Infrastructure
To optimize for rapid iteration while maintaining structural integrity, we consolidated the application into a Next.js monolithic structure, utilizing React Server Components and API routes to handle backend execution securely.

- Application Core: Next.js serves as both the client UI and the backend orchestration layer. NextAuth manages secure, HTTP-only cookie sessions to ensure API endpoints and LLM tool triggers are authenticated before executing.
- Database: A single PostgreSQL environment accessed via Prisma ORM. PostgreSQL stores structured user profiles, roadmap tables, and chat session logs in one unified state to avoid synchronization lag between disparate data stores.
- LLM & Search: AWS Bedrock handles core text generation and tool-calling execution. Qdrant is deployed as a vector database to retrieve specific career data, ensuring the LLM does not rely purely on its pre-trained weights.
The AI Pipeline

We engineered a Retrieval-Augmented Generation (RAG) pipeline combined with explicit tool calling to ground the LLM in factual, user-specific data.
Context Aggregation: When a user sends a prompt, Next.js intercepts it on the server. It queries PostgreSQL for the user's current roadmap status and their recent chat history to establish state.
Vector Retrieval: If the user asks about specific market trends, the server queries Qdrant to retrieve semantic matches.
Inference & Tooling: The aggregated context (User State + Vector Data + Prompt) is sent to AWS Bedrock. Bedrock is configured with strict JSON schemas representing our backend tools (e.g., update_roadmap).
Engineering Tradeoffs & Execution
1. The Streaming Tradeoff: Strings vs. JSON
To create a responsive chat interface, streaming LLM outputs to the client is necessary. However, streaming structured JSON (which we use to render interactive UI components) routinely causes React to crash when it attempts to parse incomplete chunks.
- The Engineering Decision: We bifurcated our response handling. When the LLM returns conversational plain text, the Next.js server streams it directly to the client via Server-Sent Events (SSE). When the LLM needs to output structured JSON for a tool call or UI component, we intentionally disable streaming. The server waits for the complete JSON object, validates its shape via the backend, and only passes the whole object to the frontend. This prioritizes application parsing stability over perceived latency.
2. Manual vs. Automated Updates (Human-in-the-Loop)
Initially, we gave the LLM direct permission to execute Prisma mutations. If a user asked to change career paths, the LLM automatically updated PostgreSQL. User testing showed this caused UX friction, as the UI changed without explicit user confirmation.
- The Engineering Decision: We re-engineered the logic to enforce a Human-in-the-Loop flow. The LLM now sends a structured proposal to the UI (e.g., "Conflict detected. Update roadmap?"). The Next.js backend suspends the database mutation until the user explicitly clicks the "Manual Update" button, at which point the Prisma transaction is securely committed.
Delivery Metrics
Our success metrics for this MVP rollout were grounded in system stability, data safety, and execution delivery:
- Stateful Continuity: Created a persistent mentor experience by reconstructing user context from roadmap progress, chat history, and retrieved knowledge on every interaction.
- Data Integrity: Achieved a strict 100% human-in-the-loop barrier for database modifications. Zero database overwrites can be executed directly by the LLM without verified NextAuth session consent and explicit UI button clicks.
- Parsing Stability: Eliminated the frontend parsing failures observed during development that resulted from incomplete streamed JSON.
- User Validation: Successfully deployed a functional MVP that tested the dynamic "5-task" model with early users.
Project Snapshot
- Project Type: Full-Stack EdTech Platform
- Role: Product Engineering & AI Architecture
- Status: Production MVP
- Core Stack: Next.js • NextAuth • Prisma • PostgreSQL • AWS Bedrock • Qdrant
- Key Feature: A bifurcated AI chat interface engineered to read live PostgreSQL states, safely handle text/JSON payloads, and require explicit user consent for database mutations.
