Book 7 — Platform & Admin (Index & Review Instrument)¶
What this book is. Books 1–6 documented the business modules — where money, stock, people and vehicles move. Book 7 documents the control plane underneath all of them: who is allowed to do what (permissions & roles), which behaviours are switched on per client (feature flags & settings), how every document gets its number, how the org is sliced (dimensions), how staff and customers raise issues (help desk, CRM), and how the system talks to the outside world (SMS, WhatsApp, email). Nothing in Book 7 sells, ships, or posts to the ledger by itself — instead, every chapter here is referenced by the other six books.
Chapters: 27 System Administration · 28 CRM · 29 Help Desk · 30 Communication Centre. Source nav (authoritative module boundaries):
system_administration.blade.php(736 lines),crm.blade.php,help_desk.blade.php,communication_centre.blade.php.
The one-sentence version¶
Book 7 is the ERP's operating system: System Administration (Ch27) defines who can act, what is switched on, and how things are numbered; CRM (Ch28) and Help Desk (Ch29) are two separate issue-tracking systems (customer-facing vs internal); and the Communication Centre (Ch30) owns the SMS/WhatsApp/email channel that the whole ERP uses to reach people.
The control-plane map¶
flowchart TB
subgraph SA["Ch27 System Administration — the control plane"]
PERM["Permissions & Roles<br/>user_permissions (module___action)<br/>role_id==1 = superuser bypass"]
FLAGS["Feature flags / settings<br/>settings + administration_settings"]
NUM["Number Series<br/>wa_numer_series_codes"]
DIM["Dimensions<br/>branches / departments / projects / gl_tags"]
APPR["Approver Limits<br/>approver_limits (level → limit)"]
end
subgraph ISSUES["Issue tracking — TWO separate systems"]
CRM["Ch28 CRM<br/>case_tickets (customer-facing)<br/>SLA + escalation matrix"]
HD["Ch29 Help Desk<br/>tickets (internal IT/dev)<br/>status = event rows"]
end
COMMS["Ch30 Communication Centre<br/>SmsService (DI) + ScenarioNotificationDispatcher<br/>SMS · WhatsApp Cloud API · Email"]
PERM -.gates.-> B16["Books 1–6<br/>(every module)"]
FLAGS -.switches behaviour.-> B16
NUM -.doc numbers.-> B16
DIM -.scopes/tags data.-> B16
APPR -.approval thresholds.-> B16
CRM -->|assign / escalate / status SMS| COMMS
HD -->|notify creator / support team| COMMS
B16 -->|OTP, POS, delivery, approval, invoice alerts| COMMS
The four chapters at a glance¶
| Ch | Module | The engine | The one thing to remember |
|---|---|---|---|
| 27 | System Administration | user_permissions + settings/administration_settings + NumberSeriesService |
The control plane every other book depends on. Permissions are enforced in controller methods, not route middleware. |
| 28 | CRM | case_tickets / CaseTicket + escalation matrix |
Customer-facing complaint/case system with an SLA clock and 3-level escalation. Supplier Tickets are the same table (channel='supplier_portal'). |
| 29 | Help Desk | tickets / Ticket + ticket_statuses |
Internal staff→IT/dev queue. Status is the latest row in ticket_statuses, not a column; the "Development" status = engineering backlog. |
| 30 | Communication Centre | SmsService (DI) + ScenarioNotificationDispatcher + 103 SmsScenarios |
The app-wide messaging backbone — consumed from ~146 files. Kenyan SMS aggregators (Airtouch default), Meta WhatsApp Cloud API, Laravel mail. |
Seams resolved in Book 7 (long-standing open questions, now answered)¶
-
"Are
*___view/*___approvepermission strings enforced, or only nav-hidden?" — the guide's single most-repeated open question, carried since Book 1. Verdict (code-proven, Ch27): they ARE enforced, but at the controller-method level, NOT via route middleware. The System-Admin route group carries only['AdminLoggedIn','ip-blocker','single.session']— none of which check a permission. Real gating is manual inside actions (e.g.RoleController:38,SettingsController:33,ApprovalLimitsController:23), each redirecting "Invalid Request" on failure. Caveat: because it is per-method and hand-written, coverage depends on developers remembering to add it — only 3 of ~60 controllers were audited, so completeness of enforcement is itself an open audit item (see §Open questions). -
"Where does 'which behaviour is live per client' actually resolve?" — carried since Book 2. Answer (Ch27): TWO flag tables — legacy
settings(typed, read via thesetting($slug)helper) and the neweradministration_settings(read viaAdministrationSetting::where('slug', …)). Every "feature-flag / tenant-difference" note in Books 1–6 (use-extensive-gl-posting,INVENTORY_SETUP='UOM BASED',activate-subbins,ACTIVATE_MANUFACTURING_MODULE,ENFORCE_DELIVERY_OFFLOADING…, etc.) reads one of these two tables.FEATURE-FLAG-typed settings are hidden from non-developer users. -
"Where do document numbers (PM-#####, FAC-, DSP-, PAYROLL series…) come from?" — referenced across Books 3–6. Answer (Ch27):
NumberSeriesService::generate($code)overwa_numer_series_codesauto-provisions the code, incrementslast_number_used, and returnsCODE-000123. There is a branch-scoped variant and alost_number_series_codesgap tracker. -
"What is the shared notification channel used by approval queues everywhere?" — carried since Book 1's approval queues. Answer (Ch30): a single
App\Interfaces\SmsServicecontract, container-bound once and consumed viaapp(SmsService::class)from ~146 files (OTPs, POS, approvals, requisitions, deliveries, invoices, CRM cases, queued jobs). Governance runs through 103SmsScenarios+ anallowed_sms_notificationson/off table + aScenarioNotificationDispatcherthat fans one business event to both SMS and WhatsApp.
Things that look connected but aren't¶
- FOUR parallel issue-tracking systems, not one. (a) CRM
case_tickets(customer complaints, Ch28); (b) Supplier Tickets = the samecase_ticketstable withchannel='supplier_portal'(the bridge to the Supplier Portal, Book 3 Ch14); (c) Help Desktickets(internal, Ch29); (d) a separate Weighbridge ticketing noted in passing. The word "ticket" is nominal noise — CRM's model is literallyCaseTicketand its overdue job operates oncase_tickets. CRM and Help Desk share zero data. - "Support Teams / Ticket Category" (in the System-Admin nav) belongs to Help Desk, NOT CRM. CRM's equivalent is its own per-category 3-level escalation matrix.
- Admin "Employees" ≠ HR "employees". Admin "Employees" is the
userslogin table (UserController, carriesrole_id); HR "employees" is the separate payroll master from Book 6 (EmployeeController). Same word, different tables. - Two feature-flag tables, not one — legacy
settingsvs neweradministration_settings; readers use different access patterns (setting($slug)vs Eloquent). A dev looking for a flag must check both. - Bulk-SMS screens do NOT use the messaging backbone. Transactional SMS goes through the
SmsServiceDI binding; the Bulk SMS blast screens route by a sender-IDswitchandnewthe provider directly. A legacyhelpers.php sendMessage()also hard-pins InfoSky. So the "backbone" is real for transactional traffic but partially fragmented for bulk/legacy paths. - The
bulk-sms-*reference in the Help Desk nav is dead copy-paste — the$active_classvariable is computed and never used; no help-desk route touches bulk SMS.
Consolidated open questions (for user/dev validation)¶
Enforcement & security
- Permission-enforcement coverage audit. Enforcement is per-controller-method and hand-written; only 3 of ~60 admin controllers were verified. Which actions (if any) lack the check and are therefore reachable by URL regardless of $my_permissions? (High-value: this is a real authorization-gap risk, not just documentation.)
- Hard-coded SMS default access token shipped in config/sms_gateway.php:14 — confirm it is overridden per environment and not a live credential in source.
- EmailController has no permission guards (Ch30 §7) — anyone past AdminLoggedIn may reach the outbound-email screens.
Multi-tenancy & data model
- Multi-tenancy boundary of the two flag tables — are settings / administration_settings per-tenant, global, or mixed? (Determines whether a flag flip affects one client or all.)
- Help Desk status has no server-side transition guard — status() writes any value the client sends; the Open→Development→Completed→Closed flow is enforced only in the blade dropdown.
- CRM scheduled --timeout-hours value, the case_category_actions UI, and the supplier-notification send path remain un-traced (Ch28 §7).
Operational - No SMS credits/cost ledger, no opt-out table, and no async SMS delivery-report (only WhatsApp has a DLR webhook) — how is cost and consent tracked?
Recurring patterns confirmed (across the whole guide)¶
- Approval queues everywhere — and now the control surface behind them is documented:
approver_limits(level → limit) + the permission model. This is the richest "approvers not curators" AI target in the ERP, with the audit trail (user_permissions, activity logs) to support it. - Tenant behaviour is flag-driven — and the flags now have a home (two tables in Ch27). A dedicated feature-flag inventory pass would let the AI phase reason about "which client runs which path."
- Legacy/dead code intermixed — Book 7 adds fresh examples (dead
bulk-smsnav in help desk; legacysettingsvsadministration_settings; legacysendMessage()helper). The recommended standalone legacy-inventory pass still stands.
AI-leverage surfaces flagged for the later phase¶
- Approver Limits + permission model (Ch27) — the concrete control plane for "make users approvers, not curators": thresholds, roles, and an audit trail already exist to drive intelligent routing/auto-approval.
- CRM SLA + 3-level escalation matrix (Ch28) — a natural target for predictive escalation, auto-triage/categorisation, and overdue-risk scoring (the
case_resolution_time_minutesclock is already there). - 103 SmsScenarios governance (Ch30) — a ready-made surface for explainable, preference-aware smart notifications (right message, right person, right channel), and for consolidating the fragmented bulk/legacy send paths.
Where this leaves the guide¶
Book 7 closes the chapter fan-out: all 30 chapters across Books 1–7 are written and on disk. Remaining to complete the guide:
- Placeholders — Manufacturing & Production (
manufacturing_and_production, flagACTIVATE_MANUFACTURING_MODULE) and Laboratory (laboratory, flagACTIVATE_LABORATORY_MODULE): listed, feature-flagged, up-and-coming — short stubs, no deep dive. - Cross-module handoff map — the end-to-end stitch across all seven books (order → dispatch → delivery → banking; procure → GRN → AP → GL; fleet money-out → GL; payroll → GL; issues → comms). Carry into it the one still-open cross-book loop: driver-INCENTIVE earnings (Book 5 tyre/fuel incentives) were never found reaching
payroll_month_detail_earnings— the penalty half is resolved (via polymorphicEmployeePenalty), the earnings half stays OPEN.
With the control plane now documented, the guide has the vocabulary it was missing — permissions, flags, dimensions, number series, and the notification backbone — to describe how the business modules are wired together.