f1dbf0b6ee44ff18132169e11931c2771e17b6cf
All checks were successful
Deploy — Staging / Detect changed apps (push) Successful in 15s
Deploy — Staging / Lint, Typecheck & Test (push) Successful in 1m27s
Deploy — Staging / Build & push — storefront (push) Successful in 2m16s
Deploy — Staging / Build & push — admin (push) Has been skipped
Deploy — Staging / Deploy to staging VPS (push) Successful in 19s
The Pet Loft — Ecommerce Monorepo
A full-stack ecommerce platform for pet supplies built with Next.js, Convex, Clerk, and Turborepo.
Project Structure
ecommerce/
├── apps/
│ ├── storefront/ # Customer-facing store (Next.js + HeroUI) — port 3000
│ └── admin/ # Admin dashboard (Next.js + ShadCN) — port 3001
├── convex/ # Convex backend (schema, functions, tests)
├── packages/
│ ├── types/ # Shared TypeScript types (Product, Order, User...)
│ ├── utils/ # Shared helper functions (formatPrice, slugify...)
│ └── convex/ # Shared Convex client provider (@repo/convex)
├── docs/ # Convex reference docs + project documentation
├── package.json # Root workspace config
└── turbo.json # Turborepo pipeline config
For detailed documentation, see docs/project-documentation/.
Getting Started
1. Install dependencies
npm install
2. Set up Convex
- Go to convex.dev and create a new project
- Run
npx convex devfrom the root — this will prompt you to log in and link your project
3. Set up Clerk
- Go to clerk.com and create a new application
- In the Clerk Dashboard, create a JWT Template named
convex(do not rename it) - Copy your Publishable Key, Secret Key, and the JWT Issuer URL
- Set
CLERK_JWT_ISSUER_DOMAINin the Convex Dashboard environment variables
4. Configure environment variables
Copy the example env files and fill in your credentials:
cp apps/storefront/.env.example apps/storefront/.env.local
cp apps/admin/.env.example apps/admin/.env.local
5. Run the development servers
# Terminal 1 — Convex backend
npx convex dev
# Terminal 2 — Both Next.js apps
npm run dev
- Storefront → http://localhost:3000
- Admin → http://localhost:3001
Packages
@repo/types
All shared TypeScript types used across both apps and the Convex backend.
import type { Product, Order, User } from "@repo/types";
@repo/utils
Shared utility functions.
import { formatPrice, slugify, formatDate } from "@repo/utils";
formatPrice(1999) // → "$19.99"
slugify("Hello World!") // → "hello-world"
@repo/convex
Shared Convex + Clerk provider. Both apps wrap their layout with this.
import { ConvexClientProvider } from "@repo/convex";
Authentication
This project uses Clerk for authentication and Convex for the backend.
- Clerk handles sign-in/sign-up UI and JWT tokens
ConvexProviderWithClerkpasses the JWT to the Convex backend- Convex functions access the user identity via
ctx.auth.getUserIdentity() - Admin-only functions check the
rolefield viarequireAdmin() - Clerk webhooks sync user changes to the Convex
userstable
Scripts
| Script | What it does |
|---|---|
npm run dev |
Run both apps in parallel via Turbo |
npm run dev:storefront |
Run only the storefront |
npm run dev:admin |
Run only the admin |
npm run build |
Build both apps |
npm run type-check |
TypeScript check across all workspaces |
npm run test:once |
Run all tests once |
npm run test |
Run tests in watch mode |
Deployment
| App | Recommended Platform |
|---|---|
| Storefront | Vercel (root dir: apps/storefront) |
| Admin | Vercel (root dir: apps/admin) |
| Backend | Convex Cloud (npx convex deploy) |
Description
Languages
TypeScript
94%
HTML
4.8%
CSS
0.7%
JavaScript
0.5%