Software Engineer based in Ethiopia with 4 years of experience specializing in TypeScript, Next.js, React, TanStack, Node.js, PostgreSQL, and Golang. I build full-stack applications—from greenfield development and prototyping to debugging production issues, maintaining legacy codebases, and architecting systems.

AI-Powered E-Commerce
CompletedThe Problem
Modern e‑commerce platforms often lack personalised, real‑time shopping experiences. Shoppers struggle to find products efficiently, face stock discrepancies at checkout, and receive generic recommendations. Meanwhile, admins need better tools to manage inventory, understand sales trends, and respond quickly to low‑stock situations.
Tech Stack
System Architecture
The following diagram illustrates the internal components of the E-Commerce platform and their interactions with external services.

Sequence Diagram
This sequence diagram shows the flow of a user requesting AI‑powered furniture recommendations and subsequently ordering a selected item.

Entity Relationship Diagram
The entity‑relationship diagram below depicts the core database schema, including users, items, orders, etc.

Deployment Architecture
The deployment diagram outlines the hosting environment and how the application connects to external services in production.

Challenges
Building this AI‑powered e‑commerce platform came with its share of technical hurdles. Below are the key issues I encountered and how I resolved them.
Sanity CMS
| Problem | Solution |
|---|---|
| "Missing write token" error when trying to create orders from the backend. | Ensured SANITY_API_WRITE_TOKEN was set in environment variables and that the token had Editor permissions in the Sanity project. |
| CORS errors when the frontend tried to fetch directly from Sanity. | Added my production and preview domains to the CORS origins list in the Sanity project settings. |
| TypeScript types out of sync after schema changes. | Ran pnpm typegen after every schema update to regenerate types, and committed the updated types to keep everything consistent. |
Clerk Authentication
| Problem | Solution |
|---|---|
| Middleware not working as expected, causing protected routes to be accessible. | Re‑checked the middleware.ts configuration against the latest Clerk docs – the issue was an incorrect matcher pattern. |
| User not found in session on the client side. | Realised ClerkProvider wasn't wrapping the entire app in the root layout; fixed the provider hierarchy. |
| AgentKit not receiving userId in AI requests. | Verified that auth() is called server‑side in API routes and the user ID is passed explicitly to the AI service. |
Stripe Payments
| Problem | Solution |
|---|---|
| Webhook signature failed errors in the development environment. | Made sure the STRIPE_WEBHOOK_SECRET environment variable exactly matched the secret shown when running stripe listen --forward-to localhost:3000/api/webhook. |
| Payment succeeded but no order created in Sanity. | Traced the issue to the webhook endpoint not having proper error handling – added logging and verified that the Sanity write token was being used correctly. Also ensured the webhook was configured to listen to the checkout.session.completed event. |
| "API key invalid" during testing. | Switched to using test keys (starting with sk_test_) in development; production uses live keys. |
AI Integration (Vercel AI Gateway & LLMs)
| Problem | Solution |
|---|---|
| "Gateway error" when calling the AI endpoint. | Verified that AI_GATEWAY_API_KEY was set correctly in the environment and that the gateway URL was correct. |
| Rate limiting causing failed requests during peak testing. | Implemented request throttling with a queue and added fallback models in case the primary one is unavailable. Also considered upgrading the plan for higher limits. |
| Wrong model response (e.g., getting GPT when expecting Claude). | Double‑checked the model name in shopping-agent.ts – the configuration was pointing to an alias that resolved to the wrong model. Fixed by using explicit model IDs. |
Security Considerations
Comprehensive security measures to protect data, prevent attacks, and ensure secure transactions.
| Area | Measure |
|---|---|
| Authentication | Clerk handles user sessions, password hashing, and MFA; no custom auth logic reduces risk. |
| API Security | All API routes are protected with Clerk's auth() middleware; only authenticated requests can access sensitive endpoints. |
| Payment Data | Stripe processes payments directly; we never touch raw card details (PCI compliance outsourced). |
| Sanity Access | Write operations use a token with minimal required permissions (Editor) and are only performed server-side. CORS settings restrict frontend access to read-only queries. |
| AI Gateway | API keys are stored as environment variables, never exposed to the client. Rate limiting is applied to prevent abuse. |
| Data Validation | Input is validated on both client and server (Zod schemas) to prevent injection attacks. |
| HTTPS | All traffic is forced over HTTPS via Vercel. |
| Environment Variables | Secrets are managed through Vercel's environment system; never committed to version control. |
Performance & Scalability
How the system handles load, keeps responses fast, and scales as traffic grows.
| Area | Measure |
|---|---|
| Frontend Performance | Next.js static generation (SSG) for product pages; incremental static regeneration (ISR) to keep content fresh. Images optimised via next/image. |
| Real-time Updates | Sanity Live uses a persistent connection (WebSocket) to push updates only when data changes—efficient and scalable. |
| AI Requests | Vercel AI Gateway caches responses where appropriate; fallback models prevent downtime. Streaming UI improves perceived performance. |
| Database (Sanity) | Sanity is a managed SaaS with built-in CDN and global edge caching; query performance is optimised with GROQ projections and filters. |
| API Routes | Next.js serverless functions scale automatically; we keep them lightweight (no heavy computation). |
| Caching | TanStack Query caches server responses on the client; Sanity CDN caches content globally. |
No sponsors yet. Be the first!
Become a Sponsor