# Technical documentation — gsa

Evidence date: 2026-10-13.

Source: `git@bitbucket.org:overdrive/gsa.git`, `master` at `ebb9cca93051bcd23a569d2b0a243a8d465bb740` (2020-08-26).

Secrets committed in bootstrap files are not reproduced here.

## Architecture

Custom procedural PHP with per-screen classes. No Laravel, CodeIgniter, Symfony, or other application framework. No root Composer autoload for the application.

Request flow:

1. Root `*.php` includes `include/system.inc.php`.
2. `gpc_extract` copies GET/POST/COOKIE into `$GLOBALS` (register_globals emulation).
3. `cMySQL` opens MySQL and selects database `gsa`.
4. Most pages call `checkLogin()` then include header, run an `act` switch on a domain class, include menu and footer.

There is no front controller and no router.

## Application structure

```text
gsa/
├── *.php                 # Screen entry points (login, advertiser, contract, reports, …)
├── include/
│   ├── system.inc.php    # Bootstrap used by pages
│   ├── systemLive.inc.php# Alternate bootstrap (same DB name, shorter cookie)
│   ├── *.cls.php         # Domain classes
│   ├── database/         # mysql.cls.php, sql.inc.php, sql_object.cls.php
│   ├── reports/          # Report classes + FPDF copies
│   ├── mailer/           # MIME/SMTP library
│   ├── header/footer/menu/version includes
│   └── style/, javascript/, calendar_control/, images/
├── _nemo.email.gsa.cls.php
├── _nemo.database.cls.php
├── cron.daily.php
├── ximport.php / zimport.php
├── db/gsa_20200811.sql
├── data.thegsa.co.za.zip
├── dompdf/ / mpdf/ / fpdf/ / htmltopdf2/
├── mysqldumper/
└── uploads/
```

## Languages and frameworks

| Layer | Technology | Evidence |
|---|---|---|
| Server | PHP (legacy style; uses `get_magic_quotes_gpc` patterns) | Application PHP |
| Client | HTML tables, JavaScript, jQuery | `jquery.js`, headers |
| Data | MySQL via mysqli wrapper `cMySQL` | `include/database/mysql.cls.php` |
| PDF | FPDF / HTML2FPDF primary; Dompdf and mPDF vendored | `include/fpdf.php`, `dompdf/`, `mpdf/` |
| Mail | Custom `NemoEmail` + `mail()` | `_nemo.email.gsa.cls.php` |

Exact PHP version required is **Unknown**. Patterns suggest a pre-PHP-8 host may have been intended.

## Database

| Setting | `system.inc.php` | `systemLive.inc.php` | Dump header |
|---|---|---|---|
| Host | `localhost` (commented alternate `cmysql5-1.wadns.net`) | `localhost` | `dedi483.jnb2.host-h.net` |
| Database | `gsa` | `gsa` | `thegsegszw_db6` |

Tables present in `db/gsa_20200811.sql` (CREATE TABLE list):

`tblA`, `tblAdvertiserPosition`, `tblBranch`, `tblColour`, `tblCompany`, `tblContact`, `tblContactLog`, `tblContactLogMagazine`, `tblContactLogStatus`, `tblContactLogType`, `tblContract`, `tblContractImage`, `tblContractItem`, `tblEmailTemplate`, `tblLocation`, `tblMagazine`, `tblmenulevel0`, `tblmenulevel1`, `tblmenulevel1Item`, `tblPaymentType`, `tblPosition`, `tblSalesPerson`, `tblSecurity`, `tblSecurityItem`, `tblShape`, `tblSize`, `tblStatus`, `tblStatusContract`, `tblSubscribeStatus`, `tblTitle`, `tblUpdateLabel`, `tblUser`, `tblUserSalesPerson`.

SQL construction is concentrated in `include/database/sql.inc.php`.

## Authentication and security

| Topic | Behaviour | Evidence |
|---|---|---|
| Auth | Cookie `ckyGSA` = `UserID\|username` | `login.php`, `checkLogin` |
| Password | MD5 compare / store | `login.php`, user SQL |
| Authorisation | `tblSecurity` / `tblSecurityItem` | `getAccess`, menu |
| CSRF | Not observed | — |
| Input handling | Globals from request; SQL often built by concatenation via helpers | `gpc_extract`, `sql.inc.php` |
| Errors | Bootstrap sets display/error behaviour | `system.inc.php` |
| Unauthenticated paths | Cron (dies), imports, renewal PDF, many report wrappers, contract XML branch | See PRD / business rules |

This is an inventory of implemented behaviour, not a security endorsement.

## APIs

No first-party REST/JSON API module was found. Integration surfaces are:

- Browser form posts and page GETs.
- Optional XML response from `contract.php?arefCompanyID=…`.
- Outbound email via PHP `mail()`.

## External integrations

| System | Direction | Trigger | Notes |
|---|---|---|---|
| MySQL | App → DB | Every page | Host/db as above |
| Email (MTA via `mail()`) | App → mail | Contract mail helpers, STAR (disabled), templates | From addresses use `thegsa.co.za` / `the-gsa.co.za` in cron |
| Public GSA site | Referenced in data/email only | — | Historical URLs in dump; not an HTTP client in app code |

## Background workers / jobs / queues

| Job | File | Status |
|---|---|---|
| STAR newsletter | `cron.daily.php` | Hard-stopped 2018-01-08 |
| Queue system | — | Not present |

How the cron would be scheduled on a host is **Unknown**.

## Storage

| Path | Role |
|---|---|
| `uploads/` | Uploaded / generated artifacts (includes nested mPDF readme) |
| `db/gsa_20200811.sql` | Committed dump |
| `data.thegsa.co.za.zip` | Committed archive (~30 MB) |
| No S3 / object-store client in app PHP | — |

## Infrastructure and deployment

| Artifact | Present in this repo? |
|---|---|
| `composer.json` (app root) | No |
| `bitbucket-pipelines.yml` | No |
| `sonar-project.properties` | No |
| Dockerfile / compose | No |
| README deploy guide | No |

Deployment process, web root, and PHP-FPM/Apache layout are **Unknown / Requires Confirmation**. Dump host naming suggests a historical dedicated MySQL host.

Documented path fragment in commented Dompdf code: `$_SERVER['DOCUMENT_ROOT']."/gsa/dompdf/..."`, which **Inferred** that a deploy may have lived under a `/gsa` web path.

## Environment configuration

Configuration is PHP source, not `.env`:

- `include/system.inc.php` — primary include for pages; cookie lifetime 3600000; DB `gsa` on `localhost`.
- `include/systemLive.inc.php` — alternate; cookie lifetime 3600; DB `gsa` on `localhost`.

Which file production includes is **Unknown**. Passwords are committed in those files and must not be copied into documentation or tickets.

## Development and testing

| Topic | Evidence |
|---|---|
| Automated tests | None found |
| PHPUnit / TestSprite / CI | None found |
| Local setup docs | None found |
| Debug helpers | `info.php` behind `checkLogin`; `print_rr` style comments in cron |

## Monitoring

No application APM, structured logging, or health endpoint was found. MySQLDumper is bundled for database administration.

## Relationship to thegsa

| Aspect | `gsa` (this repo) | `thegsa` (Silicon Ark sibling docs) |
|---|---|---|
| Remote | `overdrive/gsa` | `overdrive/thegsa` |
| Tip inspected here | 2020-08-26 | 2025-11-10 (per `silicon_ark/thegsa/`) |
| Composer Dompdf | Vendored tree only | Documented as Composer dependency |
| Pipelines / Sonar | Absent | Documented present |
| Default DB name in bootstrap | `gsa` | Documented as `gsa_qa` among options |

Whether one replaced the other is **Unknown / Requires Confirmation**.

## Development notes for agents

- Do not modify this source repository for Silicon Ark onboarding; it is read-only evidence.
- Prefer citing root scripts and `include/*.cls.php` when tracing behaviour.
- Menu and security matrices need a live DB or the dump; they are not complete in PHP alone.
- Never paste credentials from `system*.inc.php` into Silicon Ark docs or issue comments.
