# Deployment Guide (cPanel / VPS)

Production deployment for the Attendance Management System (Laravel 11, PHP 8.2+).

## 1. Server requirements

- **PHP 8.2+** with extensions: `pdo_mysql`, `mbstring`, `openssl`, `tokenizer`, `xml`,
  `ctype`, `json`, `fileinfo`, `bcmath`, `gd`, `zip`
  - `gd` + `zip` are required by the Excel report export (PhpSpreadsheet). If you
    cannot enable `gd`, see the note in step 3.
- **MySQL 5.7+ / MariaDB 10.3+**
- **Composer 2**
- A real **SMTP** account (invite + leave-decision emails depend on it)
- HTTPS certificate for the domain

On cPanel: *Select PHP Version* → tick `gd`, `zip`, `bcmath`, `fileinfo`, then *Save*.

## 2. Get the code

```bash
cd /var/www                     # or your cPanel application root
git clone <your-repo-url> attendance
cd attendance
```

Point the domain's document root at the **`public/`** folder — never the project root.

## 3. Install dependencies (production)

```bash
composer install --no-dev --optimize-autoloader
```

If the host cannot enable `gd`, the Excel writer still works (we don't embed images),
so you can skip just that platform check:

```bash
composer install --no-dev --optimize-autoloader --ignore-platform-req=ext-gd
```

No Node/npm build is required — the UI uses pre-built static assets in `public/assets`.

## 4. Environment

```bash
cp .env.example .env
php artisan key:generate
```

Edit `.env` and set the production values:

| Key | Production value |
|-----|------------------|
| `APP_NAME` | `"Attendance Management System"` |
| `APP_ENV` | `production` |
| `APP_DEBUG` | `false` |
| `APP_URL` | `https://attendance.yourdomain.com` (used in invite links) |
| `APP_TIMEZONE` | `UTC` (leave as-is — times are stored UTC, shown per-employee) |
| `DB_DATABASE` / `DB_USERNAME` / `DB_PASSWORD` | your database credentials |
| `MAIL_MAILER` | `smtp` |
| `MAIL_HOST` / `MAIL_PORT` / `MAIL_USERNAME` / `MAIL_PASSWORD` / `MAIL_ENCRYPTION` | from your SMTP provider |
| `MAIL_FROM_ADDRESS` | a real company sender, e.g. `no-reply@yourdomain.com` |
| `SESSION_SECURE_COOKIE` | `true` (since the site is HTTPS) |
| `QUEUE_CONNECTION` | `sync` is fine to start; use `database` + a worker for scale (see step 8) |

## 5. Database

```bash
php artisan migrate --force
php artisan db:seed --force      # creates admin + manager roles and the default admin user
```

## 6. Storage symlink + permissions

```bash
php artisan storage:link
chmod -R ug+rw storage bootstrap/cache
```

Make sure `storage/` and `bootstrap/cache/` are writable by the web-server user.

## 7. Cache for production

Run these after deploy and after **any** future code or `.env` change:

```bash
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

(To undo during debugging: `php artisan optimize:clear`.)

## 8. Cron (required)

Auto-closes forgotten clock-outs daily at 23:55. Add one system cron entry:

```cron
* * * * * cd /var/www/attendance && php artisan schedule:run >> /dev/null 2>&1
```

On cPanel: *Cron Jobs* → add the command above.

**Optional — async email** (recommended once you have volume): set
`QUEUE_CONNECTION=database`, run `php artisan queue:table && php artisan migrate --force`,
and keep a worker alive (Supervisor on VPS, or a cron-based `queue:work --stop-when-empty`
on cPanel).

## 9. First login & go-live checklist

- [ ] Admin panel: `https://attendance.yourdomain.com/admin`
- [ ] Log in as `admin@ams.com` / `admin@ams.com` and **change the password immediately**
- [ ] Send a test invite to confirm SMTP works
- [ ] Add **Schedules** (shift times) and the **Holiday calendar** (sidebar → Holidays)
- [ ] Create **Managers** and link them to employee records
- [ ] Invite employees
- [ ] Confirm `APP_DEBUG=false` and HTTPS redirect are active

Employee portal: `https://attendance.yourdomain.com/employee/login`

## Reporting & overtime rules

Pay multipliers live in [`config/work.php`](config/work.php): overtime (hours logged via an employee's
"Start OT" session) at 1.5×, holiday & weekly-rest-day work at 2×. Overtime is no longer auto-detected from
weekly hours — an employee must explicitly start an OT session for hours to count as overtime. Adjust the
weekly-off day and multipliers there, then re-run `config:cache`.

## Updating an existing deployment

```bash
cd /var/www/attendance
php artisan down
git pull
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize:clear
php artisan config:cache && php artisan route:cache && php artisan view:cache
php artisan up
```

Or use the helper: `bash deploy.sh`.
