- Chat-first shopping helper that understands Romanian natural language queries and recommends niche products from small vendors.
- Two-tier app: Flask backend orchestrates Gemini-powered product curation and payment intents, while a Vite + React frontend offers chat, cart, and checkout flows.
- Persisted authentication backed by PostgreSQL plus in-memory per-user chat/product history for seamless session recovery.
- Stripe Elements checkout flow and SerpAPI powered search, wrapped with custom filtering to avoid big-box retailers.
ai-shopping-backend/– Flask API for search, AI ranking, history, auth, and Stripe integration.ai-shopping-ui/– React 19 + TypeScript single-page app with chat experience, cart, and auth pages.README.md– project guide (this file).
- Frontend: React 19, TypeScript, Vite, React Router, Stripe Elements, Lucide icons.
- Backend: Flask, google-genai, SerpAPI, Stripe, psycopg2 for PostgreSQL access.
- AI & Search: Gemini 2.5 Flash for relevance scoring, SerpAPI for Google Shopping/Organic results.
- Payments: Stripe Payment Intents (RON).
- Database: PostgreSQL database
accountswith tableutilizatorifor auth records.
- Node.js 20+ and npm (or pnpm/yarn) for the UI.
- Python 3.10+ with pip for the backend.
- PostgreSQL instance reachable at
localhost:5432(configurable via code changes). - Stripe account (publishable + secret keys) and Google Gemini + SerpAPI API keys.
- Create and activate a virtual environment:
python -m venv .venv .venv\Scripts\Activate.ps1 - Install dependencies:
pip install flask flask-cors requests stripe google-genai psycopg2-binary
- Configure environment variables (PowerShell example):
Replace the hard-coded keys in
$env:GEMINI_API_KEY = "your-gemini-key" $env:SERPAPI_KEY = "your-serpapi-key" $env:STRIPE_SECRET_KEY = "sk_live_or_test"
app.pywith secure lookups (os.getenv) to avoid committing secrets. - Provision the PostgreSQL schema (run in
psqlconnected to databaseaccounts):CREATE TABLE IF NOT EXISTS utilizatori ( id SERIAL PRIMARY KEY, nume TEXT NOT NULL, prenume TEXT NOT NULL, email TEXT UNIQUE NOT NULL, parola_hash TEXT NOT NULL, data_inregistrare TIMESTAMPTZ DEFAULT NOW() );
- Start the API (defaults to port 5000):
python app.py
- Install dependencies:
npm install
- Update the Stripe publishable key in
src/pages/CartPage.tsx(value passed toloadStripe). - If the backend runs on a different host/port, adjust
API_BASEconstants insrc/context/AuthContext.tsxandsrc/pages/ChatPage.tsx. - Run the development server on port 5173 by default:
npm run dev
| Name | Used In | Purpose |
|---|---|---|
GEMINI_API_KEY |
Backend | Authenticates Gemini client for product scoring. |
SERPAPI_KEY |
Backend | Access token for Google search results via SerpAPI. |
STRIPE_SECRET_KEY |
Backend | Creates PaymentIntents for checkout. |
STRIPE_PUBLISHABLE_KEY |
Frontend | Powers Stripe Elements checkout widget. |
Store secrets outside the repo (environment, .env, or secret manager). Never commit live keys.
POST /search– body{ query, daily_users?, total_products? }; returns curatedproductsarray and inferredbusiness_size.POST /create-payment-intent– body{ items }; returns Stripeclient_secretfor completing the payment.POST /history/save– persist chat/products in memory for auser_id.GET /history/get?user_id=– retrieve cached conversation history.POST /history/clear– remove cached history when a user logs out.POST /register– create a user in PostgreSQL (hashes password with Werkzeug).POST /login– authenticate user credentials.GET /users– admin-style listing of all registered users.
AuthContextwraps the app to manage login state via the backend and localStorage.ChatPagedrives the conversational UI, persists history, and paginates AI-ranked products (4 cards/page, lazy loading batches of 12).CartContextmanages client-side cart state and communicates with Stripe checkout.RequireAuthprotects chat and cart routes, redirecting to/authwhen needed.
- Boot the backend Flask server (ensure env vars are set beforehand).
- Start the Vite dev server.
- Visit
http://localhost:5173to use the app; chat callshttp://localhost:5000for search/auth/payment APIs.
- Frontend:
npm run lintuses the ESLint configuration ineslint.config.js. - Backend: Add
pytestor Flask tests as needed (no suite included yet).
- Missing AI responses: confirm
GEMINI_API_KEYand that the Gemini model is available in your project. - Empty search results: check SerpAPI quota; review console logs for request errors.
- Stripe failures: verify both publishable and secret keys belong to the same Stripe account and that totals exceed Stripe minimum (~2 RON).
- Auth errors: ensure PostgreSQL credentials match the values in
user_routes.pyor externalize them to environment variables.
- Externalize all secrets into a
.envloader. - Add persistence for chat history (Redis or database) instead of in-memory cache.
- Implement unit/integration tests for auth, search, and payment flows.