# Devil's advocate — the weakest parts of the system, and what was done

Arguing against the build on purpose. Each weakness is ranked by what it would cost JOCYT, and marked **FIXED** (in this release), **MITIGATED** (risk reduced, decision remains) or **YOURS** (cannot be fixed in code).

## Business and content

| # | Weakness | Status | What was done / what to do |
|---|---|---|---|
| 1 | **No real photography.** The brief asks for Ghanaian owners, shops and warehouses. Stock photos would look generic; none were used. | YOURS | Built HTML "JBCS screen" illustrations (sharp, fast, labelled *sample figures*) and an upload slot for a home-page photo. **Commission a half-day shoot** in a client's shop and warehouse. |
| 2 | **Contact details, address and social links are empty at launch.** Without them local search (Google Maps, "business consultant Kumasi") has nothing to show and the mobile Call/WhatsApp bar is hidden. | MITIGATED | A 17-item **launch checklist** on the admin dashboard; structured data simply omits blank fields rather than publishing placeholders. |
| 3 | **Thin content.** Three articles is not enough authority for search or AI answers. | FIXED | Two more full articles written (5 published), three more seeded as outlines, and an editor that prompts for a quick answer and Q&A on every article. Board target: 2 a month. |
| 4 | **"Client portal" vs "JBCS login" confusion.** An owner will try to use the billing portal to log in to JBCS. | FIXED | The portal sign-in page now says plainly that it is for billing and support, and shows an example JBCS address you set in settings. |
| 5 | **Leads can go unanswered.** The site promises a reply within one working day; e-mail alerts may land in spam. | FIXED | Every lead is saved before any e-mail is attempted; a red banner on the admin dashboard names leads older than a day; the sidebar shows a count. |
| 6 | **Public prices could cheapen the brand.** | MITIGATED | Board resolution: "From" prices on the JBCS page only; engagement levels on request; one switch hides every price, including from structured data. |
| 7 | **No E-VAT on JBCS.** A Ghana E-VAT add-on for Odoo POS has appeared (since withdrawn); a rival that ships it first gains a sales argument. | YOURS | Not claimed anywhere on the site. Board resolution 7 makes it the next JBCS release. |
| 8 | **Self-registered accounts with unconfirmed e-mails can request plans.** | MITIGATED | Requests are never auto-approved; the admin list now shows **"e-mail unconfirmed"** on such requests so staff call before invoicing. |

## Operations

| # | Weakness | Status | What was done |
|---|---|---|---|
| 9 | **Renewals depend on someone remembering.** | FIXED | A daily job (`cron.php`) raises renewal invoices 7 days ahead, e-mails them, and marks late subscriptions past due. A **Run billing now** button does the same for hosts without cron. Proven safe to run repeatedly. |
| 10 | **Backups were manual only.** | FIXED | The daily job writes a compressed backup outside the web root (newest 14 kept, file mode 0600). **Proven to restore** into an empty MariaDB database with every row and every pesewa intact. |
| 11 | **One owner, one phone.** Lose the phone with the 2FA app and nobody can get in. | FIXED | A server-console recovery tool (`php recover.php owner@…`), and a checklist item asking for a second super admin. |
| 12 | **Silent server errors.** Errors go to a log nobody reads. | FIXED | Checklist item: "No server errors logged in the last 7 days". |
| 13 | **Shared IP addresses on Ghanaian mobile networks** (many phones behind one IP) could trip the contact-form limit. | FIXED | Raised from 5 to 10 messages an hour per IP; spam is mainly stopped by the honeypot and the time trap instead. |
| 14 | **Dashboard figures that link to the wrong list.** The recurring-revenue tile counted three statuses but opened a list of one; the support tile counted "waiting" requests but opened all open ones and carried an unrelated line underneath. | FIXED | New "Paying" and "Waiting on us" filters; each tile now lands on exactly the rows behind its number, and the list says so. Tested by following each link. |

## Deployment

| # | Weakness | Status | What was done |
|---|---|---|---|
| 15 | **The new root `.htaccess` would have broken the JBCS dashboard folder.** It said `DirectoryIndex index.php`, and the dashboard is a single `index.html`; it also set one-year browser caching on all `.js`/`.css`, which would have frozen the dashboard's scripts after each release. | FIXED | `index.html` added; long caching moved into `assets/.htaccess` only. Proven with a stand-in dashboard folder under real Apache. |
| 16 | **Uploading over an existing `public_html/index.php` / `.htaccess`.** | YOURS | The release note's first step is to download and keep whatever is there now. |
| 17 | **Google Fonts** would have added a third-party call and slowed first load on mobile data. | FIXED | Fonts self-hosted (Manrope + Inter, SIL OFL), preloaded, latin + latin-ext so the cedi sign (₵) uses the brand font. |

## What the devil's advocate could not break

The money logic held under every attack: prices always come from the server, every payment is re-summed from the payments table so a duplicate webhook cannot count twice, Paystack's own answer is checked for amount **and** currency, and a part payment never marks an invoice paid.
