# Project plan — doh_moodle

Evidence date: 2026-10-16.

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

Inspected revision: `main` at `b9db23cf33d9ec93ae8764a160ec98f00f6f0441` (2026-06-24, "Update azure-pipelines.yml for Azure Pipelines").

The task-creation snapshot named `1a5c746b` (2026-02-05, "Add task to set group settings on synced modules"). That commit is an ancestor of the revision above. Later commits added credits, course start-date hiding, cohort removal rules, group backfill, and the Azure pipeline. This plan describes `b9db23cf`, not the February snapshot.

The clone used for inspection was `--depth 50`. `git log` from that clone includes the initial commit `1166e795` (2025-10-24, "Initial commit") through `b9db23cf`, so the depth covered the visible history.

There was no `doh_moodle/` directory in Silicon Ark before this set.

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

## Product

**doh_moodle** is a Moodle 4.5 site tree with Silicon Overdrive plugins that connect it to a Gibbon database (the companion repository `doh_sims`).

| Fact | Evidence | Provenance |
|---|---|---|
| Core is Moodle `4.5.7+ (Build: 20251009)`, branch `405`, version `2024100707.01` | `version.php` | **Implemented** |
| Composer package name is upstream `moodle/moodle`, PHP `>=8.1.0`, GPL-3.0-or-later | `composer.json`, `COPYING.txt` | **Documented** (upstream Moodle) |
| Remote is Overdrive's `doh_moodle` | origin `git@bitbucket.org:overdrive/doh_moodle.git` | **Implemented** |
| Custom local plugins in this tree: `local_gibbon_cohort`, `local_gibbon_sync`, `local_course_startdate`, `local_adminer` | `local/*/version.php` | **Implemented** |
| Custom plagiarism plugin `plagiarism_azureai` | `plagiarism/azureai/version.php` | **Implemented** |
| A Gibbon module copy lives at `gibbon_module/MoodleSync/` inside this Moodle tree | `gibbon_module/README.md` | **Documented** and **Implemented** as files. It is not a Moodle plugin |

The repository name contains `doh`. The custom plugin READMEs in this tree do not name a Department of Health institution, campus, or production URL. Silicon Ark `doh_sims` documents Department of Health student-information work and Moodle web-service calls. That this Moodle tree is the live LMS for that Gibbon site is **Inferred** from the shared plugin names (`local_gibbon_sync`, views `moodleCohort*`) and **Requires confirmation**.

`local_adminer` is the third-party Moodle Adminer plugin by Andreas Grabs, release `4.8.2 (2023102800)`. It is not Overdrive-authored. **Documented** in `local/adminer/version.php` and `README.md`.

## Objectives visible in the repository

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

1. Run Moodle 4.5 as the learning platform (courses, gradebook, assignments, quizzes, cohorts, web services, cron). **Implemented** as the upstream tree.
2. Copy Gibbon classes into Moodle cohorts, enrol those cohorts onto Moodle courses, and map Gibbon class roles onto Moodle course roles. **Documented** in `local/gibbon_cohort/README.md` and **Implemented** in `local/gibbon_cohort/`.
3. Copy per-class credits, pass marks, year-group minimums, and course-to-year-group links from Gibbon views, and award theoretical and clinical credits when a learner's course total meets the pass mark. **Documented** in the same README and `GRADES_AND_CREDITS.md`. **Implemented** in `credits_sync.php` and the `user_graded` observer.
4. Show the logged-in user their awarded credits. **Implemented** at `local/gibbon_cohort/my_credits.php`.
5. Expose web services so Gibbon can read students, grades, and courses, and can write grade feedback back. **Documented** in `local/gibbon_sync/README.md`. **Implemented** in `db/services.php` and `classes/api/grades.php`.
6. Hide a course from students until its start date, without changing enrolment. **Implemented** in `local/course_startdate/`.
7. Send assignment (and, when enabled, quiz) submission text to a configured plagiarism API. **Implemented** in `plagiarism/azureai/`.
8. Deploy 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.
9. Run a SonarQube scan from Bitbucket Pipelines on `main`. **Implemented** as a pipeline definition. Whether the scan is green was not observed.

## Scope in the repository

In scope for this knowledge set:

- Moodle core at 4.5.7+ as the platform the custom plugins sit on. Stock modules, themes `boost` and `classic`, and stock blocks are present. They are not re-specified feature by feature.
- Overdrive plugins: `local_gibbon_cohort` 1.2.0, `local_gibbon_sync` 1.0, `local_course_startdate` 1.0.0, `plagiarism_azureai` 1.0.0.
- Third-party `local_adminer` 4.8.2, because it is in the tree and exposes a database UI.
- The Gibbon-side `gibbon_module/MoodleSync` copy and the root diagnostic PHP scripts, as files that ship in this repository.
- Deployment described by `azure-pipelines.yml` and `bitbucket-pipelines.yml`.

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

- The Gibbon application. Silicon Ark `doh_sims` documents that side. LMS Sync in `doh_sims` calls `local_gibbon_sync_*`. The `gibbon_module/` folder here is a second Gibbon client checked into the Moodle repo. Which client is installed on a server is **Unknown**.
- The virtual machine, `release.sh`, SSH endpoints, and Azure variable groups. The pipeline names them. Their contents are not in the repo.
- Live plugin settings, tokens, API keys, and which plugins are installed in a given database. Folders being present does not prove they are installed.
- Production URL and the institution name.

## System shape

```text
Browser
  → Moodle 4.5 PHP (index.php, course, gradebook, assignment, quiz)
    → local_course_startdate (hide courses before start date)
    → local_gibbon_cohort My credits page
    → plagiarism_azureai (assignment settings; adhoc check)

Moodle cron (every 5 minutes, scheduled task)
  → local_gibbon_cohort\task\sync_all
      reads Gibbon SQL views (Moodle holds the DB credentials)
      writes cohorts, enrolments, groups, credits tables

Gibbon (doh_sims LMS Sync, or gibbon_module/MoodleSync)
  → Moodle REST /webservice/rest/server.php
      token + api_key
      local_gibbon_sync_get_students / get_grades / get_courses / get_course
      local_gibbon_sync_sync_grades (feedback only)

Azure Pipelines (dev)
  → SSH upload → /home/deploy/release.sh on the Moodle host
```

Users are expected to already exist in Moodle. The cohort README says usernames are matched and points at Moodle's External database authentication (`auth_db`). This tree does not add a custom auth plugin. Whether `auth_db` is enabled in a deployment is **Unknown**. Cohort member removal depends on that plugin's "Remove user" setting.

## Major components

| Component | Path | Role |
|---|---|---|
| Moodle core | `version.php`, `index.php`, standard directories | LMS |
| Gibbon cohort sync | `local/gibbon_cohort/` release 1.2.0, plugin version `2026031903`, maturity alpha | Cohorts, enrolments, roles, credits, My credits |
| Gibbon web services | `local/gibbon_sync/` release 1.0, plugin version `2025112000`, maturity alpha | REST for students, grades, courses, feedback write-back |
| Course start date | `local/course_startdate/` release 1.0.0, version `2026051802`, maturity stable | Student visibility before `course.startdate` |
| Azure AI plagiarism | `plagiarism/azureai/` release 1.0.0, version `2025101501` | Submission text sent to a configured API |
| Moodle Adminer | `local/adminer/` | Site-admin database browser (third party) |
| Gibbon module copy | `gibbon_module/MoodleSync/` | Client that calls the Moodle web services; not installed by Moodle |
| Azure deploy | `azure-pipelines.yml` | Build tarball, SSH to `ssh-moodle`, run `release.sh` |
| SonarQube | `bitbucket-pipelines.yml`, `sonar-project.properties` | Scan on `main` |

## Milestones visible in git history

Dates are commit dates on `main`. They are delivery evidence, not an approved plan.

| When | Commit | What landed |
|---|---|---|
| 2025-10-24 | `1166e795` | Initial commit (Rachel Mogano) |
| 2025-12-11 | `4708e81f` and neighbours | Moodle file tree imported; `*Config` removed from `.gitignore` |
| 2025-12-14 | `c56fc9d7` | Gibbon cohort sync plugin |
| 2025-12-17 | `dc4ff3dd`, `2d565282` | `sonar-project.properties`, Bitbucket Pipelines file |
| 2026-01-09 to 2026-01-13 | `4db631a6`, `0ca23e7a` | Class-role sync; separate tasks folded into one `sync_all` task |
| 2026-02-05 | `1a5c746b` | Task snapshot in the onboarding issue: group settings on synced modules |
| 2026-02-17 | `2b73d6b7` | "Gibbon Sync" (Rachel Mogano) |
| 2026-02-18 to 2026-03-05 | `cdff009b` through `2bdeb758` | Pass mark and credits; My credits page; grade response credits |
| 2026-03-20 | `3d9c9f40` | Cohort removal follows `auth_db` remove-user |
| 2026-05-22 | `765c21c0` | Hide courses from students before the course start date |
| 2026-06-03 | `c2e19b96` | Azure Pipelines file |
| 2026-06-15 | `69251cfb` | Cohort sync backfills group creation |
| 2026-06-24 | `b9db23cf` | Azure Pipelines update (current HEAD) |

## Implementation status

The custom plugins are in `main`. Maturity flags on both Gibbon plugins are `MATURITY_ALPHA`. Course start date and the plagiarism plugin are `MATURITY_STABLE`. Those flags are the authors' labels. They are not a test report.

`azure-pipelines.yml` selects `deploy-secrets-dev`, pool `selfhosted-dev`, and environment `moodle-dev`. The file header still says `dob_doh_moodle` and "Created for you by bootstrap-devops.sh". QA and production pools are comments.

## Known dependencies

- PHP 8.1+ and the extensions listed in `composer.json` (iconv, mbstring, curl, openssl, ctype, zip, zlib, gd, simplexml, intl, json, and others in the rest of that file).
- A Moodle database. `configx.php` (committed) names MariaDB database `moodle_stable`, table prefix `mdl_`, wwwroot `http://localhost/moodle_stable`, dataroot `C:\moodledata`. That file is a local development config. It also contains a database username and password. Those values are not copied here.
- A Gibbon database readable by `local_gibbon_cohort`, with views defaulting to `moodleCohort`, `moodleCohortMember`, `moodleCohortCourse`, `moodleCohortCourseCredits`, `moodleYearGroupCredits`, and `moodleCourse`.
- Moodle External database enrolment (`enrol_database`) new-course table, used by step 4 of cohort sync to find courses whose group mode should be forced. If that setting is empty, step 4 skips.
- Moodle web services and a token for the Gibbon caller, plus the plugin API key.
- For plagiarism: an HTTP API. Language strings describe an Azure Function. The settings page also has defaults for GPTZero (`https://api.gptzero.me/v2/detect`) and check-plagiarism.com. Which provider a site uses is configuration, not in git.
- Azure DevOps service connection `ssh-moodle`, variable group `deploy-secrets-dev`, and `/home/deploy/release.sh` on the target.
- SonarQube variables `SONAR_HOST_URL` and `SONAR_TOKEN` in Bitbucket. Project key is in `sonar-project.properties`.

## Current project status

Code on `main` through 2026-06-24 implements the Gibbon cohort and credit sync, the outbound web services, course start-date hiding, a plagiarism plugin, Adminer, a dev Azure pipeline, and a Bitbucket SonarQube step.

Not established from this repository:

- Production, QA, and dev URLs.
- Which institution's students use the site.
- Whether `auth_db` and `enrol_database` are enabled, and the live "Remove user" value.
- Whether `gibbon_module/MoodleSync` or `doh_sims` LMS Sync is the client that runs.
- Whether the root `check_*.php` scripts are reachable on a deployed host.
- Pipeline run results.
