# Deployment Guide

This guide documents how the Licence and Permit application should be deployed, tested, and promoted from staging to production.

## Repository Setup

The project is split into two private GitHub repositories:

```text
Backend  https://github.com/Aibee430/licence-permit-backend
Frontend https://github.com/Aibee430/licence-permit-frontend
```

Each repository has two long-lived branches:

```text
staging  - testing/UAT branch
main     - production branch
```

Day-to-day development should go to `staging` first. Production releases should be made by merging tested `staging` code into `main`.

Recommended flow:

```text
feature/change -> staging -> staging server test -> main -> production server
```

Current local folders:

```text
C:\xampp\htdocs\licence\backend
C:\xampp\htdocs\licence\frontend
```

Both local repos should normally remain checked out on `staging`.

## Branch Workflow

Create a feature branch from staging:

```bash
git switch staging
git pull
git switch -c feature/my-change
```

After work is complete:

```bash
git add .
git commit -m "Describe the change"
git push -u origin feature/my-change
```

Open a pull request into `staging`.

After staging is tested and approved, merge `staging` into `main`:

```bash
git switch main
git pull
git merge staging
git push origin main
```

Tag production releases:

```bash
git tag v1.0.0
git push origin v1.0.0
```

## Environment Strategy

Use separate environments and databases:

```text
Local       developer machine
Staging     test/UAT server and staging database
Production  live server and production database
```

Do not share `.env` files between environments.

Never commit:

```text
.env
vendor/
node_modules/
dist/
storage/logs/
storage/app/private/
storage/api-docs/
database/database.sqlite
```

## Backend Environment Variables

Backend `.env` should be configured per server.

Important values:

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

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=licence_permit_staging
DB_USERNAME=...
DB_PASSWORD=...

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

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

BODOGWU_AUTH_URL=https://auth.customs.gov.ng/api/Auth/Login
BODOGWU_DECLARANT_URL=https://bodogwu.customs.gov.ng/back/api/Auth/RegisterDeclarants
BODOGWU_LOGIN=...
BODOGWU_PASSWORD=...
BODOGWU_TIMEOUT=30
```

Production should use:

```env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://api-licences.customs.gov.ng
FRONTEND_URL=https://licences.customs.gov.ng
CERTIFICATE_VERIFICATION_BASE_URL=https://licences.customs.gov.ng
```

If staging must not send real emails, set:

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

That forces project emails to the configured test inbox.

## Frontend Environment Variables

Frontend should use environment-specific Vite variables.

Staging:

```env
VITE_API_BASE_URL=https://staging-api.example.gov.ng/api
```

Production:

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

If the API is served from the same domain, configure the frontend and reverse proxy accordingly.

## Backend Deployment Steps

On the backend server:

```bash
git clone https://github.com/Aibee430/licence-permit-backend.git
cd licence-permit-backend
git switch staging
```

Install dependencies:

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

Create `.env` from `.env.example`, then configure real values.

Generate application key once per environment:

```bash
php artisan key:generate
```

Run migrations:

```bash
php artisan migrate --force
```

Seed default roles and admin account only when needed:

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

Generate Swagger/OpenAPI docs:

```bash
php artisan l5-swagger:generate
```

Optimize Laravel:

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

Ensure writable directories:

```bash
storage/
bootstrap/cache/
```

If using queues, start the queue worker using Supervisor or the server process manager:

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

## Frontend Deployment Steps

On the frontend build server:

```bash
git clone https://github.com/Aibee430/licence-permit-frontend.git
cd licence-permit-frontend
git switch staging
```

Install dependencies:

```bash
npm ci
```

Build:

```bash
npm run build
```

Deploy the generated `dist/` folder to the frontend web server.

For React Router, the web server must redirect unknown routes to:

```text
/index.html
```

Example routes that must work directly:

```text
/login
/password/setup
/verify/{code}
/applicant/licences
/admin
/command
/hq
```

## Suggested CI/CD Checks

Backend staging pipeline:

```bash
composer install
php artisan test
php artisan l5-swagger:generate
```

Frontend staging pipeline:

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

Production deployment should require manual approval after staging is tested.

## Database Backup Rule

Before every production deployment that includes migrations:

1. Take a full database backup.
2. Confirm backup can be restored.
3. Run deployment.
4. Run smoke tests.

Minimum smoke tests:

```text
Login
Applicant signup TIN validation
Applicant application list
Admin existing licence list
Command pending queue
HQ pending queue
Certificate verification page
Swagger page
```

## Legacy Data Import Overview

The system uses legacy data for:

```text
existing_licence                    renewal lookup and onboarding licence lookup
singlePage_applicants               legacy company/applicant details
singlePage_authorized_users         legacy field agents
singlePage_transmit                 legacy Bodogwu transmission history
```

Normalized destination tables:

```text
legacy_applicants
legacy_field_agents
legacy_field_agent_transmissions
existing_licence
```

The import command is:

```bash
cd backend
C:\xampp\php\php.exe artisan onboarding:import-legacy
```

On Linux/server PHP:

```bash
php artisan onboarding:import-legacy
```

It expects these source tables to already exist in the same database:

```text
singlePage_applicants
singlePage_authorized_users
singlePage_transmit
```

It imports into:

```text
singlePage_applicants       -> legacy_applicants
singlePage_authorized_users -> legacy_field_agents
singlePage_transmit         -> legacy_field_agent_transmissions
```

By default, it also creates missing `existing_licence` rows from `legacy_applicants` so renewal lookup can find companies that were not already in `existing_licence`.

## Legacy Import Procedure

### 1. Back Up The Database

Before importing legacy data:

```bash
mysqldump -u USER -p licence_permit > licence_permit_before_legacy_import.sql
```

### 2. Run Migrations

Make sure all new-system tables exist:

```bash
php artisan migrate --force
```

### 3. Import Existing Licence SQL

If you have `existing_licence.sql`, import it into the target database.

Windows/XAMPP example:

```powershell
C:\xampp\mysql\bin\mysql.exe -u root licence_permit < "C:\Users\USER\Downloads\existing_licence.sql"
```

Linux example:

```bash
mysql -u USER -p licence_permit < existing_licence.sql
```

This populates:

```text
existing_licence
```

Important columns:

```text
company       TIN
licence       licence number
company_name  company name
```

### 4. Import Legacy Onboarding Source Tables

Import the legacy SQL dumps so the raw source tables exist:

```text
singlePage_applicants
singlePage_authorized_users
singlePage_transmit
```

Windows/XAMPP examples:

```powershell
C:\xampp\mysql\bin\mysql.exe -u root licence_permit < "C:\Users\USER\Downloads\singlePage_applicants.sql"
C:\xampp\mysql\bin\mysql.exe -u root licence_permit < "C:\Users\USER\Downloads\singlePage_authorized_users.sql"
C:\xampp\mysql\bin\mysql.exe -u root licence_permit < "C:\Users\USER\Downloads\singlePage_transmit.sql"
```

Linux examples:

```bash
mysql -u USER -p licence_permit < singlePage_applicants.sql
mysql -u USER -p licence_permit < singlePage_authorized_users.sql
mysql -u USER -p licence_permit < singlePage_transmit.sql
```

### 5. Normalize Legacy Onboarding Data

Run:

```bash
php artisan onboarding:import-legacy
```

Windows local command:

```powershell
cd C:\xampp\htdocs\licence\backend
C:\xampp\php\php.exe artisan onboarding:import-legacy
```

Expected output includes counts for:

```text
Imported X legacy applicant rows.
Imported X legacy field-agent rows.
Imported X legacy transmission rows.
Created X missing existing licence rows from legacy applicants.
Legacy onboarding import completed.
```

### 6. Custom Source Table Names

If the raw import table names are different:

```bash
php artisan onboarding:import-legacy \
  --applicants-table=custom_applicants_table \
  --agents-table=custom_agents_table \
  --transmissions-table=custom_transmit_table
```

To skip automatic creation of missing `existing_licence` rows:

```bash
php artisan onboarding:import-legacy --skip-existing-licence-sync
```

## Legacy Import Verification

After import, verify:

```sql
SELECT COUNT(*) FROM existing_licence;
SELECT COUNT(*) FROM legacy_applicants;
SELECT COUNT(*) FROM legacy_field_agents;
SELECT COUNT(*) FROM legacy_field_agent_transmissions;
```

Application checks:

```text
Admin -> Existing Licences
Admin -> Onboarding -> search TIN
Command/Bond Seat -> Onboarding -> search TIN
Applicant -> Field Agents
Applicant -> Manage Licence
```

Expected behavior:

- Renewal lookup should find imported legacy licences by TIN.
- Legacy field agents should appear for the applicant company.
- Field-agent command codes should come from legacy transmissions.
- Onboarding request/transmit should use `command_code`, not internal `command_id`, when sending to Bodogwu.

## Existing Licence And Onboarding Activation

Manual/admin existing licences are active for renewal lookup.

System-issued licences created by this system are not automatically available for Bodogwu onboarding until activated by Admin.

Admin path:

```text
Admin -> Existing Licences -> Activate
```

Audit fields stored but not displayed:

```text
onboarding_activated_at
onboarding_activated_by_user_id
```

## Staging To Production Checklist

Before merging `staging` to `main`:

- Frontend build passes.
- Backend tests or smoke tests pass.
- Swagger page loads.
- Staging database migrations pass.
- Login works for admin, applicant, command, and HQ users.
- External service env values are confirmed.
- No test email override remains in production.
- Database backup has been taken.
- DevOps confirms rollback plan.

Production merge:

```bash
git switch main
git pull origin main
git merge staging
git push origin main
```

Deploy production from `main`.

## Rollback Notes

Code rollback:

```bash
git switch main
git log --oneline
git revert <commit>
git push origin main
```

Database rollback depends on the migration. Prefer restoring the pre-deployment database backup for production-critical failures.

Do not run destructive rollback commands on production without a database backup and approval.
