JUNO
đ Modern commerce & AIâpowered support infrastructure for Shopifyâbased dropshipping businesses.
Tech stack
---
JUNO is a fullâstack Next.js application that powers:
- A **Vendor Portal** for Shopify merchants
- A **Supplier Portal** for product providers
- An **Admin view** for operations
- An AIâpowered helpdesk and knowledge engine called **JUNOCHAT / Juno Engine**
Everything runs inside a single Next.js App Router project (frontend + backend + background jobs). đť
---
## đ Table of Contents
1. [HighâLevel Overview](#high-level-overview)
2. [Core Features](#core-features)
- [Vendor Portal](#vendor-portal)
- [Supplier Portal](#supplier-portal)
- [Admin / Ops](#admin--ops)
- [JUNOCHAT (AI Helpdesk)](#junochat-ai-helpdesk)
3. [Architecture & Tech Stack](#architecture--tech-stack)
4. [Problems & Solutions](#problems--solutions)
5. [Future Enhancements](#future-enhancements)
- [JUNOCHAT & AI](#future-enhancements-for-junochat--ai)
6. [Local Development](#local-development)
7. [Docker & Deployment](#docker--deployment)
8. [OpenAI, Groq & AI Setup](#openai-groq--ai-setup)
9. [Prisma & Database](#prisma--database)
10. [License](#license)
---
## đ§ HighâLevel Overview
JUNO centralizes communication and operations between **vendors** (Shopify stores) and **suppliers**:
- Vendors can:
- Connect Shopify stores and sync products.
- Receive products and price offers from suppliers.
- See new products in a clean, autoârefreshing **New Products** view.
- Get notifications when suppliers change prices or withdraw products.
- Suppliers can:
- Manage their product catalog with images and pricing.
- Accept product sync requests from vendors.
- Provide products and custom pricing per vendor.
- Edit synced product price/quantity **per vendor** with inline controls.
- Both sides are supported by:
- **JUNOCHAT** â an AI assistant powered by **OpenAI** (embeddings + chat where configured) and **Groq** (fast chat for storefront widget, Gmail flows, and KB fallback) that can answer questions using the knowledge base, FAQs, and store context.
- A **Juno Engine** area for Gmail and ticketing workflows.
---
## ⨠Core Features
### đď¸ Vendor Portal
- **Shopify connections**
- Connect one or more Shopify stores to JUNO.
- Webhooks keep orders, inventory, and products in sync.
- **New Products**
- Consolidated list of:
- Products vendors requested and had **synced** by suppliers.
- Products **provided directly** by suppliers via offers.
- Clean rowâbased layout (no heavy cards) that:
- Autoârefreshes in the background on an interval and when the tab becomes visible.
- Avoids UI flicker by only updating when data actually changes.
- Product detail sheet with:
- Price
- Supplier
- Optional quantity/amount
- Description and image
- Clicking outside the detail closes it (no need to aim at a tiny âXâ).
- **Suppliers Directory**
- Discover global suppliers.
- Send connection invitations.
- Track connection status (PENDING / CONNECTED / REJECTED).
- **Notifications**
- Vendors are notified when:
- A supplier accepts a product sync request.
- A supplier provides a new product.
- A supplier updates the price or quantity of an offered/synced product.
### đ¤ Supplier Portal
- **Vendor Connections**
- Accept invitations using secure tokens.
- See all connected vendors with status filters.
- Accept / reject product sync requests from vendors with a dedicated panel.
- **Synced Products Per Vendor**
- For each vendor, suppliers see a **synced products** block:
- Compact, scrollable list for large catalogs.
- Shows image, title, SKU, description.
- Inline edit controls for:
- **Price** (for that vendor)
- **Available amount / quantity** (for that vendor)
- Updates flow through `ProductSync` so the vendorâs New Products view reflects the new price/amount.
- **Provided Products (Offers)**
- Suppliers can:
- Select products from their catalog.
- Specify **perâvendor price** and **total quantity**.
- See all offers in a tidy list with image, SKU, and timestamps.
- **Edit offer**:
- Opens a modal (no page jump) to change price and quantity.
- Sends a notification to the vendor about the update.
- **Withdraw offer**:
- Opens a custom confirmation dialog:
- âYou are about to withdraw *{productName}* from *{vendorName}*âŚâ
- On confirm, removes the offer and the product disappears from the vendorâs New Products list.
- **Products Catalog**
- Manage own products (create/update/delete).
- Upload images via:
- S3 in hosted environments, or
- Local `public/uploads` in pure local dev.
- Safeguards:
- Synced products from vendors are **editable but not deletable**.
- UI labels clarify when a product is âSyncedâ and where it came from.
### đ ď¸ Admin / Ops
- Admin page with an overview of:
- Stores
- Vendors
- Suppliers
- Juno Engine activity
- Emailâcentric ops:
- Gmail polling and webhook endpoints.
- Email logs and templates.
- MFA setup, notifications, and account hygiene flows.
### đ¤ JUNOCHAT (AI Helpdesk)
JUNOCHAT (a.k.a. Juno Engine chat) is the AI layer that:
- Uses **OpenAI** and **Groq**:
- **OpenAI** (`text-embedding-3-small`, etc.) for knowledgeâbase **embeddings** stored in Postgres/pgvector.
- **OpenAI** (`gpt-4o-mini` by default, configurable) for **KB âAskâ** answers when `OPENAI_API_KEY` is set.
- **Groq** for **storefront widget** replies, **Gmail** classification/safety/preview flows, and **KB fallback** if OpenAI chat fails.
- Supports:
- FAQ ingestion and retrieval.
- Knowledge document upload + chunking.
- RAGâstyle responses for storeâspecific questions (orders, products, policies, etc.).
- Integrates with the rest of JUNO:
- Can respond based on vendor/supplier context.
- Ties into the Juno Engine Gmail / ticketing workflow so AI can assist with replies.
---
## Future Enhancements
### Future Enhancements for JUNOCHAT & AI
- **Deeper Shopify awareness**
- Let JUNOCHAT answer questions like:
- âWhich supplier provides the topâselling items in the last 30 days?â
- âWhat is the margin per vendor on synced products?â
- **Multiâchannel support**
- Extend Juno Engine beyond Gmail:
- WhatsApp / SMS
- Messenger / Instagram DMs
- Shopify Inbox
- **Active suggestion engine**
- Use embeddings + usage data to:
- Suggest products suppliers should offer to specific vendors.
- Recommend pricing bands per market/region.
- **Selfâservice playbooks**
- Let admins define reusable âAI playbooksâ, e.g.:
- âHandle delayed shipmentâ flow.
- âOutâofâstock productâ flow.
- JUNOCHAT would follow these playbooks when generating replies.
---
## Architecture & Tech Stack
- **Framework**: Next.js (App Router, TypeScript)
- **UI**: React + Tailwindâstyle utility classes
- **Auth**: NextAuth
- **Database**: PostgreSQL via Prisma ORM
- **Background / Integrations**:
- Gmail APIs (OAuth)
- Shopify APIs (orders, products, inventory)
- OpenAI (embeddings + optional chat) and Groq (chat / classification)
- **Deployment**: Docker + GitHub Actions â AWS EC2
---
## Problems & Solutions
### 1. Dropshipping is glued together with spreadsheets and chats đľâđŤ
**Typical Shopify dropshipping today:**
- Vendors discover suppliers in WhatsApp groups, email threads, or random marketplaces.
- Product info, pricing, and availability live in:
- Google Sheets
- Excel files
- Long chat histories and voice notes
- When something changes (price increases, product discontinued), itâs easy to miss and very hard to trace.
**How JUNO helps:**
- Formal **connections** between Shopify stores and suppliers.
- Structured models (`ProductSync`, `SupplierProductOffer`) instead of adâhoc spreadsheets.
- Every new product or change becomes:
- A record in the database.
- A visible entry in the **New Products** list.
- A notification to the affected party (vendor or supplier).
đ Result: less âDid you see my message?â and more âThe system already updated this.â
### 2. No single source of truth for cost, price, and margin per vendor đ¸
**In a typical Shopify setup:**
- Supplier sends a Google Sheet with âlatest pricesâ.
- Vendor copies that into Shopify, maybe with manual markâups.
- If the supplier changes cost for **one** vendor, everyone else may still see old prices.
- Nobody is sure what the **current agreed cost** is for a given product/vendor pair.
**How JUNO helps:**
- Suppliers manage **perâvendor offers** directly in the Supplier Portal:
- Price and quantity are editable inline.
- Synced products from vendors can be overridden per store.
- Vendors see the resulting price and available amount in one place:
- The **New Products** page, refreshed in the background.
- Notifications whenever suppliers change price/quantity.
đ Result: vendors always see the latest cost per product per supplier, and suppliers stay in control of what each partner gets.
### 3. Operational noise across email, tickets, and knowledge đŹ
**Pain today:**
- Support lives in Gmail, while operations live in Shopify, and documentation is buried in Notion/Docs.
- Agents manually copy/paste order IDs, tracking links, and policy snippets into replies.
- Repeated questions (âWhere is my order?â, âWhatâs your return policy?â) steal time from real issues.
**How JUNO helps:**
- **JUNOCHAT + Juno Engine**:
- Ingest FAQs and internal docs into a vectorized knowledge base (via OpenAI embeddings).
- Answer questions using **RAG** against that knowledge.
- Integrate with Gmail so tickets and AI context live in the same place.
đ Result: fewer repetitive replies, faster accurate responses, and a single surface for âwhat we knowâ + âwhat customers askâ.
---
## Local Development
1. **Install dependencies**
```bash
npm install
```
2. **Create `.env`**
Copy `.env.example` (or the variables listed below) into a local `.env` file and fill in your own values:
- `DATABASE_URL`
- `NEXTAUTH_SECRET`
- `NEXTAUTH_URL`
- `GOOGLE_CLIENT_ID`
- `GOOGLE_CLIENT_SECRET`
- `SMTP_HOST`
- `SMTP_PORT`
- `SMTP_SECURE`
- `SMTP_USER`
- `SMTP_PASSWORD`
- `OPENAI_API_KEY` (embeddings + KB chat; optional `OPENAI_CHAT_MODEL`, `OPENAI_EMBEDDING_MODEL`, `OPENAI_EMBEDDING_DIMENSIONS`)
- `GROQ_API_KEY` (storefront chat, Gmail AI helpers, KB chat fallback; optional `GROQ_MODEL`)
- `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_REGION` (if you use S3 or other AWS servicesânot required for AI-only local dev)
- `ADMIN_EMAIL`
- `ADMIN_PASSWORD`
> Never commit real secrets; `.env*` files are ignored by git.
3. **Run the dev server**
```bash
npm run dev
```
Visit `http://localhost:3000` in your browser.
---
## Docker & Deployment
The project can be run via Docker using the provided `Dockerfile` and `docker-compose.yml`.
Typical pattern:
```bash
docker compose up -d --build
```
Make sure your `.env` is present next to the app code so the container can read it.
### CI/CD on AWS EC2
This repo includes a GitHub Actions workflow at `.github/workflows/deploy-ec2.yml` that:
1. Runs on pushes to the `main` branch.
2. Installs dependencies and builds the Next.js app.
3. SSHes into an EC2 instance.
4. Writes an `.env` file on the EC2 instance from a **single GitHub secret** `EC2_ENV`.
5. Uses `docker compose` / `docker-compose` to build and run the app.
6. Performs a health check and **automatically rolls back** to the previous commit if the deployment or health check fails.
#### Required GitHub Secrets
Set the following secrets in **GitHub â Settings â Secrets and variables â Actions**:
- `EC2_HOST` â public IP or DNS of the EC2 instance.
- `EC2_USER` â SSH user (e.g. `ubuntu`).
- `EC2_SSH_KEY` â private SSH key for that user.
- `EC2_SSH_PORT` â (optional) port, defaults to `22` if not set.
- `EC2_ENV` â **multi-line secret containing the full contents of the `.env` file** used in production.
This is written to `.env` on the server during deployment.
#### Deployment Flow
- Push to `main`.
- GitHub Actions:
- Builds the app.
- Connects to EC2.
- Writes `.env` from `EC2_ENV`.
- Runs `docker compose up -d --build`.
- Hits the health check URL (by default `http://localhost:3000/api/health`).
- If the health check fails, the workflow:
- Resets the repo on EC2 to the previous commit.
- Re-runs `docker compose up -d --build`.
This gives you a sharp deployment with an automatic rollback path.
---
## OpenAI, Groq & AI Setup
### OpenAI (embeddings + KB answers)
1. Create an API key in the [OpenAI dashboard](https://platform.openai.com/).
2. Add to `.env`:
```bash
OPENAI_API_KEY="sk-..."
# Optional overrides:
# OPENAI_EMBEDDING_MODEL="text-embedding-3-small"
# OPENAI_EMBEDDING_DIMENSIONS="1024"
# OPENAI_CHAT_MODEL="gpt-4o-mini"
```
Embeddings are used when indexing knowledge documents, FAQs, and the structured store profile. KB **Ask** uses OpenAI chat first, then falls back to Groq.
### Groq (storefront chat, Gmail helpers, KB fallback)
1. Create an API key at [Groq Console](https://console.groq.com/).
2. Add to `.env`:
```bash
GROQ_API_KEY="gsk_..."
# Optional: GROQ_MODEL="llama-3.1-8b-instant"
```
### Database migration & reâembedding
1. Apply Prisma migrations:
```bash
npx prisma migrate deploy
```
2. After changing embedding provider or dimensions, reâembed:
```bash
npm run re-embed-knowledge-base
```
This regenerates vectors and tags chunk metadata with `provider: openai` (required for KB similarity search filters).
---
## Prisma & Database
To inspect the database locally:
```bash
export DATABASE_URL=''
npx prisma studio
```
---
## License
Private / All rights reserved unless explicitly stated otherwise.