# Features — ClickPortal

Evidence date: 2026-10-18. Source: `git@bitbucket.org:overdrive/clickportal.git`, `master` at `0e2adfb` (2023-02-07, single commit).

There is no changelog and no second commit, so "recently changed" cannot be separated from "what the initial commit contains". Nothing in git is marked deprecated. Commented-out code is listed as present but not on the live path.

## Current (on the live path)

| Feature | What it does | Where |
|---|---|---|
| Google staff sign-in | Button "Sign in using Google". Posts the Google email and token id. Server checks the token and that the email is an identity user, then returns a JWT. | `ClientApp/src/pages/account/AccountLoginPage.js`, `services/AuthenticationService.js` `loginGoogle`, `Controllers/AccountController.cs` `authenticate-google`, `Services/IdentityService.cs` |
| Session in the browser | Stores `currentUser` in `localStorage`. Sends `Authorization: Bearer`. Drops the session when `expires` has passed or the API returns 401 or 403. | `services/AuthenticationService.js` |
| Login gate | `/support` and `/support/findlearner` redirect anonymous users to `/account/login`. | `components/PrivateRoute.js`, `App.js` |
| Sign out | `/account/logout` clears the session and sends the user toward `/support`, which bounces to login. | `pages/account/AccountLogoutPage.js` |
| Land on find-learner | `/` and `/support` both push `/support/findlearner` during render. | `pages/HomePage.js`, `pages/support/SupportHomePage.js` |
| Find learner | Search by cellphone, or by province / region / district / school / grade / class plus optional names. Table of school, name, grade, class, RE / Matific / Refl logins, and password. | `pages/support/SupportFindLearnerPage.js`, `Controllers/LearnerController.cs` `search` |
| Copy logins | Copies active programme logins and the password to the clipboard. | `SupportFindLearnerPage.js` copy handler |
| School pick lists | Provinces, regions, districts, schools, grades, and classes for the signed-in user id. | `Controllers/SchoolController.cs`, `Repositories/SchoolRepository.cs` |
| Learner RE login API | Anonymous POST. Checks username and password for programme `RE`, then returns a redirect URL and clears the password. | `Controllers/LearnerController.cs` `login` |
| Programme read API | Anonymous GET by integer id. | `Controllers/ProgrammeController.cs` |
| Quiz learner name API | Anonymous GET. Shared-secret query parameter. Returns learner id and name. Comment: "Used by Mobenzi". | `Controllers/QuizController.cs` |
| Startup config API | Anonymous GET of app id and Google client id. | `Controllers/ConfigController.cs` |
| SPA host | Development runs the React dev server. Publish runs `npm install` and `npm run build` and ships `ClientApp/build`. | `ClickPortal.csproj`, `Startup.cs` |
| Request logging | Serilog, including a `UserID` from the JWT name identifier. | `Program.cs`, `Startup.cs` |
| Production error page | Non-development errors use `/Error` (Razor page, request id, no exception detail). | `Pages/Error.cshtml` |

## Present in the tree, not on the live path

| Item | Evidence | Reading |
|---|---|---|
| Staff username/password API | `AccountController.Authenticate` comments out the service call and returns 401. | Not a working login. `IdentityService.Authenticate` still verifies a password hash. |
| Staff username/password form | `AccountLoginPage` `onSubmit` does not call `login`. The form has no username or password fields. | Google is the only control on the page. |
| Client `login()` function | `AuthenticationService.login` posts `account/authenticate`. | Nothing in the live render calls it. |
| Startup fetch | `ConfigService.fetchStartupValues` is commented out. Live `startupValues()` returns a hardcoded Google client id and an empty app id. | Login does not use `api/config/startup`. |
| Staging database connection | `Startup` registers `StagingSqlConnection`. No other type injects it. | Unused. |
| EF tool | `.config/dotnet-tools.json` lists `dotnet-ef` 3.1.0. No `DbContext`, no migrations. | Unused by the code that is here. |
| Learner pages folder | `ClickPortal.csproj` includes empty `ClientApp/src/pages/learner/`. | No page component. |
| Commented learner routes | `App.js` comments mention `/learnerlogin` and `/learner/login`. | Not registered on the router. |
| Nav menu | `NavMenu.js` is commented out and still links to Counter and Fetch data. `Layout.js` does not render it. | Template residue, not a screen. |
| Service worker | `index.js` calls `unregister()`. `register()` is commented out. | Not registered. |
| `oidc-client` dependency | Listed in `package.json`. No import under `src`. | Unused by this source. |
| Programme images | `public/images/covid19/` holds careup, covid-19, feed-the-monster, and reading-eggs images. No `src` or HTML reference to those file names. | Assets only. |
| Library Manager | `libman.json` has an empty library list. | No client libraries from LibMan. |
| Release transform | `web.release.config` is an empty XDT document. | No release transform. |

## Planned

No issue list, TODO file, or roadmap was found. Commented blocks show work that was started or removed. They are not labelled as a plan. Treat them as **Unknown / Requires Confirmation**, not as committed scope.

## Completed

The only commit is the initial commit, so every file above arrived together. There is no earlier completed slice in git.

## Deprecated / removed

Git does not show a deletion after the initial commit. The commented username/password path and the commented learner routes are the closest evidence of something taken off the live path. Whether they ever shipped is **Unknown**.

## Not in this repository

- A learner login screen.
- Stored-procedure bodies and table schemas.
- Sonar files (`sonar-project.properties`, `sonarqube_scan.bat`) named by the onboarding scan. They are not in `0e2adfb`.
- CI, Docker, or a deploy script.
