JUNO logo

JUNO

🚀 Modern commerce & AI‑powered support infrastructure for Shopify based dropshipping businesses.

Tech stack

Next.js TypeScript PostgreSQL OpenAI Groq Gmail API Docker NextAuth Shopify API AES Encryption

--- 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.