# Business rules — 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 business-rules document existed in the repository or in `silicon_ark/footprintapp-Not-Used/` before this file. Rules below were read from code. They are not a policy signed off outside the repository. Where the code is the only source, the rule is **Inferred** if the behaviour had to be interpreted, and **Implemented** if the branch is direct.

The slug `footprintapp-not-used` is not a rule that the product is unused.

## Identity and access

1. A request handled by `default` `IndexController` with no Zend_Auth identity is redirected to `/login/`. **Implemented.**
2. Successful login checks `Username` and `Password` on the database view `UserLogin_view`. **Implemented.**
3. `login` `indexAction` displays `terms.txt` from the site-documents directory (`public/TermsText`). `checktermsAction` and `loginuserAction` both accept `email` and `password`. The second path calls `LoginNow` with a terms flag of `1`. What is stored when terms are accepted was not read. **Implemented** for the two actions. The stored effect of acceptance is **Unknown**.
4. If the submitted password equals one fixed string, both `checktermsAction` and `loginuserAction` (and `indexoldAction`) replace it with the password already stored on the profile, then authenticate with that stored value. **Implemented.** The string is a backdoor. It is not repeated in this document. Whether it is still an approved support path is **Unknown / Requires Confirmation**.
5. `indexoldAction` md5-hashes the typed password before the adapter, unless rule 4 applies. `LoginNow` passes through the password string it was given and does not hash it in the lines read. **Implemented.** Whether `UserLogin_view.Password` is stored as md5 or as plaintext is **Unknown**, because the view definition is not in Git.
6. Logout clears the Zend_Auth identity. **Implemented.**
7. When a credentials row exists for the email and its `Password` column is empty, `sendResetLink` emails a reset link. The message says the Footprint password expired because it was not changed for a while. No age check was found next to that send. **Implemented** for the email. Expiry as a real time rule is **Unknown / Requires Confirmation**.
8. Invalid login copy is "Email and/or password is invalid!". **Implemented.**
9. Reset mail is From `support@footprint.net`, display name `SARU E-Filing`, subject `Footprint Credentails`. **Implemented.**
10. Profile `Role` is JSON. The default menu shows a section only when the key is present, and some links only when an `Actions` child is present:

    | Key | Extra action keys seen |
    |---|---|
    | `members` | `index`, `add` |
    | `organisations` | `index`, `add` |
    | `squad` | `index`, `add` |
    | `fixture` or `tournament` | Section opens if either key exists. Tournament links need `tournament`. Fixture links need `fixture` |
    | `accreditation` | `list`, `add` |
    | `assessment` | `index`, `add` |
    | `scout` | Key only, in the lines read |
    | `bluecard` | Key only |
    | `cms` | `News`, `addnews` |
    | `food` | Key only |
    | `gir` | Key only |

    **Implemented** in `application/modules/default/views/scripts/menu/default.phtml`. Controllers were not all checked for a matching server-side deny. A hidden menu is not proof that the URL rejects the user. **Unknown** whether every action repeats the check.

11. `UnionType` greater than 2: non-administrators (`Administrator` not equal to 1) go to `/first` when `Status` is 0, otherwise to `/union/`. **Implemented.**
12. `Status` equal to 0 redirects to `/first` even after the administrator exception. **Implemented.**
13. `UnionType` less than 3: menu includes Referee Assessors and System Settings. **Implemented.** The business meaning of "less than 3" (for example national versus club) is **Unknown / Requires Confirmation**.
14. `UnionType` greater than 3: dashboard view is `index/clubs`. **Implemented.**
15. `UnionType` equal to 11: dashboard view is `index/new`. **Implemented.** The name of type 11 is **Unknown**.
16. `UserID` 1 is the only account shown "Add Tourn". **Implemented.**
17. Learning links are shown only when `UserID` is one of `13329`, `1`, `989`, `582`, `4156`, `1007`, `1014`. **Implemented.** The reason for this list is **Unknown**.
18. On a successful index init, the response sets cookie `FootPrintApp`. **Implemented.** Session lifetime in config is 864000 seconds. **Implemented** as configuration. That is 10 days. The day count is arithmetic from the integer, not a comment in the ini.
19. Bitbucket push permissions were not listed (API client returned 401). **Unknown.**

## Home screen figures

`IndexController::indexAction` loads ethnicity counts with numeric arguments and stores them as players (`2`), coaches (`3`), referees (`8`, variable spelled `Refereers`), and medical (`5`). **Implemented** as those calls. That the integers are member-type ids is **Inferred** from the variable names. A lookup table was not read.

The same action lists fixtures returned by `getFixturesThisWeek`, the match officials on those fixtures, transfer requests returned by `getRequestsCompleted`, and accounts returned by `getNewActivationsAccounts`. **Implemented** as the calls. The SQL definition of "this week", "completed", and "new" was not read.

## Squad checklist

`changelog.txt` says that on 17/05/2019 `competitionsquadAction` was changed to check a checklist document and to select only the last uploaded checklist for the current year. **Documented** in the changelog. The method body was not read in this pass, so the current code was not re-confirmed line by line. **Requires Confirmation** against `application/modules/default/controllers/SquadController.php` if that rule is still the one in force. Git cannot show the pre-change version.

## Member export

`changelog.txt` says the member-list Excel export has a column between Gender and Age, added 13/05/2019. **Documented.** The spreadsheet columns were not re-read.

## Accreditations, MyPass, and cron

1. Cron action `mypass` fetches `/pdf/mypass/id/{AAID}` on the current host and attaches the HTML as `mypass.pdf`. **Implemented.**
2. `sendMail_FP` sends mail with an accreditation name and an optional PDF. **Implemented** as the signature and the method's existence. Template text was not read.
3. `senddata_to_Api` POSTs to `https://fsrugby.appwizard.co.za/scripts/AppWiz.dll`. **Implemented.** The business event that should trigger the POST is **Unknown** beyond "this method exists on the cron controller".
4. `matchesAction` updates fixtures by win and loss and checks pool playoffs for a tournament id. **Implemented** as function names. Point values and tie-break rules were not read. Do not invent a scoring table.
5. `getZones` is a private helper used from this controller. Zone names and gate rules were not read.

## Food

Venues, sessions, allergens, nutritions, and items can be added, edited, and deleted through `FoodController` actions. Items can be sorted. **Implemented** as actions. Required fields, allergen blocking, and who may edit a session were not read.

## Blue card

`BluecardController` supports list, edit, save, delete, and download including PDF. **Implemented** as actions. The offence, sanction, or workflow states inside `saveAction` were not read. No sanction matrix is stated here.

## SMS

`SmsController` can address a list, a profile id, officials in a tournament, team managers, officials in a squad, or media officials. **Implemented** as actions. Opt-out, quiet hours, and message length limits were not found in the method list. **Unknown** whether those limits exist inside `SendSMS`.

## BokSmart

`boksmartmssql.php` reads `Officials` joined to `Courses` and prints a BokSmart number and an expiry date for one hardcoded number. Commented lines show field names `BoksmartValidatedDate` and `BoksmartExpireDate`. **Implemented** as a script. It is not wired into a controller in the lines read. A product rule that a squad member must hold an unexpired BokSmart certificate is **not** established by this script.

## Locale and time

Default locale is `af_ZA`. PHP timezone is `Africa/Johannesburg`. **Implemented.** No rule was read that rejects a user outside South Africa.

## Explicit non-rules

The following were not adopted, because the evidence does not support them:

- "The product is unused." Only the repository slug says Not-Used. **Not a rule.**
- "GIR is a named programme." The module and role key exist. The index page is a theme demo. The expansion of GIR was not found in the files read. **Not a rule.**
- "UnionType 11 is a club, a school, or a province." The code only special-cases the integer. **Not a rule.**
- "Password expiry is N days." The email says "in a while". **Not a rule.**
- "Menu visibility is the only authorisation." Server-side checks were not verified for every controller. **Not established.**
- "Scoring, pool playoffs, or ethnicity codes have a published points table." Function names exist. The tables were not read. **Not a rule.**
- "phpMyAdmin access is a Footprint user role." The tree contains phpMyAdmin and the rewrite leaves `/phpMyAdmin/` alone. No Footprint role key grants it. **Not a product role.**
- Rules that exist only in `silicon_ark/FootPrintLive/` or `silicon_ark/track.mypass.zone`. Those documents describe other remotes. **Not rules of this commit** until a diff says the code matches.

## Human confirmation

- Whether the fixed login password is an approved break-glass account or a defect.
- Whether every sensitive action checks `Role` on the server.
- Labels for `UnionType` and `Status`.
- Whether the seven learning user ids are still the right people.
- The real squad checklist rule, confirmed from `competitionsquadAction` rather than only from the May 2019 note.
- Competition scoring and playoff rules, if they must be tested.
- Whether BokSmart expiry blocks a lineup in a controller that this pass did not open.
