# PingCAP Partner Portal

A full-stack partner onboarding and deal registration portal built with **React + Vite** (frontend) and **Express + TiDB** (backend).

---

## Tech Stack

| Layer | Technology |
|---|---|
| Frontend | React 18, React Router v6, Tailwind CSS, Vite |
| Backend | Node.js, Express |
| Database | TiDB Cloud (MySQL-compatible) |
| Auth | JWT, Google OAuth 2.0 (admin SSO) |
| Email | Nodemailer (SMTP) |

---

## Prerequisites

- **Node.js** v18 or later — [Download](https://nodejs.org)
- **npm** v9 or later (bundled with Node.js)
- A **TiDB Cloud** account and cluster — [Sign up free](https://tidbcloud.com)
- A **Google Cloud** project with an OAuth 2.0 client ID (for admin SSO)

---

## Setup

### 1. Clone the repository

```bash
git clone https://github.com/Chenhao-Huang/partner_portal.git
cd partner_portal
```

### 2. Configure environment variables

Copy the example env file and fill in your values:

```bash
cp .env.example .env
```

Open `.env` and set:
- `TIDB_HOST`, `TIDB_USER`, `TIDB_PASSWORD` — from your TiDB Cloud connection details
- `JWT_SECRET` — any long random string
- `GOOGLE_CLIENT_ID` / `VITE_GOOGLE_CLIENT_ID` — from Google Cloud Console
- `SMTP_*` — your SMTP credentials for onboarding emails
- `ENABLE_USERNAME_PASSWORD_LOGIN` — Set to `true` to enable username/password login (`/loginbyuser` page)

### 3. Install all dependencies

```bash
npm run setup
```

This installs packages for the root, backend, and frontend in one command.

### 4. Run database migrations

```bash
npm run db:migrate
```

This creates all required tables in your TiDB database.

### 5. Start the development servers

```bash
npm run dev
```

This starts both servers concurrently:

| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:3001 |

---

## Project Structure

```
partner_portal/
├── .env.example          # Environment variable template
├── package.json          # Root scripts (dev, setup, migrate)
│
├── backend/
│   ├── server.js         # Express app entry point
│   ├── db.js             # TiDB connection pool
│   ├── migrate.js        # Migration runner
│   ├── controllers/      # Route handlers
│   │   ├── auth.controller.js
│   │   ├── admin.controller.js
│   │   ├── contracts.controller.js
│   │   └── opportunities.controller.js
│   ├── routes/           # Express routers
│   ├── middleware/       # Auth (JWT) + RBAC middleware
│   ├── services/         # Email service
│   └── uploads/          # Uploaded contract PDFs (git-ignored)
│
├── frontend/
│   ├── src/
│   │   ├── pages/        # React page components
│   │   ├── components/   # Shared UI components
│   │   ├── context/      # Auth context
│   │   ├── api/          # Axios client
│   │   └── constants/    # Countries, products, industries
│   └── vite.config.js
│
└── database/
    ├── 001_schema.sql    # Partners table
    ├── 002_seed.sql      # Initial seed data
    ├── 003_contracts.sql # Contracts table
    ├── 004_partner_active.sql
    └── 005_opportunities.sql
```

---

## Backend Packages

| Package | Purpose |
|---|---|
| `express` | Web framework |
| `mysql2` | TiDB/MySQL driver |
| `bcrypt` | Password hashing |
| `jsonwebtoken` | JWT auth tokens |
| `google-auth-library` | Google OAuth token verification |
| `multer` | PDF file uploads |
| `nodemailer` | SMTP email delivery |
| `cors` | Cross-origin requests |
| `dotenv` | Environment variable loading |

## Frontend Packages

| Package | Purpose |
|---|---|
| `react` / `react-dom` | UI framework |
| `react-router-dom` | Client-side routing |
| `axios` | HTTP client |
| `@react-oauth/google` | Google Sign-In button |
| `tailwindcss` | Utility-first CSS |
| `vite` | Build tool & dev server |

---

## Admin Access

Admin users sign in via **Google SSO** on the login page. Admin roles are managed in the database via the **Admin Management** tab in the portal. Any existing admin can promote or demote other PingCAP employees. New PingCAP employees default to the "employee" role on first sign-in.

---

## Test Accounts

### Admin Users (Username/Password Login)

These accounts can be used to test username/password authentication via the `/loginbyuser` page:

| Email | Password | Role |
|-------|----------|------|
| admin@pingcap.com | admin123 | admin |
| admin1@pingcap.com | admin123 | admin |
| admin2@pingcap.com | admin123 | admin |
| admin3@pingcap.com | admin123 | admin |
| manager1@pingcap.com | admin123 | employee |
| manager2@pingcap.com | admin123 | employee |

### Login URLs

| Page | URL |
|------|-----|
| SSO Login (default) | http://localhost:5173/login |
| Username/Password Login | http://localhost:5173/loginbyuser |

### Partner Users (Username/Password Login)

Partners can also use username/password authentication. All partners in the database use the same default password:

| Email | Password | Role |
|-------|----------|------|
| alex.brown@datasystems.com | admin123 | partner |

All partners in the database (45 users) share the same password: `admin123`
