# Installing the NGO Management System (Phase 1) on cPanel

Works on ordinary cPanel shared hosting: PHP 8.1 or newer, MySQL/MariaDB, Apache. No command line needed.

## Folder layout

| Upload this | To here |
|---|---|
| the `ngo_app` folder | `/home/ACCOUNT/ngo_app` (next to `public_html`, **not inside it**) |
| everything inside the `public_html` folder | your site's document root, e.g. `/home/ACCOUNT/public_html` (or a subfolder or subdomain root) |

Private code, `.env`, backups, sessions and uploads stay in `ngo_app`, out of reach of the web. If your host only lets you use `public_html`, put `ngo_app` inside it: a deny-all `.htaccess` is included, and the app finds it automatically.

## Steps

1. **Create the database.** cPanel > MySQL Databases > Create New Database (for example `ngo`). cPanel prefixes it with your account name.
2. **Create the database user.** Same page > MySQL Users > Add New User, with a strong password. Save it.
3. **Give the user privileges.** Add User To Database > choose both > tick ALL PRIVILEGES.
4. **Upload the files.** cPanel > File Manager (or FTP) > upload the zip, extract it, then move the folders as shown above. Tip: the hidden files `.htaccess` and `.user.ini` must come with `public_html`. In File Manager, Settings > Show Hidden Files.
5. **Choose PHP 8.1 or newer.** cPanel > Select PHP Version (or MultiPHP Manager) > pick 8.1+ for this domain. Enable the extensions `pdo_mysql`, `mbstring`, `fileinfo`, `openssl`, `json`, `ctype`.
6. **Run the web installer.** Open `https://your-domain/install.php`. It checks the server, asks for the database details from steps 1 to 3, the organisation name and the first administrator, then imports the tables and writes `ngo_app/.env` for you (**step 7, database credentials, and step 13, first administrator account, are done here**).
   - Prefer phpMyAdmin? Import `ngo_app/database/schema.sql` into an empty database, then copy `.env.example` to `.env`, fill it in, create `storage/installed.lock`, and add the administrator row yourself. The web installer is easier and safer.
7. **Delete `install.php`.** The installer removes itself when it can. Check File Manager and delete it if it is still there. It also refuses to run again once `storage/installed.lock` exists.
8. **Application URL.** Set automatically from the address you used in the installer. To change it later, edit `APP_URL` in `ngo_app/.env`. It is used in password-reset emails.
9. **HTTPS.** cPanel > SSL/TLS Status > run AutoSSL for the domain. Then open `public_html/.htaccess` and remove the `#` from the three HTTPS redirect lines (and from the Strict-Transport-Security line once everything works over HTTPS). HTTPS is required for the install-to-home-screen feature and for secure session cookies.
10. **Permissions.** Folders 750 (or 755 if your host needs it), files 640 (or 644). `ngo_app/storage` and everything below it must be writable by PHP. `ngo_app/.env` should be 640 or 600.
11. **PWA.** Nothing to configure. After HTTPS is on, open the site on a phone: Chrome offers *Install app* (Android), Safari uses Share > *Add to Home Screen* (iPhone). The service worker caches only public images, styles and scripts. It never stores pages, records, receipts or payslips.
12. **Cron jobs.** cPanel > Cron Jobs. Add (adjust the PHP path if cPanel suggests a different one):
    - Daily 02:00, backups, keeping 14: `/usr/local/bin/php /home/ACCOUNT/ngo_app/cron/backup.php 14`
    - Daily 03:00, maintenance: `/usr/local/bin/php /home/ACCOUNT/ngo_app/cron/maintenance.php`
13. **First administrator.** Created in step 6. Sign in at `https://your-domain/`.
14. **Set up the organisation.** Organisation profile: name, address, email, phone, logo. Then System settings. Then create your users under Users and access.
15. **Backups.** The cron job in step 12 writes to `ngo_app/storage/backups`. Also use Backups > Download regularly and keep a copy off the server. cPanel's own Backup tool is a good second layer.

## Upgrading from Phase 1 to Phase 2

1. Back up first: Backups > Back up now, then Download. Also take a cPanel backup if you can.
2. Upload and overwrite `ngo_app` and the contents of `public_html` with the Phase 2 files. **Do not delete** `ngo_app/.env` or anything in `ngo_app/storage` (your settings, uploads and backups live there). Copying the zip contents over the top is safe, because neither is in the zip.
3. Open the site. The first request after the upload creates the new tables automatically (members, charges, payments, documents, change requests) and adds the new permissions and a default **General** membership category. If you see an error with a reference code, send me `ngo_app/storage/logs/php-error.log`; the upgrade is safe to retry.
4. Sign in as administrator, go to **Membership categories** and set up your real categories and annual dues.
5. Clerks and Managers get the new permissions by role default. The administrator can adjust any person under Users and access > Permissions. Only give `payments.void` and `dues.manage` to the people who should have them.
6. Make sure `ngo_app/storage/uploads/docs` exists and is writable (the app creates it on first upload).

PHP needs the `fileinfo` extension (already required) and, for the logo to appear on PDF receipts, the `gd` extension. Without GD the PDF still works and simply omits the logo.

## Upgrading from Phase 2 to Phase 3

1. Back up first (Backups > Back up now > Download), plus a cPanel backup if you can.
2. Overwrite `ngo_app` and the `public_html` contents with the Phase 3 files. Leave `ngo_app/.env` and `ngo_app/storage` alone.
3. Open the site. The first request creates the finance tables and a starter chart of accounts for a Nigerian NGO, links member payments to income accounts, and adds the new permissions.
4. **Set up in this order:**
   1. Finance > **Chart of accounts**: review and rename the starter accounts; add your own.
   2. Finance > **Finance settings**: confirm which accounts hold cash and bank money and which income accounts member payments go to.
   3. Finance > **Journals** > New journal: enter **opening balances** (debit cash, bank and other assets; credit Accumulated fund or liabilities), dated the day before you start using the system.
   4. Finance dashboard: if it shows unposted member payments from Phase 2, press **Post them now**.
   5. **Departments** and **Suppliers and beneficiaries**: add them; assign staff to departments.
   6. Users and access > Permissions: give your finance officer `finance.view`, `finance.manage`, `income.record`, `requests.process`, and (if appropriate) `finance.journal`, `income.void`, `expenses.void`, `finance.close`, `budgets.activate`. Managers can submit requests and prepare budgets by default; the Executive Secretary can approve both by default.
   7. Chart of accounts and Finance settings can be changed later, but accounts that already have postings cannot be deleted; deactivate them instead.
5. PHP needs the `zip` extension for real .xlsx downloads (most cPanel hosts have it). Without it the Excel button falls back to a CSV file that Excel also opens.

## Upgrading from Phase 3 to Phase 4

1. Back up first (Backups > Back up now > Download), plus a cPanel backup if you can.
2. Overwrite `ngo_app` and the `public_html` contents with the Phase 4 files. Leave `ngo_app/.env` and `ngo_app/storage` alone.
3. Open the site. The first request creates the staff, attendance, leave, loan and payroll tables, a starter tax table, starter allowance and leave types, and the new permissions.
4. **Before any payroll, check the tax table.** Payroll setup shows the starter table for the Nigeria Tax Act 2025 (in force from 1 January 2026) with its source note. It was cross-checked against several published summaries, not the gazetted text, and sources differ on the minimum-wage exemption. Confirm every figure with the Act or your State Internal Revenue Service. If anything differs, add a new table (new rows never overwrite old ones) and set its verified date.
5. **Set up in this order:**
   1. HR setup: add your office as a work location (latitude, longitude, radius), enter public holidays, and set leave days to match your staff handbook.
   2. Departments (Finance menu): assign staff.
   3. Employees: register each person, then in the Pay section enter basic salary, housing and transport (pensionable) and other allowances, rent paid, and any NHF, NHIS or life assurance. Add bank, RSA PIN, pension fund administrator, TIN and state of residence.
   4. Create a login for each employee (or link an existing staff account), so they can use My employment.
   5. Users and access > Permissions: give HR staff `hr.view`, `hr.manage` and optionally `hr.salary`, `attendance.manage`; give your payroll officer `payroll.view`, `payroll.prepare`, `payroll.pay` (and `payroll.config` for tax tables); managers get leave and loan review by default; the Executive Secretary gets leave, loan and payroll approval by default. Give `loans.disburse` to whoever pays staff loans.
   6. Finance settings: the payroll accounts (salaries, employer pension, PAYE payable, pension payable, other deductions, staff loans) were created for you in the chart of accounts.
6. HTTPS is required for the phone's location to work on the clock-in page.

## Troubleshooting

- **Blank page or "Something went wrong" with a reference code:** open `ngo_app/storage/logs/php-error.log` and search for the code. Setting `APP_DEBUG=true` in `.env` shows details on screen; set it back to `false` afterwards.
- **404 on every page except the home page:** `mod_rewrite` or `.htaccess` is missing. Make sure the hidden `.htaccess` was uploaded.
- **Cannot save logo or backup:** `ngo_app/storage` is not writable. Fix permissions.
- **Reset emails do not arrive:** the host's `mail()` may be restricted. Until fixed, administrators and managers can set a temporary password from the user's page.
- **Restoring a large backup fails:** raise `upload_max_filesize` and `post_max_size` in cPanel > MultiPHP INI Editor.

## Security notes

- Passwords are stored with PHP `password_hash` (bcrypt/argon). They are never shown or logged. Temporary passwords are typed by the person who sets them, must be changed at first sign-in, and are never displayed afterwards.
- Every form is CSRF-protected, every query uses prepared statements, sessions are HttpOnly, SameSite and (on HTTPS) Secure.
- Backups contain password hashes and all records. Keep downloaded files private.
- Optional: import `ngo_app/database/optional_audit_triggers.sql` in phpMyAdmin if your host allows triggers. It makes audit rows impossible to edit or delete, even by someone with database access.
- Bootstrap, Bootstrap Icons and Chart.js load from the jsDelivr CDN. If you prefer self-hosting, download them into `public_html/assets/vendor` and change the links in `ngo_app/app/Views/layouts/`.
