# Project plan — greenfields_web

Evidence date: 2026-10-13.

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

Inspected revision: `main` at `c8fce1f4f9161d73b84b8d38b7ea8546de6ddb15` (2025-04-11, "base commit"). The scan-host path `~/projects/sonar_scan/repos/greenfields_web` was not on this machine. The tree was read from a clone of that revision. Committed secrets (encryption key, SMTP password, Slack and deploy tokens, session files) are named by file and are not reproduced.

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

## Product

The Git repository and the SonarQube project key are **greenfields_web** (`sonar.projectKey=overdrive_greenfields_web_…` in `sonar-project.properties`). The string "greenfields" does not appear in application code, views, or the README.

Several other names are in the tree at the same time:

| Surface | Name | Evidence |
|---|---|---|
| README title | Admin Overdrive Starter | `README.md` |
| Composer package | `codeigniter4/adminstarter`, description "Transactflow", homepage `https://www.overdrive.co.za` | `composer.json` |
| Login page `<title>` and keywords | Transactflow | `app/Views/common/login.php` |
| Navbar logo alt | AdminOverdrive | `app/Views/layouts/header.php` (`assets/img/adminOverdrive.png`) |
| Outbound mail | From `notifications@transactflow.io`, footer "The Transactflow Team", link `https://transactflow.io` | `app/Helpers/mail_helper.php` |
| System settings page title | Label System Settings | `app/Controllers/SystemSettings.php` |
| Web deploy script label | `SAWIS: Label` | `public/deploy.php` |
| Committed database name | `adminoverdrivev3` | `.env` |
| Committed base URL | `http://localhost/admin-overdrive-v2/` | `.env` |
| In-repo overview | "The project name is Transactflow" | `overview.md` |

`overview.md` also says the database is "likely MySQL" and that features are "likely" inferred from Composer packages. Those sentences are not treated as requirements. MySQL is **Implemented** in `app/Config/Database.php` (`DBDriver` MySQLi) and in `.env`.

What "greenfields" refers to, and which of the names above is the customer-facing product, is **Unknown / Requires Confirmation**.

The behaviour that is actually coded, beyond the Admin Overdrive shell, is an EDI operations console: pull buyer orders, export seller orders and invoices, check document faults, and chart orders and invoices. Retailer-specific code names Pick n Pay (SOAP), Shoprite (REST), M2North (SOAP invoices), Makro (email XML invoices), Godrej, and Namaqua. Provenance: **Implemented** in `app/Controllers/GetXMLData.php`, `Soap.php`, `Rest.php`, `Email.php`, and `FaultFinder.php`.

### Related Silicon Ark project

Silicon Ark already documents **`wca_dms`** as another Admin Overdrive checkout. That write-up says EDI screens exist there as views, while controllers such as `FaultFinder` and `GetXMLData` are absent. Those controllers are present in this repository. A line-by-line comparison was not done. Whether `greenfields_web` and `wca_dms` are snapshots of one Admin Overdrive / Transactflow line is **Unknown / Requires Confirmation**. This onboarding documents this repository only.

## Objectives visible in the code

No project plan, milestone list, or backlog lives in the repository. `README.md` links to a Jira board and a Confluence space. Those links were not opened.

- Jira: `https://siliconsoftware.atlassian.net/jira/software/projects/SI/boards/12`
- Confluence: `https://siliconsoftware.atlassian.net/wiki/spaces/AO/overview`

Objectives that can be read from the implementation:

1. Staff sign in to an Admin Overdrive / Transactflow shell and reach menus allowed for their role.
2. A scheduled HTTP job pulls orders for buyer companies and exports orders and invoices for seller companies.
3. Transport is folder XML, a Shoprite REST pull, or a Pick n Pay SOAP pull. Email transport is named and not implemented.
4. Fault checks run on orders, invoices, and products, and can mail a fault-type recipient list.
5. Reports chart order and invoice volumes and values.
6. SonarQube scans `main` on Bitbucket Pipelines. The pipeline does not deploy the application.

## Branch reality

Default branch is `main`. `origin/HEAD` points at `main`. No other remote branches were present at inspection.

| Commit | Date | Subject |
|---|---|---|
| `b533f4b` | 2025-04-11 | Initial commit |
| `3ea0310` | 2025-04-11 | sonar-project.properties created online with Bitbucket |
| `e59604c` | 2025-04-11 | bitbucket-pipelines.yml created online with Bitbucket |
| `c8fce1f` | 2025-04-11 | base commit |

Four commits, all on the same day. There is no longer history in this clone. Whether this repository was copied from a larger Admin Overdrive or Transactflow codebase is **Inferred** from the commit subject "base commit", leftover SAWIS label views, and routes that name controllers that are not in the tree. That origin is **Unknown / Requires Confirmation**.

The task-creation file list included `sonarqube_scan.bat` and treated `builds` as a directory. At `c8fce1f`, `sonarqube_scan.bat` is absent and `builds` is the CodeIgniter framework script that toggles Composer between release and development (`php builds [release|development]`).

## Scope in the repository

In scope of what is present on `main`:

- A CodeIgniter 4 application. `composer.lock` pins `codeigniter4/framework` `v4.6.0`. `composer.json` allows `^4.0` and PHP `^8.0`. `README.md` says PHP 8.3 is required.
- Session login, email two-factor codes, password reset, an IP block check, and login history.
- Seeded roles: Developer, Admin, Company Admin, Company User.
- Menu permissions, user administration, and system settings (cron, email templates and logs, holidays, login history, blocked list, fault types, transport methods).
- EDI intake and export in `GetXMLData`, `Soap`, `Rest`, and `Email`, started from `CronJobs`.
- Fault finder calculations and a reports controller with chart endpoints.
- Company, invoice, and client models. Company and store screens have views. There is no `Company` controller.
- A CLI loop `php spark monitor:system`.
- Developer screens: menu management (can write new controller and view files) and a CRUD generator.
- ChatGPT page that calls the OpenAI helper.
- A `.side` file runner under `Test` (Selenium IDE project files).
- SonarQube scan on `main` via Bitbucket Pipelines.

Out of scope of the code that was found, or present only as views, routes, `use` statements, or comments:

- Controllers `Products`, `Orders`, `Company`, `LabelStatus`, `LabelUserGroups`, `LabelEmailTemplates`, `StoreApiController`, and an `Organisations` resource controller. Routes in `app/Config/Routes.php` name them.
- Models `OrdersModel`, `ProductsModel`, and `EmailTemplateModel`. `Reports`, `FaultFinder`, `Csv`, `CronJobs`, and `SystemSettings` instantiate them.
- `LabelModel` is imported in `CronJobs` and the only `new LabelModel()` found is commented out.
- Migrations for domain tables the code queries (`companies`, `orders`, `invoices`, `products`, `password_reset`, `fault_type`, `company_transport_methods`, `blockedusers`, and others). Migrations that do exist cover users, menus, organisations, sessions, media, cron logs, settings, language, label email templates, user groups, sent queue, email authentication codes, login history, and `blocked_users_list`.
- Email as a transport method. The `Email` branch in `GetXMLData::main` is comments only.
- API invoice intake. The `invoices` branch under transport type `API` is empty.
- Self-registration. `Welcome::register()` is empty. A comment says registrations are not done on this application. `Welcome::registration()` still contains a create-user path and is not given a route in `Routes.php` (auto-routing is on).
- SAWIS Online login. `Welcome::getHasLoginFromSawisOnline` is fully commented.
- Salesforce and Africa's Talking. Helper bodies are empty or fully commented.
- AWS SDK, mPDF, and PhpSpreadsheet. They are Composer requirements. No `use` of those libraries was found under `app/`.
- Row-level security, captcha, and rate limits. Not found in this tree. CSRF and honeypot filters are present and commented out in `app/Config/Filters.php`.

## System architecture

```text
Browser
  → Apache or `php spark serve` (public/ is the web root)
      → CodeIgniter 4 (auto-routing on)
          → Filters: session login, then menu grant
          → Controllers under app/Controllers
          → Models under app/Models
          → MySQL database name adminoverdrivev3 (from committed .env)
          → Views (Admin Overdrive shell, Bootstrap, DataTables, Feather)

Unauthenticated HTTP
  → GET cronJobs — weekdays 08:00–22:59, optional production key
  → GET slack
  → GET tracking-pixel
  → resource routes organisations and store-api (controllers not in the tree)

External systems named in code
  → Pick n Pay SOAP pull (QA default, production URL switches WSDL)
  → Shoprite REST vendor-order pull (QA host hardcoded as the Shoprite branch)
  → SMTP smtp.transactflow.io
  → Slack webhook from sendMail (not for internal, external, or invoice-export mail)
  → OpenAI via the ChatGPT helper when that page is used
```

Timezone is set to `Africa/Johannesburg` in `BaseController::initController` and in `app/Config/App.php`.

## Major components

| Component | Path | Role |
|---|---|---|
| Auth and shell | `app/Controllers/Welcome.php`, `Home.php`, `Users.php`, `app/Filters/` | Login, 2FA, password reset, home, users, menu grant |
| EDI intake | `app/Controllers/GetXMLData.php` | Folder XML, Shoprite REST, Pick n Pay SOAP |
| Retailer adapters | `app/Controllers/Soap.php`, `Rest.php`, `Email.php` | Pull, confirm, and generate invoices |
| Scheduler | `app/Controllers/CronJobs.php` | HTTP cron: orders, invoices, mail, faults, reports, server logs, billing |
| Faults | `app/Controllers/FaultFinder.php`, `app/Models/FaultFinderModel.php` | GLN, price, quantity, and calculation checks |
| Reports | `app/Controllers/Reports.php` and `app/Views/reports/` | Charts and unmatched / uninvoiced lists |
| Companies | `app/Models/CompanyModel.php`, `app/Views/edioverdrive/company/` | Sellers, buyers, stores, vendor numbers. No company controller |
| Settings | `app/Controllers/SystemSettings.php` | Cron, mail, holidays, faults, transport, blocks |
| Monitoring | `app/Controllers/ServerMonitoring.php`, `app/Commands/MonitorSystemUsage.php` | Usage page and a CLI loop |
| Developer tools | `app/Controllers/Developers/` | Menu builder that writes PHP files, CRUD generator, DB table view |

## Milestones and implementation plan

No milestone dates are documented in the repository. The only implementation record is the four commits on 2025-04-11. Current status is "code present on `main`", not a release plan.

`README.md` setup steps, as written:

1. Copy `env` to `.env`. The tree contains a committed `.env` and no `env` template.
2. `php composer install` (the README also says `composer update` on framework release).
3. `php spark db:create`, `php spark migrate`, `php spark db:seed users`.
4. `php spark key:generate`. A key is already set in the committed `.env`.
5. `php spark serve`, or an Apache vhost whose example `ServerName` is `adminOverdrive.local` and whose document root is `c:/wamp64/www/adminOverdrive/public`.

The Users seeder inserts one Developer account (`admin@overdrive.co.za`) and then calls role, menu, menu-category, access, and organisation seeders. It does not call `FaultType`, `TransportMethodOptions`, `ErrorCheckStatus`, or `Holidays.sql`.

## Known dependencies

Runtime, from `composer.json` / `composer.lock`:

- PHP constraint `^8.0` in Composer; README states 8.3. Extensions named in the README: intl, libcurl, json, mbstring, mysqlnd, xml. Composer also requires `ext-simplexml`.
- `codeigniter4/framework` v4.6.0 (locked), constraint `^4.0`.
- `aws/aws-sdk-php` `^3.254` — no application usage found.
- `mpdf/mpdf` `^8.1` — no application usage found.
- `phpoffice/phpspreadsheet` `^1.25` — no application usage found.
- `orhanerday/open-ai` `^3.5` — used by the ChatGPT helper.
- `league/csv` `^9.16` — CSV upload controller exists.
- Dev: fakerphp/faker, mikey179/vfsstream, phpunit `^9.1`.

External systems: MySQL, Pick n Pay EDI SOAP, Shoprite B2B REST, Transactflow SMTP, Slack, OpenAI. Details are in `technical-documentation.md`.

`vendor/` is committed (7,552 tracked paths in the clone, including `vendor/autoload.php`).

## Current project status

**Implemented, with gaps.** The shell, login, EDI pull/export code, fault checks, and report queries are in the tree. Several screens and cron paths instantiate classes that are not in the tree, and several domain tables have no migration. A fresh `spark migrate` plus the Users seeder does not create the EDI schema the cron expects.

`CI_ENVIRONMENT` in the committed `.env` is `development`. The committed base URL is a local Admin Overdrive path, while mail and SOAP/REST code assume Transactflow and retailer hosts. Which host this repository is deployed to is **Unknown / Requires Confirmation**.

Bitbucket Pipelines on `main` runs only a SonarQube scan (`sonarsource/sonarqube-scan:3.0.2`). It does not build, test, or deploy. `public/deploy.php` is a separate `git pull` endpoint labelled SAWIS Label. It is not referenced by the pipeline file.
