ApplicationsDashboard
Dashboard
The merchant admin dashboard — products, orders, integrations, domains, and team management.
apps/dashboard is the merchant admin application. Merchants sign in, select an active organization (their store), and manage products, orders, customers, payment integrations, and custom domains.
Port: 3002 · Framework: Next.js 16 · Auth: Better Auth + organization plugin
Architecture
Drag to pan · Scroll to zoom
Most data operations go through the Commerce API. Integration credentials and domain records are managed directly via Drizzle (encrypted at rest).
Features
| Section | Route | Status | Description |
|---|---|---|---|
| Overview | / | Live | Dashboard stats — revenue, orders, customers |
| Products | /products | Live | List, create, edit products with variants and images |
| Orders | /orders | Live | List, detail, fulfill, refund |
| Customers | /customers | Live | Customer list and detail |
| Integrations | /integrations | Live | Payment and service provider configuration |
| Domains | /domains | Live | Custom domain setup with Vercel + DNS |
| Team | /team | Live | Organization members and invitations |
| Settings | /settings | Live | Store name, currency, contact info |
| API Keys | /settings/api-keys | Placeholder | API keys are issued by Better Auth/API today; in-dashboard creation is not wired yet |
| Analytics | /analytics | Placeholder | Future analytics dashboard |
| Billing | /billing | Placeholder | Shows current plan from DB; Stripe subscription billing is not wired yet |
Auth & organization
Merchants authenticate with email/password. Better Auth's organization plugin enables multi-store management:
- Registration creates a user + first organization
session.activeOrganizationIddetermines which store's data is shown- Organization switching updates the active org in the session
- All admin API calls are scoped to the active organization
// lib/admin.ts
export async function withActiveOrg<T>(fn: (orgId: string) => Promise<T>) {
const orgId = await requireActiveOrg()
return withTenant(orgId, fn)
}Navigation
Sidebar groups defined in lib/nav.ts:
| Group | Items |
|---|---|
| Store | Overview, Products, Orders, Customers |
| Platform | Domains, Integrations, Analytics |
| Account | Team, Settings, API Keys, Billing |
Configuration
| Variable | Purpose |
|---|---|
DATABASE_URL | Auth + integration_config + tenant_domain tables |
COMMERCE_API_URL | Admin API client base URL |
BETTER_AUTH_SECRET | Session validation on SSR (same secret as API) |
NEXT_PUBLIC_AUTH_URL | Browser auth client → apps/api (default http://localhost:3005) |
INTEGRATION_ENCRYPTION_KEY | Encrypt provider credentials at rest |
VERCEL_TOKEN, STOREFRONT_VERCEL_PROJECT_ID, VERCEL_TEAM_ID | Custom domain provisioning |
NEXT_PUBLIC_PLATFORM_DOMAIN | Shown on domains page for subdomain preview |