# Phase 2B manual test script: posting invariants, periods, numbering, attachments

For a treasurer, an accountant and someone from HQ Finance. About 25 minutes. The database guards
themselves are proved by the automated tests and were exercised on the local MariaDB; this script
checks what people see.

**Staff app:** http://localhost/church_acct_app/public/app
**Logins** (top of `database/seeders/TobasSeeder.php`): **hq.finance@toprc.test** (two-factor),
**hq.admin@toprc.test** (two-factor), **ikeja.pastor@toprc.test** (read-only, no two-factor). An
accountant login can be created by the admin under Setup › Users.

## A. Numbering per branch

1. [ ] As ikeja.pastor, open **Journals**: the sample Ikeja journal is numbered **JV-BR002-2026-000001**
   (BR002 is Ikeja's code). Headquarters journals read JV-HQ-2026-…; journals made before this change keep
   their old numbers.
2. [ ] As hq.admin, post a journal for Ikeja: it becomes JV-BR002-2026-000002. Post one for Headquarters: it
   continues the HQ series. No number is ever skipped, even when a posting is refused.

## B. Supporting documents

3. [ ] As hq.admin, open a draft journal, press **Attach a file** and choose a PDF or a photo of a receipt.
   It appears under **Supporting documents**; click it to open it in a new tab.
4. [ ] Try a Word or text file: refused ("Attach a PDF or a picture").
5. [ ] Post the journal (or open a posted one): **Remove** is gone and the page says files can be added but
   not removed. Adding another file still works.
6. [ ] As ikeja.pastor, open a Headquarters journal's file link (copy it from step 3): "Not found".

## C. Periods

7. [ ] As an accountant, **Setup › Periods**: close last month. The **Reopen…** button is not there ("Only
   HQ Finance can reopen").
8. [ ] As hq.finance, press **Reopen…** on that month and give a reason. The row shows who reopened it, when
   and why.
9. [ ] Move to a year three years back with ‹: "not open for postings" with an **Open** button. Try a journal
   dated in that year first: refused ("… is not open for postings"). Open the year with a reason
   ("Opening balances from the old cash book"): now the journal can be saved.
10. [ ] Close a month, then try to save or post a journal dated in it: refused ("The period … is closed").

## D. The nightly check

11. [ ] A developer runs `php artisan ledger:verify`: each church shows "all checks passed".
12. [ ] On the dashboard there is no red ledger notice. (When a check fails, HQ Finance is emailed and every
    dashboard with journal access shows the problems.)

## E. Traceability (developer)

13. [ ] In the database, the journals made in steps 2 and 3 have `source_module`, `created_ip`,
    `posted_ip` and, from the phone app, `created_device` filled in.

## Known limits of 2B

- The database guards protect posted entries even from raw database edits by the application's user; a
  database administrator can still drop triggers. The nightly check is there to catch that.
- The per-branch trial balance is not required to be zero (a journal can span branches); the whole-church
  trial balance is.
