Internal admin portal for the GrowDash Customer Success team. Manage clients, brands, branches, users, channels, credentials, and marketing strategies across all GrowDash markets.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, RSC) |
| Language | TypeScript 5 |
| Styling | Tailwind CSS 4 |
| Database | PostgreSQL 16 via Prisma 7 |
| Auth | JWT sessions (jose) + GrowDash Identity API |
| Icons | Lucide React |
| Linting | ESLint 9 + Prettier |
| Deployment | Docker (standalone output) / Vercel |
- Node.js >= 22
- npm >= 10
- PostgreSQL 16+ (or use the included Docker Compose setup)
git clone https://github.com/your-org/growdash-backoffice.git
cd growdash-backofficenpm installCreate a .env file in the project root:
# Database
DATABASE_URL="postgresql://growdash:growdash@localhost:5432/growdash"
POSTGRES_USER=growdash
POSTGRES_PASSWORD=growdash
POSTGRES_DB=growdash
# Auth
SESSION_SECRET="your-secure-random-secret"
IDENTITY_API_URL="https://identity.growdash.xyz"# Generate the Prisma client
npx prisma generate
# Apply migrations (or push schema to a fresh DB)
npx prisma db pushnpm run devOpen http://localhost:3000 in your browser.
| Command | Description |
|---|---|
npm run dev |
Start the development server (Turbopack) |
npm run build |
Create a production build |
npm run start |
Serve the production build |
npm run lint |
Run ESLint |
npm run lint:fix |
Run ESLint with auto-fix |
npm run format |
Format code with Prettier |
npm run format:check |
Check formatting without writing |
npm run type-check |
Run TypeScript type checking |
src/
├── app/
│ ├── api/ # API route handlers
│ │ ├── auth/ # Login, logout, session
│ │ ├── branches/ # Branch CRUD + bulk operations
│ │ ├── brands/ # Brand CRUD
│ │ ├── channels/ # Channel CRUD
│ │ ├── clients/ # Client CRUD
│ │ ├── credentials/ # Aggregator credentials CRUD
│ │ ├── strategies/ # Strategy CRUD
│ │ ├── users/ # User CRUD
│ │ ├── activities/ # Activity log
│ │ ├── options/ # Dropdown/select options
│ │ └── stats/ # Dashboard statistics
│ ├── dashboard/ # Protected dashboard pages
│ │ ├── branches/ # Branch list, detail, bulk import
│ │ ├── brands/ # Brand list & detail
│ │ ├── channels/ # Channel list & detail
│ │ ├── clients/ # Client list & detail
│ │ ├── credentials/ # Credential list & detail
│ │ ├── strategies/ # Strategy list & detail
│ │ ├── users/ # User list & detail
│ │ └── settings/ # Application settings
│ ├── login/ # Public login page
│ ├── layout.tsx # Root layout
│ └── globals.css # Global styles
├── components/
│ ├── forms/ # Entity form components
│ ├── sidebar.tsx # Dashboard sidebar navigation
│ ├── header.tsx # Page header
│ └── filter-panel.tsx # Reusable filter/search panel
├── generated/prisma/ # Auto-generated Prisma client
└── lib/
├── session.ts # JWT session management
└── identity.ts # GrowDash Identity API client
docker compose up -dThis starts:
- app — the Next.js application on port
3000 - db — PostgreSQL 16 on port
5432
docker build -t growdash-backoffice .
docker run -p 3000:3000 --env-file .env growdash-backofficeThe Dockerfile uses a multi-stage build with Node 22 Alpine, generating the Prisma client and producing a Next.js standalone output for minimal image size.
GitHub Actions runs on every push and pull request to main and develop:
| Check | Command |
|---|---|
| ESLint | npm run lint |
| Prettier | npm run format:check |
| TypeScript | npm run type-check |
See .github/workflows/lint.yml for the full pipeline.
The portal uses a two-step auth flow:
- User credentials are validated against the GrowDash Identity API (
/v1/auth/login). - On success, a signed JWT session cookie is issued (HS256, 24 h expiry) containing user profile, roles, and the upstream token.
- Only users with the manager role can access the backoffice.
Session cookies are httpOnly, secure in production, and sameSite: lax.
The project uses Prisma 7 with the prisma-client generator and the @prisma/adapter-pg driver adapter for direct PostgreSQL connections.
The Prisma client is generated into src/generated/prisma/. After modifying prisma/schema.prisma, regenerate with:
npx prisma generate- Create a feature branch from
develop. - Make your changes and ensure all checks pass:
npm run lint && npm run format:check && npm run type-check
- Open a pull request targeting
develop.
Proprietary — internal use only.