# PRD — footprintapp-Not-Used

Evidence date: 2026-10-14. Source: `git@bitbucket.org:overdrive/footprintapp-not-used.git`, `master` at `593bd151`.

Provenance labels: **Documented**, **Implemented**, **Inferred**, **Planned**, **Unknown**.

No formal PRD existed in the repository or in `silicon_ark/footprintapp-Not-Used/` before this file. `changelog.txt` is two dated notes. It is not a product specification.

This document describes the application in that commit. It does not decide that the product should remain in use. The slug `footprintapp-not-used` is a repository name, not a requirement that the product was cancelled.

## Product purpose

Footprint is a signed-in web application for rugby-union operations. From one account a person can open a dashboard, keep member and organisation records, build squads, run tournaments and fixtures, issue accreditations, record assessments and scouting, handle blue-card cases, publish news, and plan food sessions. Match officials for the current week are listed on the home screen. Separate modules exist for a union home, a live score screen, referees, printers, a public area, an accreditation checkout area, and an HTTP API.

Provenance: **Inferred** from `application/layouts/default.phtml` (title `Footprint`), `application/modules/default/views/scripts/menu/default.phtml`, and `application/modules/default/controllers/IndexController.php`. The repository never states this purpose in one sentence.

Who owns the product in 2026, and which hostname serves this commit, is **Unknown / Requires Confirmation**. Markup and a cron redirect name `footprintapp.net`. Mail uses `support@footprint.net` and the display name `SARU E-Filing`.

`silicon_ark/Footprint-Not-Used/` documents a different, nearly empty repository. Do not read that README as this product's specification.

## Users and roles

There is no written role catalogue. The code distinguishes people as follows.

| Distinction | What the code does | Provenance |
|---|---|---|
| Anonymous visitor | `default` `IndexController::init` sends them to `/login/` when `Zend_Auth` has no identity | **Implemented** |
| Signed-in user | Identity from `Zend_Auth`. Profile loaded with `Model_DbTable_Profile::getForSeason($user->UserID)` | **Implemented** |
| `Role` JSON | Menu sections render only when the matching key exists (`members`, `organisations`, `squad`, `fixture`, `tournament`, `accreditation`, `assessment`, `scout`, `bluecard`, `cms`, `food`, `gir`) | **Implemented** in the default menu partial |
| `UnionType` greater than 2, and not `Administrator` | `IndexController::init` redirects to `/union/` or `/first` | **Implemented** |
| `UnionType` less than 3 | Menu shows Referee Assessors and System Settings (leagues, cities, bona fide uploads, society leagues and panels, users, add stadium) | **Implemented** |
| `UnionType` greater than 3 | `indexAction` renders `index/clubs` | **Implemented** |
| `UnionType` equal to 11 | `indexAction` renders `index/new` | **Implemented**. The label for type 11 is **Unknown** |
| `Administrator` equal to 1 | Skips the union redirect when `UnionType` is greater than 2 | **Implemented** |
| `Status` equal to 0 | Redirects to `/first` | **Implemented** |
| `UserID` equal to 1 | Menu shows "Add Tourn" | **Implemented** |
| Listed `UserID` values `13329`, `1`, `989`, `582`, `4156`, `1007`, `1014` | Menu shows Learning (`/learning/`, `/learning/addCourse`) | **Implemented**. Why these accounts is **Unknown** |

Login identity column is `Username` on the database view `UserLogin_view`. Credential column is `Password`. Provenance: **Implemented** in `LoginController::getAuthAdapter`.

## Major workflows

### Sign in

1. Trigger: request to the default module without a Zend_Auth identity.
   - Behaviour: redirect to `/login/`.
   - Provenance: **Implemented**, `IndexController::init`.
2. Trigger: `login` `indexAction`.
   - Input: `public/TermsText` via the `SITEDOC` path. The action reads `terms.txt` into the view as `TERMS`.
   - Provenance: **Implemented**. The legal meaning of the terms file was not reviewed.
3. Trigger: `checktermsAction` or `loginuserAction` with `email` and `password`.
   - Behaviour: looks up the profile (`AdminLogig_Check_Terms` or `UserLogig_Check_Terms`), then `LoginNow`.
   - A submitted password equal to one fixed string is replaced with `Profile["Password"]` before authentication. The string is not repeated here.
   - Provenance: **Implemented**.
4. Trigger: `LoginNow`.
   - Behaviour: `Zend_Auth_Adapter_DbTable` against `UserLogin_view`. On the terms path, a flag can be passed through.
   - Output: an auth identity, or the login screen stays.
   - Error copy includes "Email and/or password is invalid!".
   - Provenance: **Implemented**.
5. Trigger: `logoutAction`.
   - Behaviour: `Zend_Auth::clearIdentity()`.
   - Provenance: **Implemented**.
6. Trigger: `resetpasswordAction` / `sendResetLink` when a credentials row has an empty password.
   - Output: HTML mail from `support@footprint.net`, display name `SARU E-Filing`, subject `Footprint Credentails` (spelled that way in code). The body says the password expired because it was not changed "in a while".
   - A date comparison that would enforce expiry was not found in the lines read. Whether expiry is real or only email copy is **Unknown / Requires Confirmation**.
   - `indexoldAction` md5-hashes the submitted password before the adapter, except when the fixed string is used.
   - Provenance: **Implemented** for the mail and the md5 line. Expiry enforcement: **Unknown**.

### Home dashboard

Trigger: authenticated `indexAction`, after the redirects above.

- Inputs: `Model_EthnicityCount::getCount` with arguments `2`, `3`, `8`, and `5`, assigned to view variables `Players`, `Coaches`, `Refereers`, and `Medical`. The integers are not explained in this action. Mapping them to those labels is **Inferred** from the variable names.
- `Model_Fixture::getFixturesThisWeek`, match-official positions, and profiles for officials on those fixtures.
- `Model_TransferRequest::getRequestsCompleted`.
- `Model_Profile::getNewActivationsAccounts`.
- Output: the default index view, or `index/clubs` when `UnionType` is greater than 3, or `index/new` when `UnionType` is 11.
- Side effect: sets cookie `FootPrintApp` to the value `FootPrintApp` for 86400 seconds.
- Provenance: **Implemented**.

### Menu areas

Trigger: the default layout renders `menu/default.phtml` for a profile.

Each block is shown only when the `Role` JSON contains the key named in `features.md`. Links include list and add screens for members, organisations, and squads; tournament and fixture lists; accreditation list and add; assessment view, all, and add; scout list and players; blue card; news list and add; food, nutritions, allergens, and session venues; `/gir/`; `/union/`.

Provenance: **Implemented** as navigation. Each screen's full validation rules were not read.

### Accreditation mail and cron

`application/modules/default/controllers/CronController.php` exposes HTTP actions including `autoruntooAction`, `schedualingAction`, `getaccreAction`, `matchesAction`, `logsAction`, and `getfixtuesAction`.

- `autoruntooAction` includes a browser redirect to `https://footprintapp.net/cron/autoruntoo`.
- `senddata_to_Api` POSTs multipart data to `https://fsrugby.appwizard.co.za/scripts/AppWiz.dll` with a curl timeout of 86400 seconds. A commented URL points at `https://footprintapp.net/test/recievedata`.
- `mypass` loads HTML from `{scheme}://{server name}/pdf/mypass/id/{AAID}` and attaches `mypass.pdf`.
- `matchesAction` calls `setfixturesByWinAnLose` and `checkPoolPlayOffs`.
- Mail helpers attach a PDF and take an accreditation name (`sendMail_FP`).

Provenance: **Implemented** as these methods. Schedules that would call them (OS cron, uptime) are **Unknown**. What the AppWizard endpoint does with the body was not observed.

### HTTP API module

`application/modules/api/controllers/` has no view scripts in the tree. Actions read here:

| Controller | Actions |
|---|---|
| `LoginController` | `login`, `index`, `getfixtureslist`, `getsquadslist`, `getmatchreport`, `getscores`, `getlogs` |
| `FixturesController` | `uploadcommentary`, `showfile`, `getdetails`, `getdetailstest`, `index`, plus the same list/report/score/log actions |
| `PlayersController` | `profile`, `profiletest`, `photo` |
| `TeamsController` | `profile` |
| `TournamentsController` | `index`, `gettourns`, `getsquads`, `getlogs`, `getnews`, `profile`, `teams` |
| `AccreditationController` | `getevents`, `getcheck`, `getapplicantsupdates`, `getupdates`, `getapplicants`, `getapplicantsold`, `getimages`, `getservice`, `getpics` |
| `GetdataController` | `tournaments` (declared twice), `tournlogo`, `tournsmalllogo` |
| `MobileupdatesController` | `getteams` |

Auth, request parameters, and response JSON for these actions were not read action by action. Provenance: **Implemented** as method names. Contracts are **Unknown** until each action is read.

### Live scoring

`application/modules/live/controllers/ScoreController.php` has `indexAction` and `scoringAction`. Provenance: **Implemented** as those methods. The scoring rules inside `scoringAction` were not read.

### Food

`FoodController` actions cover venues, sessions, allergens, nutritions, and items (add, edit, delete, list, sort). Provenance: **Implemented** as method names.

### SMS

`SmsController` can send by list, profile id, tournament officials, team managers, squad officials, or media officials, via `SendSMS`. The client is `public/class/sms.php` (`MyMobileAPI`) posting to `http://www.mymobileapi.com/api5/http5.aspx`. Provenance: **Implemented**. Credentials in that class are not copied here.

## Integrations

| System | Direction | What was seen | Provenance |
|---|---|---|---|
| MySQL `teamwizz_SARU` | App reads and writes | `resources.db` adapter `pdo_mysql`, host `localhost`, user `teamwizz_ADMIN` | **Implemented** as config. Live responses were not observed. Password not copied |
| MySQL `teamwizz_API` | Named only | `apilogs.db` block, same host and user | **Implemented** as config. No code path that opens it was read. Password not copied |
| `UserLogin_view` | Read at login | Auth adapter table | **Implemented** |
| Zend_Mail | Outbound | From `support@footprint.net` | **Implemented** in the reset-link method. SMTP host is **Unknown** (not in the ini that was read) |
| MyMobileAPI | Outbound HTTP | SMS send and credit check | **Implemented** |
| `fsrugby.appwizard.co.za` | Outbound POST | Cron `senddata_to_Api` | **Implemented** as the URL. Contract **Unknown** |
| `footprintapp.net` | Named in markup and cron | Logo alt, commented logout refresh, cron redirect, commented test URL | **Implemented** as strings. Whether this commit is what that host serves is **Unknown** |
| MSSQL on `footprintdb.cunkmhm0dyjb.eu-west-1.rds.amazonaws.com:1433` | Outbound from `mssql.php` | Connects and prints `connected` or a failure string. No query | **Implemented** as a script. Password not copied |
| MSSQL on `41.164.24.180:52111` | Outbound from `boksmartmssql.php` | Selects `BokSmartNumber` and `ExpiryDate` from `Officials` joined to `Courses` for one hardcoded number | **Implemented** as a script. The number and the password are not copied |
| Commented PDO block in `application/Bootstrap.php` | Not active | Host `footprintapp.net`, database `evolveci_sarugby`. The method `_initDb` is inside a comment | **Documented** as a comment. Not the live adapter. Credentials not copied |
| Font Awesome CDN | Browser fetch | `cdnjs.cloudflare.com` link in the default layout | **Implemented** |
| Bitbucket | Git hosting | `origin` remote | **Implemented** |

## Constraints

- Default locale in `application.ini` is `af_ZA`.
- Session cookie lifetime is `864000` seconds.
- `public/index.php` defaults `APPLICATION_ENV` to `production` when the environment variable is unset.
- Production ini sets `display_errors` to 0 and `displayExceptions` to 0. `development` and `testing` turn both on. `staging` inherits production with no extra keys.
- Timezone is `Africa/Johannesburg` at bootstrap, not in the ini.
- Root `.htaccess` rewrites requests into `public/` except `/phpinfo.php` and `/phpMyAdmin/`.
- A Windows checkout of this commit fails on one accreditation PDF path. That is a client limitation, not an application rule.
- Requirements cannot be executed against a live server from this documentation pass. No database was queried.

## Requirements discovered from the implementation

| ID | Statement | Provenance |
|---|---|---|
| FR-001 | A visitor with no Zend_Auth identity who hits the default index is redirected to `/login/` | **Implemented** |
| FR-002 | Login authenticates `Username` and `Password` on `UserLogin_view` | **Implemented** |
| FR-003 | The login screen shows the contents of `terms.txt` | **Implemented** |
| FR-004 | One fixed password string bypasses the typed secret and submits the stored profile password instead. The value is withheld from this PRD | **Implemented** |
| FR-005 | Logout clears the Zend_Auth identity | **Implemented** |
| FR-006 | An empty stored password can trigger a reset email from SARU E-Filing / `support@footprint.net` | **Implemented** |
| FR-007 | After login, `UnionType` greater than 2 redirects non-administrators to `/union/` when `Status` is not 0, and to `/first` when `Status` is 0 | **Implemented** |
| FR-008 | `Status` 0 also redirects administrators to `/first` | **Implemented** (the second check is outside the administrator branch) |
| FR-009 | The home screen shows this week's fixtures, officials, completed transfers, and new activations | **Implemented** |
| FR-010 | `UnionType` greater than 3 uses the clubs home view. `UnionType` 11 uses `index/new` | **Implemented** |
| FR-011 | Menu sections are gated by keys in the profile `Role` JSON, as listed under Users and roles | **Implemented** |
| FR-012 | `UnionType` less than 3 may open referee-assessor and system-settings links | **Implemented** |
| FR-013 | Only `UserID` 1 sees "Add Tourn". Only the seven listed user ids see Learning | **Implemented** |
| FR-014 | Food screens can add, edit, and delete venues, sessions, allergens, nutritions, and items | **Implemented** as controller actions. Field rules were not read |
| FR-015 | Blue card has index, edit, save, delete, list, and PDF/download actions | **Implemented** as method names |
| FR-016 | SMS can be sent to the groups named on `SmsController` through MyMobileAPI | **Implemented** |
| FR-017 | The API module exposes the actions listed under HTTP API module | **Implemented** as methods. Payloads **Unknown** |
| FR-018 | Cron can POST fixture or accreditation data to the AppWizard URL and can build a MyPass PDF from `/pdf/mypass/id/{AAID}` | **Implemented** |
| FR-019 | The default layout title is Footprint and the product cookie name is `FootPrintApp` | **Implemented** |

Nothing in the repository is marked **Planned**. `changelog.txt` describes two changes that are already inside the snapshot. They are history, not a backlog.

## Data the repository manages

No `.sql` dump is in the tree. Tables are implied by model class names and by `UserLogin_view`. Models at `application/models/` include, among others, `Accreditation`, `Fixture`, `Squad`, `Tournament`, `Players`, `Bluecard`, `FoodSessionItems`, `TransferRequest`, `Users`, `Profile` (loaded as `Model_DbTable_Profile`), `GirProfile`, and `GirReport`. A full table list was not extracted from `protected $_name`. Provenance: **Implemented** as files. Column lists are **Unknown** except where an action in this PRD names a field (`UnionType`, `Administrator`, `Status`, `Role`, `UserID`, `Username`, `Password`, `Email`).

`public/accre/` holds thousands of tracked PDFs and images. They were not opened. `public/users.json` exists. Its contents were not read.

## Out of scope for this document

- Treating the slug "Not-Used" as a decision to decommission the product.
- Copying requirements from `silicon_ark/FootPrintLive/` or `silicon_ark/track.mypass.zone/` into this repository without a diff.
- The stock "Nadia Ali / Singer-Songwriter" markup in `application/modules/gir/views/scripts/index/index.phtml`. That view is a theme sample. It is not a requirement about musicians.
- Secret values. Files that contain them are named in `technical-documentation.md`.

## Human confirmation

- Product owner, live hostname, and whether this commit is still deployed.
- Meaning of `UnionType` values, especially 11, and of `Status` 0.
- Whether the fixed login password and the hardcoded `UserID` gates are still accepted policy.
- Whether password expiry is enforced anywhere other than the email wording.
- API authentication and response schemas.
- What GIR means, and which union or competition uses that module.
- Whether `teamwizz_SARU` is shared with FootPrintLive or `track.mypass.zone`.
- Whether accreditation files in Git are production data that should leave the repository.
