3d50cb895c45bfd9428ef66079ffc6cee44e4542
Convex backend (AUDIT-5–10): - schema: add returnLabelUrl, returnTrackingNumber, returnCarrier fields + by_return_tracking_number_and_carrier and by_stripe_payment_intent_id indexes - orders: markReturnReceived now sets status="completed"; add getOrderByPaymentIntent and applyReturnAccepted internal helpers - returnActions: add acceptReturn action — creates Shippo return label (is_return:true), persists label data, sends return label email to customer - stripeActions: handle refund.updated webhook to auto-mark orders refunded via Stripe Dashboard - shippoWebhook: add getOrderByReturnTracking; applyTrackingUpdate extended with isReturnTracking flag (return events use return_tracking_update type, skip delivered transition) - emails: add sendReturnLabelEmail; fulfillmentActions: createShippingLabel action Admin UI (AUDIT-1–6): - OrderActionsBar: full rewrite per authoritative action matrix; remove UpdateStatusDialog; add AcceptReturnButton for delivered+returnRequested state - AcceptReturnButton: new action component matching CreateLabelButton pattern - FulfilmentCard: add returnLabelUrl prop; show "Return label" row; rename outbound label to "Outbound label" when both are present - statusConfig: add return_accepted to OrderEventType and EVENT_TYPE_LABELS - orders detail page and all supporting cards/components Storefront & shared (TS fixes): - checkout/success, CheckoutErrorState, OrderReviewStep, PaymentStep: replace Button as/color/isLoading/variant="flat" with HeroUI v3-compatible props - ReviewList: isLoading → isPending for HeroUI v3 Button - packages/utils: add return and completed entries to ORDER_STATUS_LABELS/COLORS Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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%