Alright, I'll be straight with you — I got tired of the debate. Every week there's a new post claiming AI has replaced developers, or that anyone can ship a full production app over a weekend with zero technical knowledge. So instead of arguing about it in some comment section, I decided to actually test it. On a real client project. With real requirements. Where something breaking would have actual consequences.
The project is Craftura Fine Furniture — a complete furniture manufacturing website for a client in Ahmedabad with B2B and B2C ordering, an admin panel, analytics, CMS, WhatsApp integration, email notifications, dark/light mode, and SEO baked in. Built on Next.js 14, Prisma ORM, and SQLite. I used AI heavily throughout the build. I also kept notes on everything it got right, everything it got wrong, and — most importantly — the bugs that would have quietly destroyed the app in production if nobody technical had been watching the output.
This is that honest account. Not a sales pitch for AI tools. Not a doomer take either. Just what actually happened — the fast bits, the broken bits, and the silently dangerous bits nobody usually talks about.
What Craftura Actually Is — Scope Matters Here
I want to be specific about scope because it's everything when people claim "AI can build apps." They're usually picturing a form with a database behind it. That's not what this was.
The customer-facing side includes product browsing with search and category filters, individual product pages with image galleries, an inquiry cart handling both regular and bulk B2B orders, an order tracking page with animated status progression, order self-cancellation, a masonry project gallery with lightbox, a dedicated B2B quote request page, and WhatsApp integration on every key customer action. Dark and light mode, persisted across sessions.
The admin panel is where it gets genuinely heavy — an analytics dashboard with bar charts, a donut chart for B2B/B2C split, and a revenue trend line (all custom SVG, no charting library), manufacturing cost reports, repeat customer detection, a revenue forecast widget, CSV and Excel export, full CRUD for products, categories, orders, inquiries, and gallery items, and a CMS for editing site content and toggling nav items.
Under the hood: 9 Prisma models, JWT auth with Edge-compatible middleware, Nodemailer for emails, dynamic sitemap.xml and robots.txt, JSON-LD structured data, per-page Open Graph metadata, and a schema that switches from SQLite to PostgreSQL in two line changes.
That's the baseline. Keep it in mind for everything that follows.
How the AI Workflow Actually Worked — Not What People Think
The workflow is not: write a prompt, deploy the output, go home. I genuinely don't know where that idea came from, but it's harmful to anyone trying to use these tools seriously.
What actually happened was a loop. Describe the requirement clearly → review what came back → run it → watch what broke → understand why it broke → fix it → move on. If I had to compress it into one sentence: AI is an extraordinarily fast junior developer who writes code instantly but needs someone experienced in the room at all times.
Where AI was genuinely fast and reliable:
Initial scaffolding — the Next.js 14 App Router setup, Prisma config, Tailwind wiring. Work that normally eats half a day was done in minutes, and it was clean. Once I had one API route working the way I wanted, generating four more was nearly instant and stayed consistent.
Repetitive CRUD — once the product route pattern was established, categories, orders, inquiries, and gallery items followed in seconds. Same structure, same error handling, same patterns throughout. This is genuinely one of AI's strongest areas.
Boilerplate-heavy features — email templates, the WhatsApp link builder, JWT utilities, the Prisma client singleton. These are well-understood patterns and AI executes them reliably. Review them, but expect them to work.
// AI generated this entire schema from a plain English description:
// "I need products with multiple images, categories, B2B/B2C ordering,
// and a gallery with featured items"
model Product {
id String @id @default(cuid())
name String
slug String @unique
description String?
price Float?
minOrderQty Int @default(1)
isFeatured Boolean @default(false)
isActive Boolean @default(true)
categoryId String
category Category @relation(fields: [categoryId], references: [id])
images ProductImage[]
orderItems OrderItem[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Order {
id String @id @default(cuid())
orderNumber String @unique
customerName String
email String
phone String?
orderType String @default("B2C") // B2C | B2B
status String @default("PENDING")
// PENDING → CONFIRMED → IN_PRODUCTION → DELIVERED | CANCELLED
totalAmount Float?
notes String?
items OrderItem[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// All 9 models came back correctly structured.
// Relationships made sense, cascade rules were appropriate.
// Saved roughly 2–3 hours of schema design work.What AI Got Wrong — The Bugs That Would've Shipped to Production
This is the section most AI experience posts skip entirely, and it's the most important one. The bugs that showed up on Craftura are exactly the kind of thing that quietly destroys a production app if nobody technical is reviewing the output. They don't announce themselves. They don't throw obvious errors. They just silently fail in ways that cost you customers, security, or both.
Bug 1: The Middleware That Silently Left the Admin Panel Unprotected
The admin route protection middleware AI generated looked completely reasonable. Imported my JWT verification function, pulled the token from cookies, redirected to login if it was missing. Clean, readable, made total sense when I read through it. It also crashed immediately in production with a cryptic runtime error that had nothing to do with the authentication logic itself.
The problem: Next.js 14 middleware runs in the Edge Runtime, which cannot use Node.js APIs. My verifyToken function internally called into next/headers — which chains into Node — so the whole thing collapsed. A non-developer looking at this error would have had no idea what hit them. Worse, if it had somehow partially worked, the admin panel would have appeared protected while not actually being so. That's not a bug you find until a customer or a security audit finds it for you.
// WRONG — what AI generated. Looks fine, breaks immediately.
import { verifyToken } from '@/lib/auth' // ← internally uses next/headers
export async function middleware(request: NextRequest) {
const token = request.cookies.get('admin-token')?.value
const user = await verifyToken(token) // ← crashes in Edge Runtime
if (!user) return NextResponse.redirect(new URL('/admin/login', request.url))
}
// CORRECT — after identifying the constraint and fixing it
import { jwtVerify } from 'jose'
export async function middleware(request: NextRequest) {
const token = request.cookies.get('admin-token')?.value
if (!token) return NextResponse.redirect(new URL('/admin/login', request.url))
try {
const secret = new TextEncoder().encode(process.env.JWT_SECRET)
await jwtVerify(token, secret)
return NextResponse.next()
} catch {
return NextResponse.redirect(new URL('/admin/login', request.url))
}
}
// The fix is simple once you know the constraint.
// jose works in Edge Runtime. Node.js APIs do not.
// AI didn't flag this. It just generated code that looked right and wasn't.Bug 2: The Infinite Redirect Loop
Same middleware, second problem. The matcher pattern AI generated was /admin/:path* — which sounds right, and mostly is, except it also matches /admin/login. So an unauthenticated user hitting the login page gets redirected to the login page, which matches the middleware, which redirects again, forever. The browser just spins. No error. No stack trace. Just a loop with no exit. The fix required understanding how Next.js middleware matchers actually work and explicitly listing the routes that needed protection — not lazily catching everything under /admin.
// WRONG — matches /admin/login too, causes an infinite redirect loop
export const config = {
matcher: ['/admin/:path*']
}
// CORRECT — be specific about what actually needs protecting
export const config = {
matcher: [
'/admin',
'/admin/analytics/:path*',
'/admin/products/:path*',
'/admin/orders/:path*',
'/admin/categories/:path*',
'/admin/inquiries/:path*',
'/admin/gallery/:path*',
'/admin/content/:path*',
]
}
// Once you see it, it's obvious.
// But you have to know enough about Next.js matchers to know to look for it.Bug 3: The Analytics Charts With Wrong Math
The analytics dashboard needed charts. I didn't want to pull in Chart.js just for the admin panel, so I asked for pure SVG. AI delivered — bar chart, donut, revenue trend line, all rendered cleanly in the browser. They looked great. The bar heights were wrong.
Not obviously wrong. Wrong in a way that only showed up when data values weren't evenly distributed. The SVG coordinate mapping was scaling bar heights relative to the data array maximum rather than the chart viewport height, so certain value distributions rendered at subtly incorrect proportions. You cannot catch this visually unless you already suspect something is off. Finding it meant reading the SVG path math by hand and comparing rendered heights against raw data values. A client pointing it out in production is not the way you want to discover it.
Bug 4: Stale Order Statuses Showing Wrong Data to Customers
This one is easy to miss and expensive in production. The order tracking page AI generated used a standard fetch() call to pull order status — which Next.js 14 caches aggressively by default. The result: customers refreshing their order tracking page would see a status that was hours old. An order that had moved from PENDING to IN_PRODUCTION would still show PENDING until the cache expired on its own. The fix is a single line, but you only know to add it if you understand Next.js caching behaviour. AI generated correct-looking code that silently served stale data.
// WRONG — Next.js 14 caches this by default. Customers see stale order status.
const res = await fetch(`/api/orders/${orderId}`)
// CORRECT — opt out of caching for real-time data
const res = await fetch(`/api/orders/${orderId}`, {
cache: 'no-store' // ← one line, but you have to know it's needed
})
// Alternatively, on the route handler:
export const revalidate = 0
// AI doesn't reason about caching intent vs caching behaviour.
// It generates the fetch. You have to know when the default is wrong.What You Can Actually Trust AI to Get Right
After building Craftura, here's my honest breakdown of where AI accuracy actually sits. I've stopped thinking about this in binary terms — it's not "reliable" or "unreliable." It's more like three distinct tiers, and knowing which tier you're in before you start a feature changes how much you review and how much you test.
The Cost Comparison — With Actual Numbers
Craftura is 50+ files of production TypeScript. 17+ pages, 20+ API routes, 9 database models, a full admin panel. Let me be specific about the time because vague claims don't help anyone.
Without AI (senior developer estimate):
Database schema + Prisma setup: 1 day
Customer-facing pages: 4–5 days
Admin panel: 5–6 days
API routes: 3–4 days
Auth + middleware: 1 day
Email + WhatsApp integration: 1 day
SEO + JSON-LD + metadata: 1 day
Custom SVG analytics dashboard: 2–3 days
Testing + debugging: 3–4 days
Total: roughly 21–26 days
With AI assistance (what actually happened):
8–10 days.
At a senior developer rate of $55–70/hr, those saved 15 days represent somewhere between $6,600 and $8,400 in development cost. The AI subscription for that period was under $50. That gap is real, and I'm not going to downplay it.
You can check an AI powered cost estimate completely free by clicking HERE.
Why Technical Knowledge Is Still Non-Negotiable
The time saving I described above is only real because I could review the output properly. That's the part the "anyone can build apps with AI" crowd consistently leaves out — and honestly, I think some of them know it.
On Craftura alone, catching the real issues required knowing:
Next.js Edge Runtime constraints — understanding that middleware cannot use Node.js APIs, why that matters, and knowing to reach for jose instead of a custom JWT utility
HTTP security principles — recognising that default credentials and JWT secrets should never appear in a public repo, even in example files
Database design — reading the generated schema and understanding whether the relationships, indexes, and cascade rules actually matched the intended access patterns
SVG coordinate systems — reading chart math by hand and verifying it against rendered output
Next.js caching behaviour — knowing when to add revalidate or cache: 'no-store' to calls that return real-time data like order statuses
None of that comes from watching a tutorial about AI-assisted development. It comes from actually working as a developer. AI doesn't bring that knowledge to the table — it needs it applied to everything it produces. Without it, the middleware bug alone would have meant an admin panel that appeared protected but wasn't.
The Right Way to Think About AI-Assisted Development
After building Craftura, here's the mental model that actually matches reality — not the hype, not the doomerism:
AI is a force multiplier, not a replacement. A senior developer with AI can move at a pace that genuinely wasn't possible before. A non-developer with AI will produce code that appears to work but contains security issues, logic errors, and architectural problems they have no way of identifying.
The value is in the review, not the generation. Anyone can generate code. The skill is knowing what to ask for, reading what comes back, spotting what's wrong, and fixing it correctly. That skill requires the same technical foundation it always did.
AI accelerates the known, not the unknown. Established patterns — CRUD APIs, authentication, form handling, database queries — AI handles quickly and reliably. Novel problems, complex business logic, and framework-specific edge cases need significant developer input.
The cost saving is real, but so is the responsibility. Craftura was built faster and cheaper with AI. It was also built correctly because a developer reviewed everything. The cost saving disappears fast if you're spending those savings fixing production bugs that a proper review would have caught.
Three Things I'd Do Differently
If I built Craftura again with AI assistance, I'd change three things. Not because the build went badly — it went well — but because these would have made it go faster with fewer backtrack moments.
1. Define the full architecture before generating anything. Database schema, API contract, component hierarchy — all of it written out before a single line of code. AI follows a good spec very precisely. Asking it to figure out architecture as it goes produces inconsistencies that compound over time. A few hours of upfront design pays back days of later refactoring.
2. Generate one module at a time and test it completely before moving on. Generate everything first and test later means bugs from the first module are buried under weeks of subsequent work. One route, tested end-to-end, then the next. It feels slower in the moment. It's faster overall.
3. Maintain a context file for every session — this was the single biggest productivity win. I actually did this on Craftura — there's a .ai/ folder in the repo with session context files I fed to the AI at the start of each session. Full architecture summary, schema, naming conventions, and established patterns — all in context before writing a single line. The output stayed consistent across sessions because the AI knew the existing codebase. Without this, each new session starts cold and you spend the first 15 minutes re-explaining your own project. With it, you pick up exactly where you left off. If you take nothing else from this post, take that.
Craftura's source code is on GitHub. If you're planning a similar project — a full-stack application where you want AI-assisted development done by someone who actually knows what to watch out for — or if you have existing AI-generated code you want reviewed and properly hardened before it goes live, get in touch. The gap between generated and production-ready is exactly where the real work is.
Have Thoughts? Let's Talk.
If this post raised questions, sparked a disagreement, or you're building something similar and want to compare notes — I'm genuinely interested in the conversation. Hit the link below and it'll open a draft email straight to me. No forms, no bots.
💬 Start a Discussion →
Opens your email client with my address pre-filled. No tracking, no funnel — just a real conversation.