# Features — crimemapping

Evidence date: 2026-10-18. Source: `git@bitbucket.org:overdrive/crimemapping.git`, `master` at `5927ab4` (2023-12-06).

"Current" means a route or script that runs at that revision. "Present, not routed" means the file is in git and the router does not mount it. There is no issue tracker or changelog in this repository, so "planned" is empty unless a comment or README says otherwise.

## Current

| Feature | What it does | Where | Provenance |
|---|---|---|---|
| Phone-width shell | Column capped at 400px, background `#0e0f14`, Bootstrap 5 | `PublicRoutes.js`, `PrivateRoutes.js` | **Implemented** |
| Branding | Logo `/images/CM_Logo_01.png`, theme name "Crime Map", primary `#faa31b` | `src/lib/theme.js` | **Implemented** |
| HTML title | "Crime Mapping Org" | `public/index.html` | **Implemented** |
| PWA manifest | Name "Crime Mapping Mobile Application", `display: standalone`, start URL `.` | `public/manifest.json` | **Implemented** |
| Service worker | `index.js` calls CRA `serviceWorkerRegistration.register()` in production. `index.html` also registers `serviceWorker.js` | `src/index.js`, `public/index.html` | **Implemented**. The file on disk is `src/service-worker.js`. The HTML name does not match |
| Sign up | Name, phone, organisation, email, password. `POST /apiusers/create` | `Signup.js`, `AuthContext.js` | **Implemented** |
| Organisation list | `GET /apiorganisations` with no token, shown on signup | `AuthContext.getOrganisationData` | **Implemented** |
| Sign in | Cellphone (max 10) and password. `POST /apiusers/login`. Token saved as `loginToken` | `Login.js`, `LoginForm.js`, `AuthContext.js` | **Implemented** |
| Session restore | `POST /apiusers/getUser` with bearer token | `AuthContext.js` | **Implemented** |
| Log out | Menu item. `POST /apiusers/logout`, then reload | `NavigationBar.js`, `AuthContext.js` | **Implemented** |
| Home | "Report a Crime", version, "Logged is as: {name} {surname}" | `src/pages/private/Home.js` | **Implemented** |
| User profile fetch | `GET /apiusers/{id}` into name, surname, email, role, organisation, active | `DatastoreContext.js`, `PrivateRoutes.js` | **Implemented**. `active` and `role_id` are stored and not used on home |
| Geolocation | High-accuracy current position, 50s timeout | `src/lib/services/currentposition.js` | **Implemented** |
| Fallback map centre | Latitude `-29.555`, longitude `25.107`, zoom 4, alert "Cannot get current position" | `PrivateRoutes.js`, `MapMain.js` | **Implemented** |
| Report a crime | Date/time, multi incident, notes, map, photos, confirm modal | `CreateEvent.js` | **Implemented** |
| Incident catalogue | `GET /apiincidents`, label `name`, value `name_group`, sorted by value | `DatastoreContext.getIncidentData` | **Implemented** |
| Map pin | Marker follows map centre while dragging | `MapMain.js` | **Implemented** |
| Reverse geocode | `ROOFTOP` formatted address sent as `coordinates_address` | `CreateEvent.js` | **Implemented**. Failure switches the library to `APPROXIMATE` and does not retry |
| Photo attach | Multiple files, local preview, remove, field `files[]` | `CreateEvent.js` | **Implemented**. No type or size check on this screen |
| Crime create API | `POST /apicrimes/create` multipart with bearer token | `DatastoreContext.addCrimeEntry` | **Implemented** |
| Unauthorised card | "Unautherised", spinner, redirect to `/login` after 1.5s | `UnAuth.js` | **Implemented** |
| Version label | `package.json` version `0.3.2` on home and in the menu | `Home.js`, `NavigationBar.js` | **Implemented** |
| Production URL | Build script sets `PUBLIC_URL=https://app.crimemapping.co.za/` | `package.json` | **Implemented** |
| FTP deploy | `yarn`, `yarn build`, `ncftpput` of `build/*` | `bitbucket-pipelines.yml` | **Implemented** in the pipeline file. Whether it has run successfully was not checked |

## Present, not routed

Removed from the router or the home screen. The files are still on `master`. Provenance: **Implemented** source, not a live route. Commit `2119323` (2023-04-24, "remove review crimes.") comments the home button. The route comments have no separate ticket.

| Feature | What it does | Where |
|---|---|---|
| Review crimes | Firestore `events` on a map. Role gate `userRole === 2` | `AllEvents.js`. Route `/all-crimes` commented in `PrivateRoutes.js`. `useFirestore` import is commented |
| Merge events | Average coordinates, write a merged event, copy sources to `archive`, delete sources | `AllEvents.js` |
| View crime | Firestore event by `?id=`: time, crime labels, description, one Storage image, map | `ViewEvent.js`. Route `/view-crime` commented. `useFirestore` is not imported |
| Review edit | Accordion edits crime, time, notes, jpeg upload, review flag | `components/Accordion/Default.js`, `EntryCard.js`. Used from the unrouted review list |
| Hardcoded crime list | 25 labels, including "Agrravated Robbery" | `src/lib/EventConfig.js`. Used by the accordion, not by `CreateEvent.js` |
| Debug | Device, browser, position, and controls for Firestore role and organisation | `Debug.js`. Route `/debug` commented. `react-device-detect` is only imported here |
| Static roles | Field Operator `1`, Data Manager `2`, organisation "Silicon Overdrive" id `1` | `src/lib/appConfig.js`. Only `Debug.js` imports it |
| Firestore helpers | `events` / `accounts` style CRUD. Storage prefix `ReactEventImages/{eventId}/{fileName}` | `FirestoreContext.js`. `FirestoreProvider` is not wrapped around the app |
| Firebase app | `initializeApp` with empty apiKey, authDomain, projectId, storageBucket, messagingSenderId, appId, measurementId | `src/lib/firebase-config.js` |
| Second geolocation hook | `UseCurrentLocation`, timeout 5s. Typo `enableHigAccuracy` | `src/lib/services/mycurrentposition.js`. No other file imports it |
| Maps URL signing | HMAC-SHA1 signature helper | `src/lib/services/create-signed-urls.js`. No other file imports it |

## Stub or broken on a live route

| Feature | Evidence | Provenance |
|---|---|---|
| Forgot password | Screen calls `resetPassword`. That function is commented out in `AuthContext.js` and is not provided | **Implemented** screen. The action throws "Failed to reset password" |
| README `npm run deploy` | Script name in `package.json` is `deploy:dev` (`npm version patch` and `firebase deploy --only hosting`) | **Documented** command does not exist |
| README Firebase env vars | `REACT_APP_FB_*` listed in the README. `firebase-config.js` uses empty strings and does not read those variables | **Documented** setup does not match the file |
| `npm run fb:logout` | Script body is `firebase login`, the same as `fb:login` | **Implemented** script. The README says it logs out |
| Sample unit test | Expects text "learn react" | `src/components/App.test.js` | **Implemented** test that does not describe this product |
| SonarQube pipeline step | Step `build-step` is defined under `definitions` and is not used by `pipelines.default` | `bitbucket-pipelines.yml` | **Implemented** unused definition |

## Removed from the live UI

| Feature | Evidence | Provenance |
|---|---|---|
| Firebase Authentication login | `resetPassword` comment still names `sendPasswordResetEmail(auth, email)`. Login, signup, and logout call the HTTP API | Commit `bc0c4df` "Removed firebase" (2023-03-03). **Implemented** history. The `firebase` dependency remains |
| Review Crimes button | Commented JSX, condition `userDetails.role_id === "2"` | `Home.js`. **Implemented** as a comment |
| `react-geolocated` watcher | Commented block in `PrivateRoutes.js`. Package remains in `package.json` | **Implemented** as a comment |

## Not in this repository

- Admin login, crime log, crime map, verification, export, organisations maintenance, and the GIS town feed. Those are in `crimemapping_website`.
- The API process. This client only calls it.
- A native app binary or store listing.
- `sonarqube_scan.bat` (named in the OVER-76 scan inventory, absent from `git ls-files` at `5927ab4`).
- A written roadmap.

## Planned

No TODO, ticket, or "coming soon" comment in this repository describes a next feature. The unrouted review screens are leftover code, not a stated plan. **Unknown / Requires Confirmation** whether anyone intends to turn them back on.

## Recently changed

Last product-facing subjects in git, newest first. Diffs were not expanded line by line.

| Commit | Date | Subject |
|---|---|---|
| `5927ab4` | 2023-12-06 | update |
| `2cb33e2` | 2023-07-20 | update icons |
| `770e79d` | 2023-05-11 | Null fix |
| `5a8a01c` | 2023-05-10 | auth fix |
| `2119323` | 2023-04-24 | remove review crimes. |
| `bc0c4df` | 2023-03-03 | Removed firebase |

## Relationship to the committed build

`crimemapping_website` stores a Create React App build at `app.crimemapping.co.za/` (`main.f6fb2877.js`) whose routes match this client: `/`, `/login`, `/signup`, `/forgot-password`, `/report-crime`, `/unauth`. That bundle hardcodes `https://admin.crimemapping.co.za/public`. This source uses `process.env.REACT_APP_PUBLIC_API_URL`. The website tree's app `.env` sets that variable to the same host. Provenance: **Documented** in `silicon_ark/crimemapping_website`. Whether that bundle was built from `5927ab4` is **Unknown / Requires Confirmation**.
