# Demo Deployment Guide

This guide covers deployment of the NCS Licence and Permit demo environment.

```text
Frontend: https://licences-demo.customs.gov.ng
Backend:  https://licences-demo-api.customs.gov.ng
API:      https://licences-demo-api.customs.gov.ng/api
Swagger:  https://licences-demo-api.customs.gov.ng/api/documentation
```

## Server Requirements

Backend:

```text
PHP 8.2+
Composer
MySQL or MariaDB
Required PHP extensions for Laravel 12
Web server: Apache or Nginx
Process manager for queues, if queues are enabled
```

Frontend:

```text
Node.js 20+
npm
Web server capable of serving static files
```

## DNS

Point both hostnames to the demo server or load balancer:

```text
licences-demo.customs.gov.ng      -> frontend web root
licences-demo-api.customs.gov.ng  -> backend Laravel public directory
```

Both domains should have valid HTTPS certificates.

## Backend Environment

Create the backend `.env` on the server from `.env.example` and configure:

```env
APP_NAME="NCS Licence Permit"
APP_ENV=demo
APP_DEBUG=false
APP_URL=https://licences-demo-api.customs.gov.ng
FRONTEND_URL=https://licences-demo.customs.gov.ng
CERTIFICATE_VERIFICATION_BASE_URL=https://licences-demo.customs.gov.ng

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=licence_permit_demo
DB_USERNAME=CHANGE_ME
DB_PASSWORD=CHANGE_ME

FILESYSTEM_DISK=local
SESSION_DRIVER=database
QUEUE_CONNECTION=database

FIRS_TIN_VALIDATION_URL=https://bodogwu.customs.gov.ng/back/api/Auth/GetTinInfo?tin={TIN-NUMBER}

TRADEHUB_EMAIL_API_URL=https://api-email2.customs.gov.ng/send.php
TRADEHUB_EMAIL_API_SECRET=CHANGE_ME
TRADEHUB_EMAIL_API_TIMEOUT=20
TRADEHUB_EMAIL_TEST_TO=

BODOGWU_AUTH_URL=CHANGE_ME
BODOGWU_DECLARANT_URL=CHANGE_ME
BODOGWU_LOGIN=CHANGE_ME
BODOGWU_PASSWORD=CHANGE_ME
BODOGWU_TIMEOUT=30
```

If demo emails must not go to real users, set:

```env
TRADEHUB_EMAIL_TEST_TO=test@example.com
```

## Frontend Environment

Create `frontend/.env.production` before building:

```env
VITE_API_BASE_URL=https://licences-demo-api.customs.gov.ng/api
```

The local `frontend/.env.local` can stay as:

```env
VITE_API_BASE_URL=/api
```

## Backend Deployment

From the backend release directory:

```bash
composer install --no-dev --optimize-autoloader
php artisan key:generate
php artisan migrate --force
php artisan l5-swagger:generate
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

Only run the seed command when the demo environment needs default roles or a default admin account:

```bash
php artisan db:seed --force
```

Ensure these directories are writable by the web server user:

```text
backend/storage
backend/bootstrap/cache
```

Uploaded private files are stored under:

```text
backend/storage/app/private
```

## Backend Web Root

The backend domain must point to Laravel's `public` directory:

```text
backend/public
```

Do not point the API domain to the backend project root.

Nginx location fallback:

```nginx
location / {
    try_files $uri $uri/ /index.php?$query_string;
}
```

Apache should have `mod_rewrite` enabled and allow Laravel's `public/.htaccess`.

## Frontend Deployment

From the frontend release directory:

```bash
npm ci
npm run build
```

Deploy the generated folder:

```text
frontend/dist
```

to the web root for:

```text
https://licences-demo.customs.gov.ng
```

React Router needs all unknown frontend routes to fall back to `index.html`.

Nginx example:

```nginx
location / {
    try_files $uri $uri/ /index.html;
}
```

Apache example:

```apache
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
</IfModule>
```

## Frontend Build Troubleshooting

If the build fails with:

```text
error TS18003: No inputs were found in config file '.../tsconfig.app.json'.
Specified 'include' paths were '["src"]'
```

it means TypeScript cannot find any source files under the frontend `src` folder from the directory where the build command is running.

Check these items on the server:

```bash
pwd
ls
ls src
ls src/main.tsx
ls src/App.tsx
```

The build command must be run from the frontend project root, the same folder that contains:

```text
package.json
index.html
vite.config.ts
tsconfig.app.json
src/
```

For this project, the frontend source files must be uploaded or cloned with the deployment. Do not upload only:

```text
package.json
tsconfig.app.json
vite.config.ts
```

without the `src` folder.

On a Linux server, folder names are case-sensitive. The folder must be named exactly:

```text
src
```

not:

```text
Src
SRC
source
```

If the repo contains a nested frontend folder, enter that folder before building:

```bash
cd frontend
npm ci
npm run build
```

If the server path is `/home/ncs/lp2-FrontEnd_Main`, confirm that this command shows the source files:

```bash
ls /home/ncs/lp2-FrontEnd_Main/src
```

If it says the folder does not exist, upload or clone the complete frontend project again.

## CORS And API Access

The frontend calls:

```text
https://licences-demo-api.customs.gov.ng/api
```

Confirm the backend allows requests from:

```text
https://licences-demo.customs.gov.ng
```

If Sanctum stateful browser sessions are later enabled, also configure the Sanctum and session domains for these demo hostnames. The current frontend uses bearer tokens from local storage.

## Queue Worker

If `QUEUE_CONNECTION=database`, run a worker with Supervisor, systemd, or the host process manager:

```bash
php artisan queue:work --tries=3 --timeout=90
```

Restart workers after deployment:

```bash
php artisan queue:restart
```

## Demo Smoke Tests

After deployment, verify:

```text
https://licences-demo.customs.gov.ng
https://licences-demo-api.customs.gov.ng/api/health
https://licences-demo-api.customs.gov.ng/api/documentation
```

Minimum application checks:

```text
Login as admin
Open Admin overview
Open Admin Existing Licences
Login as applicant
Open Applicant Licences
Open Command workspace
Open HQ workspace
Verify a certificate URL under /verify/{code}
Upload a test document and confirm it is stored privately
```

## Rollback

Before deployment, keep:

```text
Previous backend release
Previous frontend dist build
Database backup before migrations
```

Rollback order:

```text
Restore previous frontend dist if frontend fails
Restore previous backend release if API fails
Restore database backup only if a migration or data change must be reversed
```

Do not delete `backend/storage/app/private` during rollback. It contains applicant uploads, passports, payment evidence, and bond documents.
