Repo & Monorepo
The project lives under 02_app/ and is a pnpm monorepo (importers: ., apps/web,
packages/types, packages/utils). Note: there is currently no pnpm-workspace.yaml
checked in; each deployable app is deployed standalone via its own .vercel link.
Layout
02_app/
├── apps/
│ ├── web/ # the Next.js app (the product) → app.tryvio.ai
│ ├── docs/ # public customer docs (Nextra) → docs.tryvio.ai
│ └── docs-internal/ # this site (Nextra, gated)
├── packages/
│ ├── types/ # shared TS types
│ └── utils/ # shared utilities
├── shopify-app/ # Shopify CLI config + theme app extension
│ ├── shopify.app.toml
│ └── extensions/tryvio-theme/ # storefront widget (theme app extension)
└── docs/ # legacy markdown (poc-architecture, ingestion-workflow)apps/web internals
apps/web/src/
├── app/
│ ├── api/ # route handlers (see below)
│ ├── merchant/ settings/ billing/ products/ brand/ discounts/ … # embedded pages
│ ├── admin/ # operator dashboard
│ ├── contact/ privacy/ terms/ # public pages
│ └── page.tsx # landing vs merchant fork
├── components/
│ └── landing/landing-page.tsx # the whole marketing landing + live demo
└── lib/
├── server/ # server-only: supabase-admin, shopify, providers, auth, billing
├── billing/plans.ts
├── demo-products.ts
└── env.ts # typed env access (getServerEnv)API route groups (apps/web/src/app/api/)
| Group | Purpose |
|---|---|
auth/ | Shopify OAuth install + callback |
shopify/ | Admin-API-backed endpoints (products, metrics, billing, store settings, pixel) |
storefront/ | Public widget endpoints (session, try-on, try-on-status, capture-email, related-products) |
proxy/ | Shopify app proxy entrypoint |
webhooks/ | GDPR compliance, products, app/uninstalled, app_subscriptions/update |
admin/ | Operator dashboard APIs (billing, metrics, generations, logs, demo-leads, inquiries) |
demo/ | Standalone landing live demo (try-on, try-on-status, capture-email) |
contact/ | Public contact form |
cron/ | billing-overage, storage-cleanup |
internal/ | setup/maintenance |
Conventions
- Server-only modules import
"server-only"and live inlib/server/. - Env access goes through
getServerEnv()(lib/env.ts) — never readprocess.envad-hoc for typed config. - Route handlers create a request logger (
createRequestLogger) and alwaysflush()infinally. - Match surrounding code style; comment density and naming follow existing files.