Full Stack Development Assignment - Agentic Workflow Project
Submitted by: Desh Deepak Gautam
Date: March 19, 2026
Project: QuickBlink - B2C Quick Commerce Platform
1. Problem Statement
What problem were you trying to solve?
I was given an internship assignment to build a B2C quick commerce application (similar to
Blinkit/Zepto) within a 3-day deadline. The challenge was to create a complete production-
ready system with:
• Microservices architecture (4 separate backend services)
• Mobile application (Flutter mandatory)
• Database integration (MongoDB)
• Containerization and orchestration (Docker + Kubernetes)
• Full e-commerce workflow (authentication, product browsing, cart, checkout, order
tracking)
The real problem wasn't just building the app - it was delivering a complex, multi-component
system in an extremely tight timeframe while learning new technologies (Flutter) on the go.
Why did I choose this problem?
Well, technically I didn't choose it - it was assigned! But I saw it as an incredible learning
opportunity because:
1. Time pressure mimics real-world scenarios - Most development work involves
tight deadlines
2. Full-stack complexity - Covered both frontend and backend comprehensively
3. Modern architecture - Microservices and containerization are industry standards
4. Career relevance - Quick commerce is a booming sector in India, understanding this
domain is valuable
5. Skill demonstration - Perfect way to showcase my ability to learn fast and deliver
under pressure
2. My Approach & Thought Process
How did I break down the problem?
When I first looked at the requirements, I felt overwhelmed. Four microservices, Flutter app,
Docker, Kubernetes - that's a LOT for 3 days! So I took a step back and made a strategic
plan:
Day 1: Backend Foundation (8 hours)
• Set up 4 microservices using FastAPI
• Design MongoDB schema
• Implement core APIs (auth, products, cart, orders, delivery)
• Seed database with 30+ products
Day 2: Frontend Development (10 hours)
• Build React web app first (fallback option, faster)
• Then tackle Flutter mobile app (assignment requirement)
• Focus on core user flows, skip fancy animations
Day 3: Integration & Deployment (6 hours)
• Connect frontend to backend
• Debug connectivity issues
• Create Docker containers
• Write Kubernetes manifests
• Record demo video
Key Decision: I decided to build BOTH React web and Flutter mobile versions. This was
risk management - if Flutter took too long, I'd still have a working React app to submit.
What made my approach unique?
1. Strategic Use of AI Tools: Instead of manually coding everything, I used Google
Antigravity (an agentic AI tool) to accelerate development. But here's the key - I didn't just
blindly accept its output. My workflow was:
• Give clear, detailed prompts with exact specifications
• Review generated code thoroughly
• Test each component individually
• Debug and fix issues myself
• Iterate based on errors
2. Zero-Risk Strategy: Building both web and mobile versions meant I had a guaranteed
working submission even if one failed. This pragmatic approach ensured I'd meet the
deadline no matter what.
3. Problem-First, Not Tech-First: Instead of getting excited about cool tech and over-
engineering, I focused on: "What's the minimum needed to demonstrate a working e-
commerce flow?" This helped me prioritize features ruthlessly.
4. Iterative Testing: After building each service, I tested it immediately. I didn't wait until
everything was done. This "test as you go" approach helped me catch issues early.
3. Tech Stack
Backend:
• Framework: Python FastAPI
o Why: Fast development, automatic API documentation, async support
• Database: MongoDB
o Why: Flexible schema, perfect for microservices, easy to iterate
• Authentication: JWT tokens with bcrypt password hashing
• API Design: RESTful architecture
Frontend (Web):
• Framework: [Link] + Vite
o Why: Component-based, fast development with Vite, huge ecosystem
• Styling: Tailwind CSS
o Why: Utility-first, rapid styling without writing custom CSS
• State Management: React Context API
• HTTP Client: Axios
Frontend (Mobile):
• Framework: Flutter
o Why: Assignment requirement, cross-platform, single codebase
• State Management: Provider
o Why: Simple, recommended by Flutter team, easy to understand
• HTTP Client: http package
• Storage: shared_preferences for JWT persistence
DevOps:
• Containerization: Docker
• Orchestration: Kubernetes
• Development: Docker Compose
Agentic/Automation Tools:
• Google Antigravity: Primary AI agent for code generation
o Used for scaffolding all 4 microservices
o Generated React and Flutter frontends
o Created Docker and Kubernetes configurations
o Provided initial API integrations
• Google Stitch: UI design reference (provided in assignment)
• Manual Work: Testing, debugging, fixing connectivity issues, customizing generated
code
4. Build Explanation
How does my solution work?
Architecture Overview:
The application follows a microservices architecture where each service handles a specific
domain. At the top level, users interact through either the React web app or Flutter mobile
app. Both frontends communicate with the backend services through REST APIs.
The backend consists of four independent microservices, each running on its own port and
managing its own MongoDB collections. The User Service runs on port 8001 and handles
everything related to user accounts - registration, login, JWT token generation, and profile
management. The Product Service also runs on port 8001 and manages the product catalog,
categories, and provides search and filtering capabilities. The Cart and Order Service runs on
port 8002 and handles shopping cart operations, order creation, and order history. Finally, the
Delivery Service runs on port 8003 and tracks order status through different stages.
All these services connect to a single MongoDB instance but use separate collections to
maintain data isolation. This architecture allows each service to be developed, deployed, and
scaled independently.
Key Features & Workflows:
1. User Authentication Flow:
When a user wants to log in, they enter their credentials in the frontend. The frontend sends a
POST request to the auth/login endpoint. The User Service receives this request and validates
the credentials by comparing the entered password with the hashed password stored in the
database using bcrypt. If the credentials are valid, the service generates a JWT token with a
24-hour expiry time. This token is then sent back to the frontend, which stores it in
localStorage for web apps or SharedPreferences for Flutter. For all subsequent API requests
that require authentication, the frontend includes this token in the Authorization header. The
backend services verify this token before processing the request.
2. Product Browsing:
The Product Service has been pre-seeded with over 30 products across 5 different categories -
Fruits and Vegetables, Dairy and Eggs, Snacks and Beverages, Personal Care, and Household
Items. When users open the home screen, the frontend makes a GET request to fetch all
products. Users can filter products by category by clicking on category tabs, which triggers a
new API call with category parameters. Each product displays its name, price, description,
category, and a placeholder image. I implemented the search bar UI on the frontend, though
the backend filtering is currently basic - this is something I documented as a known
limitation.
3. Shopping Cart Management:
The cart functionality works both on the frontend and backend. When a user clicks "Add to
Cart" on a product, the frontend immediately updates its local state so the user sees instant
feedback. Then it makes an API call to POST the cart data to the Cart Service. The Cart
Service stores this information in MongoDB with the user ID, product ID, and quantity.
When calculating the total, the Cart Service fetches current product prices from the Product
Service to ensure accuracy, then computes the total and sends it back to the frontend. Users
can update quantities or remove items, and each action triggers both a local state update and
an API call to keep everything in sync.
4. Order Placement & Tracking:
When the user clicks checkout, the frontend sends all cart items to the Cart Service to create
an order. The service generates a unique order ID using the format "ORD-timestamp-random"
to ensure uniqueness. It saves the order with all items, total amount, and user information to
the orders collection in MongoDB. The initial status is set to "PLACED". After successful
order creation, the Cart Service clears the user's cart. The Delivery Service then manages the
order status progression through four stages: PLACED means the order has been received,
PACKED means items are ready for delivery, OUT_FOR_DELIVERY means the order is on
its way, and DELIVERED means the order has reached the customer. The frontend can query
the Delivery Service to show users their current order status with a visual timeline.
Technical Highlights:
Backend Implementation:
Each microservice is completely independent. They run as separate Python FastAPI
applications, each with its own MongoDB collections. While they can communicate with
each other through REST APIs when needed - like when the Cart Service needs product
prices from the Product Service - they don't share databases or code. This separation means if
one service goes down, others continue working.
All protected endpoints require JWT authentication. When a request comes in, the service
extracts the token from the Authorization header, verifies it hasn't expired, and checks the
signature. Only valid tokens get access. I implemented proper error handling throughout,
returning appropriate HTTP status codes - 200 for success, 400 for bad requests, 401 for
unauthorized, 404 for not found, and 500 for server errors. Each service also has a health
check endpoint that simply returns a 200 status, which is useful for monitoring and
Kubernetes liveness probes.
I enabled CORS on all services because the frontend runs on a different port than the
backend. Without CORS configuration, browsers would block the API calls due to security
policies.
Frontend Implementation - React:
The React app has seven main screens. There's a Login page where existing users sign in, a
Signup page for new user registration, a Home page that shows all products with category
tabs, a Product Detail page that appears when you click a product, a Cart page showing all
items with quantity controls, an Order Confirmation page after successful checkout, and an
Order Tracking page that shows delivery progress.
I implemented protected routes using React Router. If someone tries to access a page that
requires authentication without being logged in, they're automatically redirected to the login
page. The authentication state is managed globally using React Context API, so any
component can check if a user is logged in or access user information.
For API calls, I created a centralized Axios client. This client automatically adds the JWT
token to request headers, handles common error cases, and provides consistent error
messages. All the services' API endpoints are configured in one place, making it easy to
update if backend URLs change.
The styling uses Tailwind CSS throughout. I chose Tailwind because it's fast to work with
and keeps the bundle size small. The design is responsive and works on both desktop and
mobile screens.
Frontend Implementation - Flutter:
The Flutter app has eight screens with similar functionality to the React version, plus an
Order History screen. The UI follows Material Design 3 guidelines for a modern, native
Android feel.
For state management, I used the Provider package. I created separate providers for
authentication state, product data, cart items, and orders. When any of these change - like
adding an item to the cart - Provider notifies all listening widgets to rebuild with the new
data. This reactive approach means the UI always stays in sync with the underlying data.
I built a custom API service layer that handles all HTTP communication. The service uses the
http package to make requests and includes the JWT token in headers for authenticated
endpoints. One important thing I learned was that Android emulators can't use "localhost" to
reach the host machine. They need the special IP address [Link]. So all my API base URLs
use [Link] instead of [Link] For iOS simulators, localhost works
fine, but since the assignment focused on Android, I configured everything for the Android
emulator.
The JWT token is stored using shared_preferences, which is Flutter's way of persisting small
amounts of data. When the app starts, it checks if a valid token exists. If yes, the user is
automatically logged in. If no, they see the login screen.
I implemented proper error handling throughout. Network errors show user-friendly
messages like "Unable to connect. Please check your internet connection." Invalid credentials
show "Email or password is incorrect." Loading states display circular progress indicators so
users know something is happening.
Deployment Setup:
Each microservice has its own Dockerfile that specifies how to build a container image. The
Dockerfile starts with a Python base image, copies the code, installs dependencies from
[Link], exposes the appropriate port, and defines the command to run the FastAPI
server.
For local development, I created a [Link] file that orchestrates all services
together. It defines each service, maps ports to the host machine, sets environment variables
like MongoDB connection strings, and links all services to the same network so they can
communicate. There's also a MongoDB container that provides the database. Running
"docker-compose up" starts everything at once.
For production deployment, I created Kubernetes manifests. There are 14 YAML files in
total. Four deployment files define how to run each microservice - how many replicas, which
container image to use, environment variables, resource limits, and health check
configurations. Four service files define how to expose each deployment - using ClusterIP for
internal service-to-service communication and NodePort for the frontend to be accessible
from outside. There's a ConfigMap for shared configuration like API URLs, a Secret for
sensitive data like JWT signing keys and MongoDB passwords, a StatefulSet for MongoDB
to ensure data persistence, and a PersistentVolumeClaim to provide storage for MongoDB
data that survives pod restarts. The health checks include both liveness probes to restart
unhealthy pods and readiness probes to prevent traffic from going to pods that aren't ready
yet.
5. Why This Matters
What makes this project meaningful?
1. Real-World Problem Solving: This wasn't a tutorial project - it was solving an actual
business problem (quick commerce) with real constraints (time, requirements). I experienced
what professional developers face: tight deadlines, changing requirements, debugging
production issues.
2. Learning Through Building: I learned Flutter from scratch while building this. That's not
easy! But it taught me that I can pick up new technologies quickly when needed. In the tech
industry, this adaptability is crucial.
3. Agentic Workflow Mastery: This project showed me the power AND limitations of AI
tools:
• Power: Antigravity generated boilerplate code in minutes that would take me hours
• Limitations: I still needed to understand the code, debug issues, customize features,
and solve problems AI couldn't figure out (like the [Link] emulator connectivity)
The key insight: AI is a force multiplier, not a replacement. I guided Antigravity with clear
prompts, reviewed its output critically, and fixed what didn't work. This human-AI
collaboration is the future of development.
4. Professional Growth:
• Architecture: Understood microservices, why we separate concerns, how services
communicate
• Deployment: Learned Docker, Kubernetes, containerization - not just theory, actual
hands-on
• Full-Stack: Worked across database, backend, web frontend, mobile frontend -
complete picture
• Problem-Solving: When Android emulator couldn't connect to localhost, I debugged
logs, Googled, figured out [Link] solution
5. Proof of Capability: I can now confidently say I've built a production-ready application
from scratch. When recruiters ask "Tell me about a complex project," I have a detailed story
with:
• Clear problem definition
• Technical depth
• Problem-solving examples
• Measurable outcome (delivered in 3 days)
• Working demo