# 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/`](./docs/project-documentation/). ## Getting Started ### 1. Install dependencies ```bash npm install ``` ### 2. Set up Convex 1. Go to [convex.dev](https://convex.dev) and create a new project 2. Run `npx convex dev` from the root — this will prompt you to log in and link your project ### 3. Set up Clerk 1. Go to [clerk.com](https://clerk.com) and create a new application 2. In the Clerk Dashboard, create a JWT Template named `convex` (do **not** rename it) 3. Copy your Publishable Key, Secret Key, and the JWT Issuer URL 4. Set `CLERK_JWT_ISSUER_DOMAIN` in the Convex Dashboard environment variables ### 4. Configure environment variables Copy the example env files and fill in your credentials: ```bash cp apps/storefront/.env.example apps/storefront/.env.local cp apps/admin/.env.example apps/admin/.env.local ``` ### 5. Run the development servers ```bash # 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. ```ts import type { Product, Order, User } from "@repo/types"; ``` ### `@repo/utils` Shared utility functions. ```ts 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. ```tsx 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 - `ConvexProviderWithClerk` passes the JWT to the Convex backend - Convex functions access the user identity via `ctx.auth.getUserIdentity()` - Admin-only functions check the `role` field via `requireAdmin()` - Clerk webhooks sync user changes to the Convex `users` table ## 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`) |