# Business rules — members.mypass.zone

Evidence date: 2026-10-09. Source: `master` at `7268c97`.

Rules are taken from code that enforces them, or from text the application shows to the user. A rule that is only in an email or the FAQ is marked **Documented**. A rule that the code applies is marked **Implemented**. A rule inferred from the code and not stated to the user is marked **Inferred**. Conflicts are listed at the end and are not resolved here.

Secret values (database password, mailbox password, login override) are not written in this file.

## Identity and access

| ID | Rule | Provenance |
|---|---|---|
| BR-001 | Dashboard, permits, company profile, and staff require a `Zend_Auth` identity. Otherwise the user is redirected to `/login/`. | Implemented |
| BR-002 | Login matches `CompaniesLogin.Email` to the typed email and `CompaniesLogin.password` to the MD5 of the typed password. | Implemented |
| BR-003 | If the typed password equals a hardcoded string, the system substitutes the stored password for that email and then runs BR-002. Any existing account can be opened by someone who knows that string and the account email. | Implemented. Human review required. |
| BR-004 | A successful login sets session `EVENT.EID` to 61. | Implemented |
| BR-005 | Logout clears the auth identity and destroys the session. | Implemented |
| BR-006 | Registration refuses a company registration number that already exists, and refuses a person whose ID number or email already exists. Both cases return the same "account already exist" message. | Implemented |
| BR-007 | The first user is stored with role `Administrator`. | Implemented |
| BR-008 | Country value `SOUTH AFRICA` sets `IDType` 1. Any other country sets `IDType` 2. | Implemented |
| BR-009 | Email confirmation requires the `Validate_Key` from the link. On success the key is cleared, `Email_Confirmed` is 1, and `AllowLogin` is 1. | Implemented |
| BR-010 | Login does not read `AllowLogin` or `Email_Confirmed`. | Implemented. The confirmation page says the account is now active and the user may login. |
| BR-011 | Password reset requires a matching `ResetKey`. The new password is stored as MD5, the key is cleared, and `AllowLogin` and `Email_Confirmed` are set to 1. The new password is included in the email. | Implemented |
| BR-012 | Staff roles offered in the form are Administrator, Director, Management, Operations, Driver, Technician, and General Staff. | Implemented |
| BR-013 | Only one administrator is allowed per company. | Documented (FAQ). Not implemented. |
| BR-014 | Permit profile view is limited to the signed-in company. Staff profile load, permit cancel, and permit duplicate are not. | Implemented. The missing company check is **Inferred** as a defect, not as an approved rule. |
| BR-015 | `companypic` and `uploadremotecompany` do not require a session. `uploadremotecompany` writes a company image for the posted company id. | Implemented |
| BR-016 | No controller checks the staff role before showing dashboard, permits, company, or staff. | Implemented. Inferred that role is stored for display and for other systems, not for authorisation in this application. |

## Registration and company state

| ID | Rule | Provenance |
|---|---|---|
| BR-017 | A new company is inserted with `Active` = 1. | Implemented |
| BR-018 | An administrator reviews the registration before the company profile can be activated. The process can take up to 48 hours. | Documented (registration email). Contradicts BR-017 and BR-009. |
| BR-019 | The new company is linked in `Company_Events` to event id 44 with status 2. | Implemented |
| BR-020 | Without additional information or documents the company cannot connect to an event. | Documented (registration email). No document checklist is enforced. |
| BR-021 | The confirmation link in the registration email is hard-coded to `http://supplier.sarugby.online/register/validateemail/id/{key}`. | Implemented |
| BR-022 | Company profile saves write the posted `data` array onto the signed-in company id. There is no field allow-list. | Implemented |

## Events

| ID | Rule | Provenance |
|---|---|---|
| BR-023 | The header offers three events: 61 HSBC Cape Town Sevens, 62 Kyalami 9 Hour, 66 The Sun Met 2020. Choosing one sets `EVENT.EID` and reloads, on pages where `selectEventChange` is defined. | Implemented |
| BR-024 | The next login replaces that choice with 61. | Implemented |
| BR-025 | Registration does not use the header list. It always links the company to event 44. | Implemented |
| BR-026 | Changing the event does not check `Company_Events` for that company. | Implemented |

## Permits

| ID | Rule | Provenance |
|---|---|---|
| BR-027 | A new or duplicated permit is stored with status 2. | Implemented |
| BR-028 | Cancel sets status 5, the cancel message, the member id, and the cancel time. | Implemented |
| BR-029 | Status below 4 is shown as Pending. 4 Approved. 5 Cancelled. 6 Declined. 7 Checked-In. 8 Delayed. 9 Checked-Out. | Implemented (labels). The names of statuses 1 and 3 individually are Unknown; both display as Pending. |
| BR-030 | This application does not approve, decline, check in, delay, or check out a permit. | Implemented (absence). Inferred that another system writes those statuses. |
| BR-031 | The permit number is regenerated after insert from the new id and the session event. | Implemented (`getRef` is called with the new id and `EID`). The exact prefix format is inside `Model_AccreditationPermits::getRef`. |
| BR-032 | A type-1 occupant or driver is replaced with the `Company_Members` row that has the same ID number, when one exists. | Implemented |
| BR-033 | Selectable dates come from JSON `LoadinActiveDate` or `LoadOutActiveDate`. Stored date strings are split on `/` as day, month, year. | Implemented |
| BR-034 | On the create screen, a date is offered only when it is after today and noon on the previous day has not yet passed. | Implemented |
| BR-035 | On the permit profile, the form locks when 13:00 on the day before `RequestDate` has passed. Dates offered while unlocked use 13:00 on the previous day as the cutoff. | Implemented |
| BR-036 | Cancellations and changes may be submitted until 1pm daily. Changes for the next day after that time are not accepted. | Documented (permit email). The code locks the profile (BR-035) and does not apply the same check inside `savepermitAction` or `cancelAction`. |
| BR-037 | Administrators may change the requested date and time. | Documented (permit email). No administrator edit screen is in this repository. |
| BR-038 | A delivery permit cannot be longer than 2 hours. | Documented (FAQ). Not implemented. |
| BR-039 | One permit per vehicle per day. Duplicating onto another day is allowed. | Documented (FAQ) for the one-per-day rule. Duplicate is Implemented. The one-per-day uniqueness check is not. |
| BR-040 | A work permit requires a health and safety file. Delivery permits do not, in the FAQ's wording. | Documented (FAQ). Not implemented. |
| BR-041 | A printed permit and a Vehicle Access Pass are required at the gate. Staff must carry identification. | Documented (FAQ). Not implemented in software. |
| BR-042 | The permit email treats load type as Load-Out when the permit row's `Surname` equals 2, otherwise Load-In. | Implemented. This does not match the FAQ's load-in / load-out definitions. **Requires Confirmation.** |
| BR-043 | Cancel does not send the email the comment describes. | Implemented (absence of the send). |

## Staff

| ID | Rule | Provenance |
|---|---|---|
| BR-044 | The staff list is limited to the signed-in company id. | Implemented |
| BR-045 | If the add form posts `AllowLogin`, a random password is stored as MD5. Otherwise `AllowLogin` is 0. | Implemented. The new password is not emailed from `UsersController`. |
| BR-046 | Turning login on for a person whose `AllowLogin` was 0 generates a new password. Turning it on when it was already 1 does not. | Implemented |
| BR-047 | Event-day accreditation is applied for on a separate portal. | Documented (FAQ). The portal URL in the FAQ is the placeholder `[www]`. |

## Conflicts (not resolved)

| Topic | What the user is told | What the code does |
|---|---|---|
| Activation | Review, up to 48 hours, then the profile can be activated | Company `Active` = 1 on insert. Email link sets `AllowLogin` immediately. Login ignores `AllowLogin`. |
| Event | Header names three events | Login forces 61. Registration writes 44. 44 is not in the header list. |
| Change cutoff | 1pm in the email | Profile uses 13:00 the day before. Create uses 12:00 the day before. Save and cancel do not re-check. |
| One administrator | FAQ | Any number of Administrator roles can be inserted. |
| Delivery duration and one permit per vehicle per day | FAQ | Not checked. |
| Load-in versus load-out in the email | FAQ definitions | Email branch compares `Surname` to 2. |
| Repository name | Folder and git remote say `members.mypass.zone` | Product title, registration host, and deploy path say SA Rugby / `supplier.sarugby.online`. |

## Domain language found in the code

| Term | Where it is used | Meaning in this tree |
|---|---|---|
| CID | Identity and company rows | Company id |
| MID | Identity and member rows | Company member id |
| EID / AC | Session and `Accreditation_List` | Event / accreditation id |
| AMID | `AccreditationMemberProfile` | Profile row linked from the member |
| Load-in / Load-out | FAQ, permit dates, dashboard grouping by `LoadType` | Before/during event versus after the event, as the FAQ states. The numeric `LoadType` values are **Requires Confirmation** beyond the email bug in BR-042. |
| VAP | FAQ | Vehicle Access Pass. Not generated by this repository. |
| OAC | FAQ | Operations and Accreditations Centre. Not a screen in this repository. |
| B-BBEE | Company profile | Level and company type lists from `BBEE_Level` and `Accre_Company_Types`. |
