# Namecheap cPanel deployment

This package is for Namecheap cPanel hosting with **Setup Node.js App**. It requires Node.js 20 or newer and a MySQL/MariaDB database. A static cPanel website is not sufficient because this application has Next.js API routes, login cookies, uploads, and a database connection.

## Values used below

- Application URL: `https://foto-prirucnik.ex-yu-grupa.support`
- Startup file: `server.js`
- Database schema: `database/photobook.mysql.sql`
- Environment template: `.env.production.example`

Replace the example database name and credentials with the exact values cPanel creates. Do not commit or share them.

## 1. Create the subdomain

1. Sign in to Namecheap, open **Hosting List**, then **Go to cPanel** for `ex-yu-grupa.support`.
2. Open **Domains** and select **Create A New Domain** (or **Subdomains** if it is shown).
3. Create `foto-prirucnik.ex-yu-grupa.support`.
4. Note the document root. The Node application will serve the subdomain, so do not place the source inside an unrelated public website directory.
5. Wait until the new domain is shown in cPanel. SSL is normally enabled through **SSL/TLS Status** / AutoSSL. Do not launch until its certificate is valid.

## 2. Create the database and database user

1. In cPanel, open **MySQL Database Wizard**.
2. Create an empty database, for example `photobook`. cPanel normally prefixes it, such as `account_photobook`.
3. Create a dedicated database user with a strong password.
4. Assign that user to the new database with **ALL PRIVILEGES**.
5. Record the complete prefixed database name, username, password, and host. On Namecheap shared hosting the host is normally `localhost`.

## 3. Create all tables in phpMyAdmin

1. Open **phpMyAdmin** in cPanel.
2. Select the database created in step 2.
3. Open the **Import** tab.
4. Choose `database/photobook.mysql.sql` from this package.
5. Keep the SQL format selected and click **Import**.
6. Confirm that the import ends with a success message and that these tables appear: `Tenant`, `User`, `Photographer`, `Model`, `ShootType`, `Location`, `Shoot`, `ShootBrief`, `Contract`, `ContractSignature`, and `GalleryItem`.

The SQL import is only for a **new empty database**. Do not import it into a database that already contains application tables, because `CREATE TABLE` will fail.

## 4. Upload the application

1. In cPanel, open **Setup Node.js App** and choose **Create Application**.
2. Select Node.js **20** or newer, `Production` mode, and the `foto-prirucnik.ex-yu-grupa.support` application URL.
3. Set an application root outside `public_html` when the panel permits it, for example `photobook-app`.
4. Set the application startup file to `server.js`.
5. In **File Manager**, upload the ZIP to the application root and extract it there.
6. The application root must contain `package.json`, `server.js`, `app/`, `prisma/`, `database/`, and `public/`.
7. Do not upload `node_modules`, `.next`, `.env`, `dev.db`, or editor backup files. They are deliberately excluded from the ZIP.

## 5. Set production environment variables

In **Setup Node.js App**, add the variables from `.env.production.example` using your real values:

```env
DATABASE_URL=mysql://DATABASE_USER:DATABASE_PASSWORD@localhost:3306/DATABASE_NAME
JWT_SECRET=replace-with-a-random-secret-of-at-least-32-characters
NODE_ENV=production
HOSTNAME=0.0.0.0
NEXT_PUBLIC_APP_URL=https://foto-prirucnik.ex-yu-grupa.support
```

Use the port supplied by cPanel/Passenger. Do not hard-code a public port. The included `server.js` automatically reads `PORT`.

If the password contains URL-reserved characters, percent-encode them in `DATABASE_URL`. Examples: `@` becomes `%40`, `:` becomes `%3A`, `/` becomes `%2F`, and `#` becomes `%23`.

Generate a unique JWT secret locally:

```bash
openssl rand -base64 48
```

Never put real credentials into `.env.example`, source code, or the uploaded ZIP.

## 6. Install and build

1. Return to **Setup Node.js App** and use **Run NPM Install** if the button is available.
2. Otherwise, open **Terminal** in cPanel and run:

   ```bash
   cd ~/photobook-app
   npm ci
   npm run build
   ```

3. Ensure `public/uploads/profile` and `public/uploads/gallery` are writable by the Node application. The routes create them when needed; if cPanel blocks that, create both folders in File Manager and set owner-appropriate write permissions (usually `755`, or `775` only if required by the host).
4. Click **Restart** in Setup Node.js App after the build completes.

`npm run build` runs `prisma generate` before building Next.js, so the production Prisma client matches the MySQL schema.

## 7. Verify deployment

1. Open `https://foto-prirucnik.ex-yu-grupa.support`.
2. Choose registration and create the first studio account. This creates the first `Tenant`, `User`, and `Photographer` rows; no insecure demo account is required.
3. Log out and log back in.
4. Add a test location and a gallery image, then confirm the image is visible after a refresh.
5. In phpMyAdmin, confirm the new records exist in `User`, `Photographer`, and `GalleryItem`.

## Troubleshooting

### A 500 error or database connection error

- Recheck that the database user has all privileges on the exact prefixed database.
- Verify the database host is `localhost` unless Namecheap supplied another host.
- Verify every reserved character in the database password is percent-encoded in `DATABASE_URL`.
- Restart the Node.js application after changing variables.

### The site displays but API actions fail

- Confirm the app is running in `production` mode, not as a static site.
- Run `npm run build` again after `npm ci`, then restart the application.
- Check the cPanel application log for the first error message.

### Uploaded photos fail

- Ensure `public/uploads/profile` and `public/uploads/gallery` exist and are writable by the application account.
- Check cPanel disk quota.

### `localhost:3000` does not open locally

Start the application from its project folder with:

```bash
npm run dev
```

Then open `http://localhost:3000`. It only remains available while that command is running. For local use after this MySQL conversion, set `DATABASE_URL` to a reachable MySQL/MariaDB database before exercising authenticated or data-loading routes.
