Series: Building DevDocAI — A Production Multi-Agent LangGraph System
Part 4 — Coming Back, Closing Out the Backend, and Laying Down the Frontend
Where I Disappeared To
It's been about a month since Part 3.
No sugarcoating it — health took a hit, and along with a few other things piling up, DevDocAI sat untouched for weeks. Not proud of the silence, but I'd rather be honest about it than pretend the "building in public" streak was unbroken.
Here's the thing though — the project didn't die. It waited.
And this week I sat back down, opened the repo, and picked up exactly where I left off. No rewrite, no "let me restart with a cleaner approach" spiral. Just continuing.
If you're building something and life knocks you off pace — the comeback matters more than the streak. This post is that comeback.
Recap — Where Things Stood
By the end of Part 3, DevDocAI had:
✅ Full multi-agent LangGraph pipeline (parser → generator → researcher → HITL → publisher)
✅ GitHub OAuth + encrypted token storage
✅ GitHub PR webhook auto-triggering the pipeline
✅ Redis caching layer
✅ Qdrant + Cohere RAG for the onboarding chatbot
The backend was functionally complete for the pipeline itself. But the surface area a frontend would actually need to talk to — repos, pipeline state, chat — wasn't there yet.
That's what this phase closes out.
Part 1 — Finishing the Backend
The Neon Detour
Small but real lesson here: I'd been running Postgres locally in Docker, forgot the password mid-project (it happens), and instead of fighting a container password reset for the fourth time, I just switched dev to Neon.
# before — local docker, constant password drama
DATABASE_URL=postgresql+asyncpg://postgres:???@localhost:5432/devdocai
# after — one connection string, zero local state to babysit
DATABASE_URL=postgresql+asyncpg://neondb_owner:***@ep-xxxx.neon.tech/neondb?ssl=require
Two gotchas worth flagging for anyone hitting the same wall:
- Neon gives you
postgresql://— you have to manually add+asyncpgfor SQLAlchemy's async engine - Neon's copied connection string uses
sslmode=require&channel_binding=require, butasyncpgonly understandsssl=require. Drop the rest or the connection just silently fails.
Once that was sorted, all four tables (users, repositories, documents, pipeline_runs) created cleanly against Neon and stayed that way.
Three Endpoints That Were Missing
The pipeline could run end-to-end via webhook, but nothing existed to let a frontend see into it. So I added:
GET /repos + POST /repos/connect
Lets a user list their connected repos and register a new one against their account. Standard repository-pattern CRUD — route stays thin, RepoService holds the logic, RepoRepository owns the queries.
GET /pipeline/{thread_id}/state
This one's the interesting one. It doesn't touch a custom table — it reads straight from the LangGraph PostgreSQL checkpointer:
snapshot = await doc_graph.aget_state(config)
values = snapshot.values
Whatever state the graph paused at — mid-parse, mid-generation, sitting at human_review — this endpoint reflects it live. No separate "sync the graph state to a table" step needed. The checkpointer already is the source of truth.
POST /pipeline/review
The HITL resume endpoint. A dev approves or rejects on the frontend, this calls resume_pipeline(), and the paused graph continues exactly where it left off — either to doc_publisher or back to doc_generator with their notes as feedback.
POST /chat/ask
Runs the onboarding chatbot graph as a one-shot call. Each question gets its own thread_id — no need to persist a running conversation for a simple Q&A endpoint like this.
Backend endpoint count now:
POST /auth/register
POST /auth/login
GET /auth/github
POST /auth/github/callback
GET /auth/me
POST /webhooks/github
GET /repos
POST /repos/connect
GET /pipeline/{thread_id}/state
POST /pipeline/review
POST /chat/ask
Part 2 — Laying Down the Frontend
This is genuinely new ground for the series — first time anything visual exists.
The Stack
Next.js 15, TypeScript, Tailwind, App Router, src/ directory. Nothing exotic — I wanted the frontend boring and the backend interesting, not the other way around.
The Design Direction
Instead of defaulting to "dark theme, blue accent, done," I tied the visual language to the actual product: an ink background (#0b0e14), and three accent colors mapped directly to what the pipeline stages mean —
- Teal — parsing / published states
- Violet — generation / enrichment (the LLM-heavy steps)
- Amber — the human checkpoint
Typography: Space Grotesk for headings, Inter for body, JetBrains Mono for anything code- or pipeline-related.
The signature piece on the landing page is a small animated component — PipelineStrip — that cycles through the five actual agent names (codebase_parser → doc_generator → brave_researcher → human_review → doc_publisher) with the dot lighting up amber right at human_review. It's not a generic hero animation; it's literally the product's own pipeline, visualized.
Pages Built
frontend/src/
├── app/
│ ├── page.tsx ← landing, with the pipeline strip
│ ├── login/page.tsx ← email/password + GitHub OAuth
│ ├── signup/page.tsx ← same, register flow
│ ├── dashboard/page.tsx← connected repos, status dots
│ ├── review/page.tsx ← HITL approve/reject panel
│ └── chat/page.tsx ← onboarding chatbot UI
├── components/
│ ├── Navbar.tsx
│ └── PipelineStrip.tsx
└── lib/
└── api.ts ← typed fetch wrapper for the FastAPI backend
Login and signup are fully wired — they hit /auth/register, /auth/login, /auth/github for real and store the JWT. Dashboard, review, and chat are built against the real API client too, but since repo-connect and pipeline flows need an actual end-to-end run to populate them, they're currently rendering against sample data with clearly marked TODOs pointing at the exact endpoint each one needs.
A Tailwind v4 Gotcha
Quick note because it cost some time: newer create-next-app scaffolds ship Tailwind v4 by default, which no longer uses @tailwind base/components/utilities. It's:
@import "tailwindcss";
If your custom colors suddenly stop applying and everything renders as unstyled HTML, check your Tailwind major version before anything else.
What's Actually Left
Being straight about the gap, not just declaring victory:
Backend — two small pieces
-
GET /github/repos— right now/reposonly lists repos already connected in our DB. There's no endpoint yet to browse the user's actual GitHub repos to connect one for the first time. - A manual pipeline trigger (
POST /repos/{id}/run) — right now the pipeline only starts from a PR-merge webhook. For a "connect repo → see docs immediately" first-run experience, a manual trigger is needed.
Frontend — the integration pass
- Wiring dashboard/review/chat off sample data and onto the real endpoints above
- Handling the GitHub OAuth redirect callback page
- Loading and empty states for a pipeline that's actually running
Phase 7 — untouched
Docker, ECR, ECS Fargate, GitHub Actions CI/CD. Still ahead.
What I'm Taking From the Break
Momentum matters, but it's not the whole story. The month off didn't erase the project — the code was exactly as I left it, the architecture still made sense coming back to it cold, and picking it back up took an afternoon, not a rebuild.
That's the actual payoff of the layered architecture and the checkpointed graph state I set up back in Part 1 and Part 3: things I built for "production correctness" turned out to also be what made a month-long gap survivable. Clean boundaries don't just help other engineers — they help future-you.
If you're mid-break on something right now: the code will still make sense when you get back. Go take care of what you need to.
GitHub
Nevin100
/
DevdocxAI
DevDocxAI is a production-grade multi-agent AI system that automatically generates, maintains, and updates engineering documentation by deeply understanding you…DevDocAI is a production-grade multi-agent AI system that automatically generates, maintains, and updates doc. by understanding deeply.
DevDocxAI 🤖📄
DevDocxAi is a production-grade multi-agent LangGraph system that automatically generates and updates engineering documentation from your GitHub codebase.
🚨 The Problem
Every engineering team has the same dirty secret — the docs are lying.
Not intentionally. Code moves fast, documentation doesn't.
- New dev joins → 2 weeks reading outdated wikis
- Senior engineers constantly interrupted with "what does this do?"
- PR gets merged → docs never updated
- Generic RAG chatbots don't understand code structure
DevDocAI fixes this.
✨ What It Does
- 🔍 Connects to your GitHub repo via OAuth
- 🌳 Parses your codebase at the AST level — understands functions, classes, modules
- 📝 Auto-generates structured documentation per module and function
- 🔄 Updates docs on every PR merge via GitHub webhooks
- 👀 Human-in-the-Loop review — you approve before anything goes live
- 💬 Onboarding chatbot — new devs ask questions, get answers from live code
🤖 Agent Pipeline
START
↓
codebase_parser…Building in public — with real gaps, and real comebacks.
Tags: python nextjs ai langgraph fastapi typescript opensource webdev

Top comments (0)