# Project plan — thegsa

Evidence date: 2026-10-01.

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

Inspected revision: `master` at `522705535dc8a80d3676a76d4b3a189dd7a924b4` (2025-11-10 08:33:07 +0000, "bitbucket-pipelines.yml edited online with Bitbucket"). The scan-host path `~/projects/sonar_scan/repos/thegsa` was not on this machine. The tree was read from a clone of that revision. Committed database passwords 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 page title and home heading are **GSA**. The footer reads `GSA System [v0.0A, 2008]`. The login image alt text is **The GSA**. Email copy in `cron.daily.php` calls the monthly mail "The GSA Star (selling travel action report)" and names addresses at `thegsa.co.za` and `the-gsa.co.za`.

The runnable application is a PHP server-rendered system for magazine advertising. Staff keep advertisers (companies), contacts, sales people, and advertising contracts. A contract is a booking in a publication for a position, size, colour, and shape, split into monthly contract items. Staff log calls, produce operational reports, and generate renewal documents and PDFs.

Provenance: **Implemented Behaviour**, except the footer version string, which is **Documented** in `include/version.inc.php`.

There is no README, product requirements document, project plan, or feature list in the source repository. Silicon Ark had no `thegsa/` directory before this onboarding.

## Objectives visible in the code

These are inferred from what the code does, not from a written goal statement.

1. Record advertisers, their contacts, and the sales person responsible for them.
2. Record advertising contracts against a publication, with position, size, colour, shape, amount, discount, payment type, and a run of monthly items.
3. Mark contract items cancelled, skipped, or given an update label, and keep a per-item amount.
4. Log contact activity (type, status, discussion, action, follow-up date, linked publications, optional contract).
5. Restrict who may see and change each screen, and which sales people a user may edit.
6. Produce planning, invoice, cancellation, move, prospect, commission, expiry, contact, spend, income, follow-up, totals, and advert-update reports.
7. Build renewal documents and a renewal PDF.
8. Send a monthly STAR newsletter for publications flagged `blnSTAR`. That script exits before any mail is sent.

## Scope

### In the repository

- Root PHP pages for login, home, advertisers, contacts, contact logs, contracts, search, reports, lookups, renewal documents, and imports.
- Domain classes under `include/` and report classes under `include/reports/`.
- SQL builders in `include/database/sql.inc.php`.
- MySQL access in `include/database/mysql.cls.php`.
- Mail class `_nemo.email.gsa.cls.php` and the `include/mailer/` MIME/SMTP library.
- PDF via bundled FPDF (`include/fpdf.php`, `include/reports/fpdf.php`, `htmltopdf2/`) and Composer package `dompdf/dompdf` ^2.0.
- Lookup maintenance pages (branch, colour, magazine, payment type, position, sales person, shape, size, statuses, title, update label, user, email template).
- `cron.daily.php` for the STAR newsletter.
- `ximport.php` and `zimport.php` one-off data loaders.
- Bundled MySQLDumper under `mysqldumper/`.
- Bitbucket Pipelines SonarQube scan and `sonar-project.properties`.
- A committed zip `data.thegsa.co.za.zip` (about 30 MB) and files under `uploads/`.

### Out of scope of this repository

- The live menu labels and security rows. They live in MySQL (`tblmenulevel0`, `tblmenulevel1`, `tblSecurity`, `tblSecurityItem`) and are not in git.
- Hosting, DNS, and the cron schedule that would call `cron.daily.php`.
- Whether `gsa_qa` on `localhost` is the database this revision is meant to use in production.

## System architecture

Server-rendered PHP. Each screen is a root script. It includes `include/system.inc.php`, checks the `ckyGSA` cookie (except login, the STAR cron, the import scripts, `ajax.php`, and `renewalpdf.php`), then switches on `act` and prints HTML.

```text
include/header.inc.php
  title GSA, styles, jquery.js
include/menu.inc.php
  menu from tblSecurity for the cookie user
include/footer.inc.php
      ^
page script (advertiser.php, contract.php, ...)
  include/*.cls.php
      ^
include/system.inc.php
  copy GET/POST/COOKIE into globals
  open MySQL
  checkLogin / getAccess
      ^
include/database/mysql.cls.php
include/database/sql.inc.php
```

There is no router, no front controller, and no test suite. `index.php` is the post-login home. It prints the heading "GSA" and the menu.

`composer.json` requires only `dompdf/dompdf`. Most of the application does not use Composer autoload. `include/reports/salespersonreport.cls.php` does call `vendor/autoload.php`.

## Major components

| Component | Role | Evidence |
|---|---|---|
| Session cookie | `ckyGSA` holds `UserID\|username` | `login.php`, `checkLogin` in `include/system.inc.php` |
| Advertiser | Company record, contacts, contract history | `advertiser.php`, `include/advertiser.cls.php`, `tblCompany` |
| Contact | Person at an advertiser, default flag, subscribe status | `contact.php`, `include/contact.cls.php`, `tblContact` |
| Contact log | Call or meeting, follow-up, linked magazines | `contactlog.php`, `include/contactlog.cls.php` |
| Contract | Booking header plus monthly items | `contract.php`, `include/contract.cls.php`, `include/contractitem.cls.php` |
| Search | Company search that reuses contact editing | `search.php`, `include/search.cls.php` |
| Reports | Console plus one script per report | `reports.php`, `include/reports/` |
| Renewal | HTML renewal document and FPDF output | `renewaldoc.php`, `renewalpdf.php` |
| Lookups | CRUD pages for reference data | `branch.php`, `magazine.php`, and the other lookup scripts |
| Users | Login account, menu access, sales-person links | `user.php`, `include/user.cls.php` |
| STAR mail | Monthly newsletter, currently aborted | `cron.daily.php` |
| Imports | Unauthenticated bulk loaders | `ximport.php`, `zimport.php` |

## Milestones visible in comments

These dates are comments in source, not a project plan.

| Date | Comment |
|---|---|
| 2008 | Footer version `v0.0A` |
| 2009-11-26 | `mynl2br` added |
| 2013-07-26 | Copying contract positions onto the advertiser was written, then disabled: "GSA DIDN'T WANT TO PAY FOR IT" |
| 2013-08-12 | Renewal document template `renewaldoclarge_2013_1` |
| 2014-01-28 / 2014-01-29 | Gross amount and expiry on the contract list; `blnActive` on contact-log type |
| 2016-03-08 | User-to-sales-person linking |
| 2017-02-15 | Client spend report and income list report |
| 2017-04-06 | STAR newsletter script |
| 2018-01-08 | `cron.daily.php` starts with `die("site inactive 20180108")` |
| 2021-04-14 | PHP 7.4 upgrade and database connection change (comments by Russel) |
| 2022-09-26 | PHP 8 upgrade comment by Uriel |
| 2025-11-10 | Latest commit: pipeline file edited in Bitbucket |

## Implementation plan

No forward plan is in the repository. The current implementation plan, as the code stands, is: keep the PHP pages and MySQL schema in step, and run SonarQube on pull requests.

The pipeline definition runs only the SonarQube scan. It does not deploy.

## Known dependencies

- PHP with `mysqli` and `mail()`. Comments say the tree was moved to PHP 7.4 and then PHP 8. The exact runtime version on the host is **Unknown**.
- MySQL database selected in `include/system.inc.php`. The active call is `setDatabase("gsa_qa")` on `localhost`. Commented lines name `gsa`, `thegsegszw_db6` on `dedi483.jnb2.host-h.net`, and `cmysql5-1.wadns.net`.
- `dompdf/dompdf` ^2.0 and its locked dependencies (php-svg-lib, php-font-lib, php-css-parser, masterminds/html5).
- Bundled FPDF and html2pdf under `include/` and `htmltopdf2/`.
- jQuery in the root `jquery.js`.
- MySQLDumper under `mysqldumper/` (third-party backup UI).
- SonarQube, via Bitbucket Pipelines variable `SONAR_HOST_URL` and `SONAR_TOKEN`. Project key in `sonar-project.properties`: `overdrive_thegsa_60e72df9-4390-4206-b7ee-81e537e4c590`.

## Current project status

**Implemented** and present on `master` at the revision above.

The STAR job is present and hard-stopped. `settings.php` includes `include/general/settings.cls.php` and calls `checkSecurity` and `NotSufficientSecurityLevel`. That class file is not in the tree, and those two functions are not defined in `include/system.inc.php`. `ajax.php` includes `includes/database/sql.inc.php` (the directory is `include/`, not `includes/`) and calls `mysql_query`, which PHP 7 removed. `contract.php` calls `PreviewMail` and `MailContacts` on `Contract`; those methods exist on `include/zzcontract.cls.php` and were not found on `include/contract.cls.php`.

`bitbucket-pipelines.yml` runs the Sonar step for branch `{main}` and for pull requests. The inspected branch is `master`. Whether a branch named `main` exists is **Unknown** from this shallow clone.

## Unknown / Requires Confirmation

- Who owns the product, and whether it is still the system of record.
- The production host, database name, and whether `gsa_qa` is intentional on this revision.
- Menu structure and which users have which access levels (database only).
- The meaning of subscribe-status ids `2` and `3`, and of magazine ids `3`, `12`, `14`, and `19`.
- Whether `ximport.php` and `zimport.php` are still reachable on the web server.
- What is inside `data.thegsa.co.za.zip` and `uploads/`. They were not opened for this document.
- How, or whether, `cron.daily.php` is scheduled.
