# Project plan — doh_sims

Evidence date: 2026-10-16.

Source repository: `git@bitbucket.org:overdrive/doh_sims.git`.

Inspected revision: `main` at `5747dca4e0a45cb6edc95d5ec2cf262ad9278d19` (2026-10-07, "Merged in rachel_work (pull request #45)").

The clone used for this inspection was shallow (`--depth 1`). Only that commit is visible. Earlier history, including the task-creation snapshot commit `e50c5fd0` (2026-01-29, "bitbucket-pipelines.yml edited online with Bitbucket"), was not in the working tree. There is no `doh_sims/` directory already in Silicon Ark.

This plan describes what the repository contains. It does not decide what the product should become.

## Product

**doh_sims** is a fork of [Gibbon](https://gibbonedu.org/), an open-source school management platform, extended by Silicon Overdrive for Department of Health student-information work.

| Fact | Evidence | Provenance |
|---|---|---|
| Product name in Composer and the root README is Gibbon | `composer.json` name `gibbonedu/core`; `README.md` | **Documented** (upstream Gibbon text) |
| Core version in this tree is **29.0.02** | `version.php` `$version = '29.0.02'` | **Implemented** |
| Department of Health is the named customer domain for custom fields | `modules/DOHCustomFields/README.md` | **Documented** |
| Author of the DOH custom-fields module is Wessels De Wet for Silicon Overdrive | same README | **Documented** |
| The repository remote is Overdrive's `doh_sims` | origin `git@bitbucket.org:overdrive/doh_sims.git` | **Implemented** |
| Licence is GPL-3.0 | `composer.json`, `LICENSE`, module headers | **Documented** |

What "SIMS" expands to inside this repository is **Unknown / Requires Confirmation**. The LMS Sync guide calls Gibbon "SIMS" in one sentence (`modules/LMSSync/SETUP.md`). No other expansion was found.

Which Department of Health institution runs this deployment (college name, province, production URL) is **Unknown / Requires Confirmation**. House-name examples in the Registrations README ("Addington", "Umlazi") are instructions for matching form values to `gibbonHouse.name`. They are not evidence that those campuses are live.

## Objectives visible in the repository

There is no project plan, roadmap, or ticket list in the tree. Objectives below are recovered from module READMEs and code.

1. Run a Gibbon school platform (people, admissions, timetable, markbook, finance, attendance, reports, messenger). **Implemented** as the Gibbon 29 core modules under `modules/`.
2. Capture South African ID numbers and student numbers with validation. **Documented** and **Implemented** in `modules/DOHCustomFields/`.
3. Let returning students register for the next year, choose modules, and be blocked when progression rules fail. **Documented** in `modules/Registrations/README.md`. Current eligibility code lives in `src/Domain/ReEnrolment/ProgressionEligibilityService.php` and has moved past parts of that README. See discrepancies.
4. Treat Gibbon Houses as campuses and limit staff to their campuses. **Documented** and seeded in `modules/MultiCampus/`.
5. Produce Council on Higher Education (CHE) / HEMIS-shaped Excel extracts. **Documented** in `modules/CHEReports/`. The module states these extracts are not a certified CHE submission.
6. Invoice applicants (proforma and final) and let logged-out users look up an outstanding balance by email. **Documented** in Invoice Customizer and Payment Status.
7. Sync students and grades from Moodle into Gibbon, and expose Gibbon classes as Moodle cohorts. **Documented** in LMS Sync, Moodle, and Moodle Cohorts.
8. Deploy the app by Azure Pipelines over SSH to a host that runs an atomic release script. **Implemented** in `azure-pipelines.yml` for the dev pool and dev variable group. QA and production are named in comments only.

## Scope in the repository

In scope for this knowledge set:

- Gibbon core at version 29.0.02, including the modules shipped in `modules/` that are part of upstream Gibbon.
- Overdrive modules: DOHCustomFields, Registrations, MultiCampus, CHEReports, InvoiceCustomizer, Payment Status, LMSSync, Advanced Reports, Moodle Cohorts.
- The upstream Moodle module (`modules/Moodle/`, Gibbon Foundation, version 1.1.02), which Moodle Cohorts requires.
- Deployment described by `azure-pipelines.yml`.
- Database changes shipped in root `CHANGEDB.php` (Gibbon upgrades from v20.0.00 upward in this file; the header says v19 and earlier were removed) and in each module's `CHANGEDB.php` / `manifest.php`.

Out of scope of this repository, and therefore not specified here:

- The Moodle site and the `local_gibbon_sync` plugin. LMS Sync documents the web-service functions it expects. That plugin is not in this tree.
- The virtual machine, `release.sh`, SSH endpoints, and Azure variable groups. The pipeline names them. Their contents are not in the repo.
- Production data, live house lists, and which modules are actually installed in a given database. Module folders being present does not prove they are installed.

## System shape

```text
Browser
  → Apache (mod_rewrite, RewriteBase /gibbon/)
    → index.php / gibbon.php
      → Gibbon modules (PHP, Twig, MySQL)
      → Overdrive modules
        → Moodle REST (LMS Sync, outbound from Gibbon)
        → SMTP (PHPMailer; proforma invoice mail)
        → PayPal / Stripe (Omnipay; upstream Gibbon finance)
        → Google API client and Microsoft Graph (Composer dependencies; call sites not traced in this pass)
```

Houses are the campus key. Students link to a campus through `gibbonPerson.gibbonHouseID`. Staff link through `gibbonCampusPerson`.

## Major components

| Component | Path | Role |
|---|---|---|
| Gibbon core | `version.php`, `gibbon.php`, `index.php`, `src/`, `modules/` (stock names) | School platform |
| DOH custom fields | `modules/DOHCustomFields/` v0.0.14 | SA ID and student number |
| Registrations | `modules/Registrations/` v1.5.101 plus `src/Domain/ReEnrolment/` | Next-year registration and progression |
| Multi-campus | `modules/MultiCampus/` v2.1.00 | Campus roles and data filters |
| CHE reports | `modules/CHEReports/` v1.0.63 | HEMIS-shaped Excel files 61, 63, 65, 66, 67, 68 |
| Invoice customizer | `modules/InvoiceCustomizer/` v1.4.4 | Proforma and print invoices |
| Payment status | `modules/Payment Status/` v1.0.02 | Public balance lookup |
| LMS sync | `modules/LMSSync/` v1.5.9 | Moodle → Gibbon students and grades |
| Moodle views | `modules/Moodle/`, `modules/Moodle Cohorts/` | SQL views Moodle can read |
| Advanced reports | `modules/Advanced Reports/` | Enrolment, qualification, demographic, completion reports |
| Deploy | `azure-pipelines.yml` | Build tarball, SSH to the Gibbon host |

## Milestones visible in version numbers

These are release labels in the tree, not a dated project schedule.

| Label | Where | What it marks |
|---|---|---|
| Gibbon 29.0.00 | `CHANGELOG.txt` | Timetable UI, petty cash, CSRF on POST forms, and a large module tweak list |
| Gibbon 29.0.01 | root `README.md`, `CHANGELOG.txt` | TOTP MFA in `gibbonMfa` |
| Gibbon 29.0.02 | `version.php`, `CHANGELOG.txt` | Administrator impersonation |
| Registrations 1.5.101 | `modules/Registrations/version.php` | Current registration module |
| MultiCampus 2.1.00 | `modules/MultiCampus/version.php` | Requires core v29.0.00. README still describes 2.0.0 "houses as campuses" |
| CHEReports 1.0.63 | `modules/CHEReports/version.php` | Current CHE extract module. README examples stop around v1.0.27 |
| DOHCustomFields 0.0.14 | `modules/DOHCustomFields/version.php` | Unique email moved to User Admin settings; DOH Settings menu action removed |

No future milestone is written down. **Planned** work is **Unknown**.

## Implementation plan as evidenced

The repository does not contain a forward plan. The maintenance pattern the modules document is:

1. Install or update a module in **System Admin → Manage Modules**, which runs that module's `manifest.php` / `CHANGEDB.php`.
2. After a Gibbon core upgrade, re-apply integration lines that modules expect in `index.php` or `gibbon.php`. Several of those lines are **not** present in this tree. See discrepancies.
3. Deploy `main` (and `releases/*`) through Azure Pipelines: Composer install without dev dependencies, optional PHPUnit if present, tar the tree, SSH it to `/home/deploy/_incoming`, run `/home/deploy/release.sh` with `APP=gibbon` and `KEEP=5`.

## Known dependencies

Runtime (`composer.json` `require`, PHP platform pinned to 7.4):

- PHP `^7.4` with curl, intl, mbstring, gettext, PDO
- MySQL 5.7 minimum (`version.php` `$systemRequirements`)
- Apache `mod_rewrite`
- Google API client, League Container, Aura SQL Query, TCPDF, Twig 3, Slim 4, PHPMailer, matthewbdaly/sms-client, Symfony YAML, Monolog, PhpSpreadsheet, Faker, mPDF, Omnipay (PayPal and Stripe), ParseCSV, league/oauth2-client, microsoft/microsoft-graph, Aura Auth, eluceo/ical, spomky-labs/otphp, endroid/qr-code

External systems the custom modules name:

- Moodle REST (`local_gibbon_sync_get_students`, `local_gibbon_sync_get_grades`, `local_gibbon_sync_get_courses`)
- SMTP for invoice email
- Azure DevOps (pipeline, variable group `deploy-secrets-dev`, pool `selfhosted-dev`, environments `gibbon-dev`)
- Sonar project key `overdrive_doh_sims_6cb51fc6-7a0e-4436-baca-4f4625d95b76` in `sonar-project.properties` (no scanner step is in `azure-pipelines.yml`)

## Current project status

**Implemented** in source, not proven installed on a server:

- Core version string 29.0.02.
- Custom module folders and version files listed above.
- Azure pipeline file aimed at the **dev** pool and **dev** secret group. The file comments mention `deploy-secrets-qa`, `deploy-secrets-prod`, `selfhosted-qa`, `selfhosted-prod`, `gibbon-qa`, and `gibbon-prod`, but the committed YAML uses dev values for both deployment jobs (`deployGibbon` via `ssh-gibbon`, and `deploySIMSDev` via `gibbon-dev-vm-connection`). Both jobs target environment `gibbon-dev`.

**Not in this tree:**

- `bitbucket-pipelines.yml`. The 2026-09-28 task snapshot listed that file. It is absent at `5747dca4`.
- `tests/` at the repository root. `composer.json` scripts call Codeception and PHPUnit under `tests/`. That directory is not present. MultiCampus has its own `modules/MultiCampus/tests/`.
- `config.php`. Database credentials are created at install time (`src/Install/Config.php`). None are committed. That is expected.

## Discrepancies that need a human

1. **Registrations bootstrap.** `modules/Registrations/bootstrap.php` says it is loaded from `gibbon.php`. `modules/Registrations/README.md` says to add a `require` in `index.php`. Neither file contains that require. The only caller found is `modules/Admissions/applications_manage_acceptProcess.php`, which loads the bootstrap when accepting an application. Whether registration pages load the same services another way was not fully traced.
2. **MultiCampus bootstrap.** `index.php` does not contain `MultiCampus/bootstrap.php`. The module's `setup.php` and `scripts/post-upgrade.php` are written to inject that line. A deployed copy may differ from this git tree.
3. **Payment Status welcome card.** `index.php` does set `paymentStatusEnabled` from the module setting (around line 590). The README's Twig snippet for `welcome.twig.html` was not re-verified in this pass.
4. **Version files disagree with READMEs** for DOHCustomFields (code 0.0.14, README 0.0.06), CHEReports (code 1.0.63, README narrative around 1.0.27), MultiCampus (code 2.1.00, README feature list titled 2.0.0 and history ending at 1.7.00), Payment Status (code 1.0.02, README 1.0.00), Advanced Reports (`manifest.php` `$version = '1.5.01'`, `version.php` `$moduleVersion = '1.3.00'`).
5. **PHP version.** Core and Composer require PHP 7.4. MultiCampus README requires PHP 8.0. Payment Status README requires PHP 7.3. The pipeline runs Composer with `--ignore-platform-req=php`. Which PHP the servers run is **Unknown**.
6. **Progression rules.** The Registrations README describes separate theoretical and clinical minimums and a diploma rule of 1970 clinical credits. `ProgressionEligibilityService` (class comment and `isEligibleForDiploma`) uses a single `gibbonYearGroup.minimum_credits`, course-total markbook rows, `max_core_carried`, and supplementary-band handling. The 1970 figure does not appear in that class.
7. **Task snapshot vs HEAD.** Onboarding metadata recorded commit `e50c5fd0` and a `bitbucket-pipelines.yml`. Inspection used a newer `main`.

## Assumptions

- "Department of Health" in the DOHCustomFields README is the product owner named by the authors. It is not confirmed against a contract in this repo.
- Stock module folders (Students, Staff, Finance, and the rest listed in `features.md`) behave as Gibbon 29 unless a local file under `src/Domain/ReEnrolment/` or a module hook says otherwise. A line-by-line diff against upstream Gibbon was not done.
