Fadal — Home Open for projects
ID Work with me
All projects

EPS. 02 AI & automation

Agung Stationery Store — Online Orders, QRIS & a RAG Chatbot

A web app for a stationery store. Customers order and pay by QRIS, then collect their items in store, the admin verifies payments and exports reports, and a RAG chatbot answers questions about stock, prices, and opening hours from the store's own data.

Role
Full-Stack Developer
Period
Sep 2025–Aug 2026
Tools
  • Next.js 15
  • TypeScript
  • PostgreSQL
  • pgvector
  • Supabase
  • Groq
  • Vitest
The green Toko Agung homepage: the headline "Toko Agung, Alat Tulis Terlengkap" (the most complete stationery), "Hubungi Sekarang" and "Lihat Produk" buttons, opening hours, the address, and the triangular Toko Agung logo, with a chatbot button in the bottom-left corner.

The challenge

Agung Stationery Store (Toko Alat Tulis Agung) already had a profile website and a simple cashier app from the first version I built. The next step was bigger: customers should be able to order and pay by QRIS on their own and just collect their items in store, the admin needed to verify payments and export reports, and repeated questions about stock, prices, or opening hours should get answered without replying to each one by hand.

My role

I built both versions as the full-stack developer: the database schema, the shopping and payment flow, the admin panel, the RAG chatbot, security, and testing.

Process

The first version (September 2025) had the store’s landing page, a dashboard, product management, a cashier, and reports. In July–August 2026 I grew it into a second version as a single Next.js project: pages and API run together as serverless functions, backed by PostgreSQL on Supabase, which also stores embedding vectors through pgvector. The schema lives in four SQL migration files, so the database can be rebuilt from scratch.

The most important decision was in the payment flow. Stock only drops when the admin approves a payment, not at checkout, so items aren’t held by orders that never get paid. Later I reworked the mobile layout (shopping, checkout, and the admin menu) and connected the homepage catalogue straight to the database.

Solution

  • Online shopping & checkout: a catalogue from the database, a cart, and stock validation on the server. The browser only sends product IDs and quantities; prices are always re-read from the database with row locking.
  • QRIS payment: the buyer scans the store’s QRIS, uploads proof (file type checked from its contents, up to 2 MB), and the admin approves or rejects it with a reason. Rejected buyers can upload again.
  • RAG chatbot: it searches the store data first, by keyword and semantic search (768-dimension embeddings), then answers through an LLM. With no matching context it declines with a fixed message instead of making things up. The admin can ask about revenue and stock, while the same question from a buyer never reveals that data.
  • Reports: transactions, stock, and payments by date range, exported to PDF or Excel from a single data structure.
  • Admin dashboard: summaries, a sales chart, best sellers, a cashier, and a chatbot history showing the source of each answer.
  • Security: scrypt password hashing, revocable httpOnly session cookies, a 15-minute lockout after 5 failed logins, and parameterised queries throughout.

Results

Need How the app handles it
No queueing Order and pay by QRIS from a phone, then collect in store
Accurate stock Stock drops when a payment is approved and can’t go negative
Repeated questions The chatbot answers stock, price, and hours from store data
Bookkeeping Transaction, stock, and payment reports to PDF or Excel
  • 97 unit tests across 7 files pass, covering login, the cart, the chatbot, reports, and upload validation.
  • 25 black-box scenarios were written to test the flows from a user’s point of view.

Lessons

The rule “never trust the browser” ended up shaping almost the whole design: prices, stock, and user roles are always re-read on the server. For the chatbot, the hard part wasn’t calling an LLM but making sure it stays quiet when it doesn’t know and never leaks admin data to buyers. Combining keyword and semantic search also proved necessary. Keywords handle exact product names, while embeddings catch questions like “something for drawing” that never name a product.

TV remote

Keyboard shortcuts for getting around this site.

1 – 6
Jump to channel 1–6
0
Back to the main broadcast (top)
T
Switch light / night theme
M
Turn motion on / off
S
Turn sound on / off
?
Open / close this remote