# Project plan — edi_system (SAWIS Label System)

Evidence date: 2026-10-16.

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

Inspected revision: `master` at `75a67b5` (2024-02-21, "replica of latest label code").

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

## Product

The Git repository is named **edi_system**. The running application presents itself as the **SAWIS Label System**.

| Source | What it calls the product |
|---|---|
| Repository name and origin | `edi_system` |
| `app/Views/layouts/main.php` | Title and meta description "SAWIS Label System" |
| `public/deploy.php` | Slack project label `SAWIS: Label` |
| `sonar-project.properties` | Sonar project key beginning `overdrive_label_system_` |
| Committed `env` | MySQL database `labelsystem`; `app.baseURL` `http://localhost/label_system/` |
| `composer.json` | Package name `codeigniter4/adminstarter`, description "Admin Overdrive" |
| `README.md` | "Admin Overdrive Starter" |
| `app/Helpers/mail_helper.php` | From-name "Admin Overdrive" |
| Latest commit subject | "replica of latest label code" |

No electronic-data-interchange implementation (orders, invoices, retailer messages, or an EDI parser) was found in this tree. The name **edi_system** is therefore **Unknown / Requires Confirmation**. The implemented product, from views, migrations, and controllers, is wine-label submission and approval for SAWIS, built on a CodeIgniter 4 admin starter that still contains other modules.

Provenance: **Documented** in `README.md` and `composer.json` as Admin Overdrive. **Implemented** SAWIS branding in layouts, deploy script, and label screens. The repository name versus that branding is a discrepancy.

External links in `README.md`, not verified from this repository:

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

## Branch reality

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

| Commit | Date | Author | Subject |
|---|---|---|---|
| `2fd7fe3` | 2023-11-27 | Jaco Brits | Initial commit (`.gitignore` only) |
| `75a67b5` | 2024-02-21 | Jaco Brits | replica of latest label code (the application tree) |

There is no longer history in this clone. The second commit message says the tree is a replica of label code. Where that code was copied from is **Unknown / Requires Confirmation**.

## Scope in the repository

In scope of what is present on `master`:

- A CodeIgniter 4 application (`codeigniter4/framework` `^4.0`) whose screens are branded SAWIS Label System.
- Session login that first tries a SAWIS Online user database, then falls back to a local `users` password.
- Self-registration into the local `users` table.
- Role and menu permissions. Only the Developer role is seeded.
- Label list, label form (admin and member variants), PDF upload, resubmit, field update, file approve/reject, label approve / approve-with-provisions / reject / contest, meeting-group reassignment, approval-certificate PDF, email templates, and a sent-email queue with a tracking pixel.
- Label status administration, meeting groups, and user-to-group assignment.
- User administration and menu management, including a generator that writes controller and view files.
- A home dashboard that counts labels and also loads car-session statistics.
- Modules that share the same starter and are not part of the label wording: car cost import and a multi-step car API, master-file spreadsheet import (Overland and ModelliQ), uploaded files, media files, site health, a test-project runner, organisations JWT API, ChatGPT page, system settings page, embedded Adminer, and developer CRUD / table viewers.
- SonarQube analysis on the `master` branch via Bitbucket Pipelines.
- HTTP deploy scripts under `public/` that pull Git on an allowed IP.

Out of scope of the code that was found:

- Any EDI document exchange. None was found.
- A queue worker or cron that sends `sent_queue` rows. Mail is inserted as unprocessed; a logged-in user can send one row immediately.
- Spark commands under `app/Commands`. The directory is absent.
- Seed data for label statuses, provisions, email templates, or label menu rows.
- Password reset. The login view links to `/pages-reset-password.html`, and that file is not in `public/`.
- Salesforce and Africa's Talking. Helper bodies are empty or fully commented. `Home` calls them only inside comments.
- AWS SDK usage in `app/`. The package is a Composer requirement only.
- Row-level security. Not implemented; the README does not claim it either.

## System architecture

```text
Browser
  → Apache virtual host or `php spark serve` (public/ is the web root)
      → CodeIgniter 4 (auto-routing on)
          → Filters: session login, then menu grant on the first URL segment
          → Controllers under app/Controllers
          → Models under app/Models
          → MySQL database labelsystem (from the env template)
          → Views (SAWIS header/menu, Bootstrap, DataTables)

SAWIS Online login
  → MySQL group sawisAPIQa (database sawis_api)
      → sysUser, sysSecurityGroup, sysPassword

Label files
  → public uploads path `uploads/` (PDF)
  → Imagick + Ghostscript render of the first PDF page to JPEG
  → mPDF approval certificate under uploads/approvalcerts/

Email
  → sent_queue row (not sent at insert time)
  → manual send via CodeIgniter email, SMTP smtp.overdriveqa.co.za
  → public tracking pixel updates sent_queue when the viewer is not logged in

Deploy
  → public/master_deploy.php (token + Bitbucket-style IP list)
      → HTTP call to an internal deploy.php
          → git pull, Slack notification
```

## Major components

| Component | Location | Role |
|---|---|---|
| Login and registration | `app/Controllers/Welcome.php` | SAWIS Online check, local password, self-register |
| Session and menu gates | `app/Filters/Authentication.php`, `app/Filters/Authorization.php` | Redirect if logged out or if the first URL segment is not granted |
| Labels | `app/Controllers/Labels.php`, `app/Models/LabelModel.php` | Submission, review, files, certificate, queue actions |
| Label settings | `LabelStatus`, `LabelUserGroups`, `LabelEmailTemplates` | Statuses, meeting groups, templates |
| Email | `app/Controllers/Email.php`, `app/Helpers/mail_helper.php`, `EmailPixelTracking` | Template merge, queue insert, manual send, open tracking |
| Users and menus | `app/Controllers/Users.php`, `Developers/MenuManagement.php` | Users, roles, menu grants, page generator |
| Dashboard | `app/Controllers/Home.php` | Label counts and car-session counts |
| Car module | `app/Controllers/Car.php`, `app/Controllers/CarApi.php` | Spreadsheet import and stepped session API |
| Master file | `app/Controllers/MasterFile.php` | Spreadsheet import and CSV export |
| Organisations API | `app/Controllers/Organisations.php`, `app/Libraries/JwtLibrary.php` | JWT resource API, filter-exempt |
| Deploy | `public/deploy.php`, `public/master_deploy.php` | Token-gated `git pull` |
| Pipeline | `bitbucket-pipelines.yml` | SonarQube on `master` |

## Milestones visible in the repository

These are migration and commit dates, not a signed project plan. No milestone document exists in the tree.

| When | Evidence | What landed |
|---|---|---|
| 2022-11 | Migrations dated 2022-11-20 onward | Organisations, users, roles, menus, sessions |
| 2023-06 to 2023-08 | Car, app session, master file, uploaded file, test, media, settings migrations | Starter modules around cars, files, and monitoring |
| 2023-10-16 | `Label` and `LabelNote` migrations | Label table |
| 2023-11-13 to 2023-12-21 | Label log, status, provision, files, meeting groups, email templates | Review workflow tables |
| 2024-01-18 to 2024-02-16 | Sent queue, meeting group on label, provisions, tracking code, agent, trademark, CC list, send date | Queue and later label fields |
| 2023-11-27 | Commit `2fd7fe3` | Repository created with `.gitignore` only |
| 2024-02-21 | Commit `75a67b5` | Full tree committed as a replica of label code |

There are no commits after 2024-02-21. Current status is a frozen snapshot.

## Implementation plan

No forward plan is written in the repository. `README.md` lists setup commands and a Jira URL under "Development TODOS". The CRUD section of the README is an empty bullet.

What a developer can do from the files that exist:

1. Copy `env` to `.env`, set base URL and database, run `php spark migrate`, run `php spark db:seed Users`, run `php spark key:generate`, run `php spark serve` or an Apache vhost whose document root is `public/`.
2. Add menu rows for screens the seeder does not create. Without a `user_menu.url` matching the first URL segment, the authorization filter redirects to `/` or `blocked`.
3. Insert `label_status` rows whose ids match the numbers hardcoded in `LabelModel` and `Home`, or the dashboard and approve/reject actions will point at the wrong names.

That last step is **Inferred** from the code, not from a setup document. See the status-id discrepancy in `prd.md` and `business-rules.md`.

## Known dependencies

Runtime, from `README.md` and `composer.json`:

- PHP `^8.0` with intl, mbstring, mysqlnd, json, xml. libcurl if HTTP calls are used.
- Composer packages: CodeIgniter 4 `^4.0`, `aws/aws-sdk-php` `^3.254`, `mpdf/mpdf` `^8.1`, `phpoffice/phpspreadsheet` `^1.25`, `orhanerday/open-ai` `^3.5`.
- PHP extensions used by label upload and not declared in Composer: Imagick, and Ghostscript on Windows (`C:/Program Files/gs/gs10.02.1/bin` is appended to `PATH` in `Labels`).
- MySQL for the application database and a second MySQL database `sawis_api` for login.
- SMTP server named in `app/Config/Email.php` (`smtp.overdriveqa.co.za`, port 587).
- OpenAI completions endpoint, called from `app/Helpers/chatgpt_helper.php`.
- Slack incoming webhook, called from `public/deploy.php`.

Dev dependencies: PHPUnit `^9.1`, Faker, vfsStream. The Bitbucket pipeline does not run PHPUnit.

## Current project status

**Implemented** as a single snapshot on `master`, last changed 2024-02-21. There is no open branch, tag, or changelog in this repository.

The label workflow is the largest body of application code (`Labels.php` is about 1,100 lines, `LabelModel.php` about 600). Surrounding it is the Admin Overdrive starter (users, menus, cars, files, organisations, ChatGPT).

Several behaviours conflict with each other or with a fresh migrate-and-seed. They are recorded in the other four documents and listed below for human review. They are not treated as approved requirements.

## Requires human confirmation

1. Confirm the product name. The repository is `edi_system`. The UI is SAWIS Label System. Composer and the README say Admin Overdrive. No EDI feature was found.
2. Confirm whether `master` at `75a67b5` is the production label system or a copy, and which host it is deployed to. `public/deploy.php` pulls Git after an IP and token check; the live base URL is not in the committed `env` (that file points at localhost).
3. Confirm production `label_status` ids. Approve, reject, contest, and the dashboard use fixed ids 4, 5, 6, and 7. `statusDisplay()` in `app/Common.php` uses a different map. Status names are editable in the database and are not seeded.
4. Confirm how roles 3 (Board) and 6 (called Members/Farmers in a comment) are assigned. The SAWIS group switch only writes roles 1, 2, 5, 7, or 0.
5. Confirm that self-registration should create a user with role 1 (Developer). That is what `Welcome::registration()` does.
6. Confirm whether anything outside this repository sends `sent_queue` mail and honours `send_date`. No worker was found here.
7. Confirm the `user_menu` rows used in production. The seeder does not insert a Labels menu, so a fresh database blocks label URLs.
8. Confirm whether `createLabelFiles()` can insert into the migrated `label` table. The insert sets only a few columns, while the original migration marks many columns `NOT NULL` with no default.
9. Credentials, tokens, and an encryption key are committed in source (`Database.php`, `Email.php`, `env`, `chatgpt_helper.php`, `deploy.php`, `master_deploy.php`, `JwtLibrary.php`, `Users` seeder). Values are omitted from Silicon Ark on purpose. Confirm rotation and removal from Git history.
10. Confirm whether the car calculator, master file, site health, test runner, organisations API, ChatGPT, Adminer, and `public/info.php` (`phpinfo()`) are still in product scope.
11. The SAWIS login path uses the `sawisAPIQa` connection group, not `sawisAPIDev`. Confirm that every environment should use that group.
12. Jira and Confluence links in the README were not opened. Confirm they still describe this application.
