# PRD — public-procon8.com

Evidence date: 2026-10-06. Source: `git@bitbucket.org:overdrive/public-procon8.com.git` at `e5cc6be` (2020-08-27, `master`).

There is no prior PRD in the repository or in Silicon Ark. Requirements below were recovered from the PHP, HTML, JavaScript, and committed mail configuration. Provenance is marked on each item.

## Product purpose

PROCON8 publishes a public multi-page brochure. The home page says the company provides project controls and contract management to engineering, construction, and manufacturing. Provenance: **Documented** (`index.php` title and hero).

The trust section names the company **PROCON8 MANAGEMENT LIMITED** and states a commitment to value for money, open reporting, and mentoring. Provenance: **Documented** (`index.php`).

`software.php` presents Quantivia as "the end-to-end enterprise project management solution" and sends the visitor to quantivia.com. That application is not in this repository. Provenance: **Documented** (`software.php`).

`SLA.php` titles the page PROCON8 MANAGEMENT LIMITED and embeds an external dashboard. It is not linked from the menu. Provenance: **Documented** on that file. Who is meant to open it is **Unknown / Requires Confirmation**.

## Users and roles

| Role | What they do | Evidence | Provenance |
|---|---|---|---|
| Public visitor | Reads the brochure, opens service and project pages, may submit the contact form | Navigation in `header.php` | Implemented |
| Enquiry recipient | Receives the contact email at `info@procon8.com` | `mail/mail.php` | Implemented as a mailbox address. No staff login exists in this repo |
| Dashboard viewer | Opens `SLA.php` directly and sees an iframe | `SLA.php` | Implemented page. Not linked from the menu |
| Stats viewer | Opens `stats/` and is challenged for basic auth | `stats/.htaccess` | Implemented as an Apache rule. The password file is committed. Whether it still matches a live host is Unknown |

There are no accounts, sessions, passwords, or permission checks in the brochure PHP.

## Information the site manages

The site does not store enquiries in a database. A successful contact post is sent as email. The GoDaddy CGI scripts can write posted fields to files under a `data/` directory one level above the document root, but no page in this tree posts to them.

Marketing content, office details, and project lists are hardcoded in PHP.

## Main workflows

### W1 — Read the brochure

Trigger: visitor opens `index.php`.

Behaviour:

1. `index.php` opens the document and includes `header.php`, which closes `head`, prints the utility bar and menu, and leaves the body open.
2. Utility bar: address "18 – 20 Le Pollet, St Peter Port, Guernsey, GY1 1WH" and `info@procon8.com`. A LinkedIn Follow Company block (company id `2761141`) is inside a `div` with `display: none`. Comment dated 2018-01-24: "Disable social media links (p8.co.za & p8.com) - pj".
3. Menu, in order: HOME (`index.php`), WHAT WE DO (dropdown: PROJECT CONTROLS, CONTRACT MANAGEMENT, SPECIALIST SERVICES), OUR PROJECTS, SOFTWARE, ABOUT US, CONTACT US.
4. A Flexslider hero repeats the heading "Project Controls and Contract Management" and the line "ENGINEERING | CONSTRUCTION | MANUFACTURING" over three images. The first slide is preceded by a stray `</li>`, so the list markup is broken.
5. A count band shows 25+ Global Projects, 15 Countries, 6 Continents.
6. Three cards link to `project.php`, `contract.php`, and `specialist.php`.
7. `brands.php` renders a logo carousel. Each logo is an anchor to `#`.
8. Six featured project tiles are not links. A button goes to `projects.php`.
9. `form.php` prints the office block and the contact form.
10. `footer.php` repeats the Guernsey address, `info@procon8.com`, and three phone lines, then "© Copyright 2016 - Procon8". Twitter and LinkedIn blocks are `display: none` under the same 2018-01-24 comment.

Provenance: **Implemented**.

### W2 — Open a service page

Trigger: visitor chooses Project Controls, Contract Management, or Specialist Services.

Each page includes `header.php`, a title band, three cross-links, an introductory paragraph, an accordion (`accordion-1 one-open`), `companies.php` (the same logo carousel plus a shorter trust paragraph), `form.php`, and `footer.php`.

Accordion groups are listed in Features. The first group on each page has class `active`.

Provenance: **Implemented**.

### W3 — Open the project catalogue

Trigger: visitor opens `projects.php`.

The page repeats the 25+ / 15 / 6 counts, then six full-bleed case studies, then two tab sets ("Projects we've worked on" and "Bids / proposals we've supported"), then a masonry of further names. Case-study roles and places are in Features.

Provenance: **Implemented**.

### W4 — Read about Quantivia

Trigger: visitor opens `software.php` from the menu.

The page describes Quantivia, embeds a YouTube video, and links to:

- `http://www.quantivia.com/`
- `http://staging.quantivia.com/viewdemo.php`
- `http://www.quantivia.com/demo.php`
- `http://www.quantivia.com/viewdemo.php`
- `http://www.quantivia.com/index.php#contact`
- `http://www.quantivia.com/contact.php`

Measure / report / deliver icons are loaded from `http://www.quantivia.com/img/`. This page does not include `form.php`.

Provenance: **Implemented** as links and copy. Quantivia behaviour itself is out of scope.

### W5 — Read about the company

Trigger: visitor opens `about.php`.

Copy states a global network of specialists for engineering, construction, and manufacturing, with experience in civil, building, infrastructure, and defence, and a focus on rail and aviation. Involvement is described as defining requirements, planning implementation, and following DMAIC (Define, Measure, Analyse, Implement, Control). An image map swaps regional map images. The page does not include the contact form. A button links to `contact.php`.

Provenance: **Documented** on the page. **Implemented** as static HTML.

### W6 — Send a contact enquiry

Trigger: visitor submits the form in `send.php`. The form is included from `index.php`, `project.php`, `contract.php`, `specialist.php`, and `contact.php`.

Fields: `name` (required), `email` (required, email), `message` (required). No subject field. No CAPTCHA. The form has no `action` attribute.

Client checks in `validateFields` (`js/scripts.js`):

- Every `.validate-required` control must be non-empty.
- Every `.validate-email` control must match `/(.+)@(.+){2,}\.(.+){2,}/`.
- If the page URL has `?ref=`, the script appends a hidden `referrer` input.

On submit the script POSTs the serialized form plus `&url=` plus the current page URL to `mail/mail.php`.

Server behaviour (`mail/mail.php` then `mail/lib/mail_sender.php`), in order:

1. `mail.php` sets `$emailMethod` to `ses-smtp`, SES host `email-smtp.eu-west-1.amazonaws.com`, port `587`, security `tls`, recipient `info@procon8.com`, recipient display name `Quantivia`, subject `Procon8 Management Website Request`, website name `Procon8 Project Management`, timezone string `South Africa`. A previous recipient `heinrich@overdrive.co.za` is commented out.
2. `mail_sender.php` does not read `$emailMethod`. It always builds a PHPMailer SMTP message. The Swift Mailer branch below `exit` is unreachable.
3. The body is every POST field, label plus value, separated by blank lines. Checkbox arrays would be comma-joined. There is no allow-list.
4. If both `email` and `name` are present, From is `info@procon8.com` with the visitor's name as the display name. If either is missing, From is not set.
5. To is `info@procon8.com` / `Quantivia`.
6. Reply-To is the raw string `name<email>` from POST. Return-Path is `info@procon8.com`.
7. Custom header `X-SES-CONFIGURATION-SET` is `ConfigSet_www_procon8_com`.
8. `isHTML(true)` is set. The body is the plain-text field dump, not HTML tags.
9. `send()` is echoed. PHP `true` prints `1`. The script then `exit`. On exception, the exception message is echoed.

Client success rule: if the response is numeric and greater than 0, clear the fields and show "Thanks for your submission, we will be in touch shortly." Otherwise show the response text, or the HTTP error text. The form's `data-error` string is "Please fill all fields correctly." A `false` send echoes an empty body, which is not numeric, so the visitor sees an empty error.

There is no server-side required-field check, no CAPTCHA, and no rate limit in this repository.

SMTP username and password are assigned from variables in `mail/mail.php`. Those values are in the Git history. This PRD does not repeat them. A different access-key id and password remain in comments in `mail_sender.php`.

Provenance: **Implemented**.

### W7 — Open the SLA dashboard

Trigger: visitor requests `SLA.php` directly. Nothing in the menu links to it.

The page uses an older layout (`css/style.css`, `fonts.css`, `js/jq.min.js`, `js/nav.js`, `js/galleryscript.js`). Those four files are **not in this repository**. It still prints a Twitter icon to `http://www.twitter.com/` and a LinkedIn Follow Company widget for id `2761141`.

An iframe loads `http://www.procon8.co.za:9090/publishPage.do?method=getPublishedDashboard&pagekey=0656059555200eb796972296434984a9`. If `$_GET['show']` is non-empty, the page prints that value into an inline script without encoding. The matching `.pbox` markup from the older site is not in this file, so the script has nothing to show.

Provenance: **Implemented** page. Dashboard availability is **Unknown**.

### W8 — Open the unused Quantivia template

Trigger: visitor requests `quantivia.php` directly. Nothing in the menu links to it.

The title element is the literal text "Edit title tag". The hero says "The next wave ." and repeats the Quantivia sentence. A newsletter form (`form-newsletter`) contains an iframe whose MailChimp action is `//mrare.us8.list-manage.com/subscribe/post?u=77142ece814d3cff52058a51f&id=94d040322a`. That list identity belongs to the Foundry theme vendor sample, not to a Procon8 list found elsewhere in this repo. Lower sections use placeholder headings ("Section Title", "Health Monitoring", "Location Services", "Social Data", "Cloud Enterprise").

`scripts.js` treats a form that contains a `srcdoc` iframe as a mailing-list signup and GETs the iframe form's action. It does not post that form to `mail/mail.php`.

Provenance: **Implemented** file. Whether it should be deployed is **Unknown / Requires Confirmation**.

## Integrations

| System | Purpose | Direction | Trigger | Auth | Failure |
|---|---|---|---|---|---|
| Amazon SES SMTP `email-smtp.eu-west-1.amazonaws.com:587` TLS | Deliver the contact email | Outbound | POST `mail/mail.php` | SMTP username and password in `mail/mail.php` | Exception message returned to the browser. No retry, no queue |
| quantivia.com and staging.quantivia.com | Product site and demos | Outbound links and image URLs | Visitor clicks or the browser loads icons | None in this repo | Browser error only. Not handled |
| YouTube | Software-page video | Embed | `software.php` | None | Browser error only |
| Google Fonts | Raleway and Open Sans | Stylesheet | Every page via `header.php` | None | Browser falls back |
| LinkedIn / Twitter | Social widgets and profile links | Outbound, hidden on the current shell | `header.php`, `footer.php`; visible on `SLA.php` | None | Widgets are commented or `display: none` on the current shell |
| procon8.co.za:9090 | Published dashboard | Iframe | `SLA.php` only | None in this file | Empty iframe. Not handled |
| MailChimp `mrare.us8.list-manage.com` | Theme sample list | Browser GET from `quantivia.php` | Submit on that page only | None | Error text from the JSON response, if the browser can read it |
| GoDaddy form CGI | Write posted fields to `data/gdform_<time>` | Would be inbound if called | No page references `cgi/gdform.cgi` or `cgi/gdformssl.cgi` | None | Script dies if the file cannot be opened |

## Constraints

- Content changes require editing PHP files. There is no admin UI.
- Contact delivery depends on SES accepting the From address `info@procon8.com` and the configuration set `ConfigSet_www_procon8_com`.
- The mail script prints the raw PHPMailer result or exception text to the visitor.
- `header.php` is included from inside `<head>` and itself closes `</head>` and opens `<body>`. Pages must keep that order.
- Social links on the current shell were deliberately hidden on 2018-01-24. Provenance: **Documented** in comments.

## Edge cases

- `contact.php` title is "Procon8 : Contract Management", the same wording as the contract page title family. The visible heading is still "Contact Us" from `address.php`.
- Home project tiles carry `data-filter` values that do not match the project (Gautrain is `Buildings`, Hamid International Airport is `Rail`). The filter list on the home page is an empty `<ul>`.
- `address.php` comment closer is `--!>` rather than `-->`, so the HTML comment around India and Australia may not close the way the author intended. `address.php.1` removes the comment and shows those two offices.
- Disclaimer spelling: binding email agreements need written confirmation by "Alastair Davisdon". The South Africa contact is "Alastair Davidson". Provenance: **Documented** in each file. Which spelling is the person is **Unknown / Requires Confirmation**.
- Footer Europe number is `+44 (0)745 203 46333`. The Guernsey office number in `address.php` is `+44 1481 749276`. Both are printed. Which number is current is **Unknown / Requires Confirmation**.
- `mail_sender.php` sets the timezone to `UTC` and ignores `$timeZone` (`South Africa`, which is also not a PHP timezone id).
- If `name` or `email` is absent, From is unset and Reply-To is still built from the empty values.
- `SLA.php` interpolates `$_GET['show']` into JavaScript.
- `stats/.htaccess` points `AuthUserFile` at `/var/chroot/home/content/70/9991770/html/stats/.statspwd`. That path is a GoDaddy layout. It will not match a host that does not use that path.

## Requirements trace

### FR-001 — Publish the brochure shell

The visitor can open the home page and move to the seven menu destinations.

Evidence: `index.php`, `header.php`, `footer.php`.

Implementation: Implemented.

Confidence: High.

### FR-002 — Describe the three services

The visitor can read project controls, contract management, and specialist services, including the accordion groups on each page.

Evidence: `project.php`, `contract.php`, `specialist.php`.

Implementation: Implemented.

Confidence: High.

### FR-003 — Show reference work

The visitor can read the case studies and the project and bid lists.

Evidence: `projects.php`, home tiles in `index.php`.

Implementation: Implemented.

Confidence: High.

### FR-004 — Describe Quantivia and leave the site

The visitor can open the software page and follow links to quantivia.com. This repository does not provide the product.

Evidence: `software.php`.

Implementation: Implemented as marketing and links.

Confidence: High for the page. Low for whether the remote URLs still exist.

### FR-005 — Accept a contact message by email

The visitor can submit name, email, and message. The server emails `info@procon8.com` through SES and shows success only when PHPMailer returns a positive count.

Evidence: `send.php`, `js/scripts.js`, `mail/mail.php`, `mail/lib/mail_sender.php`.

Implementation: Implemented.

Confidence: High for the code path. Whether SES still accepts the stored credentials is **Unknown / Requires Confirmation**.

### FR-006 — Show office contacts

The visitor can read the four uncommented offices and their named contacts.

Evidence: `address.php`, footer phones in `footer.php`.

Implementation: Implemented.

Confidence: High for what is printed. Currency of the people and numbers requires confirmation.

## Unknown / requires confirmation

- Whether www.procon8.com still serves this commit.
- Which company name is the contracting entity.
- Whether named people in `address.php` are still the contacts.
- Whether the hidden social accounts should stay hidden.
- Whether `SLA.php` and `quantivia.php` are intentionally public.
- Whether the MailChimp list on `quantivia.php` was ever meant to be Procon8's.
- Whether the GoDaddy stats and CGI files are still deployed.
