Make supplier-side Shopify sync update tracking on existing fulfillments when fulfillment orders are closed, and make EC2 deploy extraction deletion-safe to prevent stale files from breaking builds. Made-with: Cursor |
||
|---|---|---|
| .cursor | ||
| .github/workflows | ||
| docs | ||
| Documents | ||
| prisma | ||
| public | ||
| scripts | ||
| src | ||
| tests/gmail-auto-reply | ||
| .gitignore | ||
| .npmrc | ||
| docker-compose.dev.yml | ||
| docker-compose.ec2.yml | ||
| docker-compose.yml | ||
| docker-entrypoint.sh | ||
| Dockerfile | ||
| eslint.config.mjs | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.mjs | ||
| prisma.config.ts | ||
| README.md | ||
| saad.commands | ||
| tsconfig.json | ||
| vitest.config.ts | ||
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
- High‑Level Overview
- Core Features
- Architecture & Tech Stack
- Problems & Solutions
- Future Enhancements
- Local Development
- Docker & Deployment
- AWS Bedrock & AI Setup
- Prisma & Database
- 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 AWS Bedrock (Titan + Claude) that can answer questions based on the knowledge base and FAQs.
- 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”).
- Consolidated list of:
-
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.
- Vendors are notified when:
🤝 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
ProductSyncso the vendor’s New Products view reflects the new price/amount.
- For each vendor, suppliers see a synced products block:
-
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.
- Opens a custom confirmation dialog:
- Suppliers can:
-
Products Catalog
- Manage own products (create/update/delete).
- Upload images via:
- S3 in hosted environments, or
- Local
public/uploadsin 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 AWS Bedrock:
- Amazon Titan Text Embeddings V2 for vector embeddings.
- Anthropic Claude 3 Haiku for chat and knowledge‑base answers.
- 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?”
- Let JUNOCHAT answer questions like:
-
Multi‑channel support
- Extend Juno Engine beyond Gmail:
- WhatsApp / SMS
- Messenger / Instagram DMs
- Shopify Inbox
- Extend Juno Engine beyond Gmail:
-
Active suggestion engine
- Use embeddings + usage data to:
- Suggest products suppliers should offer to specific vendors.
- Recommend pricing bands per market/region.
- Use embeddings + usage data to:
-
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.
- Let admins define reusable “AI playbooks”, e.g.:
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)
- AWS Bedrock (Titan embeddings + Claude 3 Haiku chat)
- 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 Bedrock 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
- Install dependencies
npm install
- Create
.env
Copy .env.example (or the variables listed below) into a local .env file and fill in your own values:
DATABASE_URLNEXTAUTH_SECRETNEXTAUTH_URLGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETSMTP_HOSTSMTP_PORTSMTP_SECURESMTP_USERSMTP_PASSWORDAWS_ACCESS_KEY_ID(for AWS Bedrock)AWS_SECRET_ACCESS_KEY(for AWS Bedrock)AWS_REGION(default:us-east-1)ADMIN_EMAILADMIN_PASSWORD
Never commit real secrets;
.env*files are ignored by git.
- Run the dev server
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:
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:
- Runs on pushes to the
mainbranch. - Installs dependencies and builds the Next.js app.
- SSHes into an EC2 instance.
- Writes an
.envfile on the EC2 instance from a single GitHub secretEC2_ENV. - Uses
docker compose/docker-composeto build and run the app. - 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 to22if not set.EC2_ENV– multi-line secret containing the full contents of the.envfile used in production.
This is written to.envon the server during deployment.
Deployment Flow
- Push to
main. - GitHub Actions:
- Builds the app.
- Connects to EC2.
- Writes
.envfromEC2_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.
AWS Bedrock & AI Setup
The knowledge base and JUNOCHAT features use AWS Bedrock for AI‑powered embeddings and chat completion.
Prerequisites
- AWS Account: Create an account at
https://aws.amazon.com/ - Enable Bedrock Access:
- Go to
https://console.aws.amazon.com/bedrock/ - Navigate to Model access
- Request access to:
- Amazon Titan Text Embeddings V2 (for embeddings)
- Anthropic Claude 3 Haiku (for chat completion)
- Go to
IAM Setup
Create an IAM user or role with Bedrock permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["bedrock:InvokeModel"],
"Resource": [
"arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0",
"arn:aws:bedrock:*::foundation-model/anthropic.claude-3-haiku-20240307-v1:0"
]
}
]
}
Create access keys for that user and add them to .env:
AWS_ACCESS_KEY_ID="your-access-key-id"
AWS_SECRET_ACCESS_KEY="your-secret-access-key"
AWS_REGION="us-east-1" # or your preferred region
Database Migration & Re‑Embedding
After setting up AWS Bedrock:
- Apply Prisma migrations:
npx prisma migrate deploy
- Re‑embed existing knowledge base data:
npm run re-embed-knowledge-base
This script:
- Reads all existing
KnowledgeChunkrecords. - Generates new embeddings using Titan V2.
- Updates the database in batches to avoid rate limiting.
Prisma & Database
To inspect the database locally:
export DATABASE_URL='<YOUR_DB_URL>'
npx prisma studio
License
Private / All rights reserved unless explicitly stated otherwise.