Building Tathya: My Journey in Developing an E-commerce Platform

Introduction

Building an e-commerce application as a solo developer can be both a rewarding and challenging experience. My project, Tathya, aims to create a smooth shopping experience for users, integrating modern practices and scalable architecture. This post shares insights from my development process, highlighting how I structured the project and solved technical challenges.

Adopting Agile for Solo Development

Even as a solo developer, I found the Agile methodology valuable to stay organized, focused, and adaptive.

  • Product Backlog: I started by breaking down key features such as user authentication, product catalog, and cart management into user stories.
  • Sprint Planning: Each user story was assigned to fixed sprints, allowing me to focus on manageable chunks within specific time frames.
  • Kanban Board: I used a Kanban board to visualize tasks and their progress, helping to prioritize work and stay on track.
  • Daily Standups: Though I don’t have a team, daily reviews of my progress helped me adjust plans and identify areas for improvement.
  • Building the MVP

    The core goal for the Minimum Viable Product (MVP) is a functional and intuitive shopping platform, focusing on five primary features:

  • User Authentication: Secure user registration and login form the foundation. I added basic validation and error handling, ensuring a smooth user experience.
  • Product Catalog: Users can browse products with essential details like name, description, price, and images. A basic search and filtering system enhances navigation.
  • Shopping Cart: I implemented a cart where users can add, remove, and update items. Each action reflects both on the front end and the server, thanks to React Query for handling mutations.
  • Checkout Process: The checkout system collects shipping and payment info, ensuring the cart is validated before purchase.
  • Order Management: Users can track their order history and status, keeping them informed from the moment they place an order.
  • Designing the Database Schema

    I designed my database using Prisma to define the schema:

    model User {
      id           Int      @id @default(autoincrement())
      username     String   @unique
      email        String   @unique
      password     String
      refreshTokens RefreshToken[]
    }
    
    model Clothing {
      id        Int       @id @default(autoincrement())
      name      String
      price     Float
      colors    Color[]
      sizes     Size[]
    }
    
    model CartItem {
      id          Int      @id @default(autoincrement())
      user        User     @relation(fields: [userId], references: [id])
      clothing    Clothing @relation(fields: [clothingId], references: [id])
      quantity    Int
      createdAt   DateTime @default(now())
    }
    

    This schema establishes relationships between users, products, and orders, enabling a scalable design.

    Challenges: Building the Cart System

    One challenge I encountered was designing a system where the cart state is consistent across both the frontend and backend. To solve this:

  • I retrieve the cart from the API and store it in React context.
  • When users add items to the cart, I update the state locally and in the backend using React Query. This ensures both the NavBar and CartLayout reflect the updated cart contents.
  • This synchronization between frontend and backend was essential to providing a seamless experience.

    JWT Authentication: The Backbone of Security

    For Tathya, security is critical. I implemented JWT (JSON Web Token) authentication for access and refresh tokens. Here’s a quick breakdown of how it works:

  • Access Token: A short-lived token sent with API requests, validated by middlewares like verifyJWT.
  • Refresh Token: A long-lived token, stored as an httpOnly cookie, used to request new access tokens.
  • The basic JWT authentication flow involves:

    const verifyJWT = async (req, res, next) => {
      const authHeader = req.headers.authorization;
      if (!authHeader?.startsWith("Bearer ")) return res.sendStatus(401);
      const token = authHeader.split(' ')[1];
      jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, decoded) => {
        if (err) return res.sendStatus(403);
        req.email = decoded.email;
        next();
      });
    };
    

    This keeps API requests secure while maintaining a stateless design.

    Building a Category Hierarchy

    I designed a hierarchical Category model with self-referential relationships. This allows the system to handle nested categories, such as:

    Women's Clothing
    ├── Dresses
    │   ├── Casual Dresses
    │   ├── Formal Dresses
    └── Tops
    

    Here’s a sample Prisma schema for the category structure:

    model Category {
      id          Int        @id @default(autoincrement())
      name        String
      parent      Category?  @relation("SubCategories", fields: [parentId], references: [id])
      parentId    Int?
      subCategories Category[] @relation("SubCategories")
    }
    

    This allows for recursive queries, providing a robust category filtering system for the product catalog.

    Next Steps: Expanding the Application

    Moving forward, I plan to:

  • Implement advanced product filters on the product page.
  • Refine the order flow.
  • Integrate image uploads using EC2.
  • Complete the deployment process.
  • The challenge of rendering category hierarchies and order flows is next on my roadmap, and I’m excited to dive deeper into these areas.

    Conclusion

    Building Tathya has been a journey filled with learning and problem-solving. From implementing JWT-based authentication to syncing the cart between frontend and backend, each step has contributed to building a scalable and user-friendly e-commerce platform. I’m eager to see where this project goes next as I continue to build and refine its features.

    ← Back to blog