# INFOTICS: production-readiness report

This report covers the "Remaining / Required Improvements" list (48 items) and the "Website & LMS Requirements" list (100 items), with duplicates merged. Features that already worked were kept and only changed where usability, security or correctness required it. The automated suite has **285 tests**, including one complete end-to-end journey test.

## 1. Requirement coverage

| Area | Items | Status | Where |
|---|---|---|---|
| Launch / entry offer popup, offer headline, discount, expiry, CTA and lead form | 4 · R1–3 | **Built** | Admin → Website → Offers & popups. Includes target pages, delay, code and view/lead conversion. |
| **Promotions: market a specific course or workshop** | Follow-up request | **Built** | Admin → Website → Promotions & offers. A promotion can run on every page, the home page, all course pages, **one course page** or **one workshop page**. It can show as a popup, a top announcement bar and a shareable landing page (`/promo/{slug}`). Options: delay, exit-intent or scroll triggers; mobile/desktop targeting; frequency cap; countdown; seats left; theme and image. Clicks are tracked (`/go/{id}`). A campaign link builder adds UTM tags and offers a QR download and a WhatsApp share. Each promotion shows its funnel: views, clicks, leads, applications, admissions. |
| **Homepage & headlines managed by admin** | Follow-up request | **Built** | Admin → Website → Homepage & headlines. Edits the hero badge, headline with a highlighted phrase, supporting text, buttons, WhatsApp button, counters, top-bar tagline and home SEO, with a live preview. A **scheduled campaign headline** switches on and off by date. A **featured course spotlight** sits under the hero. Reset to defaults is available. |
| **WhatsApp Cloud API (two-way)** | Follow-up request | **Built** | Signed webhook (`/webhooks/whatsapp`; `hub.challenge` verification, `X-Hub-Signature-256` check). **Shared inbox:** Communications → WhatsApp inbox, with unread counts and the 24-hour rule (free text inside the window, approved templates outside it). New numbers become leads (source *whatsapp*), and every message is added to the lead timeline. Staff get bell notifications. Delivery statuses (sent → delivered → read, failed). **STOP / START** consent keywords. **Template sync** from the WABA. **Send from the lead card.** **Campaigns** to opted-in leads, filtered by stage, course, source or age, with personalisation (`{first_name}`, `{course}`), a preview count and delivered/read/replied stats. Opt-in checkboxes on the offer, landing, application and registration forms, plus a learner preference in Account. Reminder copies skip anyone who opted out. |
| Email OTP on every important public form and at registration | 5, 6 · R4, R30 | **Built** | Contact, corporate, workshop, course details, request fee or call-back, offer, application and registration forms. Codes are hashed, expire in 10 minutes, allow 5 attempts, are rate-limited and never logged. Works without JavaScript. |
| Fake / duplicate lead prevention, rate limits, CAPTCHA | 38 · R5, R83 | **Built** | Honeypot, minimum fill time, disposable-email block, optional Cloudflare Turnstile, route throttles, and one open lead per email (repeat enquiries add a "touch"). |
| Course-wise fee Show / Hide, with a custom CTA when hidden | 7, 8 · R10, R11 | **Built** | Course → *Fee on website*. When hidden, the page shows **Apply**, **Request the fee** and **Request a call-back**. The fee is hidden on the site, schema.org, llms.txt, sorting and the public API. |
| Lead → application → admission → enrollment workflow | 9, 95, 96 · R12, R13, R16 | **Built** | `/apply`, then Admin → Admissions: review, request information, approve (enrollment + invoice, or *Set fee*) or decline. The first payment admits the applicant automatically and sends an **admission letter** with the student ID and schedule. |
| Installments, invoices, receipts, reminders | 10, 27, 28 · R14, R15, R60–63 | **Kept and audited** | Earlier rounds: plans, reminders (7/3/1 days plus overdue), receipts, statements, and online payments (JazzCash, Easypaisa, PayFast). |
| RBAC: Super Admin, Admin, Admissions, Finance, Marketing, Trainer, LMS Manager, Support, Student | 11, 12, 43–45 · R17–27 | **Built** | `config/rbac.php` plus an editable matrix (Admin → Team & roles). Every `/admin` route maps to a module (view/manage). Sidebar, dashboard KPIs and finance data follow permissions. Trainers are scoped to their own batches; students only see enrolled content. |
| 2FA for admin and privileged accounts | 13 · R29 | **Built** | TOTP authenticator app with QR setup, 8 single-use recovery codes and a login challenge. **Required for all staff** (`INFOTICS_REQUIRE_2FA`). A Super Admin can reset it. |
| Audit logs | 28, 39 · R28 | **Kept and extended** | Logins, 2FA events, role and matrix changes, integration changes (field names only), fee decisions, application decisions, lab terminations. |
| Dashboards: student, trainer, finance, admissions, admin | 14 · R32–34 | **Improved** | The admin queue adds applications, fees awaiting confirmation and overdue follow-ups, and is filtered by role. Students get an **exam-readiness** score. Admissions and marketing get dedicated screens. |
| Google Drive video inside the LMS, material management, enrollment-gated access | 15, 42 · R35–37 | **Built / kept** | Drive, Docs, Slides and Loom links play in the LMS player. Access goes through `CourseAccess`. |
| Meeting Center: Zoom, Google Meet, Webex / NetAcad, create and start meetings | 16, 17 · R38–43 | **Built** | Admin → Events → Meeting center: a 7-day board of classes, workshops and meetings with *Start as host* and *Join*, plus **Start a meeting now** (automatic link, invitations, host redirect). |
| Workshop registration and approval | R44, R45 | **Kept** | Built earlier, now protected with OTP and guards. |
| Lab Integration Portal: ESXi, vCenter, Workstation, Proxmox, AWS, Azure; browser console without credentials; temporary environments with cleanup and expiry; central orchestrator | 18–23 · R46–57 | **Built** | `app/Labs`: drivers for Proxmox, vCenter (ESXi via vCenter or the machine pool), Workstation (vmrest), AWS EC2 (SigV4, tags, terminate) and Azure (one resource group per session). The browser console runs through Apache Guacamole JSON auth. Limits: one lab per learner, per-lab capacity and one extension. Expired sessions are destroyed every 5 minutes. Lab templates are encrypted at rest. Admin → Academics → Lab portal. |
| Email / SMTP management, templates, history and delivery tracking | 24–26 · R58, R59, R64 | **Built / kept** | SMTP is set from Admin → Integrations (encrypted password) with a **test email** button. Templates and history were built earlier; **open tracking** (signed pixel) is new. |
| In-app notifications and the WhatsApp option | R65, R66, R94 | **Built** | Every email to a user also appears in the notification bell. Billing, schedule, enrollment and meeting messages are copied to WhatsApp (Cloud API template) when enabled. |
| CRM: stages, follow-ups, conversion, campaign / UTM, course-wise, marketing analytics | 29, 30 · R67–71 | **Built** | Stages (New → Contacted → Qualified → Applied → Fee/quote sent → Admitted / Lost), score, activity log, next follow-up, lost reason, a daily follow-up digest, and first/last-touch UTM, gclid and referrer tracking. Admin → Marketing analytics shows the funnel, response time, and leads/applications/admissions/revenue by source, medium, campaign, course and offer. |
| GA4 and Meta Pixel | R79 | **Built** | Set in Admin → Integrations. `generate_lead` and `Lead` events fire on conversions. Staff sessions are not tracked. |
| SEO / AEO / sitemap / robots / schema | 31, 32 · R9, R86, R87 | **Audited** | 104 URLs pass the checks. `/apply` was added to the sitemap and llms.txt. Courses get `AggregateRating` only from real learner feedback (at least 3 responses). |
| Mobile, speed, accessibility | 33 · R84, R85 | **Audited** | No horizontal overflow at 390 px on any audited page. Assets are bundled. Forms are labelled. The popup supports Esc/close and returns focus. |
| Content proofreading, consistency, standard course info | 2, 34, 35 · R8 | **Done** | Mixed "enrol"/"enroll" spellings across 38 files were unified. Exam content was refreshed in the previous round. The content-freshness screen now flags missing course fields (summary, prerequisites, duration, hours, outcomes, FAQs, curriculum, upcoming batch, fee). |
| FAQs, testimonials, success stories, trust | 36 · R88, R89 | **Improved** | Course pages show approved testimonials and real ratings. Feedback marked "testimonial OK" becomes a testimonial awaiting approval. |
| Forms, CTAs, links, emails end to end | 37, 47 | **Tested** | `tests/Feature/CompleteJourneyTest.php` runs Website → Offer → OTP → Lead → Application → Approval → JazzCash payment → Admission → Account → LMS → Class link → Lab console. A browser run used a real SMTP inbox for the OTP. |
| Security, API, sessions, data protection, encrypted credentials | 39, 41 · R77, R81, R82, R97, R98 | **Audited / fixed** | **Fixed:** the public API exposed hidden fees. Sessions are encrypted with secure cookies on HTTPS. Integration secrets and lab credentials are encrypted. The CSP is tightened per integration. Signed URLs are used for receipts and the tracking pixel. |
| Backup and recovery | 40 · R80 | **Built** | `php artisan infotics:backup` runs nightly at 02:30: an AES-256 zip of the database snapshot (SQLite/MySQL/Postgres) plus uploads, with optional off-site disk and 14-day retention. Restore was verified by the test suite. |
| Attendance, progress, assessments, certificates, outstanding fees, batches, scheduling | R72–76, R90–93 | **Kept** | Built in earlier rounds. |

## 2. RBAC summary (defaults; a Super Admin can edit the matrix)

| Role | Can open |
|---|---|
| Super Admin | Everything, including Team & roles and integration secrets |
| Admin | Everything except Team & roles and changing integrations/settings |
| Admissions | Dashboard, leads/CRM, admissions & enrollments (incl. fee confirmation), learners, quotations, workshops & meetings, communications |
| Finance | Dashboard, invoices/payments/plans, quotations, learners & enrollments (read-only), communications, analytics |
| Marketing | Dashboard, analytics, leads/CRM, website content & offers, workshops & meetings, communications |
| LMS Manager | Courses, curriculum & materials, batches & attendance, exams, labs, credentials, vouchers |
| Support | Read-only learners/enrollments/leads, communications (send/resend), batches, credentials |
| Trainer / Student / Employer | Their own portals only |

## 3. Go-live steps for the new features

1. **Team:** sign in as the Super Admin and set up 2FA. Invite staff in Team & roles; each person sets up 2FA on first sign-in.
2. **Email:** in Admin → Integrations → Email, enter SMTP details and click **Send a test email to me**.
3. **Payments / meetings / WhatsApp / analytics / Turnstile:** fill in each group in Integrations. Secrets are stored encrypted.
4. **Labs:**
   1. Deploy Apache Guacamole with the `guacamole-auth-json` extension, set `JSON_SECRET_KEY`, and enter its URL and secret in Integrations.
   2. Connect each platform you use.
   3. In Lab portal → Configure, choose the platform and paste the template JSON (examples are shown in the form).
   4. Lock lab VMs' security groups / firewalls so RDP/SSH is reachable only from the Guacamole server.
5. **Promotions and homepage:** create the launch promotion in Promotions & offers, and review the wording in Homepage & headlines.
   **WhatsApp:**
   1. In Meta Business, create a system-user token (`whatsapp_business_messaging` and `whatsapp_business_management`).
   2. Enter the phone number ID, WABA ID, token, app secret and a verify token in Integrations → WhatsApp.
   3. In the Meta app, add the webhook `https://<domain>/webhooks/whatsapp` with the same verify token, and subscribe to **messages**.
   4. Create an `infotics_update` utility template ("INFOTICS update: {{1}}") plus any marketing templates, then press **Sync from Meta** in WhatsApp → Templates.
6. **Fee visibility:** choose *Fee on request* for courses whose fee should stay private.
7. **UTM:** tag every ad and post (`?utm_source=facebook&utm_medium=paid_social&utm_campaign=oct-launch`).
8. **Scheduler:** `* * * * * php artisan schedule:run` must be running. It covers backups, reminders, lab cleanup, offers/waitlist and digests.

## 4. Backup & recovery

- **Create:** `php artisan infotics:backup`. Use `--no-files` for the database only and `--list` to show archives. Archives are written to `storage/backups/`, plus `INFOTICS_BACKUP_DISK` if set.
- **Password:** `INFOTICS_BACKUP_PASSWORD`, or `APP_KEY` when that is empty. Keep it in a password manager; without it backups cannot be opened.
- **Restore (SQLite):**
  1. Put the site in maintenance mode (`php artisan down`).
  2. `unzip -P "$PASSWORD" infotics-<date>.zip`.
  3. Copy `database/database-sqlite.sqlite` over `database/database.sqlite`.
  4. Copy `files/*` back to `storage/app/`.
  5. Bring the site back (`php artisan up`).
- **Restore (MySQL / Postgres):** `mysql infotics < database-mysql.sql`, or `pg_restore -c -d infotics database-pgsql.dump`.
- **Test:** do a restore drill on a staging server once a quarter.

## 5. Notes and limits (stated honestly)

- **WhatsApp rules:** Meta only allows free-text messages within 24 hours of the customer's last message, and marketing templates only to people who agreed. The platform enforces both. Campaigns run on the queue, so use a real queue worker in production for large lists.
- **Real systems still to be connected:** gateways, Zoom/Google/Webex, labs, WhatsApp and Turnstile were tested against simulated provider responses. Each needs your production credentials and one live smoke test.
- **NetAcad:** it has no public scheduling API, so NetAcad and Teams sessions use pasted links (auto-detected).
- **Standalone ESXi:** a standalone host (no vCenter) has no cloning REST API. Use the **machine pool** provider with snapshot-revert, or manage the host through vCenter.
- **VMware Workstation:** labs need `vmrest` running on the lab PC and reachable only from the INFOTICS server.
- **2FA locally:** 2FA is enforced, including on the local demo. Install an authenticator app before signing in as the demo admin. To demo without it, set `INFOTICS_REQUIRE_2FA=false` locally (never in production).
