Try the prototype: open the V-Buy storefront. Browse, search, add to cart, apply the coupon VBUY10 and place a demo order. The back-end schema is in schema.sql.
1. Abstract
V-Buy is an online store for everyday products such as headphones, bags, shoes and kitchen items. The project covers the design of the complete e-commerce website: requirements, architecture, UML models, database, user interface and test plan. To prove the design, the customer-facing storefront is built as a working prototype in plain HTML, CSS and JavaScript: a catalogue with search, filters and sorting, product pages, a shopping cart with coupon and delivery rules, a validated checkout and order history. The back end (Java servlets on Tomcat with a PostgreSQL database) is specified in detail, and its database schema was loaded and exercised on a PostgreSQL server.
The project deliberately uses topics from the first three years of the course, so it works as a revision of those subjects in one product. Section 3 shows which subject supports which part.
2. Objectives
- Design an end-to-end online shopping system that a small business could run.
- Build the shopper’s journey (find, choose, pay, track) as a working front end.
- Model the system with UML and a normalised relational database.
- Apply usability and accessibility principles so that the site is easy to use on a phone and with a keyboard.
- Plan and run tests against stated requirements.
- Keep payment and personal data handling safe from the start.
3. Stack and where each part comes from
3.1 Technology choices
| Layer | Technology | Status in this project |
|---|---|---|
| Structure and style | HTML5, CSS3 (grid, custom properties, media queries, prefers-color-scheme) |
Built |
| Behaviour | JavaScript (plain, no framework): DOM, events, hash routing, local storage | Built |
| Icons and shapes | Inline SVG and CSS shapes | Built |
| Server | Java 25, Jakarta Servlet 6.1 and JSP on Tomcat 11 | Designed |
| Data access | JDBC with the pgjdbc driver and a connection pool | Designed |
| Database | PostgreSQL 18 | Schema built and tried out |
| Modelling | UML: use case, class, sequence, state; ER diagram | Done in this report |
| Testing | Test cases, boundary values, automated browser tests (Playwright) | Done |
| Hosting | Linux server with Nginx in front of Tomcat; static files on any web host | Designed |
3.2 Subjects used, by year
| Year | Subject | How it is used in V-Buy |
|---|---|---|
| 1 | C Programming and Data Structures | The cart is a keyed collection of product and quantity; lists, searching and sorting drive the catalogue |
| 1 | English | Plain, consistent interface wording and error messages (technical communication) |
| 1 | Mathematics | Percentage discount with a cap, GST included in price, rounding rules |
| 2 | Object Oriented Programming through Java | Back-end classes (Product, Cart, Order) and database access through JDBC |
| 2 | Database Management Systems | ER model, normalisation, keys and constraints, SQL, transactions |
| 2 | Advanced Data Structures and Algorithms | Hash lookup of products by id, sorting by price and rating, GIN index for text search |
| 2 | Software Engineering | Requirements table, iterative build, test planning |
| 2 | Computer Graphics | Vector (SVG) icons, colour choices and contrast, the price-tag shape |
| 3 | Web Technologies | HTML5, CSS3, JavaScript, DOM, sessions and servlets/JSP |
| 3 | E-Commerce | Business-to-consumer model, catalogue, cart, checkout, payment flow, order life cycle |
| 3 | Human Computer Interaction | Usability heuristics, error prevention, accessibility, responsive layout |
| 3 | Object Oriented Analysis and Design | Use cases, class diagram, sequence and state diagrams |
| 3 | Software Testing Methodologies | Black-box and boundary-value test cases, automated regression run |
| 3 | Computer Networks | HTTP, HTTPS and TLS, caching of static files, request and response cycle |
| 3 | Unix Programming | Linux deployment, Nginx and shell-based start and backup scripts |
| 3 | Middleware Technologies | JSON over HTTP between browser and servlets, connection pooling |
| 3 | Data Warehousing and Data Mining | Future scope: sales reports and “bought together” suggestions |
4. System analysis
4.1 Actors and use cases
flowchart LR
G(["Visitor"])
C(["Customer"])
A(["Store admin"])
P(["Payment gateway"])
G --- g1["Browse and search products"]
G --- g2["View product details"]
G --- g3["Add to cart"]
G --- g4["Register or sign in"]
C --- c1["Edit cart and apply coupon"]
C --- c2["Check out with delivery details"]
C --- c3["Pay: UPI, card or cash on delivery"]
C --- c4["Track orders and view history"]
C --- c5["Cancel an order before packing"]
A --- a1["Manage products, prices, stock"]
A --- a2["Manage coupons"]
A --- a3["Process orders: pack, ship, deliver"]
A --- a4["View sales reports"]
c3 --- P
4.2 Functional requirements
| ID | Requirement | Prototype |
|---|---|---|
| F1 | Show products by category with price, discount, rating and stock | Yes |
| F2 | Search by words in name, description and category | Yes |
| F3 | Sort by popularity, rating and price | Yes |
| F4 | Product page with details, quantity and Add to cart | Yes |
| F5 | Cart with quantity change, removal, running totals that survive a page reload | Yes |
| F6 | Coupon VBUY10: 10 percent off, up to 500 rupees |
Yes |
| F7 | Delivery free over 999 rupees after discount, otherwise 49 rupees | Yes |
| F8 | Show the GST contained in the price (18 percent) | Yes |
| F9 | Checkout with validated name, email, mobile number, address, city and PIN code | Yes |
| F10 | Payment choice (UPI, card, cash on delivery) | Simulated, nothing collected |
| F11 | Order confirmation, order number and order history | Yes (stored in the browser) |
| F12 | Accounts, server-side orders, stock control, payment gateway, admin screens | Designed |
4.3 Non-functional requirements
Pages must work from 360 pixels wide upwards, be usable by keyboard and screen reader, respect the visitor’s light or dark setting and reduced-motion setting, load without a framework, and never show prices or totals that differ between cart, checkout and confirmation.
5. System architecture
5.1 Overall architecture
The prototype is the left side of the picture: the browser alone. The full system adds the server side, which becomes the source of truth for prices, stock and orders.
flowchart TB
subgraph BR["Browser: built as the prototype"]
direction TB
UI["Views: home, shop, product, cart, checkout, order, orders"]
RT["Hash router"]
CM["Cart model: add, set quantity, totals, coupon, GST"]
VL["Form validation rules"]
ST[("Local storage: cart, coupon, orders")]
UI --- RT
UI --- CM
UI --- VL
CM --- ST
end
subgraph WS["Web server: Nginx, TLS, static files, compression"]
NG["Nginx"]
end
subgraph AP["Application server: Tomcat 11 on Java 25: designed"]
direction TB
FI["Filter: session, CSRF token, role check"]
SV["Servlets: catalogue, cart, checkout, orders, account, admin"]
SE["Service layer: pricing, stock, order placement"]
DA["DAO layer: JDBC with prepared statements"]
FI --> SV --> SE --> DA
end
subgraph DB["Data tier"]
PL["Connection pool"]
PG[("PostgreSQL 18: customers, products, orders, payments")]
PL --> PG
end
GW["Payment gateway: hosted payment page"]
BR -->|"HTTPS"| NG
NG -->|"static files"| BR
NG -->|"proxy: JSON over HTTP"| FI
DA --> PL
SE -->|"create payment, receive result"| GW
5.2 Site map and page flow
flowchart TD
H["Home"] --> S["Shop: filter, search, sort"]
S --> PR["Product page"]
PR --> CA["Cart"]
S --> CA
CA --> CO["Checkout: delivery and payment"]
CO -->|"valid form"| OK["Order confirmation"]
CO -->|"invalid form"| CO
OK --> OR["Orders list"]
OR --> OK
CA -->|"empty cart"| S
5.3 Prototype wiring
| Part | File | Role |
|---|---|---|
| Page shell | index.html |
Header with search, cart count, main area, footer, skip link |
| Data | products.js |
Twelve products in six categories (stands in for the products table) |
| Logic and views | app.js |
Router, cart model, page builders, validation, order creation |
| Styling | style.css |
Design tokens, layout, components, dark mode, mobile rules |
| Back-end design | schema.sql |
Tables, constraints and indexes for the server version |
The router listens to the address hash (#/shop?cat=audio, #/product/3, #/cart), builds the right page with a small element-building helper and replaces the content of <main>. Page text always goes in as text, never as HTML, so a name typed into the checkout form cannot inject markup. After every page change focus moves to the page, so keyboard and screen reader users start at the top of the new content.
5.4 Planned server interface
| Method and path | Purpose |
|---|---|
GET /api/products?cat=&q=&sort= |
Catalogue with filter, search and sort |
GET /api/products/{id} |
One product |
POST /api/cart/items , PATCH, DELETE |
Server-side cart for signed-in customers |
POST /api/orders |
Place an order (recalculates prices, checks stock, one transaction) |
GET /api/orders , GET /api/orders/{id} |
Order history and detail for the signed-in customer |
POST /api/auth/register , login , logout |
Accounts and sessions |
POST /api/payments/callback |
Result from the payment gateway, signature checked |
GET/POST /admin/... |
Products, coupons, order processing, reports (admin role only) |
6. UML models
6.1 Class diagram
classDiagram
class Customer {
+long id
+String fullName
+String email
+String phone
+register()
+login()
}
class Category {
+String id
+String name
}
class Product {
+long id
+String name
+BigDecimal price
+BigDecimal mrp
+int stock
+discountPercent() int
+canSell(qty) boolean
}
class Cart {
+add(product, qty)
+setQuantity(product, qty)
+remove(product)
+totals(coupon) Totals
}
class CartLine {
+int qty
+lineTotal() BigDecimal
}
class Coupon {
+String code
+int pct
+BigDecimal cap
+discountFor(subtotal) BigDecimal
}
class Order {
+String publicId
+String status
+BigDecimal subtotal
+BigDecimal discount
+BigDecimal shipping
+BigDecimal total
+BigDecimal gst
+cancel()
}
class OrderItem {
+String name
+BigDecimal unitPrice
+int qty
}
class Payment {
+String method
+String status
+BigDecimal amount
}
Customer "1" --> "0..*" Order : places
Category "1" --> "0..*" Product : groups
Cart "1" *-- "0..*" CartLine : holds
CartLine "*" --> "1" Product : refers to
Cart "*" --> "0..1" Coupon : applies
Order "1" *-- "1..*" OrderItem : contains
OrderItem "*" --> "1" Product : copied from
Order "1" --> "1..*" Payment : paid by
6.2 Sequence: placing an order (full design)
sequenceDiagram
autonumber
actor C as Customer
participant B as Browser
participant S as Order servlet
participant V as Pricing and stock service
participant D as PostgreSQL
participant G as Payment gateway
C->>B: Press Place order
B->>B: Validate fields, focus the first error if any
B->>S: POST /api/orders with items, address, coupon, payment method
S->>S: Check session and CSRF token, validate again on the server
S->>V: Price the cart from the database, not from the browser
V->>D: Read current prices and coupon
D-->>V: Rows
V-->>S: Subtotal, discount, delivery, GST, total
S->>D: BEGIN
S->>D: UPDATE products SET stock = stock - qty WHERE stock >= qty
D-->>S: One row updated per item, or none if sold out
S->>D: INSERT order and order items with the paid prices
S->>D: COMMIT
S->>G: Create payment for the total (UPI or card only)
G-->>S: Payment page address
S-->>B: Order number and payment page address
B-->>C: Confirmation, or the payment page
In the prototype the same steps happen in the browser without the server and the gateway: validate, price the cart, create the order record, clear the cart and show the confirmation page.
6.3 State diagram: order life cycle
stateDiagram-v2
[*] --> PLACED
PLACED --> PACKED: admin packs items
PACKED --> SHIPPED: handed to courier
SHIPPED --> DELIVERED: courier confirms
PLACED --> CANCELLED: customer cancels
PACKED --> CANCELLED: admin cancels, stock returned
DELIVERED --> [*]
CANCELLED --> [*]
7. Database design
7.1 ER diagram
erDiagram
customers ||--o{ orders : "places"
categories ||--o{ products : "groups"
orders ||--|{ order_items : "contains"
products ||--o{ order_items : "sold as"
orders ||--o{ payments : "paid by"
coupons ||--o{ orders : "discounts"
customers {
bigint id PK
text full_name
text email UK
text phone
text password_hash
timestamptz created_at
}
categories {
text id PK
text name UK
}
products {
bigint id PK
text category_id FK
text name
text blurb
numeric price
numeric mrp
int stock
numeric rating
int reviews
boolean active
}
coupons {
text code PK
int pct
numeric cap
timestamptz expires_at
}
orders {
bigint id PK
text public_id UK
bigint customer_id FK
text status
text ship_name
text ship_addr
text ship_city
text ship_pin
text coupon_code FK
numeric subtotal
numeric discount
numeric shipping
numeric total
numeric gst
text pay_method
timestamptz placed_at
}
order_items {
bigint order_id PK
bigint product_id PK
text name
numeric unit_price
int qty
}
payments {
bigint id PK
bigint order_id FK
text gateway_ref
numeric amount
text status
}
7.2 Design notes
| Decision | Reason |
|---|---|
| Third normal form: categories and coupons in their own tables | No repeated category names or coupon rules to keep in step |
order_items copies the name and the price paid |
An old order never changes when the catalogue does |
CHECK (total = subtotal - discount + shipping) |
The database refuses an order whose arithmetic is wrong |
CHECK (stock >= 0) plus UPDATE ... WHERE stock >= qty |
Two shoppers cannot both buy the last item |
CHECK on phone and PIN patterns, unique index on lower(email) |
Bad data is rejected even if a form check is bypassed |
| GIN index on `to_tsvector(name | |
Money as NUMERIC(10,2), never floating point |
Exact rupee and paise arithmetic |
The full definitions are in schema.sql. The core of order placement is a guarded stock update inside one transaction:
BEGIN;
UPDATE products SET stock = stock - 2 WHERE id = 2 AND stock >= 2 AND active; -- 0 rows means sold out: roll back
INSERT INTO orders (public_id, customer_id, ..., total, pay_method) VALUES ('VB-TEST1', 1, ..., 3238, 'COD');
INSERT INTO order_items SELECT currval(pg_get_serial_sequence('orders','id')), id, name, price, qty FROM ...;
COMMIT;
8. User interface design
8.1 Design idea
Online shopping is built on one familiar object: the price tag. V-Buy turns it into the identity of the store. The home page hero is a hanging yellow tag that swings once when the page opens and carries the offer; each product card has a small punched hole in its corner like a tag; and the colour pairing of a strong blue and a tag yellow separates V-Buy from the common white-and-orange shop look. The rest of the interface stays quiet so that products and prices stand out.
8.2 Design tokens
| Token | Value | Use |
|---|---|---|
| Ink | #0e1330 |
Text, headings |
| Paper | #f6f7fb |
Page background |
| Blue | #2438d6 |
Buttons, links, brand |
| Tag yellow | #ffc933 |
Hero tag, cart badge, nudges |
| Good, low, bad | #0e7c4a, #b45309, #b3261e |
Savings and in stock, low stock, errors |
| Category hues | Blue, green, orange, purple, amber, sky | One colour per category, used for icon and card tint |
| Display type | Bricolage Grotesque, falling back to the system font | Headings, prices, buttons |
| Body type | DM Sans, falling back to the system font | Text and forms |
| Dark mode | Same tokens remapped for prefers-color-scheme: dark |
Automatic |
8.3 Wireframes
Home (desktop)
+------------------------------------------------------------------+
| [V] V-Buy [ Search products............ ][Search] Shop Orders Cart(0) |
+------------------------------------------------------------------+
| Everyday things, | o |
| delivered. | +---------+ hanging |
| Prices include GST. Free delivery | | Free | price |
| over Rs 999. | | delivery| tag |
| [Shop all products] [See bestsellers] | | Rs 999+ | |
+------------------------------------------------------------------+
| Browse by category: [Audio][Wearables][Footwear][Bags][Home][Kitchen] |
| Most reviewed: [tile][tile][tile][tile] |
+------------------------------------------------------------------+
Cart
+----------------------------------------+----------------------+
| [thumb] Product name Rs 549 | Order summary |
| Rs 549 each [qty v] Remove | Items Rs 3,597|
| [thumb] ... | Coupon - Rs 359 |
| | Delivery Free |
| | Total Rs 3,238 |
| | Includes GST Rs 494 |
| | [Coupon code][Apply] |
| | [Go to checkout] |
+----------------------------------------+----------------------+
8.4 Usability review (Nielsen’s heuristics)
| Heuristic | How V-Buy applies it |
|---|---|
| Visibility of system status | Cart count in the header, “added to cart” message, step labels on checkout and confirmation |
| Match with the real world | Rupees, GST, PIN code, UPI and cash on delivery, as Indian shoppers expect |
| User control and freedom | Quantity and removal in the cart; “Change cart” from checkout; coupon can be cleared |
| Consistency and standards | The same action is always named the same: “Add to cart”, “Go to checkout”, “Place order” |
| Error prevention | Quantity limited to stock and ten per item; mobile and PIN fields open the numeric keypad, limit the length and are checked before the order is placed; delivery cost shown before ordering |
| Recognition rather than recall | Breadcrumbs, category chips that show the active choice, order list with numbers |
| Flexibility and efficiency | Search, sort, direct links to any page, keyboard operation throughout |
| Aesthetic and minimal design | One accent, short copy, no pop-ups |
| Help users recover from errors | Each error says what is wrong and how to fix it, and focus moves to the first wrong field |
| Help and documentation | Plain explanations next to coupon, delivery and payment |
Accessibility measures: a skip link, visible keyboard focus, labels on every field, aria-live on the cart count, error text linked to its field, aria-invalid on wrong fields, text contrast chosen for both light and dark themes, and reduced motion respected (the hanging tag stays still).
9. Implementation highlights
9.1 Pricing rules in one place
The same function prices the cart, the checkout summary and the confirmation, so the three can never disagree:
function totals() {
var lines = cartLines();
var subtotal = lines.reduce(function (s, l) { return s + l.product.price * l.qty; }, 0);
var coupon = COUPONS[load(COUPON_KEY, '')];
var discount = coupon ? Math.min(Math.floor(subtotal * coupon.pct / 100), coupon.cap) : 0;
var afterDiscount = subtotal - discount;
var shipping = lines.length === 0 || afterDiscount >= FREE_SHIPPING_AT ? 0 : SHIPPING_FEE;
var gst = Math.round(afterDiscount * GST_RATE / (100 + GST_RATE)); // prices already include GST
return { subtotal: subtotal, discount: discount, shipping: shipping, total: afterDiscount + shipping, gst: gst };
}
Worked example: 2 bottles at 549 and 1 headphone at 2,499 give a subtotal of 3,597. With VBUY10 the discount is 359 (10 percent, below the 500 cap), the total is 3,238 with free delivery, and the GST contained in it is 3,238 x 18 / 118 = 494.
9.2 Validation rules
| Field | Rule | Message |
|---|---|---|
| Name | 2 to 80 characters | Enter your full name. |
text@text.text pattern |
Enter an email address like name@example.com. | |
| Mobile | 10 digits starting with 6 to 9 | Enter a 10-digit mobile number starting with 6, 7, 8 or 9. |
| Address | 10 to 200 characters | Enter the house number, street and area (at least 10 characters). |
| City | 2 to 60 characters | Enter your city. |
| PIN code | 6 digits, not starting with 0 | Enter a 6-digit PIN code. |
In the full system the server repeats every rule, because a browser check is a convenience and not a protection.
9.3 Building pages safely
Every page is created with a helper that makes elements and adds user-supplied values as text:
function h(tag, attrs) { // h('p', { class: 'muted' }, 'Hello ', name)
var el = document.createElement(tag);
/* attributes and event listeners are set here */
for (var i = 2; i < arguments.length; i++) append(el, arguments[i]); // strings become text nodes
return el;
}
10. Security and payment design
| Topic | Design |
|---|---|
| Payment data | Cards and UPI are handled only by the payment gateway’s hosted page. V-Buy never sees or stores card numbers, which keeps the store out of the heaviest card-data compliance burden. The prototype collects no payment details at all |
| Prices | The server recalculates prices, discount and stock from the database. A price sent by the browser is never trusted |
| Passwords | Salted PBKDF2 hashing, as in the Virtual Classroom project |
| SQL injection | Prepared statements only |
| Cross-site scripting | Page text is escaped or inserted as text; Content-Security-Policy header on the server |
| Cross-site request forgery | Token on every state-changing request |
| Transport | HTTPS only, secure and HttpOnly session cookies |
| Orders | A customer can read only their own orders (checked by customer id on every query) |
| Personal data | Only what delivery needs; the phone and address are not shown in lists |
| Concurrency | Guarded stock update inside one transaction |
11. Testing
11.1 Test cases
| No. | Test | Expected result |
|---|---|---|
| T1 | Open the home page | Hero, six categories and four featured products show |
| T2 | Open Shop | All twelve products show |
| T3 | Choose the Audio chip | Two products |
| T4 | Sort by price, low to high | The cheaper product comes first |
| T5 | Search “bottle” | One product |
| T6 | Search “zzzz” | A message explains that nothing matched and offers all products |
| T7 | Add two bottles and one headphone | Cart count shows 3 |
| T8 | Open the cart | Subtotal 3,597, delivery free, GST 549 |
| T9 | Apply an invalid coupon | A message says the code is not valid |
| T10 | Apply vbuy10 (lower case) |
Discount 359, total 3,238 |
| T11 | Reduce the bottles to one | Total becomes 2,744 |
| T12 | Place the order with an empty form | Six error messages and focus on the first field |
| T13 | Enter the mobile number 12345 |
Order blocked with the mobile message |
| T14 | Enter valid details, choose cash on delivery | Confirmation with an order number and the address |
| T15 | After ordering | Cart count is 0 and Orders lists one order |
| T16 | Enter <img src=x onerror=...> as the name |
Shown as plain text; nothing runs |
| T17 | Add an item and reload the page | The cart still has the item |
| T18 | Open an unknown product or page address | A clear “not found” message |
| T19 | View at 375 pixels wide | No sideways scrolling on home or shop |
| T20 | Watch for browser errors during the run | None |
11.2 Results
These cases were run as an automated test in Chromium (desktop width 1280 and phone width 375) with Playwright. The run made 31 checks, which cover T1 to T20 plus extra checks on the free-delivery message, the GST figure, the 12-product count and the focus on the first wrong field. All 31 checks passed. The database schema was loaded on PostgreSQL 16 and exercised with an order transaction: stock decreased by the ordered quantities, a second purchase of the sold-out item updated no rows, and the database rejected an order whose total did not add up, an order with an invalid PIN code, and a negative stock value.
Not done in this project: the Java servlet layer, the payment gateway link and server-side accounts were not built, so there are no tests for them. Fonts load from Google Fonts when online and fall back to the system font otherwise, and testing was done with the fallback.
12. Limitations and future scope
- Server side: build the servlets, JDBC layer and connection pool described in section 5, with accounts and server-side carts.
- Payments: connect a hosted payment gateway and verify its callback signature.
- Admin screens: product and coupon management, order processing and printable invoices.
- Search: typo tolerance and filters for price range and rating.
- Reviews and wish list for signed-in customers.
- Reports and suggestions: a sales data warehouse with “bought together” recommendations, using the data warehousing and data mining topics.
- Images: real product photographs with responsive sizes in place of the icon tiles.
- Notifications: order emails and SMS.
13. Conclusion
V-Buy shows how topics from three years of study combine in one product: data structures for the cart and catalogue, databases for orders and stock, Java for the server design, web technologies and HCI for the interface, UML for the models, and software testing for evidence. The prototype lets a reader experience the shopping journey today, and the back-end design is detailed enough to build next.
Written by Claude, Anthropic’s AI assistant.