Skip to content

Repository files navigation

LearnYantra MVP — backend scaffold

This is the actual "AI Intelligence Learning Agent" — not a mockup. It's built and typechecks (npx tsc --noEmit passes) and production-builds (npx next build succeeds) as-is. What's missing is a real database and API key, and the frontend (which already exists as static HTML prototypes from earlier in this project — not yet wired to these endpoints).

Setup

  1. npm install
  2. cp .env.example .env.local and fill in:
    • DATABASE_URL — a Postgres connection string (Railway, Supabase, Neon, or local)
    • ANTHROPIC_API_KEY — from https://console.anthropic.com/
    • NEXTAUTH_SECRET — generate with npx auth secret
    • NEXTAUTH_URLhttp://localhost:3000 for local dev
    • GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET — from https://console.cloud.google.com/apis/credentials (OAuth 2.0 Client ID, redirect URI http://localhost:3000/api/auth/callback/google)
  3. npm run db:setup — applies db/schema.sql then seeds the Automation Tester flagship goal (15 topics, real dependency graph, curated resources)
  4. npm run dev — starts the app at http://localhost:3000

No Postgres handy? (local testing)

npm run db:dev starts a real embedded PostgreSQL on port 5433 (data lives in .pgdata/, nothing to install) — keep it running in its own terminal and set DATABASE_URL=postgres://postgres:postgres@localhost:5433/learnyantra. If ANTHROPIC_API_KEY is missing or a placeholder, development mode substitutes a clearly-labeled stub for LLM output so the flow stays testable end to end; production still requires a real key and will refuse to start without one.

What's real vs. what's an honest placeholder

Piece Status
Postgres schema Real — matches exactly what the 4 agent functions need, nothing speculative
Automation Tester dependency graph Real — 15 topics, verified acyclic (see chat), sequenced by an actual SDET's judgment
Curated resources Real — genuine official docs / well-known resources, not placeholder links
Topic sequencing Real — deterministic topological sort, not LLM-guessed order (see comment in lib/agent.ts)
Roadmap narrative Real LLM call (Claude Sonnet) — writes framing text around the already-correct order
Daily plan generation Real LLM call (Claude Haiku) — references actual current topic + weak topics from DB
Resource matching Real — but it's a DB lookup, not live web discovery. This is intentionally the "v1" version of the blueprint's Resource Discovery Agent — see the earlier cost/scope conversation for why
Auth Real — NextAuth.js (email/password via bcrypt, plus Google OAuth). All API routes read the user from the session; a user can only ever access their own data
Frontend Partially wired. pages/auth/signin.tsx (sign up/in) and pages/onboarding/index.tsx (the 6-step onboarding flow) are real, working pages that call the live API. Dashboard/roadmap/today pages are still the next piece of work (Phase 2/3)
Other 2 flagship goals (UPSC CSE, Class 12 Science) Not authored yet. Only automation-tester has seed data

API

All routes below require an authenticated session (NextAuth cookie) and operate on the signed-in user only — there is no client-supplied userId anymore.

  • POST /api/auth/register — body: { email, password }. Creates a new user with a bcrypt-hashed password. Sign in afterward via NextAuth's credentials provider.
  • POST /api/onboarding — body: { persona, goalSlug, interests, skills, hoursPerWeek, deadline }. Updates the signed-in user's profile, then calls generateRoadmap() and generateDailyPlan(). Returns { userId }.
  • GET /api/roadmap — returns the roadmap narrative plus every topic with its status (locked/current/done) and dependency info, for the signed-in user.
  • GET /api/daily-plan — returns today's plan for the signed-in user, generating one if it doesn't exist yet.
  • POST /api/progress — body: { topicSlug, confidence }. Marks a topic done for the signed-in user, unlocks any topic whose dependencies are now satisfied.

Auth

NextAuth.js (v5 beta) with two providers:

  • Credentials (email/password) — pages/auth/signin.tsx posts to /api/auth/register to create the account, then signs in. Passwords are hashed with bcrypt (lib/auth.ts).
  • Google OAuth — needs GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET set.

Sessions are JWT-based (no separate session table lookups needed per request). See lib/auth.ts for the full config and types/next-auth.d.ts for the session.user.id type augmentation.

Note for future sessions: auth() from lib/auth.ts must be called as auth(req, res) inside Pages Router API routes (see any file under pages/api/) — calling it with no arguments only works in App Router Server Components, and will silently return null here.

Why sequencing isn't an LLM call

This is worth understanding before touching lib/agent.ts: topic order comes from topologicalSort(), a plain graph algorithm over the hand-authored depends_on edges in db/seed_automation_tester.sql. An LLM asked to sequence a dependency graph will occasionally produce an invalid order (skip a prerequisite, loop back). A topological sort mathematically cannot. The LLM's only job is writing the narrative text around an order that's already guaranteed correct. This is the actual honest shape of "dynamic roadmap generation" for an MVP — real per-user computation, without pretending an LLM is doing graph theory it doesn't need to do.

Deployment (Railway)

The app is deploy-ready as-is — no code changes needed once you're in the Railway dashboard. railway.json pins the build to Nixpacks and the start command to npm run start; lib/db.ts auto-enables SSL for any DATABASE_URL that isn't localhost (Railway's managed Postgres requires it). This section is the checklist for the actual deploy, which only you can do (it needs your Railway account and control of learnyantra.com's DNS).

  1. Create the Railway projectrailway.app → New Project → Deploy from GitHub repo (this repo). Add a Postgres plugin to the same project; Railway sets DATABASE_URL for you automatically.
  2. Set these environment variables on the app service (Railway → service → Variables):
    • DATABASE_URL — already set by the Postgres plugin, leave as-is
    • ANTHROPIC_API_KEY — a real key from https://console.anthropic.com/ (production refuses to start without one — no dev-stub fallback)
    • NEXTAUTH_SECRET — generate a fresh one with npx auth secret (don't reuse the .env.local dev value)
    • NEXTAUTH_URLhttps://learnyantra.com
    • GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET — from https://console.cloud.google.com/apis/credentials. Add a second authorized redirect URI to the same OAuth client (don't need a new one): https://learnyantra.com/api/auth/callback/google — keep the localhost one too so local dev keeps working.
  3. Apply the schema once — from your machine, with DATABASE_URL temporarily set to the Railway Postgres's connection string (Railway → Postgres plugin → Connect tab has it): npm run db:setup. This is a one-time step, not something that runs on every deploy.
  4. Point the domain — Railway → service → Settings → Networking → Custom Domain → add learnyantra.com. Railway gives you a CNAME (or A/ALIAS) target; add that record at whichever registrar learnyantra.com is registered with. DNS propagation can take up to ~30 minutes.
  5. Verify: https://learnyantra.com loads the app, Google sign-in redirects back to learnyantra.com (not localhost), and a fresh sign-up → onboarding → roadmap run completes end to end.

Next steps

See PHASES.md for the full remaining roadmap to your Sep 1st-week launch, with literal copy-paste prompts for each phase and a week-by-week calendar. See CLAUDE.md for the architectural decisions and conventions every future session (Claude Code or otherwise) on this repo should follow — it's written so you can work independently from here without needing this conversation's context.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages