# QA Audit Report - 2026-03-16

## Scope

Post-roadmap QA audit covering:

- project runtime/config readiness
- package/install readiness
- automated test status mapped to Tasks 01-27
- split flow story for manual end-to-end verification
- concrete error report from current automated runs

---

## 1. Setup Audit

### Runtime and config status

- Laravel: `12.52.0`
- PHP: `8.2.12`
- Composer: `2.5.5`
- Environment: `local`
- `APP_URL`: `http://erp.local`
- `APP_LOCALE`: `en`
- App timezone: `UTC`
- Cache/routes/config: not cached
- Views: cached
- Database driver: `mysql`
- Session driver: `database`
- Queue driver: `database`
- Cache store: `database`
- Mail driver: `log`

### Dependency/install status

- Composer packages are installed: `vendor/` exists
- Composer lock exists: `composer.lock`
- Node runtime is available: `npm 11.6.0`
- Frontend dependencies are **not installed**: `node_modules/` missing
- No JS lockfile is present: no `package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml`

### Environment gaps affecting test/manual QA

- `public/storage` is **not linked**
- Local MySQL database is **behind the codebase**
- The following migrations are still pending in the local app database:
  - `2026_03_15_000001_create_journal_entries_table.php`
  - `2026_03_15_000002_create_journal_entry_lines_table.php`
  - `2026_03_15_000003_create_account_period_balances_table.php`
  - `2026_03_15_000004_add_posting_columns_to_journal_entries_table.php`
  - `2026_03_16_000001_create_warehouses_table.php`
  - `2026_03_16_000002_create_items_table.php`
  - `2026_03_16_000003_create_stock_movements_table.php`
  - `2026_03_16_000004_create_customers_table.php`
  - `2026_03_16_000005_create_sales_orders_table.php`
  - `2026_03_16_000006_create_sales_order_lines_table.php`
  - `2026_03_16_000007_create_invoices_table.php`
  - `2026_03_16_000008_create_invoice_lines_table.php`
  - `2026_03_16_000009_create_employees_table.php`
  - `2026_03_16_000010_create_payrolls_table.php`
  - `2026_03_16_000011_create_notifications_table.php`
  - `2026_03_16_000012_create_activity_logs_table.php`
  - `create_fiscal_periods_table.php`

### Setup conclusion

Automated tests can run because Laravel uses the in-memory test database, but manual/browser validation on the local MySQL app is incomplete until pending migrations are applied. Frontend asset work also remains incomplete until `npm install` is run.

---

## 2. Automated Test Status by Task

### Core

| Task | Topic | Automated status | Notes |
|---|---|---:|---|
| Task 01 | Branches | FAIL | `tests/Feature/BranchTest.php` |
| Task 02 | Number Sequences | FAIL | `tests/Feature/NumberSequenceTest.php` |
| Task 03 | Settings | FAIL | `tests/Feature/Core/SettingTest.php` |
| Task 04 | Fiscal Years | PASS | `tests/Feature/Finance/FiscalYearModuleTest.php` |
| Task 05 | Cost Centers | PASS | `tests/Feature/Core/CostCenterServiceTest.php` |

### Finance

| Task | Topic | Automated status | Notes |
|---|---|---:|---|
| Task 06 | Chart of Accounts | NO DEDICATED TEST | Coverage still missing |
| Task 07 | Journals | NO DEDICATED TEST | Coverage still missing |
| Task 08 | Journal Entries | PARTIAL PASS | covered indirectly in `PostingEngineTest` |
| Task 09 | Posting Engine | PASS | `tests/Feature/Finance/PostingEngineTest.php` |
| Task 10 | Trial Balance | NO DEDICATED TEST | Coverage still missing |
| Task 11 | General Ledger | PARTIAL PASS | covered in `PostingEngineTest` |
| Task 12 | Income Statement | NO DEDICATED TEST | Coverage still missing |

### Inventory

| Task | Topic | Automated status | Notes |
|---|---|---:|---|
| Task 13 | Warehouses | NO DEDICATED TEST | Coverage still missing |
| Task 14 | Items | NO DEDICATED TEST | Coverage still missing |
| Task 15 | Stock Movements | PASS | `tests/Feature/Inventory/StockMovementModuleTest.php` |
| Task 16 | Stock Report | PASS | covered in `StockMovementModuleTest` |

### Sales

| Task | Topic | Automated status | Notes |
|---|---|---:|---|
| Task 17 | Customers | NO DEDICATED TEST | Coverage still missing |
| Task 18 | Sales Orders | NO DEDICATED TEST | Coverage still missing |
| Task 19 | Invoices | PASS | `tests/Feature/Sales/InvoiceModuleTest.php` |
| Task 20 | Sales Reports | PASS | covered in `InvoiceModuleTest` |

### HR

| Task | Topic | Automated status | Notes |
|---|---|---:|---|
| Task 21 | Employees | NO DEDICATED TEST | Coverage still missing |
| Task 22 | Payroll | PASS | `tests/Feature/HR/PayrollModuleTest.php` |
| Task 23 | Payroll Summary | PASS | covered in `PayrollModuleTest` |

### System

| Task | Topic | Automated status | Notes |
|---|---|---:|---|
| Task 24 | Notifications | PASS | `tests/Feature/System/SystemModuleTest.php` |
| Task 25 | Audit Logs | PASS | covered in `SystemModuleTest` |
| Task 26 | Dashboard Analytics | PASS | covered in `SystemModuleTest` |
| Task 27 | System Tests | PASS (new scope) | new grouped coverage added |

### Full-suite status

- Targeted task-linked modern tests: PASS
- Full suite: FAIL
- Full suite summary: `151 passed, 36 failed, 1 risky`

---

## 3. Split Flow Story

This story splits the ERP into practical QA flows so testing can happen in meaningful stages instead of isolated screens.

### Flow A - Core bootstrap

1. Login as admin.
2. Open Branches and confirm list/detail/create/edit/delete/restore work.
3. Open Settings and confirm system values save.
4. Create a fiscal year and confirm periods are created.
5. Create a cost center tree and confirm parent/child display.

Expected result:

- Admin navigation works without localization redirect confusion.
- Core masters are usable before finance/inventory/sales flows start.

### Flow B - Finance transaction flow

1. Create chart of accounts hierarchy.
2. Create journals.
3. Create a draft journal entry with balanced lines.
4. Post the journal entry.
5. Open General Ledger for the posted account.
6. Open Trial Balance and Income Statement.

Expected result:

- Only posted entries affect reports.
- Posting updates balances and respects open periods.

### Flow C - Inventory flow

1. Create warehouse.
2. Create stock item and non-stock item.
3. Create stock movement for stock item.
4. Try creating stock movement for non-stock item.
5. Open stock report.

Expected result:

- Stock movement rejects non-stock items.
- Stock report totals reflect in/out/adjustment movement logic.

### Flow D - Sales flow

1. Create customer.
2. Create sales order with lines.
3. Create invoice with lines and tax.
4. Confirm totals and status behavior.
5. Open sales report with branch/customer filters.

Expected result:

- Invoice totals are server-calculated.
- Sales report includes confirmed invoices only.

### Flow E - HR flow

1. Create employee.
2. Create payroll for the employee.
3. Confirm net salary calculation.
4. Open payroll summary with branch/month filters.

Expected result:

- Net salary equals `basic + allowances - deductions`.
- Summary totals aggregate correctly.

### Flow F - System oversight flow

1. Open dashboard and confirm KPIs render.
2. Generate a notification and mark it as read.
3. Open audit logs and confirm filters work.

Expected result:

- Admin can use system-level monitoring screens without crashes.

---

## 4. Errors Found

### A. Setup/config errors and risks

1. Frontend packages are not installed.
   - Evidence: `node_modules/` missing.
   - Impact: `npm run build` and Vite asset verification cannot be trusted yet.

2. Storage symlink is missing.
   - Evidence: `php artisan about` reports `public/storage` as `NOT LINKED`.
   - Impact: file/image flows may fail in browser testing.

3. Local MySQL schema is incomplete.
   - Evidence: module migrations from Tasks 08-26 are still pending.
   - Impact: real app browsing on the local database will not match the codebase.

4. App timezone is still `UTC`.
   - Evidence: `php artisan about`.
   - Impact: date/time-sensitive screens may differ from expected local usage in Cairo.

### B. Failing automated tests

#### Task 01 - Branches

- `tests/Feature/BranchTest.php`
- Result: `3 failed, 18 passed`
- Failing cases:
  - `admin can view branches list`
  - `admin can view branch details`
  - `user without permission cannot view branches`
- Error pattern:
  - expected `200` or `403`
  - actual `302`
- Likely cause:
  - legacy tests are not aligned with the current localized route/middleware behavior on GET requests.

#### Task 02 - Number Sequences

- `tests/Feature/NumberSequenceTest.php`
- Result: `8 failed, 38 passed`
- Failing cases are all sequence generation assertions:
  - `get next number increments counter`
  - `get next number with prefix`
  - `get next number respects padding`
  - `get next number with branch id`
  - `peek next number then get returns same`
  - `can get multiple next numbers`
  - `get next numbers increments correctly`
  - `batch get respects prefix and padding`
- Error pattern:
  - expected first generated number `00001`
  - actual first generated number `00002`
- Root cause:
  - `App\Models\Core\NumberSequence::generateFormattedNumber()` formats `getNextNumber()` instead of current value after increment, causing an off-by-one error once `current_number` has already been incremented.

#### Task 03 - Settings

- `tests/Feature/Core/SettingTest.php`
- Result: `2 failed, 3 passed`
- Failing cases:
  - `super admin can view settings page`
  - `unauthorized admin gets 403`
- Error pattern:
  - expected `200` or `403`
  - actual `302`
- Likely cause:
  - same route/middleware redirect mismatch as the Branch tests for GET requests.

### C. Full-suite legacy failures outside the task-linked matrix

The full suite still contains many pre-existing failures beyond the task-linked module files. Main failing areas:

- `tests/Feature/FormSecurityTest.php`
  - null-byte sanitization expectation failing
  - redirect/status expectations not matching current app behavior
- `tests/Feature/FormSubmissionTest.php`
  - admin user update expectation mismatch
  - permission create redirect mismatch
  - XSS/SQL-injection expectations not aligned with actual current validation/storage behavior
  - logout redirect mismatch due localization
  - GET/POST method expectation mismatch
- `tests/Feature/FormValidationTest.php`
  - email/password validation assertions not receiving expected session errors

---

## 5. Recommended Next QA Actions

1. Apply pending local migrations before any manual browser QA.
2. Run `npm install` before frontend asset verification.
3. Decide whether branch/settings tests should:
   - disable localization middleware like the new Task 27 tests, or
   - assert localized redirect behavior intentionally.
4. Fix the number sequence off-by-one implementation before relying on generated document numbers.
5. Add missing dedicated tests for:
   - Accounts
   - Journals
   - Trial Balance
   - Income Statement
   - Warehouses
   - Items
   - Customers
   - Sales Orders
   - Employees

