# Features — pmf-frontend-ah (PayMyFines)

Evidence date: 2026-10-06. Source: `master` at `3e8d2a5` (2022-05-06).

Status words mean:

- **Current** — reachable in the route table on `master`, or running without a route (analytics snippets, footer).
- **Present, not linked** — code and sometimes a route exist, and the menu does not point at it.
- **Removed from the menu** — route entries are commented out.
- **Planned** — named by a workflow or comment, with no branch or screen to match.
- **Not in this repository** — a document mentions it and the tree does not implement it.

No release notes distinguish "completed" from "current". Both commits are dated 2022-05-06. Nothing in git is "recently changed" relative to a later release.

## Current

| Feature | What the user gets | Code |
|---|---|---|
| Home notice search | Banner, notice field, results routed to AARTO or CPA detail | `src/components/LandingPage.js` |
| AARTO fine detail | eNatis fields, charges, demerit sum, add to cart when signed in | `src/components/AARTOFineDetails.js` |
| CPA fine detail | iForce fine, charges, evidence image when a token exists, add to cart when signed in | `src/components/CPAFineDetails.js` |
| Registration | Profile form, reCAPTCHA v2, Cognito sign-up, email code, Unity `/register` or `/updateregistration` | `src/components/Register.js` |
| Login | Cognito sign-in, Unity profile, role and ID list, redirect to outstanding fines | `src/components/Login.js` |
| First-login profile capture | Modal when Unity has no user for the Cognito uuid | `Login.js` |
| Migrated-account message | Popup when `dtLastEdit` is `1/1/0001 12:00:00 AM`, pointing at forgot password | `Login.js` |
| Forgot password | Email match, Cognito reset code, or the sign-up branch described in the PRD | `src/components/ForgotPassword.js` |
| Outstanding fines | Merged eNatis and iForce table, ID and authority filters, search, export, add one or many to cart | `src/components/OutstandingFines.js`, `common/ExportableTable.js` |
| Cart | Line list, per-line convenience fee, remove, empty state, iVeri checkout | `src/components/Cart.js` |
| Payment result | Success, fail, error, try-later copy; cart cleared only on success | `src/components/PaymentNotification.js` |
| Profile | View and update name, ID, mobile, email; add, edit, delete additional IDs; change password | `src/components/Profile.js` |
| Transactions | Filter by ID, searchable exportable table, amount sum, detail modal | `src/components/Transactions.js` |
| Admin dashboard | Date range, graph/table/counter tabs, finance report by issuing authority | `src/components/AdminDashboard.js`, `common/Graphs.js` |
| Admin settings | Email-template accordions, convenience fee, graph CRUD | `src/components/AdminSettings.js` |
| About | Static Paymyfines copy and iVeri security link | `src/components/About.js` |
| Terms and privacy | Static legal copy. Terms name TMT and `https://all.paymyfines.co.za` | `TermsAndConditions.js`, `PrivacyPolicy.js` |
| Header and footer | Logo, role-filtered links, cart count, logout, mailto contacts, AARTO / eNatis / RTIA images | `common/TopNav.js`, `common/Footer.js` |
| Client role gate | GUEST, CUSTOMER, MANAGER, ADMIN, SUPER_ADMIN | `src/config/Roles.js`, `src/config/RoutingConfig.js`, `src/utils/index.js` |
| Field validation | SA ID check digit, foreign ID and business registration accepted, name, phone, email, text | `src/utils/index.js` `validateFieldType` |
| Popup messages | Shared modal context | `src/contexts/popupModalContext.js`, `common/PopupModal.js` |
| Matomo and Google Analytics | Loaded from `public/index.html` on every page | `public/index.html` |
| Production deploy workflow | Push to `master` builds and syncs to S3, then invalidates CloudFront | `.github/workflows/master.yml` |

## Present, not linked

| Feature | Evidence |
|---|---|
| Quick Fine Search page | Route `/quickfinesearch`, `canNavigate: false`. Home link is commented out in `LandingPage.js`. Behaviour is a second notice search with different "no response" strings |
| Admin analytics page | Route `/adminAnalytics`, `canNavigate: false`. Menu entry commented in `RoutingConfig.js`. Component `AdminAnalytics.js` |
| Pivot table, Plotly renderers, Table renderers | `src/components/Pivot*.jsx`, `TableRenderers.jsx`, `PlotlyRenderers.jsx`, `pivottable.css`. No screen imports them. `react-pivottable` and `plotly.js` are dependencies |
| Storybook | Script `storybook` / `build-storybook`. One story: `common/JumbotronWrapper.stories.js` |
| CRA smoke test | `src/App.test.js` renders `App` and unmounts. No fine, auth, or payment tests |
| Amplify Storage bucket | `src/index.js` configures S3 bucket `tmt-pmf-prod-invoices`. No `Storage.put` / `Storage.get` call under `src/` |
| `RequestsAPI` fetch helper | `src/components/RequestsAPI.js`. Call sites use `unityRequests` or `API.get` / `API.post` instead |
| TinyMCE editor | `common/WYSIWYG.js`, mounted by `AdminSettings.js` for email templates. Dependency `@tinymce/tinymce-react` |
| FullCalendar, react-trello, namor | In `package.json`. No screen import was found |
| iVeri static redirect | `public/iveri.html` sends the browser to the S3 website `/PaymentNotification`. `documentation/iveri.php` redirects using `veriLocation`. Checkout posts to the Unity `/iveripayment` URL, not to these files |
| Committed production build | `build/` is in git, including hashed JS/CSS and `iveri.html` |
| Committed scanner and IDE state | `.scannerwork/`, `.vs/` |

## Removed from the menu

| Feature | Evidence |
|---|---|
| Admin dashboard test | `AdminDashboardTest.js` plus commented routes `/adminDashTest` in `RoutingConfig.js`. Uses in-file sample graph data (`dashboardTestData.js` is also present) |

## Planned or named without a matching branch

| Item | Evidence | Status |
|---|---|---|
| Developer environment | `.github/workflows/developer.yml` on branch `dev`, S3 secret `AWS_DEVELOPER_BUCKET_NAME` | **Unknown / Requires Confirmation**. `origin` has no `dev` branch |
| QA environment | `.github/workflows/qa.yml` on branch `qa` | Same. No `qa` branch |
| Sonar scan scripts | 2026-09-28 onboarding snapshot listed `sonar-project.properties`, `sonarqube_scan.bat`, `sonar-scanner.bat` | Not in git at `3e8d2a5`. `.scannerwork/` is committed, so a scan was run in a working copy that was later committed in part |
| Placeholder roles | Comment in `Roles.js`: "These are the placeholder roles you can replace these with yours" | The five names are what the route table uses. Replacement was not done in this tree |

## Not in this repository

| Mention | Where it appears | What is missing |
|---|---|---|
| Warrant-of-arrest block on payment | Terms clause 5.1.3 | No warrant field. The UI uses `paymentNotAllowedCode` and `customerPaymentAllowed` |
| Contact Us service for complaints | Terms clause 5.1.5 | Footer mailto only |
| Terms clauses 9 and 10 | Terms clauses 5.1.2 and 5.1.5 point at them | `TermsAndConditions.js` ends in clause 5 |
| Lambda implementation | `README.md` "Using Amplify / lambda" | This repo is the browser app. Lambdas are not here |
| Daily credit-card transaction cap | Terms clause 5.1.4 | No cap in the cart |

## Deprecated

Nothing in git history or comments marks a feature deprecated. The unused pivot/Plotly files and the commented dashboard-test routes are the closest cases. Treat them as unused, not as a declared deprecation.

## Changed

Both commits are the same calendar day (2022-05-06). A line-by-line handover diff was not used as a feature list. The tip message is `After handover commit`. What changed inside that commit versus `ae541e8` is **not** itemised here. **Unknown / Requires Confirmation** if a human still has the handover notes.
